diff --git a/.github/workflows/deploy-docusaurus.yml b/.github/workflows/deploy-docusaurus.yml new file mode 100644 index 00000000000..db1745a9f28 --- /dev/null +++ b/.github/workflows/deploy-docusaurus.yml @@ -0,0 +1,79 @@ +# .github/workflows/deploy-docusaurus.yml +# This workflow deploys the Blockly documentation to GitHub Pages. +# Run this manually after a release to publish updated documentation. + +name: Deploy Docusaurus to GitHub Pages + +on: + # To run: GitHub -> Actions -> "Deploy Docusaurus to GitHub Pages" -> Run workflow + # Optionally set `ref` to the release branch/tag + workflow_dispatch: + inputs: + ref: + description: 'Branch, tag, or commit SHA to deploy (defaults to main)' + required: false + default: 'main' + type: string + +# Sets the permissions for the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued +# However, do not cancel in-progress runs as we want to allow these production deployments to complete +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout your repository + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref || 'main' }} + # Allow Docusaurus to view the full commit history (required for "last edited at by " functionality) + fetch-depth: 0 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'npm' + cache-dependency-path: 'package-lock.json' # root level, since we're using npm workspaces + + - name: Install dependencies + run: npm ci + + - name: Generate reference docs + working-directory: ./packages/blockly + run: | + npx gulp typings + npm run docs + + - name: Build the Docusaurus site + working-directory: ./packages/docs + run: npm run build + env: + # when deploying to a subdirectory of the .github.io domain, + # we need to set the BASE_URL to the name of the repo, for a custom + # domain this could be /docs/ + BASE_URL: /blockly/ + + - name: Setup GitHub Pages + uses: actions/configure-pages@v5 + + - name: Upload build artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./packages/docs/build + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/package-lock.json b/package-lock.json index 9952e738908..e5e9a4c6a24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,264 +12,20908 @@ "packages/*" ] }, + "node_modules/@algolia/abtesting": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.13.0.tgz", + "integrity": "sha512-Zrqam12iorp3FjiKMXSTpedGYznZ3hTEOAr2oCxI8tbF8bS1kQHClyDYNq/eV0ewMNLyFkgZVWjaS+8spsOYiQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.47.0.tgz", + "integrity": "sha512-aOpsdlgS9xTEvz47+nXmw8m0NtUiQbvGWNuSEb7fA46iPL5FxOmOUZkh8PREBJpZ0/H8fclSc7BMJCVr+Dn72w==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.47.0.tgz", + "integrity": "sha512-EcF4w7IvIk1sowrO7Pdy4Ako7x/S8+nuCgdk6En+u5jsaNQM4rTT09zjBPA+WQphXkA2mLrsMwge96rf6i7Mow==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.47.0.tgz", + "integrity": "sha512-Wzg5Me2FqgRDj0lFuPWFK05UOWccSMsIBL2YqmTmaOzxVlLZ+oUqvKbsUSOE5ud8Fo1JU7JyiLmEXBtgDKzTwg==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.47.0.tgz", + "integrity": "sha512-Ci+cn/FDIsDxSKMRBEiyKrqybblbk8xugo6ujDN1GSTv9RIZxwxqZYuHfdLnLEwLlX7GB8pqVyqrUSlRnR+sJA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.47.0.tgz", + "integrity": "sha512-gsLnHPZmWcX0T3IigkDL2imCNtsQ7dR5xfnwiFsb+uTHCuYQt+IwSNjsd8tok6HLGLzZrliSaXtB5mfGBtYZvQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.47.0.tgz", + "integrity": "sha512-PDOw0s8WSlR2fWFjPQldEpmm/gAoUgLigvC3k/jCSi/DzigdGX6RdC0Gh1RR1P8Cbk5KOWYDuL3TNzdYwkfDyA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.47.0.tgz", + "integrity": "sha512-b5hlU69CuhnS2Rqgsz7uSW0t4VqrLMLTPbUpEl0QVz56rsSwr1Sugyogrjb493sWDA+XU1FU5m9eB8uH7MoI0g==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", + "license": "MIT" + }, + "node_modules/@algolia/ingestion": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.47.0.tgz", + "integrity": "sha512-WvwwXp5+LqIGISK3zHRApLT1xkuEk320/EGeD7uYy+K8WwDd5OjXnhjuXRhYr1685KnkvWkq1rQ/ihCJjOfHpQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.47.0.tgz", + "integrity": "sha512-j2EUFKAlzM0TE4GRfkDE3IDfkVeJdcbBANWzK16Tb3RHz87WuDfQ9oeEW6XiRE1/bEkq2xf4MvZesvSeQrZRDA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.47.0.tgz", + "integrity": "sha512-+kTSE4aQ1ARj2feXyN+DMq0CIDHJwZw1kpxIunedkmpWUg8k3TzFwWsMCzJVkF2nu1UcFbl7xsIURz3Q3XwOXA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.47.0.tgz", + "integrity": "sha512-Ja+zPoeSA2SDowPwCNRbm5Q2mzDvVV8oqxCQ4m6SNmbKmPlCfe30zPfrt9ho3kBHnsg37pGucwOedRIOIklCHw==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.47.0.tgz", + "integrity": "sha512-N6nOvLbaR4Ge+oVm7T4W/ea1PqcSbsHR4O58FJ31XtZjFPtOyxmnhgCmGCzP9hsJI6+x0yxJjkW5BMK/XI8OvA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.47.0.tgz", + "integrity": "sha512-z1oyLq5/UVkohVXNDEY70mJbT/sv/t6HYtCvCwNrOri6pxBJDomP9R83KOlwcat+xqBQEdJHjbrPh36f1avmZA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", + "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", + "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", + "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", + "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", + "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", + "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.6.tgz", + "integrity": "sha512-9knsChgsMzBV5Yh3kkhrZNxH3oCYAfMBkNNaVN4cP2RVlFPe8wYdwwcnOsAbkdDoV9UjFtOXWrWB52M8W4jNeA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", + "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.28.6.tgz", + "integrity": "sha512-5suVoXjC14lUN6ZL9OLKIHCNVWCrqGqlmEp/ixdXjvgnEl/kauLvvMO/Xw9NyMc95Joj1AeLVPVMvibBgSoFlA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", + "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz", + "integrity": "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", + "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.28.6.tgz", + "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-syntax-jsx": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", + "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", + "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.6.tgz", + "integrity": "sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", + "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz", + "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.6.tgz", + "integrity": "sha512-GaTI4nXDrs7l0qaJ6Rg06dtOXTBCG6TMDB44zbqofCIC4PqC7SEvmFFtpxzCDw9W5aJ7RKVshgXTLvLdBFV/qw==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.28.6", + "@babel/plugin-syntax-import-attributes": "^7.28.6", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.6", + "@babel/plugin-transform-async-to-generator": "^7.28.6", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.6", + "@babel/plugin-transform-class-properties": "^7.28.6", + "@babel/plugin-transform-class-static-block": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-computed-properties": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-dotall-regex": "^7.28.6", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.28.6", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.6", + "@babel/plugin-transform-exponentiation-operator": "^7.28.6", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.28.6", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.28.6", + "@babel/plugin-transform-modules-systemjs": "^7.28.5", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", + "@babel/plugin-transform-numeric-separator": "^7.28.6", + "@babel/plugin-transform-object-rest-spread": "^7.28.6", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.28.6", + "@babel/plugin-transform-optional-chaining": "^7.28.6", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.6", + "@babel/plugin-transform-regexp-modifiers": "^7.28.6", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.28.6", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.28.6", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", + "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-transform-react-display-name": "^7.28.0", + "@babel/plugin-transform-react-jsx": "^7.27.1", + "@babel/plugin-transform-react-jsx-development": "^7.27.1", + "@babel/plugin-transform-react-pure-annotations": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", + "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.6.tgz", + "integrity": "sha512-kz2fAQ5UzjV7X7D3ySxmj3vRq89dTpqOZWv76Z6pNPztkwb/0Yj1Mtx1xFrYj6mbIHysxtBot8J4o0JLCblcFw==", + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.43.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", + "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", + "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@csstools/cascade-layer-name-parser": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz", + "integrity": "sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/postcss-alpha-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-alpha-function/-/postcss-alpha-function-1.0.1.tgz", + "integrity": "sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.2.tgz", + "integrity": "sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.12.tgz", + "integrity": "sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-function-display-p3-linear": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function-display-p3-linear/-/postcss-color-function-display-p3-linear-1.0.1.tgz", + "integrity": "sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-function": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.12.tgz", + "integrity": "sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.2.tgz", + "integrity": "sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-content-alt-text": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.8.tgz", + "integrity": "sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-contrast-color-function": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-contrast-color-function/-/postcss-contrast-color-function-2.0.12.tgz", + "integrity": "sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-exponential-functions": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz", + "integrity": "sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", + "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gamut-mapping": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.11.tgz", + "integrity": "sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gradients-interpolation-method": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.12.tgz", + "integrity": "sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.12.tgz", + "integrity": "sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.4.tgz", + "integrity": "sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-initial": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.1.tgz", + "integrity": "sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz", + "integrity": "sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-light-dark-function": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.11.tgz", + "integrity": "sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-float-and-clear": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz", + "integrity": "sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overflow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz", + "integrity": "sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overscroll-behavior": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz", + "integrity": "sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-resize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz", + "integrity": "sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-viewport-units": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.4.tgz", + "integrity": "sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-minmax": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.9.tgz", + "integrity": "sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.5.tgz", + "integrity": "sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz", + "integrity": "sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.1.tgz", + "integrity": "sha512-TQUGBuRvxdc7TgNSTevYqrL8oItxiwPDixk20qCB5me/W8uF7BPbhRrAvFuhEoywQp/woRsUZ6SJ+sU5idZAIA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.12.tgz", + "integrity": "sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-position-area-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-position-area-property/-/postcss-position-area-property-1.0.0.tgz", + "integrity": "sha512-fUP6KR8qV2NuUZV3Cw8itx0Ep90aRjAZxAEzC3vrl6yjFv+pFsQbR18UuQctEKmA72K9O27CoYiKEgXxkqjg8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.2.1.tgz", + "integrity": "sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-property-rule-prelude-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-property-rule-prelude-list/-/postcss-property-rule-prelude-list-1.0.0.tgz", + "integrity": "sha512-IxuQjUXq19fobgmSSvUDO7fVwijDJaZMvWQugxfEUxmjBeDCVaDuMpsZ31MsTm5xbnhA+ElDi0+rQ7sQQGisFA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-random-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-2.0.1.tgz", + "integrity": "sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-relative-color-syntax": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.12.tgz", + "integrity": "sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz", + "integrity": "sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-sign-functions": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.4.tgz", + "integrity": "sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.9.tgz", + "integrity": "sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-syntax-descriptor-syntax-production": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-syntax-descriptor-syntax-production/-/postcss-syntax-descriptor-syntax-production-1.0.1.tgz", + "integrity": "sha512-GneqQWefjM//f4hJ/Kbox0C6f2T7+pi4/fqTqOFGTL3EjnvOReTqO1qUQ30CaUjkwjYq9qZ41hzarrAxCc4gow==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-system-ui-font-family": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-system-ui-font-family/-/postcss-system-ui-font-family-1.0.0.tgz", + "integrity": "sha512-s3xdBvfWYfoPSBsikDXbuorcMG1nN1M6GdU0qBsGfcmNR0A/qhloQZpTxjA3Xsyrk1VJvwb2pOfiOT3at/DuIQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.3.tgz", + "integrity": "sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.9.tgz", + "integrity": "sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz", + "integrity": "sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/selector-resolve-nested": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz", + "integrity": "sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/utilities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-2.0.0.tgz", + "integrity": "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docsearch/core": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.5.2.tgz", + "integrity": "sha512-0omQR/KF89HoZ28Mcz7Q7yJaL1Nc4eDZGI7Pbe1kJXlxL8daRSTt04YKYqu2Rg9Y8IeBwRL267ISTO7YzOH+HA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": ">= 16.8.0 < 20.0.0", + "react": ">= 16.8.0 < 20.0.0", + "react-dom": ">= 16.8.0 < 20.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@docsearch/css": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.5.0.tgz", + "integrity": "sha512-RgGlYf1WsYf3bmZ1Zmc7YzthUwmnYhtQgdLWp5A7xIs6KwwAxDPkmxYbLW/uYIv/8/Dq/pU3azNzKP6/fSjQfQ==", + "license": "MIT" + }, + "node_modules/@docsearch/react": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.5.0.tgz", + "integrity": "sha512-Fwd9TRwkdJ3V+kPesB1pR+hiNRCQi11ZR2lu58t8MF1jybx3gwaHEHmz6f5MdeHmJoNkCLvyYb+QZ7RPv7JQRA==", + "license": "MIT", + "dependencies": { + "@docsearch/css": "4.5.0" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 20.0.0", + "react": ">= 16.8.0 < 20.0.0", + "react-dom": ">= 16.8.0 < 20.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@docusaurus/babel": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.9.2.tgz", + "integrity": "sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.25.9", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.25.9", + "@babel/runtime": "^7.25.9", + "@babel/runtime-corejs3": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "babel-plugin-dynamic-import-node": "^2.3.3", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/bundler": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.9.2.tgz", + "integrity": "sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@docusaurus/babel": "3.9.2", + "@docusaurus/cssnano-preset": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "babel-loader": "^9.2.1", + "clean-css": "^5.3.3", + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.11.0", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "file-loader": "^6.2.0", + "html-minifier-terser": "^7.2.0", + "mini-css-extract-plugin": "^2.9.2", + "null-loader": "^4.0.1", + "postcss": "^8.5.4", + "postcss-loader": "^7.3.4", + "postcss-preset-env": "^10.2.1", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "webpack": "^5.95.0", + "webpackbar": "^6.0.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/faster": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.9.2.tgz", + "integrity": "sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==", + "license": "MIT", + "dependencies": { + "@docusaurus/babel": "3.9.2", + "@docusaurus/bundler": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "core-js": "^3.31.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "execa": "5.1.1", + "fs-extra": "^11.1.1", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.6.0", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "open": "^8.4.0", + "p-map": "^4.0.0", + "prompts": "^2.4.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.6", + "tinypool": "^1.0.2", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "webpack": "^5.95.0", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-dev-server": "^5.2.2", + "webpack-merge": "^6.0.1" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/core/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@docusaurus/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@docusaurus/core/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.9.2.tgz", + "integrity": "sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ==", + "license": "MIT", + "dependencies": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.5.4", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/logger": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.9.2.tgz", + "integrity": "sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/logger/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@docusaurus/logger/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@docusaurus/logger/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.9.2.tgz", + "integrity": "sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^2.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/mdx-loader/node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@docusaurus/mdx-loader/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/@docusaurus/mdx-loader/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/@docusaurus/mdx-loader/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/@docusaurus/mdx-loader/node_modules/remark-directive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", + "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.9.2.tgz", + "integrity": "sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew==", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.9.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-client-redirects": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.9.2.tgz", + "integrity": "sha512-lUgMArI9vyOYMzLRBUILcg9vcPTCyyI2aiuXq/4npcMVqOr6GfmwtmBYWSbNMlIUM0147smm4WhpXD0KFboffw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.9.2.tgz", + "integrity": "sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "cheerio": "1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "schema-dts": "^1.1.2", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz", + "integrity": "sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "schema-dts": "^1.1.2", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-pages": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.9.2.tgz", + "integrity": "sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-css-cascade-layers": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.9.2.tgz", + "integrity": "sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-debug": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.9.2.tgz", + "integrity": "sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^2.3.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.9.2.tgz", + "integrity": "sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.9.2.tgz", + "integrity": "sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.9.2.tgz", + "integrity": "sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.9.2.tgz", + "integrity": "sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-svgr": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.9.2.tgz", + "integrity": "sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@svgr/core": "8.1.0", + "@svgr/webpack": "^8.1.0", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/preset-classic": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.9.2.tgz", + "integrity": "sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/plugin-content-blog": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/plugin-content-pages": "3.9.2", + "@docusaurus/plugin-css-cascade-layers": "3.9.2", + "@docusaurus/plugin-debug": "3.9.2", + "@docusaurus/plugin-google-analytics": "3.9.2", + "@docusaurus/plugin-google-gtag": "3.9.2", + "@docusaurus/plugin-google-tag-manager": "3.9.2", + "@docusaurus/plugin-sitemap": "3.9.2", + "@docusaurus/plugin-svgr": "3.9.2", + "@docusaurus/theme-classic": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-search-algolia": "3.9.2", + "@docusaurus/types": "3.9.2" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-classic": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.9.2.tgz", + "integrity": "sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/plugin-content-blog": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/plugin-content-pages": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-translations": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "infima": "0.2.0-alpha.45", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.5.4", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-common": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.9.2.tgz", + "integrity": "sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==", + "license": "MIT", + "dependencies": { + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz", + "integrity": "sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw==", + "license": "MIT", + "dependencies": { + "@docsearch/react": "^3.9.0 || ^4.1.0", + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-translations": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "algoliasearch": "^5.37.0", + "algoliasearch-helper": "^3.26.0", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-translations": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.9.2.tgz", + "integrity": "sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==", + "license": "MIT", + "dependencies": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/types": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.9.2.tgz", + "integrity": "sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q==", + "license": "MIT", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/mdast": "^4.0.2", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.95.0", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/types/node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docusaurus/utils": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.9.2.tgz", + "integrity": "sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "escape-string-regexp": "^4.0.0", + "execa": "5.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "p-queue": "^6.6.2", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/utils-common": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.9.2.tgz", + "integrity": "sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw==", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/utils-validation": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.9.2.tgz", + "integrity": "sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.3", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.3.tgz", + "integrity": "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.3", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.3.tgz", + "integrity": "sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.1.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.1.tgz", + "integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.3.tgz", + "integrity": "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", + "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.1.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@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==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/buffers": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.65.0.tgz", + "integrity": "sha512-eBrIXd0/Ld3p9lpDDlMaMn6IEfWqtHMD+z61u0JrIiPzsV1r7m6xDZFRxJyvIFTEO+SWdYF9EiQbXZGd8BzPfA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.56.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.56.4.tgz", + "integrity": "sha512-mgiAa7w0N0mlr7G3PUY/iRSYuJwyZmHBt+y7D9veiXfAqsIhEi9+FCu47tU+y/3KPqaTNJMsfgAGwUnLPnRdqA==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.56.4", + "@jsonjoy.com/fs-node-utils": "4.56.4", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.56.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.56.4.tgz", + "integrity": "sha512-D6tHSr8xMiZnV9pQcX0ysoEg1kTsTFK6fRV+TX+1uFcEiNKJR7hooGBq8iKnkZCXRxY8S4nZJ+rErpVF1XJ4vw==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.56.4", + "@jsonjoy.com/fs-node-builtins": "4.56.4", + "@jsonjoy.com/fs-node-utils": "4.56.4", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.56.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.56.4.tgz", + "integrity": "sha512-4G7KBypcWy2BGPnuDCmUQWHasbNZnEqcb3DLODuH22J8fre7YK8MiyciIohkUTFMqR9qem84LK22T1FmUwiTSQ==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.56.4", + "@jsonjoy.com/fs-node-builtins": "4.56.4", + "@jsonjoy.com/fs-node-utils": "4.56.4", + "@jsonjoy.com/fs-print": "4.56.4", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.56.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.56.4.tgz", + "integrity": "sha512-/HMj267Ygg/fa3kHuZL+L7rVXvZ7HT2Bm7d8CpKs6l7QpT4mzTnN4f2/E0u+LsrrJVbT+R34/nsBr2dIZSYIgg==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.56.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.56.4.tgz", + "integrity": "sha512-Wewg2JlMkFpUt2Z+RrhdxLrbG6o4XAZB9UdGbpcQS+acvwytmhEjUCCodD3kqY5wPSNpnIbD614VeTA/5jPzvg==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.56.4", + "@jsonjoy.com/fs-node-builtins": "4.56.4", + "@jsonjoy.com/fs-node-utils": "4.56.4" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.56.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.56.4.tgz", + "integrity": "sha512-7yvPBX+YUPvoljJ5ELmHrK7sLYzEVdLnILoNXLtsztN4Ag8UbS7DteWRiW3BFAUIvI4kDBJ8OymdxwLLCkX+AQ==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.56.4" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.56.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.56.4.tgz", + "integrity": "sha512-GtTDri9Ot1l7XPe3ft+ViTqxFOqtKcM4RLyXEXWDvQEoqgmU/6bCNNjfSze9VlpfC8KfuUYAixuDLD1quzHdow==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.56.4", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.56.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.56.4.tgz", + "integrity": "sha512-qQxl+GVp9gzT21/Ot8qa+pcNurpfTL/ruMODYmshpcTLXy6x06aP4/xdhBOJpBclhqbnQcMTVDCny98CtGvyzQ==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.56.4", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.65.0.tgz", + "integrity": "sha512-Xrh7Fm/M0QAYpekSgmskdZYnFdSGnsxJ/tHaolA4bNwWdG9i65S8m83Meh7FOxyJyQAdo4d4J97NOomBLEfkDQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.65.0.tgz", + "integrity": "sha512-7MXcRYe7n3BG+fo3jicvjB0+6ypl2Y/bQp79Sp7KeSiiCgLqw4Oled6chVv07/xLVTdo3qa1CD0VCCnPaw+RGA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.65.0.tgz", + "integrity": "sha512-e0SG/6qUCnVhHa0rjDJHgnXnbsacooHVqQHxspjvlYQSkHm+66wkHw6Gql+3u/WxI/b1VsOdUi0M+fOtkgKGdQ==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.65.0", + "@jsonjoy.com/buffers": "17.65.0", + "@jsonjoy.com/codegen": "17.65.0", + "@jsonjoy.com/json-pointer": "17.65.0", + "@jsonjoy.com/util": "17.65.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.65.0.tgz", + "integrity": "sha512-uhTe+XhlIZpWOxgPcnO+iSCDgKKBpwkDVTyYiXX9VayGV8HSFVJM67M6pUE71zdnXF1W0Da21AvnhlmdwYPpow==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/util": "17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.65.0.tgz", + "integrity": "sha512-cWiEHZccQORf96q2y6zU3wDeIVPeidmGqd9cNKJRYoVHTV0S1eHPy5JTbHpMnGfDvtvujQwQozOqgO9ABu6h0w==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "17.65.0", + "@jsonjoy.com/codegen": "17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "license": "MIT" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/config": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-8.3.4.tgz", + "integrity": "sha512-01rtHedemDNhUXdicU7s+QYz/3JyV5Naj84cvdXGH4mgCdL+agmSYaLF4LUG4vMCLzhBO8YtS0gPpH1FGvbgAw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/package-json": "^5.1.1", + "ci-info": "^4.0.0", + "ini": "^4.1.2", + "nopt": "^7.2.1", + "proc-log": "^4.2.0", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/config/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/@npmcli/config/node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", + "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/map-workspaces": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz", + "integrity": "sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz", + "integrity": "sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz", + "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", + "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@peculiar/asn1-cms": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.0.tgz", + "integrity": "sha512-2uZqP+ggSncESeUF/9Su8rWqGclEfEiz1SyU02WX5fUONFfkjzS2Z/F1Li0ofSmf4JqYXIOdCAZqIXAIBAT1OA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "@peculiar/asn1-x509-attr": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-csr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.0.tgz", + "integrity": "sha512-BeWIu5VpTIhfRysfEp73SGbwjjoLL/JWXhJ/9mo4vXnz3tRGm+NGm3KNcRzQ9VMVqwYS2RHlolz21svzRXIHPQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-ecc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.0.tgz", + "integrity": "sha512-FF3LMGq6SfAOwUG2sKpPXblibn6XnEIKa+SryvUl5Pik+WR9rmRA3OCiwz8R3lVXnYnyRkSZsSLdml8H3UiOcw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pfx": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.0.tgz", + "integrity": "sha512-rtUvtf+tyKGgokHHmZzeUojRZJYPxoD/jaN1+VAB4kKR7tXrnDCA/RAWXAIhMJJC+7W27IIRGe9djvxKgsldCQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-pkcs8": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.0.tgz", + "integrity": "sha512-KyQ4D8G/NrS7Fw3XCJrngxmjwO/3htnA0lL9gDICvEQ+GJ+EPFqldcJQTwPIdvx98Tua+WjkdKHSC0/Km7T+lA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.0.tgz", + "integrity": "sha512-b78OQ6OciW0aqZxdzliXGYHASeCvvw5caqidbpQRYW2mBtXIX2WhofNXTEe7NyxTb0P6J62kAAWLwn0HuMF1Fw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-pfx": "^2.6.0", + "@peculiar/asn1-pkcs8": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "@peculiar/asn1-x509-attr": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-rsa": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.0.tgz", + "integrity": "sha512-Nu4C19tsrTsCp9fDrH+sdcOKoVfdfoQQ7S3VqjJU6vedR7tY3RLkQ5oguOIB3zFW33USDUuYZnPEQYySlgha4w==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz", + "integrity": "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==", + "license": "MIT", + "dependencies": { + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.0.tgz", + "integrity": "sha512-uzYbPEpoQiBoTq0/+jZtpM6Gq6zADBx+JNFP3yqRgziWBxQ/Dt/HcuvRfm9zJTPdRcBqPNdaRHTVwpyiq6iNMA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.0.tgz", + "integrity": "sha512-MuIAXFX3/dc8gmoZBkwJWxUWOSvG4MMDntXhrOZpJVMkYX+MYc/rUAU2uJOved9iJEoiUx7//3D8oG83a78UJA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", + "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-csr": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.0", + "@peculiar/asn1-pkcs9": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-3.0.2.tgz", + "integrity": "sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==", + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "license": "MIT" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/concat-stream": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-2.0.3.tgz", + "integrity": "sha512-3qe4oQAPNwVNwK4C9c8u+VJqv9kez+2MR4qJpoPFfXtgxxif1QbFusvXzK0/Wra2VX07smostI2VMmJNSpZjuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "^1" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.8", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", + "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==", + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "license": "MIT" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "license": "MIT" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.17", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz", + "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/is-empty": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/is-empty/-/is-empty-1.2.3.tgz", + "integrity": "sha512-4J1l5d79hoIvsrKh5VUKVRA1aIdsOb10Hu5j3J2VfP/msDnfTdGPmNp2E1Wg+vs97Bktzo+MZePFFXSGoykYJw==", + "dev": true, + "license": "MIT" + }, + "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==", + "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==", + "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==", + "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", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.0.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.9.tgz", + "integrity": "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/prismjs": { + "version": "1.26.5", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", + "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.9.tgz", + "integrity": "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==", + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", + "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "license": "MIT" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/supports-color": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.3.tgz", + "integrity": "sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "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==", + "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==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "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/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.47.0.tgz", + "integrity": "sha512-AGtz2U7zOV4DlsuYV84tLp2tBbA7RPtLA44jbVH4TTpDcc1dIWmULjHSsunlhscbzDydnjuFlNhflR3nV4VJaQ==", + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.13.0", + "@algolia/client-abtesting": "5.47.0", + "@algolia/client-analytics": "5.47.0", + "@algolia/client-common": "5.47.0", + "@algolia/client-insights": "5.47.0", + "@algolia/client-personalization": "5.47.0", + "@algolia/client-query-suggestions": "5.47.0", + "@algolia/client-search": "5.47.0", + "@algolia/ingestion": "1.47.0", + "@algolia/monitoring": "1.47.0", + "@algolia/recommend": "5.47.0", + "@algolia/requester-browser-xhr": "5.47.0", + "@algolia/requester-fetch": "5.47.0", + "@algolia/requester-node-http": "5.47.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.27.0.tgz", + "integrity": "sha512-eNYchRerbsvk2doHOMfdS1/B6Tm70oGtu8mzQlrNzbCeQ8p1MjCW8t/BL6iZ5PD+cL5NNMgTMyMnmiXZ1sgmNw==", + "license": "MIT", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1js": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.7.tgz", + "integrity": "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==", + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.23", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", + "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1", + "caniuse-lite": "^1.0.30001760", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/b4a": { "version": "1.7.3", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", - "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", "dev": true, - "license": "Apache-2.0", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "license": "MIT", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "license": "MIT", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.8.2", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.16", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.16.tgz", + "integrity": "sha512-KeUZdBuxngy825i8xvzaK1Ncnkx0tBmb3k8DkEuqjKRkmtvNTjey2ZsNeh8Dw4lfKvbCOu9oeNx2TKm2vHqcRw==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "license": "MIT" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blockly": { + "resolved": "packages/blockly", + "link": true + }, + "node_modules/blockly-docs": { + "resolved": "packages/docs", + "link": true + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", + "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/boxen/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bytestreamjs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz", + "integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "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.30001765", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001765.tgz", + "integrity": "sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "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==", + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" + }, + "node_modules/combine-promises": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "license": "ISC" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compressible/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "license": "MIT" + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", + "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", + "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.47.0.tgz", + "integrity": "sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-blank-pseudo": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz", + "integrity": "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.3.1.tgz", + "integrity": "sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA==", + "license": "ISC", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-has-pseudo": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.3.tgz", + "integrity": "sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz", + "integrity": "sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssdb": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.7.0.tgz", + "integrity": "sha512-UxiWVpV953ENHqAKjKRPZHNDfRo3uOymvO5Ef7MFCWlenaohkYj7PTO7WCBdjZm8z/aDZd6rXyUIlwZ0AjyFSg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ], + "license": "MIT-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==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", + "license": "MIT", + "dependencies": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "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==", + "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==", + "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/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.4.0.tgz", + "integrity": "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT" + }, + "node_modules/detect-port": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", + "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", + "license": "MIT", + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "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==", + "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==", + "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==", + "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==", + "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/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "license": "ISC" + }, + "node_modules/email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/emoticon": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", + "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "license": "MIT", + "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==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.1.0.tgz", + "integrity": "sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.3", + "@eslint/config-helpers": "^0.5.3", + "@eslint/core": "^1.1.1", + "@eslint/plugin-kit": "^0.6.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-mdx": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-mdx/-/eslint-mdx-3.7.0.tgz", + "integrity": "sha512-QpPdJ6EeFthHuIrfgnWneZgwwFNOLFj/nf2jg/tOTBoiUnqNTxUUpTGAn0ZFHYEh5htVVoe5kjvD02oKtxZGeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "espree": "^9.6.1 || ^10.4.0", + "estree-util-visit": "^2.0.0", + "remark-mdx": "^3.1.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "synckit": "^0.11.8", + "unified": "^11.0.5", + "unified-engine": "^11.2.2", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.3" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "eslint": ">=8.0.0", + "remark-lint-file-extension": "*" + }, + "peerDependenciesMeta": { + "remark-lint-file-extension": { + "optional": true + } + } + }, + "node_modules/eslint-mdx/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-mdx/node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-mdx": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mdx/-/eslint-plugin-mdx-3.7.0.tgz", + "integrity": "sha512-JXaaQPnKqyti/QSOSQDThLV1EemHm/Fe2l/nMKH0vmhvmABtN/yV/9+GtKgh8UTZwrwuTfQq1HW5eR8HXneNLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-mdx": "^3.7.0", + "mdast-util-from-markdown": "^2.0.2", + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0", + "remark-mdx": "^3.1.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "synckit": "^0.11.8", + "unified": "^11.0.5", + "vfile": "^6.0.3" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "eslint": ">=8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.5.0.tgz", + "integrity": "sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/express/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "license": "MIT", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "license": "MIT", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "license": "MIT", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", + "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "license": "ISC" + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gh-pages": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.3.0.tgz", + "integrity": "sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^3.2.4", + "commander": "^13.0.0", + "email-addresses": "^5.0.0", + "filenamify": "^4.3.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^11.1.1", + "globby": "^11.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gh-pages/node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/gh-pages/node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/gh-pages/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gh-pages/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gh-pages/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gh-pages/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gh-pages/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/gh-pages/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, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", + "license": "ISC" + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/google-closure-compiler": { + "version": "20260114.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "chalk": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 <5.6.1 || ^5.6.2 >5.6.1", + "google-closure-compiler-java": "^20260114.0.0", + "minimist": "^1.0.0", + "vinyl": "^3.0.1", + "vinyl-sourcemaps-apply": "^0.2.0" + }, + "bin": { + "google-closure-compiler": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "google-closure-compiler-linux": "^20260114.0.0", + "google-closure-compiler-linux-arm64": "^20260114.0.0", + "google-closure-compiler-macos": "^20260114.0.0", + "google-closure-compiler-windows": "^20260114.0.0" + } + }, + "node_modules/google-closure-compiler-java": { + "version": "20260114.0.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/google-closure-compiler-macos": { + "version": "20260114.0.0", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "license": "MIT" + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.6", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.6.tgz", + "integrity": "sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw==", + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", + "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", + "license": "MIT", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infima": { + "version": "0.2.0-alpha.45", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz", + "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", + "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-empty": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", + "integrity": "sha512-F2FnH/otLNJv0J6wc73A5Xo7oHLNnqplYqZhUu01tD54DIPvxIRSTSLkrUB/M0nHO4vo1O9PDfN4KoTxCzLh/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "license": "MIT", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz", + "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.1.0.tgz", + "integrity": "sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "license": "MIT", + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launch-editor": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.12.0.tgz", + "integrity": "sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.3" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.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==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/load-plugin": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-6.0.3.tgz", + "integrity": "sha512-kc0X2FEUZr145odl68frm+lMJuQ23+rTXYmR6TImqPtbpmXC4vVXbWKDQ9IzndA0HfyQamWfKLhzsqGSTxE63w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@npmcli/config": "^8.0.0", + "import-meta-resolve": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "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==", + "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==", + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", + "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.56.4", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.56.4.tgz", + "integrity": "sha512-GKqmHEFyFwccco9NmTEY38AemzpNLs5tKKxGfNpnLI/5D92NAr7STItdzTMeUlKdd3FjkE5w18TPLyKTb6MDVA==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.56.4", + "@jsonjoy.com/fs-fsa": "4.56.4", + "@jsonjoy.com/fs-node": "4.56.4", + "@jsonjoy.com/fs-node-builtins": "4.56.4", + "@jsonjoy.com/fs-node-to-fsa": "4.56.4", + "@jsonjoy.com/fs-node-utils": "4.56.4", + "@jsonjoy.com/fs-print": "4.56.4", + "@jsonjoy.com/fs-snapshot": "^4.56.4", + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", + "tslib": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-directive": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", + "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "license": "MIT", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "license": "MIT", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.0.tgz", + "integrity": "sha512-540P2c5dYnJlyJxTaSloliZexv8rji6rY8FhQN+WF/82iHQfA23j/xtJx97L+mXOML27EqksSek/g4eK7jaL3g==", + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "license": "MIT" + }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", + "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz", + "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", + "license": "MIT" + }, + "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==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/null-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", + "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/null-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/null-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/null-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/null-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "license": "MIT", + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", + "license": "ISC" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "license": "(WTFPL OR MIT)" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkijs": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.3.3.tgz", + "integrity": "sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw==", + "license": "BSD-3-Clause", + "dependencies": { + "@noble/hashes": "1.4.0", + "asn1js": "^3.0.6", + "bytestreamjs": "^2.0.1", + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz", + "integrity": "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.12.tgz", + "integrity": "sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz", + "integrity": "sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz", + "integrity": "sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-custom-media": { + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.6.tgz", + "integrity": "sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-properties": { + "version": "14.0.6", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.6.tgz", + "integrity": "sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.5.tgz", + "integrity": "sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz", + "integrity": "sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.4.tgz", + "integrity": "sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz", + "integrity": "sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-focus-within": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz", + "integrity": "sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz", + "integrity": "sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-image-set-function": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz", + "integrity": "sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-lab-function": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.12.tgz", + "integrity": "sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", + "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-logical": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.1.0.tgz", + "integrity": "sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-merge-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "license": "MIT", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nesting": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz", + "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-resolve-nested": "^3.1.0", + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz", + "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz", + "integrity": "sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-10.0.0.tgz", + "integrity": "sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-preset-env": { + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.6.1.tgz", + "integrity": "sha512-yrk74d9EvY+W7+lO9Aj1QmjWY9q5NsKjK2V9drkOPZB/X6KZ0B3igKsHUYakb7oYVhnioWypQX3xGuePf89f3g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-alpha-function": "^1.0.1", + "@csstools/postcss-cascade-layers": "^5.0.2", + "@csstools/postcss-color-function": "^4.0.12", + "@csstools/postcss-color-function-display-p3-linear": "^1.0.1", + "@csstools/postcss-color-mix-function": "^3.0.12", + "@csstools/postcss-color-mix-variadic-function-arguments": "^1.0.2", + "@csstools/postcss-content-alt-text": "^2.0.8", + "@csstools/postcss-contrast-color-function": "^2.0.12", + "@csstools/postcss-exponential-functions": "^2.0.9", + "@csstools/postcss-font-format-keywords": "^4.0.0", + "@csstools/postcss-gamut-mapping": "^2.0.11", + "@csstools/postcss-gradients-interpolation-method": "^5.0.12", + "@csstools/postcss-hwb-function": "^4.0.12", + "@csstools/postcss-ic-unit": "^4.0.4", + "@csstools/postcss-initial": "^2.0.1", + "@csstools/postcss-is-pseudo-class": "^5.0.3", + "@csstools/postcss-light-dark-function": "^2.0.11", + "@csstools/postcss-logical-float-and-clear": "^3.0.0", + "@csstools/postcss-logical-overflow": "^2.0.0", + "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", + "@csstools/postcss-logical-resize": "^3.0.0", + "@csstools/postcss-logical-viewport-units": "^3.0.4", + "@csstools/postcss-media-minmax": "^2.0.9", + "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.5", + "@csstools/postcss-nested-calc": "^4.0.0", + "@csstools/postcss-normalize-display-values": "^4.0.1", + "@csstools/postcss-oklab-function": "^4.0.12", + "@csstools/postcss-position-area-property": "^1.0.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/postcss-property-rule-prelude-list": "^1.0.0", + "@csstools/postcss-random-function": "^2.0.1", + "@csstools/postcss-relative-color-syntax": "^3.0.12", + "@csstools/postcss-scope-pseudo-class": "^4.0.1", + "@csstools/postcss-sign-functions": "^1.1.4", + "@csstools/postcss-stepped-value-functions": "^4.0.9", + "@csstools/postcss-syntax-descriptor-syntax-production": "^1.0.1", + "@csstools/postcss-system-ui-font-family": "^1.0.0", + "@csstools/postcss-text-decoration-shorthand": "^4.0.3", + "@csstools/postcss-trigonometric-functions": "^4.0.9", + "@csstools/postcss-unset-value": "^4.0.0", + "autoprefixer": "^10.4.23", + "browserslist": "^4.28.1", + "css-blank-pseudo": "^7.0.1", + "css-has-pseudo": "^7.0.3", + "css-prefers-color-scheme": "^10.0.0", + "cssdb": "^8.6.0", + "postcss-attribute-case-insensitive": "^7.0.1", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^7.0.12", + "postcss-color-hex-alpha": "^10.0.0", + "postcss-color-rebeccapurple": "^10.0.0", + "postcss-custom-media": "^11.0.6", + "postcss-custom-properties": "^14.0.6", + "postcss-custom-selectors": "^8.0.5", + "postcss-dir-pseudo-class": "^9.0.1", + "postcss-double-position-gradients": "^6.0.4", + "postcss-focus-visible": "^10.0.1", + "postcss-focus-within": "^9.0.1", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^6.0.0", + "postcss-image-set-function": "^7.0.0", + "postcss-lab-function": "^7.0.12", + "postcss-logical": "^8.1.0", + "postcss-nesting": "^13.0.2", + "postcss-opacity-percentage": "^3.0.0", + "postcss-overflow-shorthand": "^6.0.0", + "postcss-page-break": "^3.0.4", + "postcss-place": "^10.0.0", + "postcss-pseudo-class-any-link": "^10.0.1", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^8.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz", + "integrity": "sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz", + "integrity": "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sort-media-queries": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", + "license": "MIT", + "dependencies": { + "sort-css-media-queries": "2.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.23" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/postcss-zindex": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", + "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", + "license": "MIT", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "license": "ISC" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.3.0.tgz", + "integrity": "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==", + "license": "MIT", + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz", + "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/qs": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.3" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-helmet-async": { + "name": "@slorber/react-helmet-async", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-json-view-lite": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-2.5.0.tgz", + "integrity": "sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-loadable": { + "name": "@docusaurus/react-loadable", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", + "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.3" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "react-loadable": "*", + "webpack": ">=4.41.1 || 5.x" + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-config": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", + "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router": ">=5" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", + "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.1.tgz", + "integrity": "sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==", + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^3.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "license": "MIT", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-directive": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-4.0.0.tgz", + "integrity": "sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", + "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "license": "MIT", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/replace-ext": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "license": "MIT" + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rtlcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/schema-dts": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz", + "integrity": "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==", + "license": "Apache-2.0" + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-5.5.0.tgz", + "integrity": "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==", + "license": "MIT", + "dependencies": { + "@peculiar/x509": "^1.14.2", + "pkijs": "^3.3.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-handler": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", + "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.2", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/sitemap": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", + "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sort-css-media-queries": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", + "license": "MIT", + "engines": { + "node": ">= 6.3.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "license": "MIT" + }, + "node_modules/streamx": { + "version": "2.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/stylehacks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "license": "MIT" + }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/synckit": { + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/teex": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "streamx": "^2.12.5" + } + }, + "node_modules/terser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/thingies": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz", + "integrity": "sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==", + "license": "MIT", + "engines": { + "node": ">=10.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tree-dump": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsyringe": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", + "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-engine": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-11.2.2.tgz", + "integrity": "sha512-15g/gWE7qQl9tQ3nAEbMd5h9HV1EACtFs6N9xaRBZICoCwnNGbal1kOs++ICf4aiTdItZxU2s/kYWhW7htlqJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/concat-stream": "^2.0.0", + "@types/debug": "^4.0.0", + "@types/is-empty": "^1.0.0", + "@types/node": "^22.0.0", + "@types/unist": "^3.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.0.0", + "extend": "^3.0.0", + "glob": "^10.0.0", + "ignore": "^6.0.0", + "is-empty": "^1.0.0", + "is-plain-obj": "^4.0.0", + "load-plugin": "^6.0.0", + "parse-json": "^7.0.0", + "trough": "^2.0.0", + "unist-util-inspect": "^8.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0", + "vfile-reporter": "^8.0.0", + "vfile-statistics": "^3.0.0", + "yaml": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-engine/node_modules/@types/node": { + "version": "22.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/unified-engine/node_modules/ignore": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/unified-engine/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unified-engine/node_modules/lines-and-columns": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/unified-engine/node_modules/parse-json": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unified-engine/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unified-engine/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-inspect": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-8.1.0.tgz", + "integrity": "sha512-mOlg8Mp33pR0eeFpo5d2902ojqFFOKMMG2hF8bmH7ZlhnmjFgh0NI3/ZDwdaBJNbvrS7LZFVrBVtIE9KZ9s7vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "license": "BSD-2-Clause", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/url-loader/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "license": "MIT" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-reporter": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-8.1.1.tgz", + "integrity": "sha512-qxRZcnFSQt6pWKn3PAk81yLK2rO2i7CDXpy8v8ZquiEOMLSnPw6BMSi9Y1sUCwGGl7a9b3CJT1CKpnRF7pp66g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/supports-color": "^8.0.0", + "string-width": "^6.0.0", + "supports-color": "^9.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0", + "vfile-sort": "^4.0.0", + "vfile-statistics": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-reporter/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/vfile-reporter/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/vfile-reporter/node_modules/string-width": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", + "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^10.2.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vfile-reporter/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/vfile-reporter/node_modules/supports-color": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/vfile-sort": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-4.0.0.tgz", + "integrity": "sha512-lffPI1JrbHDTToJwcq0rl6rBmkjQmMuXkAxsZPRS9DXbaJQvc642eCg6EGxcX2i1L+esbuhq+2l9tBll5v8AeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-statistics": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-3.0.0.tgz", + "integrity": "sha512-/qlwqwWBWFOmpXujL/20P+Iuydil0rZZNglR+VNm6J0gpLHwuVM5s7g2TfVoswbXjZ4HuIhLMySEyIw5i7/D8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vinyl": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^2.1.2", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-sourcemaps-apply": { + "version": "0.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "source-map": "^0.5.1" + } + }, + "node_modules/walk-up-path": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", + "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", + "dev": true, + "license": "ISC" + }, + "node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpack": { + "version": "5.104.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz", + "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.4", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.3.1", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz", + "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.43.1", + "mime-types": "^3.0.1", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, "peerDependencies": { - "react-native-b4a": "*" + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/webpack-dev-middleware/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz", + "integrity": "sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==", + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.25", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.8.1", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.22.1", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.9", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^5.5.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpackbar": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", + "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "consola": "^3.2.3", + "figures": "^3.2.0", + "markdown-table": "^2.0.0", + "pretty-time": "^1.1.0", + "std-env": "^3.7.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/webpackbar/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/webpackbar/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/webpackbar/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/webpackbar/node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "license": "MIT", + "dependencies": { + "repeat-string": "^1.0.0" }, - "peerDependenciesMeta": { - "react-native-b4a": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/bare-events": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", - "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", - "dev": true, - "license": "Apache-2.0", - "peerDependencies": { - "bare-abort-controller": "*" + "node_modules/webpackbar/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - } + "engines": { + "node": ">=8" } }, - "node_modules/blockly": { - "resolved": "packages/blockly", - "link": true + "node_modules/webpackbar/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, + "node_modules/webpackbar/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "license": "MIT", + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, "engines": { - "node": ">=0.8" + "node": ">=0.8.0" } }, - "node_modules/events-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", - "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", - "dev": true, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", "dependencies": { - "bare-events": "^2.7.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "license": "MIT" }, - "node_modules/google-closure-compiler": { - "version": "20260114.0.0", - "resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20260114.0.0.tgz", - "integrity": "sha512-6zOmAfIkEuj2D+52q1TGTzGypYuxra5uc7YOij3GTLQRMoT6gcJ+hnMM1lWVxibksvISe2ieLBjOjHKyVp3Fkw==", + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", "dependencies": { - "chalk": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 <5.6.1 || ^5.6.2 >5.6.1", - "google-closure-compiler-java": "^20260114.0.0", - "minimist": "^1.0.0", - "vinyl": "^3.0.1", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "bin": { - "google-closure-compiler": "cli.js" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=18" + "node": ">=12" }, - "optionalDependencies": { - "google-closure-compiler-linux": "^20260114.0.0", - "google-closure-compiler-linux-arm64": "^20260114.0.0", - "google-closure-compiler-macos": "^20260114.0.0", - "google-closure-compiler-windows": "^20260114.0.0" + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/google-closure-compiler-java": { - "version": "20260114.0.0", - "resolved": "https://registry.npmjs.org/google-closure-compiler-java/-/google-closure-compiler-java-20260114.0.0.tgz", - "integrity": "sha512-JBv3hVie4mI/DFtrrl6eMm0yHY/sp6wnKd6VIOL/eAxWDSHN7NUxnrmT7bwZpsKQU+Z0frPeBoJtIXiZZJxkjA==", + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "license": "Apache-2.0" + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, - "node_modules/google-closure-compiler-linux": { - "version": "20260114.0.0", - "resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20260114.0.0.tgz", - "integrity": "sha512-u8N6mGsUiHhNrVGyGTewWT2GyqTuiSZzq2T/Kyxc8cA06eQaprvx4ljkeH5eVRispItJH7uPwbxCjZ/zdNRBuA==", - "cpu": [ - "x32", - "x64" - ], + "node_modules/wrap-ansi-cjs/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": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ] + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/google-closure-compiler-linux-arm64": { - "version": "20260114.0.0", - "resolved": "https://registry.npmjs.org/google-closure-compiler-linux-arm64/-/google-closure-compiler-linux-arm64-20260114.0.0.tgz", - "integrity": "sha512-qArfqTXVFPbjh6sSWuObo7cTTnpFVkqyChdTFoEKcySmGMiOoJjgyk6BeH6+wRpum9C/6Hi9jhN3yaZ7g1PZmA==", - "cpu": [ - "arm64" - ], + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ] + "license": "MIT" }, - "node_modules/google-closure-compiler-macos": { - "version": "20260114.0.0", - "resolved": "https://registry.npmjs.org/google-closure-compiler-macos/-/google-closure-compiler-macos-20260114.0.0.tgz", - "integrity": "sha512-hlqaZqSvMp8Se/LeJaUW+RjSIlXxG8MvA58f0EpKw6DsFAmzLBa4QvFYW+t1BFmiMxR8LIX3wkijzzjC8i43ZQ==", - "cpu": [ - "arm64" - ], + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ] + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } }, - "node_modules/google-closure-compiler-windows": { - "version": "20260114.0.0", - "resolved": "https://registry.npmjs.org/google-closure-compiler-windows/-/google-closure-compiler-windows-20260114.0.0.tgz", - "integrity": "sha512-LtEPcrhe7ls9Mqlk6jRdoPlHM2eo1k+CJ5MaOrN8wBCi6XWcNdjeS1OFXAHgN4/tcNjg4qNsLHsHUk+bJ70hZQ==", - "cpu": [ - "x32", - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ] + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true, - "license": "ISC" + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } }, - "node_modules/replace-ext": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", - "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", - "dev": true, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wsl-utils/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, "engines": { - "node": ">= 10" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/streamx": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", - "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", - "dev": true, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", "license": "MIT", "dependencies": { - "events-universal": "^1.0.0", - "fast-fifo": "^1.3.2", - "text-decoder": "^1.1.0" + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" } }, - "node_modules/teex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", - "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "streamx": "^2.12.5" - } + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" }, - "node_modules/text-decoder": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", - "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "b4a": "^1.6.4" + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, - "node_modules/vinyl": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", - "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", - "dev": true, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", "license": "MIT", - "dependencies": { - "clone": "^2.1.2", - "remove-trailing-separator": "^1.1.0", - "replace-ext": "^2.0.0", - "teex": "^1.0.1" - }, "engines": { - "node": ">=10.13.0" + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==", - "dev": true, - "license": "ISC", - "dependencies": { - "source-map": "^0.5.1" + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "packages/blockly": { @@ -333,14 +20977,6 @@ "node": ">=18" } }, - "packages/blockly/node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "packages/blockly/node_modules/@asamuzakjp/css-color": { "version": "3.1.1", "license": "MIT", @@ -356,32 +20992,6 @@ "version": "10.4.3", "license": "ISC" }, - "packages/blockly/node_modules/@babel/code-frame": { - "version": "7.27.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "packages/blockly/node_modules/@babel/code-frame/node_modules/picocolors": { - "version": "1.1.1", - "dev": true, - "license": "ISC" - }, - "packages/blockly/node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "packages/blockly/node_modules/@blockly/block-test": { "version": "7.0.2", "dev": true, @@ -895,106 +21505,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "packages/blockly/node_modules/@csstools/color-helpers": { - "version": "5.0.2", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - } - }, - "packages/blockly/node_modules/@csstools/css-calc": { - "version": "2.1.2", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3" - } - }, - "packages/blockly/node_modules/@csstools/css-color-parser": { - "version": "3.0.8", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/color-helpers": "^5.0.2", - "@csstools/css-calc": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3" - } - }, - "packages/blockly/node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.4", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.3" - } - }, - "packages/blockly/node_modules/@csstools/css-tokenizer": { - "version": "3.0.3", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "packages/blockly/node_modules/@es-joy/jsdoccomment": { "version": "0.52.0", "dev": true, @@ -1010,31 +21520,6 @@ "node": ">=20.11.0" } }, - "packages/blockly/node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "packages/blockly/node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, "packages/blockly/node_modules/@eslint/config-array": { "version": "0.21.0", "dev": true, @@ -1251,68 +21736,12 @@ "packages/blockly/node_modules/@gulpjs/to-absolute-glob": { "version": "4.0.0", "dev": true, - "license": "MIT", - "dependencies": { - "is-negated-glob": "^1.0.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "packages/blockly/node_modules/@humanfs/core": { - "version": "0.19.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "packages/blockly/node_modules/@humanfs/node": { - "version": "0.16.6", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "packages/blockly/node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "packages/blockly/node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "packages/blockly/node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" + "license": "MIT", + "dependencies": { + "is-negated-glob": "^1.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "engines": { + "node": ">=10.13.0" } }, "packages/blockly/node_modules/@hyperjump/browser": { @@ -1403,84 +21832,6 @@ "node": "20 || >=22" } }, - "packages/blockly/node_modules/@isaacs/cliui": { - "version": "8.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "packages/blockly/node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/blockly/node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/blockly/node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "packages/blockly/node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "packages/blockly/node_modules/@microsoft/api-documenter": { "version": "7.22.4", "dev": true, @@ -1721,58 +22072,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "packages/blockly/node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/blockly/node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "packages/blockly/node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "packages/blockly/node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "packages/blockly/node_modules/@pkgr/core": { - "version": "0.2.7", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, "packages/blockly/node_modules/@promptbook/utils": { "version": "0.69.5", "dev": true, @@ -1994,21 +22293,11 @@ "@types/node": "*" } }, - "packages/blockly/node_modules/@types/estree": { - "version": "1.0.8", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/@types/expect": { "version": "1.20.4", "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/@types/json-schema": { - "version": "7.0.15", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/@types/node": { "version": "20.19.21", "dev": true, @@ -2036,14 +22325,6 @@ "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/@types/ws": { - "version": "8.18.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "packages/blockly/node_modules/@types/yauzl": { "version": "2.10.3", "dev": true, @@ -2513,25 +22794,6 @@ "node": ">=6.5" } }, - "packages/blockly/node_modules/acorn": { - "version": "8.15.0", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "packages/blockly/node_modules/acorn-jsx": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, "packages/blockly/node_modules/agent-base": { "version": "7.1.3", "license": "MIT", @@ -2539,21 +22801,6 @@ "node": ">= 14" } }, - "packages/blockly/node_modules/ajv": { - "version": "8.17.1", - "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" - } - }, "packages/blockly/node_modules/ajv-draft-04": { "version": "1.0.0", "dev": true, @@ -2632,18 +22879,6 @@ "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/anymatch": { - "version": "3.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "packages/blockly/node_modules/archiver": { "version": "7.0.1", "dev": true, @@ -2853,11 +23088,6 @@ "node": ">=14" } }, - "packages/blockly/node_modules/argparse": { - "version": "2.0.1", - "dev": true, - "license": "Python-2.0" - }, "packages/blockly/node_modules/aria-query": { "version": "5.3.0", "dev": true, @@ -2927,11 +23157,6 @@ "dev": true, "license": "0BSD" }, - "packages/blockly/node_modules/async": { - "version": "3.2.5", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/async-done": { "version": "2.0.0", "dev": true, @@ -2980,11 +23205,6 @@ "node": ">=10.13.0" } }, - "packages/blockly/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/bare-fs": { "version": "4.1.5", "dev": true, @@ -3084,14 +23304,6 @@ "node": ">=10.0.0" } }, - "packages/blockly/node_modules/binary-extensions": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "packages/blockly/node_modules/binaryextensions": { "version": "2.3.0", "dev": true, @@ -3113,31 +23325,6 @@ "readable-stream": "^3.4.0" } }, - "packages/blockly/node_modules/boolbase": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "packages/blockly/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "packages/blockly/node_modules/braces": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, "packages/blockly/node_modules/browser-stdout": { "version": "1.3.1", "dev": true, @@ -3167,59 +23354,19 @@ } }, "packages/blockly/node_modules/buffer-crc32": { - "version": "0.2.13", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "packages/blockly/node_modules/buffer-from": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/bytes": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "packages/blockly/node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "packages/blockly/node_modules/call-bound": { - "version": "1.0.4", + "version": "0.2.13", "dev": true, "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "*" } }, - "packages/blockly/node_modules/callsites": { - "version": "3.1.0", + "packages/blockly/node_modules/bytes": { + "version": "3.1.2", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.8" } }, "packages/blockly/node_modules/chai": { @@ -3269,48 +23416,6 @@ "url": "https://github.com/cheeriojs/cheerio?sponsor=1" } }, - "packages/blockly/node_modules/cheerio-select": { - "version": "2.1.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "packages/blockly/node_modules/chokidar": { - "version": "3.5.3", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "packages/blockly/node_modules/chromium-bidi": { "version": "8.0.0", "dev": true, @@ -3323,20 +23428,6 @@ "devtools-protocol": "*" } }, - "packages/blockly/node_modules/ci-info": { - "version": "3.8.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "packages/blockly/node_modules/cliui": { "version": "7.0.4", "dev": true, @@ -3384,22 +23475,6 @@ "util-deprecate": "~1.0.1" } }, - "packages/blockly/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "packages/blockly/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/color-support": { "version": "1.1.3", "dev": true, @@ -3498,11 +23573,6 @@ "safe-buffer": "~5.2.0" } }, - "packages/blockly/node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/concat-stream": { "version": "1.6.2", "dev": true, @@ -3584,14 +23654,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "packages/blockly/node_modules/content-type": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "packages/blockly/node_modules/conventional-changelog-angular": { "version": "7.0.0", "dev": true, @@ -3651,11 +23713,6 @@ "node": ">= 10.13.0" } }, - "packages/blockly/node_modules/core-util-is": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/corser": { "version": "2.0.1", "dev": true, @@ -3770,19 +23827,6 @@ "safe-buffer": "~5.2.0" } }, - "packages/blockly/node_modules/cross-spawn": { - "version": "7.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "packages/blockly/node_modules/css": { "version": "3.0.0", "dev": true, @@ -3793,21 +23837,6 @@ "source-map-resolve": "^0.6.0" } }, - "packages/blockly/node_modules/css-select": { - "version": "5.1.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, "packages/blockly/node_modules/css-shorthand-properties": { "version": "1.1.1", "dev": true @@ -3816,17 +23845,6 @@ "version": "0.0.1", "dev": true }, - "packages/blockly/node_modules/css-what": { - "version": "6.1.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, "packages/blockly/node_modules/css/node_modules/source-map": { "version": "0.6.1", "dev": true, @@ -3890,21 +23908,6 @@ "node": ">=18" } }, - "packages/blockly/node_modules/debug": { - "version": "4.4.1", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "packages/blockly/node_modules/debug-fabulous": { "version": "1.1.0", "dev": true, @@ -3946,11 +23949,6 @@ "node": ">=0.10" } }, - "packages/blockly/node_modules/deep-is": { - "version": "0.1.4", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/deepmerge-ts": { "version": "7.1.5", "dev": true, @@ -3972,14 +23970,6 @@ "node": ">= 14" } }, - "packages/blockly/node_modules/dequal": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "packages/blockly/node_modules/detect-file": { "version": "1.0.0", "dev": true, @@ -4009,57 +23999,6 @@ "node": ">=0.3.1" } }, - "packages/blockly/node_modules/dom-serializer": { - "version": "2.0.0", - "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" - } - }, - "packages/blockly/node_modules/domelementtype": { - "version": "2.3.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "packages/blockly/node_modules/domhandler": { - "version": "5.0.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "packages/blockly/node_modules/domutils": { - "version": "3.1.0", - "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" - } - }, "packages/blockly/node_modules/dot-prop": { "version": "5.3.0", "dev": true, @@ -4071,19 +24010,6 @@ "node": ">=8" } }, - "packages/blockly/node_modules/dunder-proto": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "packages/blockly/node_modules/each-props": { "version": "3.0.0", "dev": true, @@ -4096,11 +24022,6 @@ "node": ">= 10.13.0" } }, - "packages/blockly/node_modules/eastasianwidth": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/edge-paths": { "version": "3.0.5", "dev": true, @@ -4193,61 +24114,16 @@ "version": "1.4.4", "dev": true, "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "packages/blockly/node_modules/entities": { - "version": "4.5.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "packages/blockly/node_modules/env-paths": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/blockly/node_modules/error-ex": { - "version": "1.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "packages/blockly/node_modules/es-define-property": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "packages/blockly/node_modules/es-errors": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "once": "^1.4.0" } }, - "packages/blockly/node_modules/es-object-atoms": { - "version": "1.1.1", + "packages/blockly/node_modules/env-paths": { + "version": "2.2.1", "dev": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=6" } }, "packages/blockly/node_modules/es5-ext": { @@ -4290,25 +24166,6 @@ "es6-symbol": "^3.1.1" } }, - "packages/blockly/node_modules/escalade": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "packages/blockly/node_modules/escape-string-regexp": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/blockly/node_modules/escodegen": { "version": "2.1.0", "dev": true, @@ -4532,17 +24389,6 @@ "url": "https://opencollective.com/eslint" } }, - "packages/blockly/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "packages/blockly/node_modules/eslint/node_modules/ajv": { "version": "6.12.6", "dev": true, @@ -4612,40 +24458,6 @@ "url": "https://opencollective.com/eslint" } }, - "packages/blockly/node_modules/esprima": { - "version": "4.0.1", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "packages/blockly/node_modules/esquery": { - "version": "1.6.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "packages/blockly/node_modules/esrecurse": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, "packages/blockly/node_modules/estraverse": { "version": "5.3.0", "dev": true, @@ -4654,14 +24466,6 @@ "node": ">=4.0" } }, - "packages/blockly/node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "packages/blockly/node_modules/event-emitter": { "version": "0.3.5", "dev": true, @@ -4679,19 +24483,6 @@ "node": ">=6" } }, - "packages/blockly/node_modules/eventemitter3": { - "version": "4.0.7", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/events": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, "packages/blockly/node_modules/expand-tilde": { "version": "2.0.2", "dev": true, @@ -4716,11 +24507,6 @@ "dev": true, "license": "ISC" }, - "packages/blockly/node_modules/extend": { - "version": "3.0.2", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/extend-shallow": { "version": "3.0.2", "dev": true, @@ -4766,56 +24552,11 @@ "node": ">= 0.10" } }, - "packages/blockly/node_modules/fast-deep-equal": { - "version": "3.1.3", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/fast-diff": { "version": "1.3.0", "dev": true, "license": "Apache-2.0" }, - "packages/blockly/node_modules/fast-glob": { - "version": "3.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "packages/blockly/node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/fast-levenshtein": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/fast-uri": { - "version": "3.0.6", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, "packages/blockly/node_modules/fast-xml-parser": { "version": "4.5.3", "dev": true, @@ -4841,14 +24582,6 @@ "node": ">= 4.9.1" } }, - "packages/blockly/node_modules/fastq": { - "version": "1.13.0", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "packages/blockly/node_modules/fd-slicer": { "version": "1.1.0", "dev": true, @@ -4879,28 +24612,6 @@ "node": "^12.20 || >= 14.13" } }, - "packages/blockly/node_modules/file-entry-cache": { - "version": "8.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/blockly/node_modules/fill-range": { - "version": "7.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "packages/blockly/node_modules/find-up": { "version": "5.0.0", "dev": true, @@ -4961,50 +24672,6 @@ "node": ">= 10.13.0" } }, - "packages/blockly/node_modules/flat": { - "version": "5.0.2", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "packages/blockly/node_modules/flat-cache": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "packages/blockly/node_modules/flatted": { - "version": "3.3.2", - "dev": true, - "license": "ISC" - }, - "packages/blockly/node_modules/follow-redirects": { - "version": "1.15.6", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "packages/blockly/node_modules/for-in": { "version": "1.0.2", "dev": true, @@ -5024,21 +24691,6 @@ "node": ">=0.10.0" } }, - "packages/blockly/node_modules/foreground-child": { - "version": "3.3.1", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "packages/blockly/node_modules/formdata-polyfill": { "version": "4.0.10", "dev": true, @@ -5091,26 +24743,6 @@ "node": ">=10.13.0" } }, - "packages/blockly/node_modules/fsevents": { - "version": "2.3.3", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "packages/blockly/node_modules/function-bind": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "packages/blockly/node_modules/geckodriver": { "version": "5.0.0", "dev": true, @@ -5160,38 +24792,15 @@ "dev": true, "license": "ISC", "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "packages/blockly/node_modules/get-func-name": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "packages/blockly/node_modules/get-intrinsic": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, + "node": "6.* || 8.* || >= 10.*" + } + }, + "packages/blockly/node_modules/get-func-name": { + "version": "2.0.2", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "*" } }, "packages/blockly/node_modules/get-port": { @@ -5205,18 +24814,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/blockly/node_modules/get-proto": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "packages/blockly/node_modules/get-stream": { "version": "5.2.0", "dev": true, @@ -5290,17 +24887,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "packages/blockly/node_modules/glob-parent": { - "version": "5.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "packages/blockly/node_modules/glob-stream": { "version": "8.0.3", "dev": true, @@ -5439,22 +25025,6 @@ "node": ">= 10.13.0" } }, - "packages/blockly/node_modules/gopd": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/blockly/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "packages/blockly/node_modules/grapheme-splitter": { "version": "1.0.4", "dev": true, @@ -5854,44 +25424,6 @@ "node": ">= 10.13.0" } }, - "packages/blockly/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/has-symbols": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/blockly/node_modules/hasown": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "packages/blockly/node_modules/he": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, "packages/blockly/node_modules/homedir-polyfill": { "version": "1.0.3", "dev": true, @@ -5937,19 +25469,6 @@ "entities": "^4.5.0" } }, - "packages/blockly/node_modules/http-proxy": { - "version": "1.18.1", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, "packages/blockly/node_modules/http-proxy-agent": { "version": "7.0.2", "license": "MIT", @@ -6027,64 +25546,11 @@ ], "license": "BSD-3-Clause" }, - "packages/blockly/node_modules/ignore": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "packages/blockly/node_modules/immediate": { "version": "3.0.6", "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/import-fresh": { - "version": "3.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/blockly/node_modules/import-lazy": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/import-meta-resolve": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "packages/blockly/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "packages/blockly/node_modules/inherits": { - "version": "2.0.4", - "dev": true, - "license": "ISC" - }, "packages/blockly/node_modules/ini": { "version": "1.3.8", "dev": true, @@ -6127,47 +25593,6 @@ "node": ">=0.10.0" } }, - "packages/blockly/node_modules/is-arrayish": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/is-binary-path": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/is-core-module": { - "version": "2.13.1", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/blockly/node_modules/is-docker": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/blockly/node_modules/is-extendable": { "version": "1.0.1", "dev": true, @@ -6190,33 +25615,6 @@ "node": ">=0.10.0" } }, - "packages/blockly/node_modules/is-extglob": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/blockly/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/is-glob": { - "version": "4.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "packages/blockly/node_modules/is-negated-glob": { "version": "1.0.0", "dev": true, @@ -6225,14 +25623,6 @@ "node": ">=0.10.0" } }, - "packages/blockly/node_modules/is-number": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "packages/blockly/node_modules/is-obj": { "version": "2.0.0", "dev": true, @@ -6269,17 +25659,6 @@ "node": ">=0.10.0" } }, - "packages/blockly/node_modules/is-stream": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/blockly/node_modules/is-text-path": { "version": "2.0.0", "dev": true, @@ -6329,35 +25708,11 @@ "node": ">=0.10.0" } }, - "packages/blockly/node_modules/is-wsl": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "packages/blockly/node_modules/isarray": { "version": "1.0.0", "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "packages/blockly/node_modules/isobject": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "packages/blockly/node_modules/istextorbinary": { "version": "3.3.0", "dev": true, @@ -6395,27 +25750,11 @@ "jiti": "lib/jiti-cli.mjs" } }, - "packages/blockly/node_modules/jju": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/js-yaml": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, + "packages/blockly/node_modules/jju": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, "packages/blockly/node_modules/jsbn": { "version": "1.1.0", "dev": true, @@ -6486,21 +25825,6 @@ "node": ">=18" } }, - "packages/blockly/node_modules/json-buffer": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/json-stable-stringify": { "version": "1.0.2", "dev": true, @@ -6512,11 +25836,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "packages/blockly/node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/json-stringify-deterministic": { "version": "1.0.12", "dev": true, @@ -6525,28 +25844,6 @@ "node": ">= 4" } }, - "packages/blockly/node_modules/json5": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "packages/blockly/node_modules/jsonfile": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "packages/blockly/node_modules/jsonify": { "version": "0.0.1", "dev": true, @@ -6613,14 +25910,6 @@ "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/keyv": { - "version": "4.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, "packages/blockly/node_modules/klaw-sync": { "version": "6.0.0", "dev": true, @@ -6670,18 +25959,6 @@ "node": ">=10.13.0" } }, - "packages/blockly/node_modules/levn": { - "version": "0.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "packages/blockly/node_modules/lie": { "version": "3.3.0", "dev": true, @@ -6707,11 +25984,6 @@ "node": ">=10.13.0" } }, - "packages/blockly/node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/locate-app": { "version": "2.5.0", "dev": true, @@ -6757,11 +26029,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/blockly/node_modules/lodash": { - "version": "4.17.21", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/lodash._reinterpolate": { "version": "3.0.0", "dev": true, @@ -6839,11 +26106,6 @@ "lodash._reinterpolate": "^3.0.0" } }, - "packages/blockly/node_modules/lodash.uniq": { - "version": "4.5.0", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/lodash.upperfirst": { "version": "4.3.1", "dev": true, @@ -6926,14 +26188,6 @@ "@ts-stack/markdown": "^1.3.0" } }, - "packages/blockly/node_modules/math-intrinsics": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "packages/blockly/node_modules/memoizee": { "version": "0.4.15", "dev": true, @@ -6965,56 +26219,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/blockly/node_modules/merge2": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "packages/blockly/node_modules/micromatch": { - "version": "4.0.8", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "packages/blockly/node_modules/mime": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "packages/blockly/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "packages/blockly/node_modules/minipass": { - "version": "7.1.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "packages/blockly/node_modules/mitt": { "version": "3.0.1", "dev": true, @@ -7190,10 +26394,6 @@ "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/ms": { - "version": "2.1.3", - "license": "MIT" - }, "packages/blockly/node_modules/mute-stdout": { "version": "2.0.0", "dev": true, @@ -7202,11 +26402,6 @@ "node": ">= 10.13.0" } }, - "packages/blockly/node_modules/natural-compare": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/netmask": { "version": "2.0.2", "dev": true, @@ -7267,14 +26462,6 @@ "url": "https://opencollective.com/node-fetch" } }, - "packages/blockly/node_modules/normalize-path": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "packages/blockly/node_modules/now-and-later": { "version": "3.0.0", "dev": true, @@ -7286,40 +26473,10 @@ "node": ">= 10.13.0" } }, - "packages/blockly/node_modules/nth-check": { - "version": "2.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, "packages/blockly/node_modules/nwsapi": { "version": "2.2.20", "license": "MIT" }, - "packages/blockly/node_modules/object-assign": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/blockly/node_modules/object-inspect": { - "version": "1.13.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "packages/blockly/node_modules/object.defaults": { "version": "1.1.0", "dev": true, @@ -7368,30 +26525,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/blockly/node_modules/opener": { - "version": "1.5.2", - "dev": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "packages/blockly/node_modules/optionator": { - "version": "0.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "packages/blockly/node_modules/p-limit": { "version": "3.1.0", "dev": true, @@ -7450,27 +26583,11 @@ "node": ">= 14" } }, - "packages/blockly/node_modules/package-json-from-dist": { - "version": "1.0.1", - "dev": true, - "license": "BlueOak-1.0.0" - }, "packages/blockly/node_modules/pako": { "version": "1.0.11", "dev": true, "license": "(MIT AND Zlib)" }, - "packages/blockly/node_modules/parent-module": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "packages/blockly/node_modules/parse-filepath": { "version": "1.0.2", "dev": true, @@ -7492,23 +26609,6 @@ "parse-statements": "1.0.11" } }, - "packages/blockly/node_modules/parse-json": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/blockly/node_modules/parse-node-version": { "version": "1.0.1", "dev": true, @@ -7530,28 +26630,6 @@ "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/parse5": { - "version": "7.2.1", - "license": "MIT", - "dependencies": { - "entities": "^4.5.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "packages/blockly/node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, "packages/blockly/node_modules/parse5-parser-stream": { "version": "7.1.2", "dev": true, @@ -7620,19 +26698,6 @@ "node": ">=8" } }, - "packages/blockly/node_modules/path-key": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/path-parse": { - "version": "1.0.7", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/path-root": { "version": "0.1.1", "dev": true, @@ -7673,20 +26738,7 @@ "license": "ISC", "engines": { "node": "20 || >=22" - } - }, - "packages/blockly/node_modules/path-to-regexp": { - "version": "1.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } - }, - "packages/blockly/node_modules/path-to-regexp/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" + } }, "packages/blockly/node_modules/pend": { "version": "1.2.0", @@ -7698,17 +26750,6 @@ "dev": true, "license": "ISC" }, - "packages/blockly/node_modules/picomatch": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "packages/blockly/node_modules/plugin-error": { "version": "1.0.1", "dev": true, @@ -7787,28 +26828,6 @@ "node": ">=0.10.0" } }, - "packages/blockly/node_modules/prelude-ls": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/blockly/node_modules/prettier": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "packages/blockly/node_modules/prettier-linter-helpers": { "version": "1.0.0", "dev": true, @@ -7843,11 +26862,6 @@ "node": ">= 0.6.0" } }, - "packages/blockly/node_modules/process-nextick-args": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/progress": { "version": "2.0.3", "dev": true, @@ -7896,13 +26910,6 @@ "once": "^1.3.1" } }, - "packages/blockly/node_modules/punycode": { - "version": "2.3.1", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "packages/blockly/node_modules/puppeteer-core": { "version": "24.20.0", "dev": true, @@ -7920,65 +26927,11 @@ "node": ">=18" } }, - "packages/blockly/node_modules/qs": { - "version": "6.14.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "packages/blockly/node_modules/query-selector-shadow-dom": { "version": "1.0.1", "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/queue-microtask": { - "version": "1.2.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "packages/blockly/node_modules/randombytes": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "packages/blockly/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "packages/blockly/node_modules/readdir-glob": { "version": "1.1.3", "dev": true, @@ -8006,17 +26959,6 @@ "node": ">=10" } }, - "packages/blockly/node_modules/readdirp": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "packages/blockly/node_modules/readline-sync": { "version": "1.4.10", "dev": true, @@ -8084,35 +27026,6 @@ "node": ">=0.10.0" } }, - "packages/blockly/node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/blockly/node_modules/requires-port": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/resolve": { - "version": "1.22.8", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "packages/blockly/node_modules/resolve-dir": { "version": "1.0.1", "dev": true, @@ -8125,14 +27038,6 @@ "node": ">=0.10.0" } }, - "packages/blockly/node_modules/resolve-from": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "packages/blockly/node_modules/resolve-options": { "version": "2.0.0", "dev": true, @@ -8157,15 +27062,6 @@ "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/reusify": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "packages/blockly/node_modules/rgb2hex": { "version": "0.2.5", "dev": true, @@ -8264,28 +27160,6 @@ "version": "0.8.0", "license": "MIT" }, - "packages/blockly/node_modules/run-parallel": { - "version": "1.2.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "packages/blockly/node_modules/rxjs": { "version": "7.8.2", "dev": true, @@ -8312,10 +27186,6 @@ "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/safer-buffer": { - "version": "2.1.2", - "license": "MIT" - }, "packages/blockly/node_modules/saxes": { "version": "6.0.0", "license": "ISC", @@ -8342,155 +27212,38 @@ "semver": "bin/semver.js" }, "engines": { - "node": ">=10" - } - }, - "packages/blockly/node_modules/semver-greatest-satisfied-range": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "sver": "^1.8.3" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "packages/blockly/node_modules/serialize-error": { - "version": "11.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^2.12.2" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/blockly/node_modules/serialize-javascript": { - "version": "6.0.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "packages/blockly/node_modules/setimmediate": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "packages/blockly/node_modules/shebang-command": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/shebang-regex": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/shell-quote": { - "version": "1.8.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/blockly/node_modules/side-channel": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "packages/blockly/node_modules/side-channel-list": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, - "packages/blockly/node_modules/side-channel-map": { - "version": "1.0.1", + "packages/blockly/node_modules/semver-greatest-satisfied-range": { + "version": "2.0.0", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" + "sver": "^1.8.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 10.13.0" } }, - "packages/blockly/node_modules/side-channel-weakmap": { - "version": "1.0.2", + "packages/blockly/node_modules/serialize-error": { + "version": "11.0.3", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" + "type-fest": "^2.12.2" }, "engines": { - "node": ">= 0.4" + "node": ">=14.16" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/blockly/node_modules/signal-exit": { - "version": "4.0.1", + "packages/blockly/node_modules/setimmediate": { + "version": "1.0.5", "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "license": "MIT" }, "packages/blockly/node_modules/sinon": { "version": "9.2.4", @@ -8584,16 +27337,6 @@ "node": ">= 10.13.0" } }, - "packages/blockly/node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "license": "CC-BY-3.0" - }, - "packages/blockly/node_modules/spdx-license-ids": { - "version": "3.0.11", - "dev": true, - "license": "CC0-1.0" - }, "packages/blockly/node_modules/split2": { "version": "4.2.0", "dev": true, @@ -8602,11 +27345,6 @@ "node": ">= 10.x" } }, - "packages/blockly/node_modules/sprintf-js": { - "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, "packages/blockly/node_modules/stream-composer": { "version": "1.0.2", "dev": true, @@ -8688,78 +27426,6 @@ "node": ">=8" } }, - "packages/blockly/node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "packages/blockly/node_modules/strip-bom-string": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "packages/blockly/node_modules/strip-json-comments": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/blockly/node_modules/strnum": { "version": "1.1.2", "dev": true, @@ -8782,17 +27448,6 @@ "node": ">=8" } }, - "packages/blockly/node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "packages/blockly/node_modules/sver": { "version": "1.8.4", "dev": true, @@ -8814,20 +27469,6 @@ "version": "3.2.4", "license": "MIT" }, - "packages/blockly/node_modules/synckit": { - "version": "0.11.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.2.4" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, "packages/blockly/node_modules/tar-fs": { "version": "3.1.1", "dev": true, @@ -8922,17 +27563,6 @@ "node": ">=14.14" } }, - "packages/blockly/node_modules/to-regex-range": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "packages/blockly/node_modules/to-through": { "version": "3.0.0", "dev": true, @@ -8993,17 +27623,6 @@ "dev": true, "license": "ISC" }, - "packages/blockly/node_modules/type-check": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "packages/blockly/node_modules/type-detect": { "version": "4.0.8", "dev": true, @@ -9012,27 +27631,11 @@ "node": ">=4" } }, - "packages/blockly/node_modules/type-fest": { - "version": "2.13.0", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/blockly/node_modules/typed-query-selector": { "version": "2.12.0", "dev": true, "license": "MIT" }, - "packages/blockly/node_modules/typedarray": { - "version": "0.0.6", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/typescript": { "version": "5.9.3", "dev": true, @@ -9139,22 +27742,6 @@ "node": ">= 0.8.0" } }, - "packages/blockly/node_modules/universalify": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "packages/blockly/node_modules/uri-js": { - "version": "4.4.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, "packages/blockly/node_modules/url-join": { "version": "4.0.1", "dev": true, @@ -9173,11 +27760,6 @@ "node": ">= 0.8.0" } }, - "packages/blockly/node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, "packages/blockly/node_modules/uuid": { "version": "9.0.0", "dev": true, @@ -9435,17 +28017,6 @@ } } }, - "packages/blockly/node_modules/webdriverio/node_modules/is-plain-obj": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/blockly/node_modules/webidl-conversions": { "version": "7.0.0", "license": "BSD-2-Clause", @@ -9482,20 +28053,6 @@ "node": ">=18" } }, - "packages/blockly/node_modules/which": { - "version": "2.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "packages/blockly/node_modules/workerpool": { "version": "9.3.2", "dev": true, @@ -9517,23 +28074,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "packages/blockly/node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "packages/blockly/node_modules/wrappy": { "version": "1.0.2", "dev": true, @@ -9590,14 +28130,6 @@ "dev": true, "license": "ISC" }, - "packages/blockly/node_modules/yaml": { - "version": "2.2.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 14" - } - }, "packages/blockly/node_modules/yargs": { "version": "17.7.2", "dev": true, @@ -9637,17 +28169,6 @@ "node": ">=10" } }, - "packages/blockly/node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/blockly/node_modules/yargs-unparser/node_modules/decamelize": { "version": "4.0.0", "dev": true, @@ -9781,6 +28302,35 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "packages/docs": { + "name": "blockly-docs", + "version": "0.0.0", + "license": "Apache-2.0", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/plugin-client-redirects": "^3.9.2", + "@docusaurus/preset-classic": "3.9.2", + "@mdx-js/react": "^3.0.1", + "clsx": "^2.1.1", + "js-yaml": "^4.1.0", + "prism-react-renderer": "^2.3.1", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "remark-directive": "^4.0.0" + }, + "devDependencies": { + "@docsearch/core": "^4.5.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/types": "3.9.2", + "eslint": "^10.1.0", + "eslint-plugin-mdx": "^3.7.0", + "gh-pages": "^6.3.0", + "prettier": "^3.8.1" + }, + "engines": { + "node": ">=20.0.0" + } } } } diff --git a/packages/blockly/gulpfile.mjs b/packages/blockly/gulpfile.mjs index ad61bcb516d..7c961305f59 100644 --- a/packages/blockly/gulpfile.mjs +++ b/packages/blockly/gulpfile.mjs @@ -39,7 +39,7 @@ import { syncMaster, updateGithubPages, } from './scripts/gulpfiles/git_tasks.mjs'; -import {cleanReleaseDir, pack} from './scripts/gulpfiles/package_tasks.mjs'; +import {cleanReleaseDir, pack, typings} from './scripts/gulpfiles/package_tasks.mjs'; import { publish, publishBeta, @@ -88,6 +88,7 @@ export { buildAdvancedCompilationTest, createRC as gitCreateRC, docs, + typings, } // Legacy targets, to be deleted. diff --git a/packages/blockly/scripts/gulpfiles/docs_tasks.mjs b/packages/blockly/scripts/gulpfiles/docs_tasks.mjs index 51abd480f95..68d29065132 100644 --- a/packages/blockly/scripts/gulpfiles/docs_tasks.mjs +++ b/packages/blockly/scripts/gulpfiles/docs_tasks.mjs @@ -1,11 +1,12 @@ import {execSync} from 'child_process'; -import {Extractor} from 'markdown-tables-to-json'; import * as fs from 'fs'; +import * as path from 'path'; import * as gulp from 'gulp'; -import header from 'gulp-header'; import replace from 'gulp-replace'; +import rename from 'gulp-rename'; -const DOCS_DIR = 'docs'; +const DOCS_DIR = '../docs/docs/reference'; +const REFERENCE_SIDEBAR_DIR = DOCS_DIR; /** * Run API Extractor to generate the intermediate json file. @@ -30,9 +31,7 @@ const removeRenames = function() { */ const generateDocs = function(done) { if (!fs.existsSync(DOCS_DIR)) { - // Create the directory if it doesn't exist. - // If it already exists, the contents will be deleted by api-documenter. - fs.mkdirSync(DOCS_DIR); + fs.mkdirSync(DOCS_DIR, {recursive: true}); } execSync( `api-documenter markdown --input-folder temp --output-folder ${DOCS_DIR}`, @@ -41,15 +40,282 @@ const generateDocs = function(done) { } /** - * Prepends the project and book metadata that devsite requires. + * Extracts the title from the H2 heading in the content. + * Falls back to filename-based title if H2 not found. */ -const prependBook = function() { - return gulp.src('docs/*.md') - .pipe(header( - 'Project: /blockly/_project.yaml\nBook: /blockly/_book.yaml\n\n')) +const extractTitleFromContent = function(content, filename) { + // Remove frontmatter if exists + let cleanContent = content.replace(/^---[\s\S]*?---\n\n/, ''); + + // Remove MDX comments + cleanContent = cleanContent.replace(/\{\/\*[\s\S]*?\*\/\}/g, ''); + + // Find the first ## heading + const headingMatch = cleanContent.match(/##\s+(.+)/); + if (headingMatch) { + // Get the full H2 heading text + let fullTitle = headingMatch[1].trim(); + // Remove markdown links + fullTitle = fullTitle.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1'); + // Remove inline code backticks + fullTitle = fullTitle.replace(/`([^`]+)`/g, '$1'); + + // Simplify title: "BlocklyOptions.comments property" -> "Comments property" + // Extract the last part after the last dot + const parts = fullTitle.split('.'); + if (parts.length > 1) { + // Get everything after the last dot + return parts[parts.length - 1]; + } + + return fullTitle; + } + + // Fallback to filename-based title + return extractTitle(filename); +}; + +/** + * Extracts a clean title from the filename. + * Example: "blockly.block_class" -> "Block class" + * Example: "blockly.block_class.addicon_1_method" -> "Addicon method" + */ +const extractTitle = function(filename) { + const nameWithoutExt = filename.replace('.mdx', '').replace('.md', ''); + const parts = nameWithoutExt.split('.'); + + if (parts.length === 2) { + // Top-level page: blockly.block_class -> "Block class" + let name = parts[1]; + // Remove suffixes like _class, _namespace, etc. + const suffix = name.match(/_(class|namespace|interface|enum|type|variable)$/); + name = name.replace(/_(class|namespace|interface|enum|type|variable)$/, ''); + + // Split by underscores and capitalize each word + const words = name.split('_').map(word => + word.charAt(0).toUpperCase() + word.slice(1) + ); + + // Add back the suffix with proper spacing + if (suffix) { + words.push(suffix[1]); + } + + return words.join(' '); + } else if (parts.length > 2) { + // Sub-page: blockly.block_class.addicon_1_method -> "Addicon method" + let name = parts[parts.length - 1]; + // Remove number suffixes and type suffixes + name = name.replace(/_\d+_(method|property|constructor|function|variable)$/, ' $1'); + name = name.replace(/^_constructor__\d+_constructor$/, 'Constructor'); + // Replace double underscores with space, but keep single underscores + name = name.replace(/__/g, ' '); + name = name.trim(); + // Capitalize first letter only + return name.charAt(0).toUpperCase() + name.slice(1); + } + + // Fallback: capitalize first letter + return nameWithoutExt.charAt(0).toUpperCase() + nameWithoutExt.slice(1); +}; + +/** + * Extracts description from the content. + * Gets the first paragraph after the heading, up to the first code block or newline. + * If no paragraph is found, generates a generic fallback description. + */ +const extractDescription = function(content, filename) { + // Remove frontmatter if exists + content = content.replace(/^---[\s\S]*?---\n\n/, ''); + + // Remove MDX comments + content = content.replace(/\{\/\*[\s\S]*?\*\/\}/g, ''); + + // Find the first ## heading (usually the main title) + const headingMatch = content.match(/##\s+(.+)/); + if (!headingMatch) { + const title = extractTitle(filename); + return `Blockly - usage reference for the ${title}`; + } + + // Get the full H2 heading for fallback description + let fullTitle = headingMatch[1].trim(); + fullTitle = fullTitle.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1'); + fullTitle = fullTitle.replace(/`([^`]+)`/g, '$1'); + + // Get content after the heading + const afterHeading = content.substring(content.indexOf(headingMatch[0]) + headingMatch[0].length); + + // Look for the first non-empty text after the heading + // It might have 1 or 2 newlines before the description paragraph + const paragraphMatch = afterHeading.match(/\n+([^\n]+(?:\n(?!\n|\*\*|```|##|)[^\n]+)*)/); + + if (paragraphMatch) { + // Clean up the description + let description = paragraphMatch[1].trim(); + + // Remove markdown links but keep the text + description = description.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1'); + + // Remove inline code backticks + description = description.replace(/`([^`]+)`/g, '$1'); + + // Remove extra whitespace and newlines + description = description.replace(/\s+/g, ' '); + + // Skip if it's empty after cleaning + if (!description) { + return `Blockly - usage reference for the ${fullTitle}`; + } + + // Limit to first sentence or 160 characters + const firstSentence = description.match(/^[^.!?]+[.!?]/); + if (firstSentence) { + description = firstSentence[0]; + } + + if (description.length > 160) { + description = description.substring(0, 157) + '...'; + } + + return description; + } + + // Fallback: Generate generic description using full H2 heading title + return `Blockly - usage reference for the ${fullTitle}`; +}; + +/** + * Prepends frontmatter to MDX files with title, description, and sidebar config. + */ +const prependFrontmatter = function(done) { + const files = fs.readdirSync(DOCS_DIR); + + for (const file of files) { + if (!file.endsWith('.mdx')) continue; + + const filePath = path.join(DOCS_DIR, file); + let content = fs.readFileSync(filePath, 'utf8'); + + // Remove existing frontmatter if present + if (content.startsWith('---\n')) { + const endOfFrontmatter = content.indexOf('---\n', 4); + if (endOfFrontmatter !== -1) { + content = content.substring(endOfFrontmatter + 4).trim() + '\n\n'; + } + } + + const title = extractTitleFromContent(content, file); + const description = extractDescription(content, file); + + let frontmatter = '---\n'; + frontmatter += 'displayed_sidebar: referenceSidebar\n'; + frontmatter += 'hide_title: true\n'; + frontmatter += `title: "${title}"\n`; + frontmatter += `description: ${JSON.stringify(description)}\n`; + frontmatter += '---\n\n'; + + // Write the file with frontmatter + fs.writeFileSync(filePath, frontmatter + content); + } + + done(); +}; + +/** + * Converts .md files to .mdx for Docusaurus. + */ +/** + * Post-process MDX files to fix problematic patterns + */ +const fixMdxIssues = function(done) { + const files = fs.readdirSync(DOCS_DIR).filter(f => f.endsWith('.mdx')); + + for (const file of files) { + const filePath = path.join(DOCS_DIR, file); + let content = fs.readFileSync(filePath, 'utf8'); + + const lines = content.split('\n'); + let inCodeBlock = false; + + for (let i = 0; i < lines.length; i++) { + if (lines[i].trim().startsWith('```')) { + inCodeBlock = !inCodeBlock; + continue; + } + if (inCodeBlock) continue; + + // Remove all MDX comments (artifacts from HTML comment conversion) + lines[i] = lines[i].replace(/\{\/\*[\s\S]*?\*\/\}/g, ''); + + // Remove unnecessary markdown escapes for underscores and brackets + lines[i] = lines[i].replace(/\\_/g, '_'); + lines[i] = lines[i].replace(/\\\[/g, '['); + lines[i] = lines[i].replace(/\\\]/g, ']'); + + // Escape HTML tags (with or without attributes) outside of table markup + const isTableMarkup = /^<\/?(table|thead|tbody|tr|th|td)[\s>]/.test(lines[i].trim()); + if (!isTableMarkup) { + lines[i] = lines[i].replace(/<([a-z]+)(\s[^>]*)?>/g, '`$&`'); + lines[i] = lines[i].replace(/<\/([a-z]+)>/g, '`$&`'); + } + + // Escape curly braces so MDX doesn't parse them as JSX expressions. + // First undo any backslash-escaping from api-documenter, then re-escape. + lines[i] = lines[i].replace(/\\\{/g, '{').replace(/\\\}/g, '}'); + lines[i] = lines[i].replace(/\{/g, '\\{').replace(/\}/g, '\\}'); + } + + content = lines.join('\n'); + fs.writeFileSync(filePath, content, 'utf8'); + } + + done(); +}; + +const convertToMdx = function() { + return gulp.src(`${DOCS_DIR}/*.md`) + // Convert HTML comments to MDX comments + .pipe(replace(//g, '{/* $1 */}')) + // Fix malformed markdown links: [text][/path](https://developers.google.com/path) -> [text](/path) + .pipe(replace(/\[([^\]]+)\]\[([^\]]+)\]\(https:\/\/developers\.google\.com([^)]+)\)/g, '[$1]($2)')) + // Fix all internal links: remove .md extension and convert ./filename to /reference/filename + .pipe(replace(/\]\(\.\/([^)]+)\.md\)/g, '](/reference/$1)')) + // Replace developers.google.com links with relative paths + .pipe(replace(/https:\/\/developers\.google\.com(\/blockly\/[^)\s"']+)/g, '$1')) + // Replace developers.devsite.google.com links with relative paths + .pipe(replace(/https:\/\/developers\.devsite\.google\.com(\/blockly\/[^)\s"']+)/g, '$1')) + + // Fix underscore to hyphen in URL fragments + .pipe(replace(/(\/blockly\/[^)\s"'#]*#[^)\s"']*)_([^)\s"']*)/g, function(match) { + return match.replace(/_/g, '-'); + })) + // Remove %5C (URL-encoded backslash) and literal backslash before anchor tags + .pipe(replace(/(%5C|\\)(#[^)\s"']*)/g, '$2')) + // Fix breadcrumb "Home" link to point to the overview page + .pipe(replace(/\[Home\]\(\/reference\/index\)/g, '[Home](/reference/blockly)')) + // Convert text to markdown backtick code + .pipe(replace(/([^<]*)<\/code>/g, '`$1`')) + // Convert paragraph breaks to spaces (for table cells) and remove remaining p tags + .pipe(replace(/<\/p>

/g, ' ')) + .pipe(replace(/<\/?p>/g, '')) + .pipe(rename({ extname: '.mdx' })) .pipe(gulp.dest(DOCS_DIR)); } +/** + * Delete original .md files after conversion to .mdx + */ +const cleanMdFiles = function(done) { + const files = fs.readdirSync(DOCS_DIR); + for (const file of files) { + if (file.endsWith('.md')) { + fs.unlinkSync(path.join(DOCS_DIR, file)); + } + } + done(); +} + /** * Creates a map of top-level pages to sub-pages, e.g. a mapping * of `block_class` to every page associated with that class. @@ -60,87 +326,176 @@ const prependBook = function() { const buildAlternatePathsMap = function(allFiles) { let map = new Map(); for (let file of allFiles) { - // Get the name of the class/namespaces/variable/etc., i.e. the top-level - // page. - let filePieces = file.split('.'); - let name = filePieces[1]; - if (!map.has(name)) { - map.set(name, []); - } - if (filePieces[2] === 'md') { - // Don't add the top-level page to the map. - continue; + if (!file.endsWith('.mdx') || file === 'blockly.mdx' || file === '_reference.js') continue; + + // Remove extension + const nameWithoutExt = file.replace('.mdx', ''); + + // Get the name of the class/namespace/etc., i.e. the top-level page + // Example: blockly.block_class._constructor__1.mdx -> block_class + // Example: blockly.block_class.mdx -> block_class + const parts = nameWithoutExt.split('.'); + + if (parts.length === 2) { + // This is a top-level page (e.g., blockly.block_class) + const topLevelName = parts[1]; + if (!map.has(topLevelName)) { + map.set(topLevelName, []); + } + } else if (parts.length > 2) { + // This is a sub-page (e.g., blockly.block_class._constructor__1_constructor) + const topLevelName = parts[1]; + if (!map.has(topLevelName)) { + map.set(topLevelName, []); + } + // Add the full name without extension + map.get(topLevelName).push(nameWithoutExt); } - // Add all sub-pages to the array for the corresponding top-level page. - map.get(name).push(file); } + + // Sort sub-pages: constructors first, then alphabetically + for (const [key, value] of map.entries()) { + value.sort((a, b) => { + const aIsConstructor = a.includes('._constructor'); + const bIsConstructor = b.includes('._constructor'); + if (aIsConstructor && !bIsConstructor) return -1; + if (!aIsConstructor && bIsConstructor) return 1; + return a.localeCompare(b); + }); + } + return map; } /** - * Create the _toc.yaml file used by devsite to create the leftnav. - * This file is generated from the contents of `blockly.md` which contains links + * Parse HTML tables from the blockly.md file to extract classes, interfaces, etc. + * @param {string} fileContent The content of blockly.md + * @returns {Object} Object with sections as keys and arrays of {name, path} as values + */ +const parseHtmlTables = function(fileContent) { + const result = {}; + + // Split by ## headings + const sections = fileContent.split('##'); + + for (let section of sections) { + const lines = section.split('\n'); + const sectionName = lines[0].trim(); + + if (!sectionName || sectionName === 'blockly package') continue; + + // Match links in markdown pipe tables: | [Name](/reference/path) | ... + const tableRowRegex = /\|\s*\[([^\]]+)\]\(\/reference\/([^\)]+)\)/g; + const items = []; + + let match; + while ((match = tableRowRegex.exec(section)) !== null) { + const name = match[1]; + const href = match[2]; + items.push({ name, path: href }); + } + + if (items.length > 0) { + result[sectionName] = items; + } + } + + return result; +} + +/** + * Create the _reference.js file for Docusaurus sidebar. + * This file is generated from the contents of `blockly.mdx` which contains links * to the other top-level API pages (each class, namespace, etc.). - * - * The `alternate_paths` for each top-level page contains the path for - * each associated sub-page. All subpages must be linked to their top-level page - * in the TOC for the left nav bar to remain correct after drilling down into a - * sub-page. */ -const createToc = function(done) { - const fileContent = fs.readFileSync(`${DOCS_DIR}/blockly.md`, 'utf8'); - // Create the TOC file. The file should not yet exist; if it does, this - // operation will fail. - const toc = fs.openSync(`${DOCS_DIR}/_toc.yaml`, 'ax'); +const createReferenceSidebar = function(done) { + const fileContent = fs.readFileSync(`${DOCS_DIR}/blockly.mdx`, 'utf8'); const files = fs.readdirSync(DOCS_DIR); const map = buildAlternatePathsMap(files); - const referencePath = '/blockly/reference/js'; + + // Parse HTML tables from the file + const sections = parseHtmlTables(fileContent); + + let sidebarContent = 'export const referenceSidebar = [\n'; + + // Add overview + sidebarContent += ' {\n'; + sidebarContent += ' "type": "doc",\n'; + sidebarContent += ' "label": "Overview",\n'; + sidebarContent += ' "id": "reference/blockly"\n'; + sidebarContent += ' },\n'; + + // Process each section (Classes, Interfaces, Functions, etc.) + for (const [sectionName, items] of Object.entries(sections)) { + sidebarContent += ' {\n'; + sidebarContent += ' "type": "category",\n'; + sidebarContent += ` "label": "${sectionName}",\n`; + sidebarContent += ' "collapsible": true,\n'; + sidebarContent += ' "className": "hide-level-3",\n'; - const tocHeader = `toc: -- title: Overview - path: /blockly/reference/js/blockly.md\n`; - fs.writeSync(toc, tocHeader); - - // Generate a section of TOC for each section/heading in the overview file. - const sections = fileContent.split('##'); - for (let section of sections) { - // This converts the md table in each section to a JS object - const table = Extractor.extractObject(section, 'rows', false); - if (!table) { - continue; - } - // Get the name of the section, i.e. the text immediately after the `##` in - // the source doc - const sectionName = section.split('\n')[0].trim(); - fs.writeSync(toc, `- heading: ${sectionName}\n`); - for (let row in table) { - // After going through the Extractor, the markdown is now HTML. - // Each row in the table is now a link (anchor tag). - // Get the target of the link, excluding the first `.` since we don't want - // a relative path. - const path = /href="\.(.*?)"/.exec(row)?.[1]; - // Get the name of the link (text in between the and ) - const name = /">(.*?) 0) { + // Item with sub-pages - create a category + sidebarContent += ' {\n'; + sidebarContent += ' "type": "category",\n'; + sidebarContent += ` "label": "${itemName}",\n`; + sidebarContent += ' "link": {\n'; + sidebarContent += ' "type": "doc",\n'; + sidebarContent += ` "id": "reference/${itemPath}"\n`; + sidebarContent += ' },\n'; + sidebarContent += ' "items": [\n'; + + // Add sub-pages + for (const subPage of subPages) { + const subPageId = subPage.replace('blockly.', ''); + sidebarContent += ' {\n'; + sidebarContent += ' "type": "doc",\n'; + sidebarContent += ` "label": "${subPage}",\n`; + sidebarContent += ` "id": "reference/${subPage}"\n`; + sidebarContent += ' },\n'; } + + sidebarContent += ' ],\n'; + + if (sectionName === 'Classes' || sectionName === 'Abstract Classes') { + sidebarContent += ' "className": "hide-from-sidebar"\n'; + } + + sidebarContent += ' },\n'; + } else { + // Simple item without sub-pages + sidebarContent += ' {\n'; + sidebarContent += ' "type": "doc",\n'; + sidebarContent += ` "label": "${itemName}",\n`; + sidebarContent += ` "id": "reference/${itemPath}"\n`; + sidebarContent += ' },\n'; } } + + sidebarContent += ' ]\n'; + sidebarContent += ' },\n'; } - + + sidebarContent += '];\n'; + + // Write the file to the reference directory + if (!fs.existsSync(REFERENCE_SIDEBAR_DIR)) { + fs.mkdirSync(REFERENCE_SIDEBAR_DIR, { recursive: true }); + } + fs.writeFileSync(`${REFERENCE_SIDEBAR_DIR}/_reference.js`, sidebarContent); + done(); } export const docs = gulp.series( - generateApiJson, removeRenames, generateDocs, - gulp.parallel(prependBook, createToc)); - + generateApiJson, removeRenames, generateDocs, convertToMdx, cleanMdFiles, fixMdxIssues, prependFrontmatter, createReferenceSidebar); diff --git a/packages/blockly/scripts/gulpfiles/package_tasks.mjs b/packages/blockly/scripts/gulpfiles/package_tasks.mjs index 948f855b096..d69a426d29f 100644 --- a/packages/blockly/scripts/gulpfiles/package_tasks.mjs +++ b/packages/blockly/scripts/gulpfiles/package_tasks.mjs @@ -240,6 +240,11 @@ export function cleanReleaseDir() { * * Prerequisite: build. */ +export const typings = gulp.series( + gulp.parallel(build.cleanBuildDir, cleanReleaseDir), + build.tsc, + packageDTS); + export const pack = gulp.series( gulp.parallel( build.cleanBuildDir, diff --git a/packages/docs/.gitignore b/packages/docs/.gitignore new file mode 100644 index 00000000000..acf2e74db1b --- /dev/null +++ b/packages/docs/.gitignore @@ -0,0 +1,4 @@ +# Autogenerated reference docs, do not check in +docs/reference/ +.docusaurus +build/ diff --git a/packages/docs/.prettierignore b/packages/docs/.prettierignore new file mode 100644 index 00000000000..8fed2cb7bb5 --- /dev/null +++ b/packages/docs/.prettierignore @@ -0,0 +1,11 @@ +# Markdown/MDX (linted by ESLint + eslint-plugin-mdx instead) +*.md +*.mdx + +# Build artifacts +build/ +.docusaurus/ +node_modules/ + +# Auto-generated +CHANGELOG.md diff --git a/packages/docs/.prettierrc.json b/packages/docs/.prettierrc.json new file mode 100644 index 00000000000..0e3ca84133b --- /dev/null +++ b/packages/docs/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "bracketSameLine": true, + "proseWrap": "preserve" +} diff --git a/packages/docs/README.md b/packages/docs/README.md new file mode 100644 index 00000000000..2ea142ec257 --- /dev/null +++ b/packages/docs/README.md @@ -0,0 +1,65 @@ +# Blockly Documentation Website + +This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. + +## Installation + +Run `npm install` at the root of the blockly repo, then all other commands from the `packages/docs` directory. + +```bash +npm install +cd packages/docs +``` + +## Local development + +```bash +npm start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. + +## Build + +```bash +npm run build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +## Test your build locally + +```bash +npm run serve +``` + +The build folder is now served at http://localhost:3000/ + +## Formatting and linting + +```bash +# check formatting: +npm run format:check +# fix formatting: +npm run format +# check linting: +npm run lint +# fix linting: +npm run lint:fix +``` + +Prettier is used for formatting JavaScript files (the `format` script). + +ESlint is used for linting `.md` and `.mdx` files due to poor support for these in Prettier (the `lint` script). + +## Generating reference docs + +The API reference pages are auto-generated from the Blockly TypeScript source using `@microsoft/api-extractor` and `@microsoft/api-documenter`. This is a separate step from the Docusaurus build and must be run from the `packages/blockly` directory: + +```bash +cd packages/blockly +npm run build && npm run package +npm run docs +``` + +This generates MDX files into `packages/docs/docs/reference/`. These files are gitignored, so this needs to be run locally (and / or in CI). diff --git a/packages/docs/docs/codelabs/context-menu-option/add-a-context-menu-item.mdx b/packages/docs/docs/codelabs/context-menu-option/add-a-context-menu-item.mdx new file mode 100644 index 00000000000..5dbcc857899 --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/add-a-context-menu-item.mdx @@ -0,0 +1,87 @@ +--- +slug: /codelabs/context-menu-option/add-a-context-menu-item/index.html +description: How to add a context menu item to the registry. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Customizing context menus + +## 3. Add a context menu item + +In this section you will create a very basic `Blockly.ContextMenuRegistry.RegistryItem`, then register it to display when you open a context menu on the workspace, a block, or a comment. + +### The RegistryItem + +A context menu consists of one or more menu options that a user can select. Blockly stores information about menu option as items in a registry. You can think of the _registry items_ as templates for constructing _menu options_. When the user opens a context menu, Blockly retrieves all of the registry items that apply to the current context and uses them to construct a list of menu options. + +Each item in the registry has several properties: + +- `displayText`: The text to show in the menu. Either a string, or HTML, or a function that returns either of the former. +- `preconditionFn`: Function that returns one of `'enabled'`, `'disabled'`, or `'hidden'` to determine whether and how the menu option should be rendered. +- `callback`: A function called when the menu option is selected. +- `id`: A unique string id for the item. +- `weight`: A number that determines the sort order of the option. Options with higher weights appear later in the context menu. + +We will discuss these in detail in later sections of the codelab. + +### Make a RegistryItem + +Add a function to `index.js` named `registerHelloWorldItem`. Create a new registry item in your function: + +```js +function registerHelloWorldItem() { + const helloWorldItem = { + displayText: 'Hello World', + preconditionFn: function (scope) { + return 'enabled'; + }, + callback: function (scope) {}, + id: 'hello_world', + weight: 100, + }; +} +``` + +Call your function from `start`: + +```js +function start() { + registerHelloWorldItem(); + + Blockly.ContextMenuItems.registerCommentOptions(); + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxSimple, + }); +} +``` + +### Register it + +Next, register your item with Blockly: + +```js +function registerHelloWorldItem() { + const helloWorldItem = { + // ... + }; + Blockly.ContextMenuRegistry.registry.register(helloWorldItem); +} +``` + +:::note +you will never need to make a new `ContextMenuRegistry`. Always use the singleton `Blockly.ContextMenuRegistry.registry`. +::: + +### Test it + +Reload your web page and open a context menu on the workspace (right-click with a mouse, or press `Ctrl+Enter` (Windows) or `Command+Enter` (Mac) if you are navigating Blockly with the keyboard). You should see a new option labeled "Hello World" at the bottom of the context menu. + + + {' '} + ![A context menu. The last option says "Hello + World".](../../../static/images/codelabs/context-menu-option/hello_world.png){' '} + + +Next, drag a block onto the workspace and open a context menu on the block. You'll see "Hello World" at the bottom of the block's context menu. Finally, open a context menu on the workspace and create a comment, then open a context menu on the comment's header. "Hello World" should be at the bottom of the context menu. diff --git a/packages/docs/docs/codelabs/context-menu-option/callback.mdx b/packages/docs/docs/codelabs/context-menu-option/callback.mdx new file mode 100644 index 00000000000..a3e06359189 --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/callback.mdx @@ -0,0 +1,33 @@ +--- +slug: /codelabs/context-menu-option/callback/index.html +description: How to add a callback to a context menu item. +--- + +# Customizing context menus + +## 7. Callback + +The callback function determines what happens when you select the context menu option. Like the precondition, it can use the `scope` argument to access the Blockly component on which the context menu was invoked. + +It is also passed a `PointerEvent` which is the original event that triggered opening the context menu (not the event that selected the current option). This lets you, for example, figure out where on the workspace the context menu was opened so you can create a new element there. + +As an example, update the help item's `callback` to add a block to the workspace when selected: + +```js + callback: function(scope) { + Blockly.serialization.blocks.append({ + 'type': 'text', + 'fields': { + 'TEXT': 'Now there is a block' + } + }, scope.focusedNode); + }, +``` + +### Test it + +- Reload the page and open a context menu on the workspace. +- Select the **Help** option. +- A text block should appear in the top left of the workspace. + +![A text block containing the text "Now there is a block".](../../../static/images/codelabs/context-menu-option/there_is_a_block.png) diff --git a/packages/docs/docs/codelabs/context-menu-option/codelab-overview.mdx b/packages/docs/docs/codelabs/context-menu-option/codelab-overview.mdx new file mode 100644 index 00000000000..486ed67f67c --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/codelab-overview.mdx @@ -0,0 +1,31 @@ +--- +pagination_prev: null +slug: /codelabs/context-menu-option/codelab-overview/index.html +description: Overview of the "Customizing context menus" codelab. +--- + +# Customizing context menus + +## 1. Codelab overview + +### What you'll learn + +In this codelab you will learn how to: + +- Add a context menu option to the workspace. +- Add a context menu option to all blocks. +- Use precondition functions to hide or disable context menu options. +- Take an action when a menu option is selected. +- Customize ordering and display text for context menu options. + +### What you'll build + +A very simple Blockly workspace with a few new context menu options. + +### What you'll need + +- A browser. +- A text editor. +- Basic knowledge of HTML, CSS, and JavaScript. + +This codelab is focused on Blockly's context menus. Non-relevant concepts and code are glossed over and are provided for you to simply copy and paste. diff --git a/packages/docs/docs/codelabs/context-menu-option/complete-code/index.html b/packages/docs/docs/codelabs/context-menu-option/complete-code/index.html new file mode 100644 index 00000000000..c0821a8ec2e --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/complete-code/index.html @@ -0,0 +1,40 @@ + + + + + Context Menu Codelab + + + + + + + + +

Context Menu Codelab

+
+ + diff --git a/packages/docs/docs/codelabs/context-menu-option/complete-code/index.js b/packages/docs/docs/codelabs/context-menu-option/complete-code/index.js new file mode 100644 index 00000000000..8d192656bb2 --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/complete-code/index.js @@ -0,0 +1,115 @@ +'use strict'; + +let workspace = null; + +function start() { + registerHelloWorldItem(); + registerHelpItem(); + registerDisplayItem(); + Blockly.ContextMenuRegistry.registry.unregister('workspaceDelete'); + registerSeparators(); + + Blockly.ContextMenuItems.registerCommentOptions(); + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxSimple, + }); +} + +function registerHelloWorldItem() { + const helloWorldItem = { + displayText: 'Hello World', + preconditionFn: function (scope) { + // Only display this option for workspaces and blocks. + if ( + scope.focusedNode instanceof Blockly.WorkspaceSvg || + scope.focusedNode instanceof Blockly.BlockSvg + ) { + // Enable for the first 30 seconds of every minute; disable for the next 30 seconds. + const now = new Date(Date.now()); + if (now.getSeconds() < 30) { + return 'enabled'; + } + return 'disabled'; + } + return 'hidden'; + }, + callback: function (scope) {}, + id: 'hello_world', + weight: 100, + }; + // Register. + Blockly.ContextMenuRegistry.registry.register(helloWorldItem); +} + +function registerHelpItem() { + const helpItem = { + displayText: 'Help! There are no blocks', + preconditionFn: function (scope) { + // Only display this option on workspace context menus. + if (!(scope.focusedNode instanceof Blockly.WorkspaceSvg)) return 'hidden'; + // Use the focused node, which is a WorkspaceSvg, to check for blocks on the workspace. + if (!scope.focusedNode.getTopBlocks().length) { + return 'enabled'; + } + return 'hidden'; + }, + // Use the focused node in the callback function to add a block to the workspace. + callback: function (scope) { + Blockly.serialization.blocks.append( + { + type: 'text', + fields: { + TEXT: 'Now there is a block', + }, + }, + scope.focusedNode, + ); + }, + id: 'help_no_blocks', + weight: 100, + }; + Blockly.ContextMenuRegistry.registry.register(helpItem); +} + +function registerDisplayItem() { + const displayItem = { + // Use the focused node (a BlockSvg) to set display text dynamically based on the type of the block. + displayText: function (scope) { + if (scope.focusedNode.type.startsWith('text')) { + return 'Text block'; + } else if (scope.focusedNode.type.startsWith('controls')) { + return 'Controls block'; + } else { + return 'Some other block'; + } + }, + preconditionFn: function (scope) { + return scope.focusedNode instanceof Blockly.BlockSvg + ? 'enabled' + : 'hidden'; + }, + callback: function (scope) {}, + id: 'display_text_example', + weight: 100, + }; + Blockly.ContextMenuRegistry.registry.register(displayItem); +} + +function registerSeparators() { + const workspaceSeparator = { + id: 'workspace_separator', + scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE, + weight: 99, + separator: true, + }; + Blockly.ContextMenuRegistry.registry.register(workspaceSeparator); + + const blockSeparator = { + id: 'block_separator', + scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK, + weight: 99, + separator: true, + }; + Blockly.ContextMenuRegistry.registry.register(blockSeparator); +} diff --git a/packages/docs/docs/codelabs/context-menu-option/display-text.mdx b/packages/docs/docs/codelabs/context-menu-option/display-text.mdx new file mode 100644 index 00000000000..d25b2fec16e --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/display-text.mdx @@ -0,0 +1,46 @@ +--- +slug: /codelabs/context-menu-option/display-text/index.html +description: How to set the display text of a context menu item. +--- + +# Customizing context menus + +## 8. Display text + +So far the `displayText` has always been a simple string, but it can also be HTML, or a function that returns either of the former. Using a function can be useful when you want a context-dependent message. + +When defined as a function `displayText` accepts a `scope` argument, just like `callback` and `preconditionFn`. + +As an example, add this registry item. The display text depends on the block type. + +```js +function registerDisplayItem() { + const displayItem = { + displayText: function (scope) { + if (scope.focusedNode.type.startsWith('text')) { + return 'Text block'; + } else if (scope.focusedNode.type.startsWith('controls')) { + return 'Controls block'; + } else { + return 'Some other block'; + } + }, + preconditionFn: function (scope) { + return scope.focusedNode instanceof Blockly.BlockSvg + ? 'enabled' + : 'hidden'; + }, + callback: function (scope) {}, + id: 'display_text_example', + weight: 100, + }; + Blockly.ContextMenuRegistry.registry.register(displayItem); +} +``` + +As usual, remember to call `registerDisplayItem()` from your `start` function. + +### Test it + +- Reload the workspace and open context menus on various blocks. +- The last context menu option's text should vary based on the block type. diff --git a/packages/docs/docs/codelabs/context-menu-option/precondition-blockly-state.mdx b/packages/docs/docs/codelabs/context-menu-option/precondition-blockly-state.mdx new file mode 100644 index 00000000000..8b81edb7b28 --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/precondition-blockly-state.mdx @@ -0,0 +1,36 @@ +--- +slug: /codelabs/context-menu-option/precondition-blockly-state/index.html +description: How to include a context menu item based on Blockly's state. +--- + +# Customizing context menus + +## 6. Precondition: Blockly state + +Disabling your context menu options half of the time is not useful, but you may want to show or hide an option based on what the user is doing. For example, let's show a **Help** option in the context menu if the user doesn't have any blocks on the workspace. Add this code in `index.js`: + +```js +function registerHelpItem() { + const helpItem = { + displayText: 'Help! There are no blocks', + preconditionFn: function (scope) { + if (!(scope.focusedNode instanceof Blockly.WorkspaceSvg)) return 'hidden'; + if (!scope.focusedNode.getTopBlocks().length) { + return 'enabled'; + } + return 'hidden'; + }, + callback: function (scope) {}, + id: 'help_no_blocks', + weight: 100, + }; + Blockly.ContextMenuRegistry.registry.register(helpItem); +} +``` + +Don't forget to call `registerHelpItem` from your `start` function. + +### Test it + +- Reload your page and open a context menu on the workspace. You should see an option labeled "Help! There are no blocks". +- Add a block to the workspace and open a context menu on the workspace again. The **Help** option should be gone. diff --git a/packages/docs/docs/codelabs/context-menu-option/precondition-external-state.mdx b/packages/docs/docs/codelabs/context-menu-option/precondition-external-state.mdx new file mode 100644 index 00000000000..1b8dcd2723e --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/precondition-external-state.mdx @@ -0,0 +1,32 @@ +--- +slug: /codelabs/context-menu-option/precondition-external-state/index.html +description: How to include a context menu item based on an external condition. +--- + +# Customizing context menus + +## 5. Precondition: External state + +Use of the `preconditionFn` is not limited to checking the type of the Blockly component that the context menu was invoked on. You can use it to check for conditions entirely outside of Blockly. For instance, let's disable `helloWorldItem` for the second half of every minute: + +```js + preconditionFn: function (scope) { + if ( + scope.focusedNode instanceof Blockly.WorkspaceSvg || + scope.focusedNode instanceof Blockly.BlockSvg + ) { + const now = new Date(Date.now()); + if (now.getSeconds() < 30) { + return 'enabled'; + } + return 'disabled'; + } + return 'hidden'; + }, +``` + +### Test it + +Reload your workspace, check your watch, and open a context menu on the workspace to confirm the timing. The option will always be in the menu, but will sometimes be greyed out. + +![A context menu. The last option says "Hello World" but the text is grey, indicating that it cannot be selected.](../../../static/images/codelabs/context-menu-option/hello_world_grey.png) diff --git a/packages/docs/docs/codelabs/context-menu-option/precondition-node-type.mdx b/packages/docs/docs/codelabs/context-menu-option/precondition-node-type.mdx new file mode 100644 index 00000000000..f98c21bc4e5 --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/precondition-node-type.mdx @@ -0,0 +1,46 @@ +--- +slug: /codelabs/context-menu-option/precondition-node-type/index.html +description: How to include a context menu item based on the node type. +--- + +# Customizing context menus + +## 4 . Precondition: Node type + +Each registry item has a `preconditionFn`. It is called by Blockly to decide whether and how to display an option on a context menu. You'll use it to display the "Hello, World" option on workspace and block context menus, but not on comment context menus. + +### The scope argument + +The `scope` argument is an object that is passed to `preconditionFn`. You'll use the `scope.focusedNode` property to determine which object the context menu was invoked on. Why a focused node? Because Blockly keeps track of where the user is -- that is, what node (component) the user is focused on -- and opens the context menu on that node. + +### Return value + +The return value of `preconditionFn` is `'enabled'`, `'disabled'`, or `'hidden'`. An **enabled** option is shown with black text and is selectable. A **disabled** option is shown with grey text and is not selectable. A **hidden** option is not included in the context menu at all. + +### Write the function + +You can now test `scope.focusedNode` to display the "Hello World" option in workspace and block context menus, but not on any others. Change `preconditionFn` to: + +```js + const helloWorldItem = { + ... + preconditionFn: function (scope) { + if ( + scope.focusedNode instanceof Blockly.WorkspaceSvg || + scope.focusedNode instanceof Blockly.BlockSvg + ) { + return 'enabled'; + } + return 'hidden'; + }, + ... + }; +``` + +Notice that the code tests for where context menus are allowed, rather than where they are not allowed. This is because custom code (such as a plugin) can add context menus to any Blockly component that can be focused. Thus, testing for specific types rather than allowing all (or all but certain types) ensures that context menus are not shown on more components than you anticipated. + +### Test it + +Open a context menu on the workspace, a block, and a comment. You should see a "Hello World" option on the workspace and block context menus, but not on the comment context menu. + +![An if block with a context menu with five options. The last option says "Hello World".](../../../static/images/codelabs/context-menu-option/hello_world_block.png) diff --git a/packages/docs/docs/codelabs/context-menu-option/separators.mdx b/packages/docs/docs/codelabs/context-menu-option/separators.mdx new file mode 100644 index 00000000000..999ce8f262c --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/separators.mdx @@ -0,0 +1,42 @@ +--- +slug: /codelabs/context-menu-option/separators/index.html +description: How to add a separator to a context menu. +--- + +# Customizing context menus + +## 10. Separators + +You can use separators to break your context menu into different sections. + +Separators differ from other items in two ways: They cannot have `displayText`, `preconditionFn`, or `callback` properties and they can only be scoped with the `scopeType` property. The latter accepts an enum value of `Blockly.ContextMenuRegistry.ScopeType.WORKSPACE`, `Blockly.ContextMenuRegistry.ScopeType.BLOCK`, or `Blockly.ContextMenuRegistry.ScopeType.COMMENT`. + +Use the `weight` property to position the separator. You'll use a weight of `99` to position the separator just above the other options you added, all of which have a weight of `100`. + +You need to add a separate item for each separator: + +```js +function registerSeparators() { + const workspaceSeparator = { + id: 'workspace_separator', + scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE, + weight: 99, + separator: true, + }; + Blockly.ContextMenuRegistry.registry.register(workspaceSeparator); + + const blockSeparator = { + id: 'block_separator', + scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK, + weight: 99, + separator: true, + }; + Blockly.ContextMenuRegistry.registry.register(blockSeparator); +} +``` + +As usual, remember to call `registerSeparators()` from your `start` function. + +### Test it + +Open a context menu on the workspace and a block and check that the separator line is there. diff --git a/packages/docs/docs/codelabs/context-menu-option/setup.mdx b/packages/docs/docs/codelabs/context-menu-option/setup.mdx new file mode 100644 index 00000000000..fc9e4359e60 --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/setup.mdx @@ -0,0 +1,41 @@ +--- +slug: /codelabs/context-menu-option/setup/index.html +description: Setting up the "Customizing context menus" codelab. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Customizing context menus + +## 2. Setup + +### Download the sample code + +You can get the sample code for this code by either downloading the zip here: + +[Download zip](https://github.com/RaspberryPiFoundation/blockly/archive/main.zip) + +or by cloning this git repo: + +```bash +git clone https://github.com/RaspberryPiFoundation/blockly.git +``` + +If you downloaded the source as a zip, unpacking it should give you a root folder named `blockly-main`. + +The relevant files are in `docs/docs/codelabs/context-menu-option`. There are two versions of the app: + +- `starter-code/`: The starter code that you'll build upon in this codelab. +- `complete-code/`: The code after completing the codelab, in case you get lost or want to compare to your version. + +Each folder contains: + +- `index.js` - The codelab's logic. To start, it just injects a simple workspace. +- `index.html` - A web page containing a simple blockly workspace. + +To run the code, simple open `starter-code/index.html` in a browser. You should see a Blockly workspace with an always-open flyout. + + + ![A web page with the text "Context Menu Codelab" and a simple Blockly + workspace.](../../../static/images/codelabs/context-menu-option/starter_workspace.png) + diff --git a/packages/docs/docs/codelabs/context-menu-option/starter-code/index.html b/packages/docs/docs/codelabs/context-menu-option/starter-code/index.html new file mode 100644 index 00000000000..c0821a8ec2e --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/starter-code/index.html @@ -0,0 +1,40 @@ + + + + + Context Menu Codelab + + + + + + + + +

Context Menu Codelab

+
+ + diff --git a/packages/docs/docs/codelabs/context-menu-option/starter-code/index.js b/packages/docs/docs/codelabs/context-menu-option/starter-code/index.js new file mode 100644 index 00000000000..bf58b8165ec --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/starter-code/index.js @@ -0,0 +1,11 @@ +'use strict'; + +let workspace = null; + +function start() { + Blockly.ContextMenuItems.registerCommentOptions(); + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxSimple, + }); +} diff --git a/packages/docs/docs/codelabs/context-menu-option/summary.mdx b/packages/docs/docs/codelabs/context-menu-option/summary.mdx new file mode 100644 index 00000000000..2a7fcb99c5a --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/summary.mdx @@ -0,0 +1,17 @@ +--- +pagination_next: null +slug: /codelabs/context-menu-option/summary/index.html +description: Summary of the "Customizing context menus" codelab. +--- + +# Customizing context menus + +## 11. Summary + +In this codelab you have learned how to create and modify context menu options. You have learned about scope, preconditions, callbacks, and display text. + +### Additional information + +- [Context menu documentation](/guides/configure/web/context-menus) + +- You can also define [block context menus](/guides/configure/web/context-menus#customize-per-block) directly on a block definition, which is equivalent to adding a precondition based on the type of the block. diff --git a/packages/docs/docs/codelabs/context-menu-option/weight-and-id.mdx b/packages/docs/docs/codelabs/context-menu-option/weight-and-id.mdx new file mode 100644 index 00000000000..8b586eb07fb --- /dev/null +++ b/packages/docs/docs/codelabs/context-menu-option/weight-and-id.mdx @@ -0,0 +1,32 @@ +--- +slug: /codelabs/context-menu-option/weight-and-id/index.html +description: How to set the weight and ID of a context menu item. +--- + +# Customizing context menus + +## 9. Weight and id + +The last two properties of a registry item are `weight` and `id`. + +### Weight + +The `weight` property is a number that determines the order of the options in the context menu. A higher number means your option will be lower in the list. + +Test this by updating the `weight` property on one of your new registry items and confirming that the corresponding option moves to the top or bottom of the list. + +Note that weight does not have to be positive or integer-valued. + +### Id + +Every registry item has an `id` that can be used to unregister it. You can use this to get rid of registry items that you don't want. + +For instance, you can remove the item that deletes all blocks on the workspace: + +```js +Blockly.ContextMenuRegistry.registry.unregister('workspaceDelete'); +``` + +### Default items + +For a list of the default registry items that Blockly provides, look at [contextmenu_items.ts](https://github.com/RaspberryPiFoundation/blockly/blob/main/core/contextmenu_items.ts). Each entry contains both the `id` and the `weight`. diff --git a/packages/docs/docs/codelabs/css/blocks.mdx b/packages/docs/docs/codelabs/css/blocks.mdx new file mode 100644 index 00000000000..d71f33572f3 --- /dev/null +++ b/packages/docs/docs/codelabs/css/blocks.mdx @@ -0,0 +1,224 @@ +--- +title: Use CSS in Blockly - Blocks +slug: /codelabs/css/blocks/index.html +description: Styling blocks with CSS +--- + +# Use CSS in Blockly + +## 6. Blocks + +In this section, you will create CSS rules to assign the colours used by the [blocks section](/codelabs/theme-extension-identifier/customize-block-styles/index.html) of the themes codelab to the logic, loops, text, and lists blocks. This is a bit more complex than setting component or category colours and you'll do it in several steps. + +### Block fill and stroke + +Your first step is to set the `fill` and `stroke` of the logic blocks. + +Note that setting the `fill` and `stroke` is specific to the +[renderer](/guides/create-custom-blocks/renderers/overview) +you are using. (In this codelab, you are using the Thrasos renderer.) An +important consequence of this is that you need different CSS for different +renderers. + +#### Identify the block element + +Drag an `if do` block onto the workspace and find it with the element inspector: + +``` + +
+
+ + + + +``` + +Notice that the block's `` element has classes for the block's type (`controls_if`) and style (`logic_blocks`). These are the values of the [`type` and `style` properties in the block's definition](https://github.com/RaspberryPiFoundation/blockly/blob/1c280d10cc1dcad7d50a1678211871058d4e9cfb/blocks/logic.ts#L50). You will use the style class to assign the same colour to all of the logic blocks. + +(If you were building blocks from scratch and wanted to avoid themes, you would assign this class with the `classes` property in the block definition. However, because these are standard blocks and they were built with themes in mind, using the style class works just as well.) + +#### Choose an element to use + +Next, you need to decide what element to use in your colour rule. The `` element identifies the block but doesn't draw it. Instead, you can use the `` element's first child. This is a `` element with `fill` and `stroke` presentation attributes, which are easily overridden. + +Note that different renderers use different numbers of `` elements to +draw a block: Thrasos uses a single `` element, Geras uses three `` +elements, and Zelos uses one `` for the outside of the block and one +`` for each inline input. + +#### Choose colours + +The last step before writing your colour rules is to decide what colours to use. The Halloween theme in the themes codelab sets three colours: + +``` + 'logic_blocks': { + 'colourPrimary': "#8b4513", + 'colourSecondary':"#ff0000", + 'colourTertiary':"#c5eaff" + }, +``` + +How these colours are used depends on the renderer. The Thrasos renderer uses +the primary colour as the `fill` of the block, the tertiary colour as the +`stroke`, and the secondary colour as the `fill` when the block is a +[shadow block](/guides/configure/web/toolboxes/preset#shadow-blocks). + +#### Add your rules + +You're now ready to add your rules to set the `fill` and `stroke` of the logic blocks: + +```css +/**********/ +/* BLOCKS */ +/**********/ + +/* LOGIC BLOCKS */ + +.logic_blocks > .blocklyPath { + fill: #8b4513; + stroke: #c5eaff; +} + +.logic_blocks.blocklyShadow > .blocklyPath { + fill: #ff0000; + stroke: none; +} +``` + +Refresh your web page and open the **Logic** category. You should see that the +logic blocks are now rendered in autumnal brown instead of blue: +![A Blockly editor with the Logic category open. The blocks in the flyout are brown.](../../../static/images/codelabs/css/blocks-logic.png) + +### Disabled blocks + +Your next step is to handle disabled blocks. Drag an `if do` block and any block from the **Loops** category onto the workspace. Right-click on each block and disable it using the context menu. Notice that the loop block has a cross-hatch pattern while the `if do` block does not: + +![An 'if do' block and a 'repeat 10 times' block, both of which are disabled. The 'if do' block is solid brown and the 'repeat 10 times' block has a cross-hatch pattern.](../../../static/images/codelabs/css/blocks-disabled-wrong.png) + +This is because the rules you just added have the same specificity as the Blockly rules that set the cross-hatch pattern. (You can see this if you click on the `if do` block's `` element and inspect its styles.) Because your rules occur later in the document, they take precedence. To use the standard CSS for disabled blocks, add a `:not(.blocklyDisabledPattern)` to your rules: + +```css +/* LOGIC BLOCKS */ + +.logic_blocks:not(.blocklyDisabledPattern) > .blocklyPath { + fill: #8b4513; + stroke: #c5eaff; +} + +.logic_blocks:not(.blocklyDisabledPattern).blocklyShadow > .blocklyPath { + fill: #ff0000; + stroke: none; +} +``` + +Refresh your page, drag the `if do` block onto the workspace, and disable it. It should now use the disabled pattern: + +![A disabled 'if do' block with a cross-hatch pattern.](../../../static/images/codelabs/css/blocks-disabled-right.png) + +### Dropdown arrows + +You now need to handle dropdown arrows. Drag a logic comparison block onto the workspace and look closely at the inverted triangle in the dropdown field -- it's blue even though the rest of the block is brown: + +![A brown logic comparison block with a blue dropdown arrow.](../../../static/images/codelabs/css/blocks-arrow-wrong.png) + +If you look at the triangle with the element inspector, you'll see that it's a character in an SVG `` element: + +``` + +
+
+ + + + + + + +``` + +You can also see that its colour is set with a `style` attribute, which can only be overridden with an `!important` declaration. To do this, add the following rules: + +```css +.logic_blocks > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #8b4513 !important; +} + +.logic_blocks.blocklyShadow > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #ff0000 !important; +} +``` + +Reload your page and drag the comparison block out again. The arrow should be the same colour as the rest of the block: + +![A brown logic comparison block with a brown dropdown arrow.](../../../static/images/codelabs/css/blocks-arrow-right.png) + +### Loop, text, and list blocks + +Your last step is to add similar rules for the loop, text, and list blocks: + +```css +/* LOOP BLOCKS */ + +.loop_blocks:not(.blocklyDisabledPattern) > .blocklyPath { + fill: #85e21f; + stroke: #c5eaff; +} + +.loop_blocks:not(.blocklyDisabledPattern).blocklyShadow > .blocklyPath { + fill: #ff0000; + stroke: none; +} + +.loop_blocks > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #85e21f !important; +} + +.loop_blocks.blocklyShadow > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #ff0000 !important; +} + +/* TEXT BLOCKS */ + +.text_blocks:not(.blocklyDisabledPattern) > .blocklyPath { + fill: #fe9b13; + stroke: #c5eaff; +} + +.text_blocks:not(.blocklyDisabledPattern).blocklyShadow > .blocklyPath { + fill: #ff0000; + stroke: none; +} + +.text_blocks > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #fe9b13 !important; +} + +.text_blocks.blocklyShadow > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #ff0000 !important; +} + +/* LIST BLOCKS */ + +.list_blocks:not(.blocklyDisabledPattern) > .blocklyPath { + fill: #4a148c; + stroke: #cdb6e9; +} + +.list_blocks:not(.blocklyDisabledPattern).blocklyShadow > .blocklyPath { + fill: #ad7be9; + stroke: none; +} + +.list_blocks > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #4a148c !important; +} + +.list_blocks.blocklyShadow > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #ad7be9 !important; +} +``` + +And that's it! Reload your page and explore the blocks in your Halloween-themed editor: + +![A Blockly editor with Halloween colors: a yellow toolbox, orange workspace, red scrollbars, and neon green loop blocks.](../../../static/images/codelabs/css/blocks-loops.png) diff --git a/packages/docs/docs/codelabs/css/categories.mdx b/packages/docs/docs/codelabs/css/categories.mdx new file mode 100644 index 00000000000..0575518de37 --- /dev/null +++ b/packages/docs/docs/codelabs/css/categories.mdx @@ -0,0 +1,155 @@ +--- +title: Use CSS in Blockly - Toolbox Categories +slug: /codelabs/css/categories/index.html +description: Styling toolbox categories with CSS +--- + +# Use CSS in Blockly + +## 5. Toolbox categories + +In this section, you will create CSS rules to assign the colours used by the [categories section](/codelabs/theme-extension-identifier/customize-category-styles/index.html) of the themes codelab to the toolbox's categories. + +### Identify the category element + +Your first rule will set the colour of the **Logic** category. This rule needs to uniquely identify the element used by the **Logic** category, so open the developer tools and find the `blocklyToolboxCategory` `
` for the **Logic** category: + +``` + +
+
+
+
+
+
+``` + +Unfortunately, the only thing that distinguishes this `
` from other category `
`s is a generated `id` attribute (`blockly-1`). This isn't stable enough to use in a CSS rule -- for example, if you switched the order of two categories you'd also have to switch the selectors in their rules. + +To solve this problem, you'll need to add a class to the +`blocklyToolboxCategory` `
` for the **Logic** category. Open the +`toolbox.js` file and find the definition of the **Logic** category: + +```js + { + kind: 'category', + name: 'Logic', + categorystyle: 'logic_category', + contents: [...], + }, +``` + +The `categorystyle` property assigns a style that is used by a theme. Because +you're not using themes to assign category colours, you don't need the +`categorystyle` property. Delete it and add a `cssConfig` property that adds two +classes to the **Logic** category's `
`: `logic_category` uniquely +identifies the `
` and `blocklyToolboxCategory` is used by Blockly's CSS to +define rules that apply to all categories. + +```js + { + kind: 'category', + name: 'Logic', + cssConfig: { + row: 'blocklyToolboxCategory logic_category', + }, + contents: [...], + }, +``` + +For a complete explanation of how `cssConfig` works, see [Custom CSS classes](/guides/configure/web/toolboxes/appearance#custom-css-classes) in the toolbox documentation. + +### Add your rules + +Next, add the following rules, which set the row colour and its colour when selected: + +```css +/**************/ +/* CATEGORIES */ +/**************/ + +.logic_category { + border-left: 8px solid #8b4513; +} + +.logic_category.blocklyToolboxSelected { + background-color: #8b4513 !important; +} +``` + +Refresh your web page and click the **Logic** category. The row is highlighted with your new colour: + +![A Blockly editor with the Logic category open. The category name is written in white on a brown background.](../../../static/images/codelabs/css/categories-logic.png) + +### Update the other categories + +Before you can write rules for the remaining categories, you need to replace `categorystyle` with `cssConfig` in each of their definitions: + +```js + { + kind: 'category', + name: 'Loops', + cssConfig: { + row: 'blocklyToolboxCategory loop_category', + }, + contents: [...], + }, + + // Repeat for remaining categories +``` + +Next, add the following rules to `halloween.css`. These rules use the colours from themes codelab for the **Loops**, **Text**, and **Lists** categories and the colours from the Classic theme (the default theme) for the **Math**, **Variables**, and **Functions** categories. + +```css +.loop_category { + border-left: 8px solid #85e21f; +} + +.loop_category.blocklyToolboxSelected { + background-color: #85e21f !important; +} + +.math_category { + border-left: 8px solid #5b67a5; +} + +.math_category.blocklyToolboxSelected { + background-color: #5b67a5 !important; +} + +.text_category { + border-left: 8px solid #fe9b13; +} + +.text_category.blocklyToolboxSelected { + background-color: #fe9b13 !important; +} + +.list_category { + border-left: 8px solid #4a148c; +} + +.list_category.blocklyToolboxSelected { + background-color: #4a148c !important; +} + +.variable_category { + border-left: 8px solid #a55b80; +} + +.variable_category.blocklyToolboxSelected { + background-color: #a55b80 !important; +} + +.procedure_category { + border-left: 8px solid #b88cc0; +} + +.procedure_category.blocklyToolboxSelected { + background-color: #b88cc0 !important; +} +``` + +Refresh your web page. You should see the new colours beside each category: + +![A Blockly editor with Halloween colours next to each category.](../../../static/images/codelabs/css/categories-halloween.png) diff --git a/packages/docs/docs/codelabs/css/codelab-overview.mdx b/packages/docs/docs/codelabs/css/codelab-overview.mdx new file mode 100644 index 00000000000..756a8458656 --- /dev/null +++ b/packages/docs/docs/codelabs/css/codelab-overview.mdx @@ -0,0 +1,36 @@ +--- +pagination_prev: null +title: Use CSS in Blockly - Codelab Overview +slug: /codelabs/css/codelab-overview/index.html +description: Overview of the CSS in Blockly codelab +--- + +# Use CSS in Blockly + +## 1. Codelab overview + +### What you'll learn + +In this codelab you will learn how to use CSS to customize the colours of: + +- Components +- Categories +- Blocks + +If you don't need the fine-grained control provided by CSS, consider using +themes instead. For more information, see the +[Customizing your themes](/codelabs/theme-extension-identifier/codelab-overview/index.html) +codelab. + +### What you'll build + +A simple Blockly workspace that uses the same Halloween colours as the [Customizing your themes](/codelabs/theme-extension-identifier/codelab-overview/index.html) codelab. + +### What you'll need + +- A browser +- Basic knowledge of HTML, CSS, SVG, and JavaScript. +- Basic knowledge of your browser's developer tools. +- Basic understanding of Blockly, including workspace components, category toolboxes, block definitions, and themes. + +This codelab is focused on using CSS with Blockly. Non-relevant concepts are glossed over and provided for you to simply copy and paste. diff --git a/packages/docs/docs/codelabs/css/complete-code/halloween.css b/packages/docs/docs/codelabs/css/complete-code/halloween.css new file mode 100644 index 00000000000..052cf0ddef2 --- /dev/null +++ b/packages/docs/docs/codelabs/css/complete-code/halloween.css @@ -0,0 +1,184 @@ +/**************/ +/* COMPONENTS */ +/**************/ + +.blocklySvg { + background-color: #ff7518; +} + +.blocklyMutatorBackground { + fill: #ff7518; +} + +.blocklyToolbox { + background-color: #f9c10e; + color: #fff; +} + +.blocklyFlyoutBackground { + fill: #252526; + fill-opacity: 1; +} + +.blocklyFlyoutLabel > .blocklyFlyoutLabelText { + fill: #ccc !important; +} + +.blocklyFlyoutButton > .blocklyText { + fill: #ccc !important; +} + +.blocklyScrollbarHandle { + fill: #ff0000; + fill-opacity: 0.4; +} + +.blocklyInsertionMarker > .blocklyPath { + fill: #fff !important; + fill-opacity: 0.3 !important; + stroke: none; +} + +/**************/ +/* CATEGORIES */ +/**************/ + +.logic_category { + border-left: 8px solid #8b4513; +} + +.logic_category.blocklyToolboxSelected { + background-color: #8b4513 !important; +} + +.loop_category { + border-left: 8px solid #85e21f; +} + +.loop_category.blocklyToolboxSelected { + background-color: #85e21f !important; +} + +.math_category { + border-left: 8px solid #5b67a5; +} + +.math_category.blocklyToolboxSelected { + background-color: #5b67a5 !important; +} + +.text_category { + border-left: 8px solid #fe9b13; +} + +.text_category.blocklyToolboxSelected { + background-color: #fe9b13 !important; +} + +.list_category { + border-left: 8px solid #4a148c; +} + +.list_category.blocklyToolboxSelected { + background-color: #4a148c !important; +} + +.variable_category { + border-left: 8px solid #a55b80; +} + +.variable_category.blocklyToolboxSelected { + background-color: #a55b80 !important; +} + +.procedure_category { + border-left: 8px solid #b88cc0; +} + +.procedure_category.blocklyToolboxSelected { + background-color: #b88cc0 !important; +} + +/**********/ +/* BLOCKS */ +/**********/ + +/* LOGIC BLOCKS */ + +.logic_blocks:not(.blocklyDisabledPattern) > .blocklyPath { + fill: #8b4513; + stroke: #c5eaff; +} + +.logic_blocks:not(.blocklyDisabledPattern).blocklyShadow > .blocklyPath { + fill: #ff0000; + stroke: none; +} + +.logic_blocks > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #8b4513 !important; +} + +.logic_blocks.blocklyShadow > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #ff0000 !important; +} + +/* LOOP BLOCKS */ + +.loop_blocks:not(.blocklyDisabledPattern) > .blocklyPath { + fill: #85e21f; + stroke: #c5eaff; +} + +.loop_blocks:not(.blocklyDisabledPattern).blocklyShadow > .blocklyPath { + fill: #ff0000; + stroke: none; +} + +.loop_blocks > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #85e21f !important; +} + +.loop_blocks.blocklyShadow > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #ff0000 !important; +} + +/* TEXT BLOCKS */ + +.text_blocks:not(.blocklyDisabledPattern) > .blocklyPath { + fill: #fe9b13; + stroke: #c5eaff; +} + +.text_blocks:not(.blocklyDisabledPattern).blocklyShadow > .blocklyPath { + fill: #ff0000; + stroke: none; +} + +.text_blocks > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #fe9b13 !important; +} + +.text_blocks.blocklyShadow > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #ff0000 !important; +} + +/* LIST BLOCKS */ + +.list_blocks:not(.blocklyDisabledPattern) > .blocklyPath { + fill: #4a148c; + stroke: #cdb6e9; +} + +.list_blocks:not(.blocklyDisabledPattern).blocklyShadow > .blocklyPath { + fill: #ad7be9; + stroke: none; +} + +.list_blocks > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #4a148c !important; +} + +.list_blocks.blocklyShadow > .blocklyDropdownField .blocklyDropdownText tspan { + fill: #ad7be9 !important; +} diff --git a/packages/docs/docs/codelabs/css/complete-code/index.html b/packages/docs/docs/codelabs/css/complete-code/index.html new file mode 100644 index 00000000000..1b77752f150 --- /dev/null +++ b/packages/docs/docs/codelabs/css/complete-code/index.html @@ -0,0 +1,41 @@ + + + + + CSS Codelab + + + + + + + + + +

CSS Codelab

+
+ + diff --git a/packages/docs/docs/codelabs/css/complete-code/index.js b/packages/docs/docs/codelabs/css/complete-code/index.js new file mode 100644 index 00000000000..294d45869bf --- /dev/null +++ b/packages/docs/docs/codelabs/css/complete-code/index.js @@ -0,0 +1,11 @@ +'use strict'; + +let workspace = null; + +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxCategories, + renderer: 'thrasos', + }); +} diff --git a/packages/docs/docs/codelabs/css/complete-code/toolbox.js b/packages/docs/docs/codelabs/css/complete-code/toolbox.js new file mode 100644 index 00000000000..f2e48271ae6 --- /dev/null +++ b/packages/docs/docs/codelabs/css/complete-code/toolbox.js @@ -0,0 +1,800 @@ +const toolboxCategories = { + kind: 'categoryToolbox', + contents: [ + { + kind: 'category', + name: 'Logic', + cssConfig: { + row: 'blocklyToolboxCategory logic_category', + }, + contents: [ + { + type: 'controls_if', + kind: 'block', + }, + { + type: 'logic_compare', + kind: 'block', + fields: { + OP: 'EQ', + }, + }, + { + type: 'logic_operation', + kind: 'block', + fields: { + OP: 'AND', + }, + }, + { + type: 'logic_negate', + kind: 'block', + }, + { + type: 'logic_boolean', + kind: 'block', + fields: { + BOOL: 'TRUE', + }, + }, + { + type: 'logic_null', + kind: 'block', + enabled: false, + }, + { + type: 'logic_ternary', + kind: 'block', + }, + ], + }, + { + kind: 'category', + name: 'Loops', + cssConfig: { + row: 'blocklyToolboxCategory loop_category', + }, + contents: [ + { + type: 'controls_repeat_ext', + kind: 'block', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + type: 'controls_repeat', + kind: 'block', + enabled: false, + fields: { + TIMES: 10, + }, + }, + { + type: 'controls_whileUntil', + kind: 'block', + fields: { + MODE: 'WHILE', + }, + }, + { + type: 'controls_for', + kind: 'block', + fields: { + VAR: { + name: 'i', + }, + }, + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + BY: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + type: 'controls_forEach', + kind: 'block', + fields: { + VAR: { + name: 'j', + }, + }, + }, + { + type: 'controls_flow_statements', + kind: 'block', + enabled: false, + fields: { + FLOW: 'BREAK', + }, + }, + ], + }, + { + kind: 'category', + name: 'Math', + cssConfig: { + row: 'blocklyToolboxCategory math_category', + }, + contents: [ + { + type: 'math_number', + kind: 'block', + fields: { + NUM: 123, + }, + }, + { + type: 'math_arithmetic', + kind: 'block', + fields: { + OP: 'ADD', + }, + inputs: { + A: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + B: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + type: 'math_single', + kind: 'block', + fields: { + OP: 'ROOT', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 9, + }, + }, + }, + }, + }, + { + type: 'math_trig', + kind: 'block', + fields: { + OP: 'SIN', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 45, + }, + }, + }, + }, + }, + { + type: 'math_constant', + kind: 'block', + fields: { + CONSTANT: 'PI', + }, + }, + { + type: 'math_number_property', + kind: 'block', + fields: { + PROPERTY: 'EVEN', + }, + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, + }, + }, + }, + }, + }, + { + type: 'math_round', + kind: 'block', + fields: { + OP: 'ROUND', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 3.1, + }, + }, + }, + }, + }, + { + type: 'math_on_list', + kind: 'block', + fields: { + OP: 'SUM', + }, + }, + { + type: 'math_modulo', + kind: 'block', + inputs: { + DIVIDEND: { + shadow: { + type: 'math_number', + fields: { + NUM: 64, + }, + }, + }, + DIVISOR: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + type: 'math_constrain', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'math_number', + fields: { + NUM: 50, + }, + }, + }, + LOW: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + HIGH: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + type: 'math_random_int', + kind: 'block', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + type: 'math_random_float', + kind: 'block', + }, + { + type: 'math_atan2', + kind: 'block', + inputs: { + X: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + Y: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Text', + cssConfig: { + row: 'blocklyToolboxCategory text_category', + }, + contents: [ + { + type: 'text', + kind: 'block', + fields: { + TEXT: '', + }, + }, + { + type: 'text_join', + kind: 'block', + }, + { + type: 'text_append', + kind: 'block', + fields: { + name: 'item', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_length', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_isEmpty', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_indexOf', + kind: 'block', + fields: { + END: 'FIRST', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + FIND: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_charAt', + kind: 'block', + fields: { + WHERE: 'FROM_START', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + }, + }, + { + type: 'text_getSubstring', + kind: 'block', + fields: { + WHERE1: 'FROM_START', + WHERE2: 'FROM_START', + }, + inputs: { + STRING: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + }, + }, + { + type: 'text_changeCase', + kind: 'block', + fields: { + CASE: 'UPPERCASE', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_trim', + kind: 'block', + fields: { + MODE: 'BOTH', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_count', + kind: 'block', + inputs: { + SUB: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_replace', + kind: 'block', + inputs: { + FROM: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TO: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_reverse', + kind: 'block', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + + { + type: 'text_print', + kind: 'block', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_prompt_ext', + kind: 'block', + fields: { + TYPE: 'TEXT', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Lists', + cssConfig: { + row: 'blocklyToolboxCategory list_category', + }, + contents: [ + { + type: 'lists_create_with', + kind: 'block', + extraState: { + itemCount: 0, + }, + }, + { + type: 'lists_create_with', + kind: 'block', + }, + { + type: 'lists_repeat', + kind: 'block', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, + }, + }, + }, + }, + }, + { + type: 'lists_length', + kind: 'block', + }, + { + type: 'lists_isEmpty', + kind: 'block', + }, + { + type: 'lists_indexOf', + kind: 'block', + + fields: { + END: 'FIRST', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_getIndex', + kind: 'block', + fields: { + MODE: 'GET', + WHERE: 'FROM_START', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_setIndex', + kind: 'block', + fields: { + MODE: 'SET', + WHERE: 'FROM_START', + }, + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_getSublist', + kind: 'block', + fields: { + WHERE1: 'FROM_START', + WHERE2: 'FROM_START', + }, + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_split', + kind: 'block', + + fields: { + MODE: 'SPLIT', + }, + inputs: { + DELIM: { + shadow: { + type: 'text', + fields: { + TEXT: ',', + }, + }, + }, + }, + }, + { + type: 'lists_sort', + kind: 'block', + + fields: { + TYPE: 'NUMERIC', + DIRECTION: '1', + }, + }, + { + type: 'lists_reverse', + kind: 'block', + }, + ], + }, + { + kind: 'sep', + }, + { + kind: 'category', + name: 'Variables', + custom: 'VARIABLE', + cssConfig: { + row: 'blocklyToolboxCategory variable_category', + }, + }, + { + kind: 'category', + name: 'Functions', + custom: 'PROCEDURE', + cssConfig: { + row: 'blocklyToolboxCategory procedure_category', + }, + }, + ], +}; diff --git a/packages/docs/docs/codelabs/css/components.mdx b/packages/docs/docs/codelabs/css/components.mdx new file mode 100644 index 00000000000..8d2801877b5 --- /dev/null +++ b/packages/docs/docs/codelabs/css/components.mdx @@ -0,0 +1,156 @@ +--- +title: Use CSS in Blockly - Components +slug: /codelabs/css/components/index.html +description: Styling Blockly components with CSS +--- + +# Use CSS in Blockly + +## 4. Components + +In this section, you will create CSS rules to assign the colours used by the [components section](/codelabs/theme-extension-identifier/customize-components/index.html) of the themes codelab to various components. + +To start, create a file named `halloween.css` and add it to your `index.html` file: + +```html +... + + +``` + +### Main workspace colour + +Your first rule will set the background colour of the main workspace. In your Blockly editor, find the `` element with the `blocklyMainBackground` class: + +``` + +
+
+ + + +``` + +This seems like a good target for your rule, except that the `fill` property is already used to set the grid pattern. Instead, we'll set the `background-color` property of the `blocklySvg` element. To do this, add the following rule to `halloween.css`: + +```css +/**************/ +/* COMPONENTS */ +/**************/ + +.blocklySvg { + background-color: #ff7518; +} +``` + +Refresh your page and notice that the workspace background is now orange: + +![A Blockly editor with an orange workspace.](../../../static/images/codelabs/css/components-workspace.png) + +### Mutator workspace colour + +Now drag an `if do` block onto the workspace and click the mutator (gear) icon. Notice that the mutator workspace's background colour is unchanged. This is because it's a different workspace. See if you can find the `` that draws the mutator workspace. (Here's a hint: It's on the bubble canvas, which is where the bubbles used by mutators, comments, and warnings are drawn.) + +Don't worry if you didn't find it right away -- Blockly's DOM tree is fairly complex: + +``` + +
+
+ + + + + + + + +``` + +Next, add a CSS rule to set the workspace's background colour: + +```css +.blocklyMutatorBackground { + fill: #ff7518; +} +``` + +To see your new colours, reload the web page, drag the `if do` block out again, +and reopen the mutator. You should see that the mutator workspace background +colour is orange, matching the main workspace background: +![An 'if do' block with a mutator that has an orange background.](../../../static/images/codelabs/css/components-mutator.png) + +### Other component colours + +Themes allow you to define the colours of many (but not all) components. The following table shows what classes and properties to use to set the same colours as the component styles in themes: + +| Component style | Selectors (properties) | +| --------------------------- | ---------------------------------------------------------------------------------------------------- | +| `workspaceBackgroundColour` | `.blocklySvg (background-color)`, `.blocklyMutatorBackground (fill)` | +| `toolboxBackgroundColour` | `.blocklyToolbox (background-color)` | +| `toolboxForegroundColour` | `.blocklyToolbox (color)` | +| `flyoutBackgroundColour` | `.blocklyFlyoutBackground (fill)` | +| `flyoutForegroundColour` | `.blocklyFlyoutLabel > .blocklyFlyoutLabelText (fill)`, `.blocklyFlyoutButton > .blocklyText (fill)` | +| `flyoutOpacity` | `.blocklyFlyoutBackground (fill-opacity)` | +| `scrollbarColour` | `.blocklyScrollbarHandle (fill)` | +| `scrollbarOpacity` | `.blocklyScrollbarHandle (fill-opacity)` | +| `insertionMarkerColour` | `.blocklyInsertionMarker > .blocklyPath (fill)` | +| `insertionMarkerOpacity` | `.blocklyInsertionMarker > .blocklyPath (fill-opacity)` | + +Add the following rules to `halloween.css`: + +```css +.blocklyToolbox { + background-color: #f9c10e; + color: #fff; +} + +.blocklyFlyoutBackground { + fill: #252526; + fill-opacity: 1; +} + +.blocklyFlyoutLabel > .blocklyFlyoutLabelText { + fill: #ccc !important; +} + +.blocklyFlyoutButton > .blocklyText { + fill: #ccc !important; +} + +.blocklyScrollbarHandle { + fill: #ff0000; + fill-opacity: 0.4; +} + +.blocklyInsertionMarker > .blocklyPath { + fill: #fff !important; + fill-opacity: 0.3 !important; + stroke: none; +} +``` + +Now reload your page. You should see a Blockly editor with a yellow toolbox and +red scrollbars: +![A Blockly editor with Halloween colors.](../../../static/images/codelabs/css/components-halloween.png) + +### fill vs background-color + +You might have noticed that some rules use `background-color` and `color` and +others use `fill` and `stroke`. This is because `background-color` and `color` +apply to HTML elements, like the `
` used by the toolbox, and `fill` and +`stroke` apply to most SVG elements, like the `` used by the flyout +background. (An exception to this is the top-level `` element that contains +Blockly, which uses `background-color` and `color`.) + +### The !important declaration + +You might have also noticed that some rules use an `!important` declaration while others don't. This is because Blockly sets colours in several different ways, some of which are easily overridden and some of which aren't. + +- **Presentation attributes:** These are attributes on SVG elements, such as `fill` and `stroke`. They have a specificity of 0 and are overridden by any rules you write. As you will see later, block colours use presentation attributes. + +- **`` tag. Your rules override these if they have the same or higher specificity. For example, the rule for `.blocklyScrollbarHandle` has the same specificity as Blockly's rule for this class, but overrides Blockly's rule because it occurs later in the document. On the other hand, the rule for `.blocklyFlyoutLabel > .blocklyFlyoutLabelText` has a lower specificity than Blockly's rule and must override it with an `!important` declaration. + +- **Inline styles:** These rules are included via a `style` attribute and can only be overridden by an `!important` declaration. As you will see later, the colour of the arrow in a dropdown field is set with an inline style and must be overridden with `!important`. + +The easiest way to determine how a rule is set is to highlight the appropriate element in the element inspector and look at the corresponding style information. In a few cases, this isn't possible. For example, an insertion marker is created only when you drag a child near its parent and is deleted when you let go of the parent to highlight the insertion marker's element. In these cases, you will need to [search Blockly's rules](/guides/configure/web/appearance/css#blockly-css-rules). diff --git a/packages/docs/docs/codelabs/css/setup.mdx b/packages/docs/docs/codelabs/css/setup.mdx new file mode 100644 index 00000000000..7484893d4e9 --- /dev/null +++ b/packages/docs/docs/codelabs/css/setup.mdx @@ -0,0 +1,40 @@ +--- +title: Use CSS in Blockly - Setup +slug: /codelabs/css/setup/index.html +description: Setup for the CSS in Blockly codelab +--- + +# Use CSS in Blockly + +## 2. Setup + +### Download the sample code + +You can get the sample code for this code by either downloading the zip here: + +[Download zip](https://github.com/RaspberryPiFoundation/blockly/archive/main.zip) + +or by cloning this git repo: + +```bash +git clone https://github.com/RaspberryPiFoundation/blockly.git +``` + +If you downloaded the source as a zip, unpacking it should give you a root folder named `blockly-main`. + +The relevant files are in `docs/docs/codelabs/css`. There are two versions of the app: + +- `starter-code/`: The starter code that you'll build upon in this codelab. +- `complete-code/`: The code after completing the codelab, in case you get lost or want to compare to your version. + +Each folder contains: + +- `index.html` - A web page containing a simple Blockly workspace. +- `toolbox.js` - A toolbox with multiple categories. +- `index.js` - Code to inject a simple workspace. + +The `complete-code` folder also contains the `halloween.css` file you'll create. + +To run the code, simply open `starter-code/index.html` in a browser. You should see a Blockly workspace with multiple categories. + +![A web page with the text 'CSS Codelab' and a Blockly editor with seven categories.](../../../static/images/codelabs/css/setup-starter.png) diff --git a/packages/docs/docs/codelabs/css/starter-code/index.html b/packages/docs/docs/codelabs/css/starter-code/index.html new file mode 100644 index 00000000000..7d090738731 --- /dev/null +++ b/packages/docs/docs/codelabs/css/starter-code/index.html @@ -0,0 +1,40 @@ + + + + + CSS Codelab + + + + + + + + +

CSS Codelab

+
+ + diff --git a/packages/docs/docs/codelabs/css/starter-code/index.js b/packages/docs/docs/codelabs/css/starter-code/index.js new file mode 100644 index 00000000000..294d45869bf --- /dev/null +++ b/packages/docs/docs/codelabs/css/starter-code/index.js @@ -0,0 +1,11 @@ +'use strict'; + +let workspace = null; + +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxCategories, + renderer: 'thrasos', + }); +} diff --git a/packages/docs/docs/codelabs/css/starter-code/toolbox.js b/packages/docs/docs/codelabs/css/starter-code/toolbox.js new file mode 100644 index 00000000000..2c10d89ddeb --- /dev/null +++ b/packages/docs/docs/codelabs/css/starter-code/toolbox.js @@ -0,0 +1,786 @@ +const toolboxCategories = { + kind: 'categoryToolbox', + contents: [ + { + kind: 'category', + name: 'Logic', + categorystyle: 'logic_category', + contents: [ + { + type: 'controls_if', + kind: 'block', + }, + { + type: 'logic_compare', + kind: 'block', + fields: { + OP: 'EQ', + }, + }, + { + type: 'logic_operation', + kind: 'block', + fields: { + OP: 'AND', + }, + }, + { + type: 'logic_negate', + kind: 'block', + }, + { + type: 'logic_boolean', + kind: 'block', + fields: { + BOOL: 'TRUE', + }, + }, + { + type: 'logic_null', + kind: 'block', + enabled: false, + }, + { + type: 'logic_ternary', + kind: 'block', + }, + ], + }, + { + kind: 'category', + name: 'Loops', + categorystyle: 'loop_category', + contents: [ + { + type: 'controls_repeat_ext', + kind: 'block', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + type: 'controls_repeat', + kind: 'block', + enabled: false, + fields: { + TIMES: 10, + }, + }, + { + type: 'controls_whileUntil', + kind: 'block', + fields: { + MODE: 'WHILE', + }, + }, + { + type: 'controls_for', + kind: 'block', + fields: { + VAR: { + name: 'i', + }, + }, + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + BY: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + type: 'controls_forEach', + kind: 'block', + fields: { + VAR: { + name: 'j', + }, + }, + }, + { + type: 'controls_flow_statements', + kind: 'block', + enabled: false, + fields: { + FLOW: 'BREAK', + }, + }, + ], + }, + { + kind: 'category', + name: 'Math', + categorystyle: 'math_category', + contents: [ + { + type: 'math_number', + kind: 'block', + fields: { + NUM: 123, + }, + }, + { + type: 'math_arithmetic', + kind: 'block', + fields: { + OP: 'ADD', + }, + inputs: { + A: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + B: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + type: 'math_single', + kind: 'block', + fields: { + OP: 'ROOT', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 9, + }, + }, + }, + }, + }, + { + type: 'math_trig', + kind: 'block', + fields: { + OP: 'SIN', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 45, + }, + }, + }, + }, + }, + { + type: 'math_constant', + kind: 'block', + fields: { + CONSTANT: 'PI', + }, + }, + { + type: 'math_number_property', + kind: 'block', + fields: { + PROPERTY: 'EVEN', + }, + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, + }, + }, + }, + }, + }, + { + type: 'math_round', + kind: 'block', + fields: { + OP: 'ROUND', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 3.1, + }, + }, + }, + }, + }, + { + type: 'math_on_list', + kind: 'block', + fields: { + OP: 'SUM', + }, + }, + { + type: 'math_modulo', + kind: 'block', + inputs: { + DIVIDEND: { + shadow: { + type: 'math_number', + fields: { + NUM: 64, + }, + }, + }, + DIVISOR: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + type: 'math_constrain', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'math_number', + fields: { + NUM: 50, + }, + }, + }, + LOW: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + HIGH: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + type: 'math_random_int', + kind: 'block', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + type: 'math_random_float', + kind: 'block', + }, + { + type: 'math_atan2', + kind: 'block', + inputs: { + X: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + Y: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Text', + categorystyle: 'text_category', + contents: [ + { + type: 'text', + kind: 'block', + fields: { + TEXT: '', + }, + }, + { + type: 'text_join', + kind: 'block', + }, + { + type: 'text_append', + kind: 'block', + fields: { + name: 'item', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_length', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_isEmpty', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_indexOf', + kind: 'block', + fields: { + END: 'FIRST', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + FIND: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_charAt', + kind: 'block', + fields: { + WHERE: 'FROM_START', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + }, + }, + { + type: 'text_getSubstring', + kind: 'block', + fields: { + WHERE1: 'FROM_START', + WHERE2: 'FROM_START', + }, + inputs: { + STRING: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + }, + }, + { + type: 'text_changeCase', + kind: 'block', + fields: { + CASE: 'UPPERCASE', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_trim', + kind: 'block', + fields: { + MODE: 'BOTH', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_count', + kind: 'block', + inputs: { + SUB: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_replace', + kind: 'block', + inputs: { + FROM: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TO: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_reverse', + kind: 'block', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + + { + type: 'text_print', + kind: 'block', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_prompt_ext', + kind: 'block', + fields: { + TYPE: 'TEXT', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Lists', + categorystyle: 'list_category', + contents: [ + { + type: 'lists_create_with', + kind: 'block', + extraState: { + itemCount: 0, + }, + }, + { + type: 'lists_create_with', + kind: 'block', + }, + { + type: 'lists_repeat', + kind: 'block', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, + }, + }, + }, + }, + }, + { + type: 'lists_length', + kind: 'block', + }, + { + type: 'lists_isEmpty', + kind: 'block', + }, + { + type: 'lists_indexOf', + kind: 'block', + + fields: { + END: 'FIRST', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_getIndex', + kind: 'block', + fields: { + MODE: 'GET', + WHERE: 'FROM_START', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_setIndex', + kind: 'block', + fields: { + MODE: 'SET', + WHERE: 'FROM_START', + }, + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_getSublist', + kind: 'block', + fields: { + WHERE1: 'FROM_START', + WHERE2: 'FROM_START', + }, + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_split', + kind: 'block', + + fields: { + MODE: 'SPLIT', + }, + inputs: { + DELIM: { + shadow: { + type: 'text', + fields: { + TEXT: ',', + }, + }, + }, + }, + }, + { + type: 'lists_sort', + kind: 'block', + + fields: { + TYPE: 'NUMERIC', + DIRECTION: '1', + }, + }, + { + type: 'lists_reverse', + kind: 'block', + }, + ], + }, + { + kind: 'sep', + }, + { + kind: 'category', + name: 'Variables', + custom: 'VARIABLE', + categorystyle: 'variable_category', + }, + { + kind: 'category', + name: 'Functions', + custom: 'PROCEDURE', + categorystyle: 'procedure_category', + }, + ], +}; diff --git a/packages/docs/docs/codelabs/css/summary.mdx b/packages/docs/docs/codelabs/css/summary.mdx new file mode 100644 index 00000000000..0ab49d4337d --- /dev/null +++ b/packages/docs/docs/codelabs/css/summary.mdx @@ -0,0 +1,12 @@ +--- +pagination_next: null +title: Use CSS in Blockly - Summary +slug: /codelabs/css/summary/index.html +description: Summary of the CSS in Blockly codelab +--- + +## 7. Summary + +In this codelab, you learned how to use CSS to set the colours of your Blockly editor. + +For more information, see [Style with CSS](/guides/configure/web/appearance/css) in the Blockly user guides. diff --git a/packages/docs/docs/codelabs/css/tour.mdx b/packages/docs/docs/codelabs/css/tour.mdx new file mode 100644 index 00000000000..a0340316119 --- /dev/null +++ b/packages/docs/docs/codelabs/css/tour.mdx @@ -0,0 +1,45 @@ +--- +title: Use CSS in Blockly - A tour of Blockly's elements +slug: /codelabs/css/tour/index.html +description: Explore Blockly's HTML and SVG elements in the CSS codelab +--- + +# Use CSS in Blockly + +## 3. A tour of Blockly's elements + +In this section, you'll explore the HTML and SVG elements used by Blockly, as well as the classes assigned to these elements. + +In your Blockly editor, drag a `count with` block from the **Loops** category and an `if do` block from the **Logic** category onto your workspace and open your browser's [developer tools](https://developer.mozilla.org/en-US/docs/Learn_web_development/Howto/Tools_and_setup/What_are_browser_developer_tools). Your screen should look something like this: + +![A Blockly editor with two blocks on the workspace and the developer tools open.](../../../static/images/codelabs/css/tour-dev-tools.png) + +Using the element inspector, explore the elements used by Blockly. For example, see if you can find the SVG `` element used to draw the `count with` block. If you're having trouble finding things, the following outline might help. (Note that it omits some elements and most attributes.) + +``` +Description DOM elements +------------------------------- ---------------------------------------------- + element + App-specific container
+ Injection element
+ Toolbox
+ Main SVG element + Main workspace + Trash + Block canvas + Block 1 + element + Child block 1 + Child block 2 + ... ... + Field 1 + Field 2 + ... ... + Block 2 + Bubble canvas + Scrollbar background + Scrollbars, flyouts, etc. s + Widget, dropdown, tooltip divs
s +``` + +One thing that's important to notice are the `blocklyXxxx` classes assigned to most elements. These explain how Blockly uses each element and will be the targets of many of your CSS rules. If you look closely, you'll notice that many elements have multiple classes -- for example, the `` element for the dropdown field in the `counts with` block has `blocklyField`, `blocklyDropdownField`, `blocklyVariableField`, and `blocklyEditableField` classes. Having multiple classes allows you to write CSS rules that affect different ranges of elements. diff --git a/packages/docs/docs/codelabs/custom-generator/array-block-generator.mdx b/packages/docs/docs/codelabs/custom-generator/array-block-generator.mdx new file mode 100644 index 00000000000..b0115f4ea3d --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/array-block-generator.mdx @@ -0,0 +1,108 @@ +--- +slug: /codelabs/custom-generator/array-block-generator/index.html +description: How to write a block code generator that creates an array. +--- + +# Build a custom generator + +## 7. Array block generator + +This step will build the generator for the array block. You will learn how to indent code and handle a variable number of inputs. + +The array block uses a mutator to dynamically change the number of inputs it has. + +![The array block can have multiple value inputs. This example has four blocks connected to it: 1, "two", false, and true.](../../../static/images/codelabs/custom-generator/array_block.png) + +The generated code looks like: + +```json +[1, "two", false, true] +``` + +As with member blocks, there are no restrictions on the types of blocks connected to inputs. + +### Gather values + +Each value input on the block has a name: `ADD0`, `ADD1`, etc. Use `valueToCode` in a loop to build an array of values: + +```js +const values = []; +for (let i = 0; i < block.itemCount_; i++) { + const valueCode = generator.valueToCode(block, 'ADD' + i, Order.ATOMIC); + if (valueCode) { + values.push(valueCode); + } +} +``` + +Notice that the code skips empty inputs by checking if `valueCode` is `null`. + +To include empty inputs, use the string `'null'` as the value: + +```js +const values = []; +for (let i = 0; i < block.itemCount_; i++) { + const valueCode = + generator.valueToCode(block, 'ADD' + i, Order.ATOMIC) || 'null'; + values.push(valueCode); +} +``` + +### Format + +At this point `values` is an array of `string`s. The strings contain the generated code for each input. + +Convert the list into a single `string`, with a comma and newline separating each element: + +```js +const valueString = values.join(',\n'); +``` + +Next, use `prefixLines` to add indentation at the beginning of each line: + +```js +const indentedValueString = generator.prefixLines( + valueString, + generator.INDENT, +); +``` + +`INDENT` is a property on the generator. It defaults to two spaces, but language generators may override it to increase indent or change to tabs. + +Finally, wrap the indented values in brackets and return the string: + +```js +const codeString = '[\n' + indentedValueString + '\n]'; +return [codeString, Order.ATOMIC]; +``` + +### Putting it all together + +Here is the final array block generator: + +```js +jsonGenerator.forBlock['lists_create_with'] = function (block, generator) { + const values = []; + for (let i = 0; i < block.itemCount_; i++) { + const valueCode = generator.valueToCode(block, 'ADD' + i, Order.ATOMIC); + if (valueCode) { + values.push(valueCode); + } + } + const valueString = values.join(',\n'); + const indentedValueString = generator.prefixLines( + valueString, + generator.INDENT, + ); + const codeString = '[\n' + indentedValueString + '\n]'; + return [codeString, Order.ATOMIC]; +}; +``` + +### Test it + +Test the block generator by adding an array to the onscreen blocks and populating it. + +What code does it generate if there are no inputs? + +What if there are five inputs, one of which is empty? diff --git a/packages/docs/docs/codelabs/custom-generator/block-generator-overview.mdx b/packages/docs/docs/codelabs/custom-generator/block-generator-overview.mdx new file mode 100644 index 00000000000..5cc462aff88 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/block-generator-overview.mdx @@ -0,0 +1,64 @@ +--- +slug: /codelabs/custom-generator/block-generator-overview/index.html +description: Introduction to block generators. +--- + +# Build a custom generator + +## 4. Block generator overview + +At its core, a block generator is a function that takes in a block (and optionally the language generator instance), translates the block into code, and returns that code as a string. + +Each language generator has a property called `forBlock`, which is a dictionary object where all block generator functions must be placed. For instance, here is the code to add a block generator for blocks of type `sample_block` on a language generator object (`sampleGenerator`). + +```js +sampleGenerator.forBlock['sample_block'] = function (block, generator) { + return 'my code string'; +}; +``` + +### Statement blocks + +Statement blocks represent code that does not return a value. + +A statement block's generator simply returns a string. + +For example, this code defines a block generator that always returns the same function call. + +```js +sampleGenerator.forBlock['left_turn_block'] = function (block, generator) { + return 'turnLeft()'; +}; +``` + +### Value blocks + +Value blocks represent code that returns a value. + +A value block's generator returns an array containing a string and a [precedence value](/guides/create-custom-blocks/code-generation/operator-precedence). The built-in generators have predefined operator precedence values exported as an `Order` enum. + +This code defines a block generator that always returns `1 + 1`: + +```js +sampleGenerator.forBlock['two_block'] = function (block, generator) { + return ['1 + 1', Order.ADDITION]; +}; +``` + +### Operator precedence + +Operator precedence rules determine how the correct order of operations is maintained during parsing. In Blockly's generators, operator precedence determines when to add parentheses. + +--> Read more about [operator precedence in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence). + +--> Read more about [operator precedence in Blockly](/guides/create-custom-blocks/code-generation/operator-precedence). + +Since JSON does not allow values that are expressions, the code does not need to consider operator precedence for the generator being built in this codelab. The same value can be used everywhere a precedence value is required. Since parentheses never need to be added to the JSON, call this value `ATOMIC`. + +In `src/generators/json.js`, declare a new enum called `Order` and add the `ATOMIC` value: + +```js +const Order = { + ATOMIC: 0, +}; +``` diff --git a/packages/docs/docs/codelabs/custom-generator/codelab-overview.mdx b/packages/docs/docs/codelabs/custom-generator/codelab-overview.mdx new file mode 100644 index 00000000000..58b1f6b941b --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/codelab-overview.mdx @@ -0,0 +1,35 @@ +--- +pagination_prev: null +slug: /codelabs/custom-generator/codelab-overview/index.html +description: Overview of the "Build a custom generator" codelab. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Build a custom generator + +## 1. Codelab overview + +### What you'll learn + +- How to create a custom language generator. +- How to create block generator definitions for existing blocks. +- How to create block generator definitions for new blocks. +- How to use a custom generator in an application. + +### What you'll build + +You will build a JSON generator that implements the [JSON language spec](https://www.json.org/json-en.html). + + + ![Screenshot of the toolbox and workspace built in this codelab. It contains + blocks that implement the JSON spec, like member, object, lists, strings, and + numbers.](../../../static/images/codelabs/custom-generator/json_workspace.png) + + +### What you'll need + +- Familiarity with JSON and the JSON specification. +- Basic understanding of blocks and toolboxes in Blockly. +- NPM installed ([instructions](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)). +- Comfort using the command line/terminal. diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/README.mdx b/packages/docs/docs/codelabs/custom-generator/complete-code/README.mdx new file mode 100644 index 00000000000..1b3c36d82b8 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/README.mdx @@ -0,0 +1,50 @@ +# Blockly Sample App + +## Purpose + +This app illustrates how to use Blockly together with common programming tools like node/npm, webpack, typescript, eslint, and others. You can use it as the starting point for your own application and modify it as much as you'd like. It contains basic infrastructure for running, building, testing, etc. that you can use even if you don't understand how to configure the related tool yet. When your needs outgrow the functionality provided here, you can replace the provided configuration or tool with your own. + +## Quick Start + +1. [Install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) npm if you haven't before. +2. Run [`npx @blockly/create-package app `](https://www.npmjs.com/package/@blockly/create-package) to clone this application to your own machine. +3. Run `npm install` to install the required dependencies. +4. Run `npm run start` to run the development server and see the app in action. +5. If you make any changes to the source code, just refresh the browser while the server is running to see them. + +## Tooling + +The application uses many of the same tools that the Blockly team uses to develop Blockly itself. Following is a brief overview, and you can read more about them on our [developer site](https://developers.google.com/blockly/guides/contribute/get-started/development_tools). + +- Structure: The application is built as an npm package. You can use npm to manage the dependencies of the application. +- Modules: ES6 modules to handle imports to/exports from other files. +- Building/bundling: Webpack to build the source code and bundle it into one file for serving. +- Development server: webpack-dev-server to run locally while in development. +- Testing: Mocha to run unit tests. +- Linting: Eslint to lint the code and ensure it conforms with a standard style. +- UI Framework: Does not use a framework. For more complex applications, you may wish to integrate a UI framework like React or Angular. + +You can disable, reconfigure, or replace any of these tools at any time, but they are preconfigured to get you started developing your Blockly application quickly. + +## Structure + +- `package.json` contains basic information about the app. This is where the scripts to run, build, etc. are listed. +- `package-lock.json` is used by npm to manage dependencies +- `webpack.config.js` is the configuration for webpack. This handles bundling the application and running our development server. +- `src/` contains the rest of the source code. +- `dist/` contains the packaged output (that you could host on a server, for example). This is ignored by git and will only appear after you run `npm run build` or `npm run start`. + +### Source Code + +- `index.html` contains the skeleton HTML for the page. This file is modified during the build to import the bundled source code output by webpack. +- `index.js` is the entry point of the app. It configures Blockly and sets up the page to show the blocks, the generated code, and the output of running the code in JavaScript. +- `serialization.js` has code to save and load the workspace using the browser's local storage. This is how your workspace is saved even after refreshing or leaving the page. You could replace this with code that saves the user's data to a cloud database instead. +- `toolbox.js` contains the toolbox definition for the app. The current toolbox contains nearly every block that Blockly provides out of the box. You probably want to replace this definition with your own toolbox that uses your custom blocks and only includes the default blocks that are relevant to your application. +- `blocks/text.js` has code for a custom text block, just as an example of creating your own blocks. You probably want to delete this block, and add your own blocks in this directory. +- `generators/javascript.js` contains the JavaScript generator for the custom text block. You'll need to include block generators for any custom blocks you create, in whatever programming language(s) your application will use. + +## Serving + +To run your app locally, run `npm run start` to run the development server. This mode generates source maps and ingests the source maps created by Blockly, so that you can debug using unminified code. + +To deploy your app so that others can use it, run `npm run build` to run a production build. This will bundle your code and minify it to reduce its size. You can then host the contents of the `dist` directory on a web server of your choosing. If you're just getting started, try using [GitHub Pages](https://pages.github.com/). diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/package-lock.json b/packages/docs/docs/codelabs/custom-generator/complete-code/package-lock.json new file mode 100644 index 00000000000..7c0f36f0e94 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/package-lock.json @@ -0,0 +1,8906 @@ +{ + "name": "generator-sample-app", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "generator-sample-app", + "version": "1.0.0", + "license": "Apache-2.0", + "dependencies": { + "blockly": "^12.0.0" + }, + "devDependencies": { + "css-loader": "^6.7.1", + "html-webpack-plugin": "^5.5.0", + "source-map-loader": "^4.0.1", + "style-loader": "^3.3.1", + "webpack": "^5.93.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.0.4" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.3.tgz", + "integrity": "sha512-XBG3talrhid44BY1x3MHzUx/aTG8+x/Zi57M4aTKK9RFB4aLlF3TTSzfzn8nWVHWL3FgAXAxmupmDd6VWww+pw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.9.tgz", + "integrity": "sha512-wILs5Zk7BU86UArYBJTPy/FMPPKVKHMj1ycCEyf3VUptol0JNRLFU/BZsJ4aiIHJEbSLiizzRrw8Pc1uAEDrXw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz", + "integrity": "sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz", + "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.4.9", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.9.tgz", + "integrity": "sha512-jFCSo4wJzlHQLCpceUhUnXdrPuCNOjGFMQ8Eg6JXxlz3QaCKOb7eGi2cephQdM4XTYsNej69P9JDJ1zqNIbncQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.9", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", + "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.11.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.8.tgz", + "integrity": "sha512-uGwPWlE0Hj972KkHtCDVwZ8O39GmyjfMane1Z3GUBGGnkZ2USDq7SxLpVIiIHpweY9DS0QTDH0Nw7RNBsAAZ5A==", + "dev": true + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.11", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", + "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blockly": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-12.0.0.tgz", + "integrity": "sha512-CrwxGjbgCh/zGg46VTlp26NYblSi/82n4VFsamyW5b4W6t3HXaf/b3CbMuu4/YnFvqlyJs+8zR4OKNTbIc28EA==", + "dependencies": { + "jsdom": "26.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clean-css": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", + "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "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 + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", + "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.7", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "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/cssstyle": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.1.tgz", + "integrity": "sha512-ZgW+Jgdd7i52AaLYCriF8Mxqft0gD/R9i9wi6RWBhs1pqdPEzPjym7rvRKi397WmQFf3SlyUsszhw+VVCbx79Q==", + "dependencies": { + "@asamuzakjp/css-color": "^3.1.2", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==" + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/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" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.1.tgz", + "integrity": "sha512-FKbOCOQ5QRB3VlIbl1LZQefWIYwszlBloaXcY2rbfpu9ioJnNh3TK03YtIDKDo3WKBi8u+YV4+Fn2CkEozgf4w==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "dev": true, + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "webpack": "^5.20.0" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "dependencies": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", + "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.4.tgz", + "integrity": "sha512-Xlj8b2rU11nM6+KU6wC7cuWcHQhVINWCUgdPS4Ar9nPxLaOya3RghqK7ALyDW2QtGebYAYs6uEdEVnwPVT942A==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.1.2", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz", + "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==" + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", + "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz", + "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/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.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "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", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dev": true, + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", + "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "14 >=14.20 || 16 >=16.20 || >=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==" + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", + "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy-transport/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/spdy/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/style-loader": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.31.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", + "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "dev": true + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/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, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.1.0", + "ws": "^8.16.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/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, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + }, + "dependencies": { + "@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "requires": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + }, + "dependencies": { + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + } + } + }, + "@csstools/color-helpers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==" + }, + "@csstools/css-calc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.3.tgz", + "integrity": "sha512-XBG3talrhid44BY1x3MHzUx/aTG8+x/Zi57M4aTKK9RFB4aLlF3TTSzfzn8nWVHWL3FgAXAxmupmDd6VWww+pw==", + "requires": {} + }, + "@csstools/css-color-parser": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.9.tgz", + "integrity": "sha512-wILs5Zk7BU86UArYBJTPy/FMPPKVKHMj1ycCEyf3VUptol0JNRLFU/BZsJ4aiIHJEbSLiizzRrw8Pc1uAEDrXw==", + "requires": { + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.3" + } + }, + "@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "requires": {} + }, + "@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==" + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "requires": {} + }, + "@jsonjoy.com/json-pack": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz", + "integrity": "sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==", + "dev": true, + "requires": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + } + }, + "@jsonjoy.com/util": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz", + "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==", + "dev": true, + "requires": {} + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/eslint": { + "version": "8.4.9", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.9.tgz", + "integrity": "sha512-jFCSo4wJzlHQLCpceUhUnXdrPuCNOjGFMQ8Eg6JXxlz3QaCKOb7eGi2cephQdM4XTYsNej69P9JDJ1zqNIbncQ==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "dev": true + }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "@types/http-proxy": { + "version": "1.17.9", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", + "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "@types/node": { + "version": "18.11.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.8.tgz", + "integrity": "sha512-uGwPWlE0Hj972KkHtCDVwZ8O39GmyjfMane1Z3GUBGGnkZ2USDq7SxLpVIiIHpweY9DS0QTDH0Nw7RNBsAAZ5A==", + "dev": true + }, + "@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "requires": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/ws": { + "version": "8.5.11", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", + "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "requires": {} + }, + "@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true + }, + "acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "requires": {} + }, + "agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + } + }, + "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 + } + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true + }, + "blockly": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-12.0.0.tgz", + "integrity": "sha512-CrwxGjbgCh/zGg46VTlp26NYblSi/82n4VFsamyW5b4W6t3HXaf/b3CbMuu4/YnFvqlyJs+8zR4OKNTbIc28EA==", + "requires": { + "jsdom": "26.1.0" + } + }, + "body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + } + } + }, + "bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "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 + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "requires": { + "fill-range": "^7.1.1" + } + }, + "browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "requires": { + "run-applescript": "^7.0.0" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "caniuse-lite": { + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "dev": true + }, + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "clean-css": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", + "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true + }, + "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 + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true + }, + "cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-loader": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", + "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "dev": true, + "requires": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.7", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.5" + } + }, + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true + }, + "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 + }, + "cssstyle": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.1.tgz", + "integrity": "sha512-ZgW+Jgdd7i52AaLYCriF8Mxqft0gD/R9i9wi6RWBhs1pqdPEzPjym7rvRKi397WmQFf3SlyUsszhw+VVCbx79Q==", + "requires": { + "@asamuzakjp/css-color": "^3.1.2", + "rrweb-cssom": "^0.8.0" + } + }, + "data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "requires": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==" + }, + "default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "requires": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + } + }, + "default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true + }, + "default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "requires": { + "execa": "^5.0.0" + } + }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "requires": { + "utila": "~0.4" + } + }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.1.tgz", + "integrity": "sha512-FKbOCOQ5QRB3VlIbl1LZQefWIYwszlBloaXcY2rbfpu9ioJnNh3TK03YtIDKDo3WKBi8u+YV4+Fn2CkEozgf4w==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + }, + "envinfo": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "dev": true + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true + }, + "foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "requires": { + "whatwg-encoding": "^3.1.1" + } + }, + "html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true + }, + "html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "requires": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "dependencies": { + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true + } + } + }, + "html-webpack-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "dev": true, + "requires": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + } + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "dependencies": { + "debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "requires": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "requires": {} + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true + }, + "ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dev": true, + "requires": { + "hasown": "^2.0.2" + } + }, + "is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "requires": { + "is-docker": "^3.0.0" + } + }, + "is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "requires": { + "is-inside-container": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true + }, + "jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "requires": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + } + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "launch-editor": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", + "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", + "dev": true, + "requires": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true + }, + "memfs": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.4.tgz", + "integrity": "sha512-Xlj8b2rU11nM6+KU6wC7cuWcHQhVINWCUgdPS4Ar9nPxLaOya3RghqK7ALyDW2QtGebYAYs6uEdEVnwPVT942A==", + "dev": true, + "requires": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.1.2", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true + }, + "node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "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, + "requires": { + "boolbase": "^1.0.0" + } + }, + "nwsapi": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz", + "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==" + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "requires": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-retry": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", + "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "dev": true, + "requires": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "requires": { + "entities": "^6.0.0" + }, + "dependencies": { + "entities": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz", + "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==" + } + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + } + } + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "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, + "requires": { + "find-up": "^4.0.0" + } + }, + "postcss": { + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dev": true, + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + } + }, + "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", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "requires": {} + }, + "postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dev": true, + "requires": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + } + } + }, + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "requires": { + "resolve": "^1.20.0" + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true + }, + "renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dev": true, + "requires": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true + }, + "rimraf": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", + "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==", + "dev": true, + "requires": { + "glob": "^10.3.7" + } + }, + "rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==" + }, + "run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "requires": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true + }, + "side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true + }, + "source-map-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", + "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + } + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "style-loader": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "dev": true, + "requires": {} + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "terser": { + "version": "5.31.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", + "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } + }, + "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==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + } + }, + "thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "requires": {} + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "requires": { + "tldts-core": "^6.1.86" + } + }, + "tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "requires": { + "tldts": "^6.1.32" + } + }, + "tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "requires": { + "punycode": "^2.3.1" + } + }, + "tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "requires": {} + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "requires": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true + }, + "w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "requires": { + "xml-name-validator": "^5.0.0" + } + }, + "watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + } + }, + "webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true + } + } + }, + "webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "requires": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + } + }, + "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, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "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 + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + } + } + }, + "webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", + "dev": true, + "requires": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.1.0", + "ws": "^8.16.0" + }, + "dependencies": { + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + } + }, + "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, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "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 + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + } + } + }, + "webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "requires": { + "iconv-lite": "0.6.3" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" + }, + "whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "requires": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "requires": {} + }, + "xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/package.json b/packages/docs/docs/codelabs/custom-generator/complete-code/package.json new file mode 100644 index 00000000000..156af8ca504 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/package.json @@ -0,0 +1,29 @@ +{ + "name": "generator-sample-app", + "version": "1.0.0", + "description": "A sample app using Blockly and custom generators", + "main": "index.js", + "private": true, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "webpack --mode production", + "start": "webpack serve --open --mode development" + }, + "keywords": [ + "blockly" + ], + "author": "", + "license": "Apache-2.0", + "devDependencies": { + "css-loader": "^6.7.1", + "html-webpack-plugin": "^5.5.0", + "source-map-loader": "^4.0.1", + "style-loader": "^3.3.1", + "webpack": "^5.93.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.0.4" + }, + "dependencies": { + "blockly": "^12.0.0" + } +} diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/src/blocks/json.js b/packages/docs/docs/codelabs/custom-generator/complete-code/src/blocks/json.js new file mode 100644 index 00000000000..f5def025db8 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/src/blocks/json.js @@ -0,0 +1,53 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview All the custom JSON-related blocks defined in the custom + * generator codelab. + */ + +import * as Blockly from 'blockly'; + +export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray([ + { + type: 'object', + message0: '{ %1 %2 }', + args0: [ + { + type: 'input_dummy', + }, + { + type: 'input_statement', + name: 'MEMBERS', + }, + ], + output: null, + colour: 230, + }, + { + type: 'member', + message0: '%1 %2 %3', + args0: [ + { + type: 'field_input', + name: 'MEMBER_NAME', + text: '', + }, + { + type: 'field_label', + name: 'COLON', + text: ':', + }, + { + type: 'input_value', + name: 'MEMBER_VALUE', + }, + ], + previousStatement: null, + nextStatement: null, + colour: 230, + }, +]); diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/src/generators/json.js b/packages/docs/docs/codelabs/custom-generator/complete-code/src/generators/json.js new file mode 100644 index 00000000000..383e2c93fb6 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/src/generators/json.js @@ -0,0 +1,76 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview The full custom JSON generator built during the custom + * generator codelab. + */ + +import * as Blockly from 'blockly'; + +export const jsonGenerator = new Blockly.Generator('JSON'); + +const Order = { + ATOMIC: 0, +}; + +jsonGenerator.scrub_ = function (block, code, thisOnly) { + const nextBlock = block.nextConnection && block.nextConnection.targetBlock(); + if (nextBlock && !thisOnly) { + return code + ',\n' + jsonGenerator.blockToCode(nextBlock); + } + return code; +}; + +jsonGenerator.forBlock['logic_null'] = function (block) { + return ['null', Order.ATOMIC]; +}; + +jsonGenerator.forBlock['text'] = function (block) { + const textValue = block.getFieldValue('TEXT'); + const code = `"${textValue}"`; + return [code, Order.ATOMIC]; +}; + +jsonGenerator.forBlock['math_number'] = function (block) { + const code = String(block.getFieldValue('NUM')); + return [code, Order.ATOMIC]; +}; + +jsonGenerator.forBlock['logic_boolean'] = function (block) { + const code = block.getFieldValue('BOOL') == 'TRUE' ? 'true' : 'false'; + return [code, Order.ATOMIC]; +}; + +jsonGenerator.forBlock['member'] = function (block, generator) { + const name = block.getFieldValue('MEMBER_NAME'); + const value = generator.valueToCode(block, 'MEMBER_VALUE', Order.ATOMIC); + const code = `"${name}": ${value}`; + return code; +}; + +jsonGenerator.forBlock['lists_create_with'] = function (block, generator) { + const values = []; + for (let i = 0; i < block.itemCount_; i++) { + const valueCode = generator.valueToCode(block, 'ADD' + i, Order.ATOMIC); + if (valueCode) { + values.push(valueCode); + } + } + const valueString = values.join(',\n'); + const indentedValueString = generator.prefixLines( + valueString, + generator.INDENT, + ); + const codeString = '[\n' + indentedValueString + '\n]'; + return [codeString, Order.ATOMIC]; +}; + +jsonGenerator.forBlock['object'] = function (block, generator) { + const statementMembers = generator.statementToCode(block, 'MEMBERS'); + const code = '{\n' + statementMembers + '\n}'; + return [code, Order.ATOMIC]; +}; diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/src/index.css b/packages/docs/docs/codelabs/custom-generator/complete-code/src/index.css new file mode 100644 index 00000000000..f282700701f --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/src/index.css @@ -0,0 +1,40 @@ +body { + margin: 0; + max-width: 100vw; +} + +pre, +code { + overflow: auto; +} + +#pageContainer { + display: flex; + width: 100%; + max-width: 100vw; + height: 100vh; +} + +#blocklyDiv { + flex-basis: 100%; + height: 100%; + min-width: 600px; +} + +#outputPane { + display: flex; + flex-direction: column; + width: 400px; + flex: 0 0 400px; + overflow: auto; + margin: 1rem; +} + +#generatedCode { + height: 50%; + background-color: rgb(247, 240, 228); +} + +#output { + height: 50%; +} diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/src/index.html b/packages/docs/docs/codelabs/custom-generator/complete-code/src/index.html new file mode 100644 index 00000000000..36d8eeacd99 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/src/index.html @@ -0,0 +1,16 @@ + + + + + Blockly Sample App + + +
+
+
+
+
+
+
+ + diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/src/index.js b/packages/docs/docs/codelabs/custom-generator/complete-code/src/index.js new file mode 100644 index 00000000000..a21768aa9ff --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/src/index.js @@ -0,0 +1,54 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from 'blockly'; +import { blocks } from './blocks/json'; +import { jsonGenerator } from './generators/json'; +import { save, load } from './serialization'; +import { toolbox } from './toolbox'; +import './index.css'; + +// Register the blocks with Blockly +Blockly.common.defineBlocks(blocks); + +// Set up UI elements and inject Blockly +const codeDiv = document.getElementById('generatedCode').firstChild; +const blocklyDiv = document.getElementById('blocklyDiv'); +const ws = Blockly.inject(blocklyDiv, { toolbox }); + +// This function resets the code div and shows the +// generated code from the workspace. +const runCode = () => { + const code = jsonGenerator.workspaceToCode(ws); + codeDiv.innerText = code; +}; + +// Load the initial state from storage and run the code. +load(ws); +runCode(); + +// Every time the workspace changes state, save the changes to storage. +ws.addChangeListener((e) => { + // UI events are things like scrolling, zooming, etc. + // No need to save after one of these. + if (e.isUiEvent) return; + save(ws); +}); + +// Whenever the workspace changes meaningfully, run the code again. +ws.addChangeListener((e) => { + // Don't run the code when the workspace finishes loading; we're + // already running it once when the application starts. + // Don't run the code during drags; we might have invalid state. + if ( + e.isUiEvent || + e.type == Blockly.Events.FINISHED_LOADING || + ws.isDragging() + ) { + return; + } + runCode(); +}); diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/src/serialization.js b/packages/docs/docs/codelabs/custom-generator/complete-code/src/serialization.js new file mode 100644 index 00000000000..2ffda8b4609 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/src/serialization.js @@ -0,0 +1,33 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from 'blockly/core'; + +// Use a unique storage key for this codelab +const storageKey = 'jsonGeneratorWorkspace'; + +/** + * Saves the state of the workspace to browser's local storage. + * @param {Blockly.Workspace} workspace Blockly workspace to save. + */ +export const save = function (workspace) { + const data = Blockly.serialization.workspaces.save(workspace); + window.localStorage?.setItem(storageKey, JSON.stringify(data)); +}; + +/** + * Loads saved state from local storage into the given workspace. + * @param {Blockly.Workspace} workspace Blockly workspace to load into. + */ +export const load = function (workspace) { + const data = window.localStorage?.getItem(storageKey); + if (!data) return; + + // Don't emit events during loading. + Blockly.Events.disable(); + Blockly.serialization.workspaces.load(JSON.parse(data), workspace, false); + Blockly.Events.enable(); +}; diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/src/toolbox.js b/packages/docs/docs/codelabs/custom-generator/complete-code/src/toolbox.js new file mode 100644 index 00000000000..45e5b237d1e --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/src/toolbox.js @@ -0,0 +1,39 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +export const toolbox = { + kind: 'flyoutToolbox', + contents: [ + { + kind: 'block', + type: 'object', + }, + { + kind: 'block', + type: 'member', + }, + { + kind: 'block', + type: 'math_number', + }, + { + kind: 'block', + type: 'text', + }, + { + kind: 'block', + type: 'logic_boolean', + }, + { + kind: 'block', + type: 'logic_null', + }, + { + kind: 'block', + type: 'lists_create_with', + }, + ], +}; diff --git a/packages/docs/docs/codelabs/custom-generator/complete-code/webpack.config.js b/packages/docs/docs/codelabs/custom-generator/complete-code/webpack.config.js new file mode 100644 index 00000000000..1a095648fd7 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/complete-code/webpack.config.js @@ -0,0 +1,59 @@ +const path = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); + +// Base config that applies to either development or production mode. +const config = { + entry: './src/index.js', + output: { + // Compile the source files into a bundle. + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist'), + clean: true, + }, + // Enable webpack-dev-server to get hot refresh of the app. + devServer: { + static: './build', + }, + module: { + rules: [ + { + // Load CSS files. They can be imported into JS files. + test: /\.css$/i, + use: ['style-loader', 'css-loader'], + }, + ], + }, + plugins: [ + // Generate the HTML index page based on our template. + // This will output the same index page with the bundle we + // created above added in a script tag. + new HtmlWebpackPlugin({ + template: 'src/index.html', + }), + ], +}; + +module.exports = (env, argv) => { + if (argv.mode === 'development') { + // Set the output path to the `build` directory + // so we don't clobber production builds. + config.output.path = path.resolve(__dirname, 'build'); + + // Generate source maps for our code for easier debugging. + // Not suitable for production builds. If you want source maps in + // production, choose a different one from https://webpack.js.org/configuration/devtool + config.devtool = 'eval-cheap-module-source-map'; + + // Include the source maps for Blockly for easier debugging Blockly code. + config.module.rules.push({ + test: /(blockly[/\\].*\.js)$/, + use: [require.resolve('source-map-loader')], + enforce: 'pre', + }); + + // Ignore spurious warnings from source-map-loader + // It can't find source maps for some Closure modules and that is expected + config.ignoreWarnings = [/Failed to parse source map.*blockly/]; + } + return config; +}; diff --git a/packages/docs/docs/codelabs/custom-generator/generating-a-stack.mdx b/packages/docs/docs/codelabs/custom-generator/generating-a-stack.mdx new file mode 100644 index 00000000000..6d1a49cfd3e --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/generating-a-stack.mdx @@ -0,0 +1,34 @@ +--- +slug: /codelabs/custom-generator/generating-a-stack/index.html +description: How to generate code for the blocks in a stack. +--- + +# Build a custom generator + +## 9. Generating a stack + +### The scrub\_ function + +The `scrub_` function is called on every block from `blockToCode`. It takes in three arguments: + +- `block` is the current block. +- `code` is the code generated for this block, which includes code from all attached value blocks. +- `opt_thisOnly` is an optional `boolean`. If true, code should be generated for this block but no subsequent blocks. + +By default, `scrub_` simply returns the passed-in code. A common pattern is to override the function to also generate code for any blocks that follow the current block in a stack. In this case, the code will add commas and newlines between object members: + +```js +jsonGenerator.scrub_ = function (block, code, thisOnly) { + const nextBlock = block.nextConnection && block.nextConnection.targetBlock(); + if (nextBlock && !thisOnly) { + return code + ',\n' + jsonGenerator.blockToCode(nextBlock); + } + return code; +}; +``` + +### Testing scrub\_ + +Create a stack of `member` blocks on the workspace. There should be generated code for all of the blocks, not just the first one. + +Next, add an `object` block and drag the `member` blocks into it. This case tests `statementToCode`, and should generate code for all of of the blocks. diff --git a/packages/docs/docs/codelabs/custom-generator/member-block-generator.mdx b/packages/docs/docs/codelabs/custom-generator/member-block-generator.mdx new file mode 100644 index 00000000000..20e11857880 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/member-block-generator.mdx @@ -0,0 +1,65 @@ +--- +slug: /codelabs/custom-generator/member-block-generator/index.html +description: How to write a block code generator using field and input values. +--- + +# Build a custom generator + +## 6. Member block generator + +This step will build the generator for the `member` block. It will use the function `getFieldValue`, and introduce the function `valueToCode`. + +The member block has a text input field and a value input. + +![The member block is for JSON properties with a name and a value. The value comes from a connected block.](../../../static/images/codelabs/custom-generator/member_block.png) + +The generated code looks like `"property name": "property value"`. + +### Field value + +The **property name** is the value of the text input, which is fetched via `getFieldValue`: + +```js +const name = block.getFieldValue('MEMBER_NAME'); +``` + +Recall: the name of the value being fetched is `MEMBER_NAME` because that is how it was defined in `src/blocks/json.js`. + +### Input value + +The **property value** is whatever is attached to the value input. A variety of blocks could be attached there: `logic_null`, `text`, `math_number`, `logic_boolean`, or even an array (`lists_create_with`). Use `valueToCode` to get the correct value: + +```js +const value = generator.valueToCode(block, 'MEMBER_VALUE', Order.ATOMIC); +``` + +`valueToCode` does three things: + +- Finds the blocks connected to the named value input (the second argument) +- Generates the code for that block +- Returns the code as a string + +If no block is attached, `valueToCode` returns `null`. In another generator, `valueToCode` might need to replace `null` with a different default value; in JSON, `null` is fine. + +The third argument is related to operator precedence. It is used to determine if parentheses need to be added around the value. In JSON, parentheses will never be added, as discussed in an earlier section. + +### Build the code string + +Next, assemble the arguments `name` and `value` into the correct code, of the form `"name": value`. + +```js +const code = `"${name}": ${value}`; +``` + +### Put it all together + +All together, here is block generator for the member block: + +```js +jsonGenerator.forBlock['member'] = function (block, generator) { + const name = block.getFieldValue('MEMBER_NAME'); + const value = generator.valueToCode(block, 'MEMBER_VALUE', Order.ATOMIC); + const code = `"${name}": ${value}`; + return code; +}; +``` diff --git a/packages/docs/docs/codelabs/custom-generator/object-block-generator.mdx b/packages/docs/docs/codelabs/custom-generator/object-block-generator.mdx new file mode 100644 index 00000000000..c3e17e49a8e --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/object-block-generator.mdx @@ -0,0 +1,73 @@ +--- +slug: /codelabs/custom-generator/object-block-generator/index.html +description: How to write a block code generator that creates an object. +--- + +# Build a custom generator + +## 8. Object block generator + +This section will write the generator for the `object` block and will demonstrate how to use `statementToCode`. + +The `object` block generates code for a JSON Object. It has a single statement input, in which member blocks may be stacked. + +![This object block has multiple member blocks stacked inside it. The members are called a, b, and c and each has a value.](../../../static/images/codelabs/custom-generator/object_block.png) + +The generated code looks like this: + +```json +{ + "a": true, + "b": "one", + "c": 1 +} +``` + +### Get the contents + +We'll use `statementToCode` to get the code for the blocks attached to the statement input of the `object` block. + +`statementToCode` does three things: + +- Finds the first block connected to the named statement input (the second argument) +- Generates the code for that block +- Returns the code as a string + +In this case the input name is `'MEMBERS'`. + +```js +const statement_members = generator.statementToCode(block, 'MEMBERS'); +``` + +### Format and return + +Wrap the statements in curly brackets and return the code, using the default precedence: + +```js +const code = '{\n' + statement_members + '\n}'; +return [code, Order.ATOMIC]; +``` + +Note that `statementToCode` handles the indentation automatically. + +### Test it + +Here is the full block generator: + +```js +jsonGenerator.forBlock['object'] = function (block, generator) { + const statementMembers = generator.statementToCode(block, 'MEMBERS'); + const code = '{\n' + statementMembers + '\n}'; + return [code, Order.ATOMIC]; +}; +``` + +Test it by generating code for an `object` block containing a single `member` block. The result should look like this: + +```json +{ + "test": true +} +``` + +Next, add a second member block and rerun the generator. Did the resulting code change? Let's look at the next section to find out why not. diff --git a/packages/docs/docs/codelabs/custom-generator/setup.mdx b/packages/docs/docs/codelabs/custom-generator/setup.mdx new file mode 100644 index 00000000000..48582bcfd1a --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/setup.mdx @@ -0,0 +1,171 @@ +--- +slug: /codelabs/custom-generator/setup/index.html +description: Setting up the "Build a custom generator" codelab. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Build a custom generator + +## 2. Setup + +This codelab will demonstrate how to add code to the Blockly sample app to create and use a new generator. + +### The application + +Use the [`npx @blockly/create-package app`](https://www.npmjs.com/package/@blockly/create-package) command to create a standalone application that contains a sample setup of Blockly, including custom blocks and a display of the generated code and output. + +1. Run `npx @blockly/create-package app custom-generator-codelab`. This will create a blockly application in the folder `custom-generator-codelab`. +1. `cd` into the new directory: `cd custom-generator-codelab`. +1. Run `npm start` to start the server and run the sample application. +1. The sample app will automatically run in the browser window that opens. + +The initial application has one custom block and includes JavaScript generator definitions for that block. Since this codelab will be creating a JSON generator instead, it will remove that custom block and add its own. + +The complete code used in this codelab can be viewed in the `blockly` repository under [docs/docs/codelabs/custom-generator](https://github.com/RaspberryPiFoundation/blockly/docs/docs/codelabs/custom-generator/complete-code). + +Before setting up the rest of the application, change the storage key used for this codelab application. This will ensure that the workspace is saved in its own storage, separate from the regular sample app, so that it doesn't interfere with other demos. In `serialization.js`, change the value of `storageKey` to some unique string. `jsonGeneratorWorkspace` will work: + +```js +// Use a unique storage key for this codelab +const storageKey = 'jsonGeneratorWorkspace'; +``` + +### Blocks + +This codelab will use two custom blocks, as well as five blocks from Blockly's standard set. + +The custom blocks represent the _Object_ and _Member_ sections of the JSON specification. + +The blocks are: + +- `object` +- `member` +- `math_number` +- `text` +- `logic_boolean` +- `logic_null` +- `lists_create_with` + +### Custom block definitions + +Create a new file in the `src/blocks/` directory called `json.js`. This will hold the custom JSON-related blocks. Add the following code: + +```js +import * as Blockly from 'blockly'; + +export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray([ + { + type: 'object', + message0: '{ %1 %2 }', + args0: [ + { + type: 'input_dummy', + }, + { + type: 'input_statement', + name: 'MEMBERS', + }, + ], + output: null, + colour: 230, + }, + { + type: 'member', + message0: '%1 %2 %3', + args0: [ + { + type: 'field_input', + name: 'MEMBER_NAME', + text: '', + }, + { + type: 'field_label', + name: 'COLON', + text: ':', + }, + { + type: 'input_value', + name: 'MEMBER_VALUE', + }, + ], + previousStatement: null, + nextStatement: null, + colour: 230, + }, +]); +``` + +This code creates the block definitions, but it doesn't register the definitions with Blockly to make the blocks usable. We'll do that in `src/index.js`. +Currently, the app imports `blocks` from the original sample file, `text.js`. Instead, it should import the definitions that were just added. Remove the original import: + +```js +// Remove this! +import { blocks } from './blocks/text'; +``` + +and add the import for the new blocks: + +```js +import { blocks } from './blocks/json'; +``` + +Later in the file the block definitions are registered with Blockly (this code is already present and does not need to be added): + +```js +Blockly.common.defineBlocks(blocks); +``` + +### Toolbox definition + +Next, define a toolbox that includes these custom blocks. For this example, there's a flyout-only toolbox with seven blocks in it. + +The file `src/toolbox.js` contains the original sample toolbox. Replace the entire contents of that file with this code: + +```js +export const toolbox = { + kind: 'flyoutToolbox', + contents: [ + { + kind: 'block', + type: 'object', + }, + { + kind: 'block', + type: 'member', + }, + { + kind: 'block', + type: 'math_number', + }, + { + kind: 'block', + type: 'text', + }, + { + kind: 'block', + type: 'logic_boolean', + }, + { + kind: 'block', + type: 'logic_null', + }, + { + kind: 'block', + type: 'lists_create_with', + }, + ], +}; +``` + +Our `index.js` file already handles importing the toolbox and using it in Blockly. + +If the server is already running, refresh the page to see changes. Otherwise, run `npm start` to start the server. New blocks should now exist in the toolbox, like this: + + + ![Screenshot of toolbox showing the added blocks, including the new member and + object blocks, plus the built-in number, text, boolean, null, and list + blocks.](../../../static/images/codelabs/custom-generator/toolbox_blocks.png) + + +The app is still trying to generate and run JavaScript for the workspace, instead of JSON. We will change that soon. diff --git a/packages/docs/docs/codelabs/custom-generator/summary.mdx b/packages/docs/docs/codelabs/custom-generator/summary.mdx new file mode 100644 index 00000000000..db769d92bc2 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/summary.mdx @@ -0,0 +1,28 @@ +--- +pagination_next: null +slug: /codelabs/custom-generator/summary/index.html +description: Summary of the "Build a custom generator" codelab. +--- + +# Build a custom generator + +## 10. Summary + +In this codelab you learned: + +- How to build a custom language generator to generate JSON. +- How to define block generators for built in blocks and for custom blocks. +- How to use a custom generator in a sample app. +- How to use the core generator functions: `statementToCode`, `valueToCode`, `blockToCode`, and `getFieldValue`. +- How to generate code for stacks of blocks. + +JSON is a simple language, and there are many additional features that could be implemented in a custom generator. Blockly's built-in language generators are a good place to learn more about some additional features: + +- Variable definition and use. +- Function definition and use. +- Initialization and cleanup. +- Injecting additional functions and variables. +- Handling comments. +- Handling parentheses with operator precedence. + +Blockly ships with five language generators: Python, Dart, JavaScript, PHP, and Lua. The language generators and block generators can be found in the [generators directory](https://github.com/RaspberryPiFoundation/blockly/tree/main/generators). diff --git a/packages/docs/docs/codelabs/custom-generator/the-basics.mdx b/packages/docs/docs/codelabs/custom-generator/the-basics.mdx new file mode 100644 index 00000000000..d03d72a03d6 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/the-basics.mdx @@ -0,0 +1,78 @@ +--- +slug: /codelabs/custom-generator/the-basics/index.html +description: How to define and call a language generator. +--- + +# Build a custom generator + +## 3. The basics + +A _language generator_ defines the basic properties of a language, such as how indentation works. _Block generators_ define how individual blocks are turned into code, and must be defined for every block used. + +A language generator has a single entry point: `workspaceToCode`. This function takes in a workspace and: + +- Initializes the generator and any necessary state by calling `init`. +- Walks the list of top blocks on the workspace and calls `blockToCode` on each top block. +- Cleans up any leftover state by calling `finish`. +- Returns the generated code. + +### Create the language generator + +The first step is to define and call the custom language generator. + +A custom language generator is simply an instance of `Blockly.Generator`. Create a new file `src/generators/json.js`. In it, import Blockly and call the `Blockly.Generator` constructor, passing in the generator's name and storing the result. + +```js +import * as Blockly from 'blockly'; + +export const jsonGenerator = new Blockly.CodeGenerator('JSON'); +``` + +### Generate code + +Next, hook up the new generator with the sample app. First, remove the old code that imports the new block generator properties and assigns them to the `javascriptGenerator`. Remove these lines from `src/index.js`: + +```js +// Remove these lines! +import { forBlock } from './generators/javascript'; +import { javascriptGenerator } from 'blockly/javascript'; + +// Also remove this line! (further down) +Object.assign(javascriptGenerator.forBlock, forBlock); +``` + +Now import the new generator: + +```js +import { jsonGenerator } from './generators/json'; +``` + +Currently, there are two panels in the app next to the workspace. One shows the generated JavaScript code, and one executes it. The one panel showing the generated Javascript code will be changed to show the generated JSON code instead. Since JSON can't be directly executed, the panel that shows the execution will be left blank. Change the `runCode` function to the following: + +```js +// This function resets the code div and shows the +// generated code from the workspace. +const runCode = () => { + const code = jsonGenerator.workspaceToCode(ws); + codeDiv.innerText = code; +}; +``` + +Since the bottom panel is not being modified, delete this line: + +```js +// Remove this line! +const outputDiv = document.getElementById('output'); +``` + +The generated code will now be shown automatically in the top left panel. Refresh the sample app page to see the changes so far. + +### Test it + +Put a number block on the workspace and check the generator output area. It's empty, so check the console. You should see an error: + +``` +Language "JSON" does not know how to generate code for block type "math_number". +``` + +This error occurs because there has to be a block generator for each type of block. Read the next section for more details. diff --git a/packages/docs/docs/codelabs/custom-generator/value-block-generators.mdx b/packages/docs/docs/codelabs/custom-generator/value-block-generators.mdx new file mode 100644 index 00000000000..e7102456ecb --- /dev/null +++ b/packages/docs/docs/codelabs/custom-generator/value-block-generators.mdx @@ -0,0 +1,102 @@ +--- +slug: /codelabs/custom-generator/value-block-generators/index.html +description: How to write a block code generator for a simple value block. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Build a custom generator + +## 5. Value block generators + +This step will build the generators for the simple value blocks: `logic_null`, `text`, `math_number`, and `logic_boolean`. + +It will use `getFieldValue` on several types of fields. + +### Null + +The simplest block in this example is the `logic_null` block. + + + ![The null block simply returns + "null".](../../../static/images/codelabs/custom-generator/null_block.png) + + +No matter what, it generates the code `'null'`. Notice that this is a string, because all generated code is a string. +Add the following code to `src/generators/json.js`: + +```js +jsonGenerator.forBlock['logic_null'] = function (block) { + return ['null', Order.ATOMIC]; +}; +``` + +### String + +Next is the `text` block. + + + ![The text block has an input for the user to type text + into.](../../../static/images/codelabs/custom-generator/text_block.png) + + +Unlike `logic_null`, there is a single text input field on this block. Use `getFieldValue`: + +```js +const textValue = block.getFieldValue('TEXT'); +``` + +Since this is a string in the generated code, wrap the value in quotation marks and return it: + +```js +jsonGenerator.forBlock['text'] = function (block) { + const textValue = block.getFieldValue('TEXT'); + const code = `"${textValue}"`; + return [code, Order.ATOMIC]; +}; +``` + +### Number + +The `math_number` block has a number field. + + + ![The number block has an input for a user to type a + number](../../../static/images/codelabs/custom-generator/number_block.png) + + +Like the `text` block, the `math_number` block can use `getFieldValue`. Unlike the text block, the function doesn't need to wrap it in additional quotation marks, because in the JSON code, it won't be a string. + +However, like all generated code and as with `null` above, the function needs to return the code as a string from the generator. + +```js +jsonGenerator.forBlock['math_number'] = function (block) { + const code = String(block.getFieldValue('NUM')); + return [code, Order.ATOMIC]; +}; +``` + +### Boolean + +The `logic_boolean` block has a dropdown field named `BOOL`. + + + ![The boolean block lets the user select 'true' or 'false' from a dropdown + menu.](../../../static/images/codelabs/custom-generator/boolean_block.png) + + +Calling `getFieldValue` on a dropdown field returns the value of the selected option, which may not be the same as the display text. In this case the dropdown has two possible values: `TRUE` and `FALSE`. + +```js +jsonGenerator.forBlock['logic_boolean'] = function (block) { + const code = block.getFieldValue('BOOL') === 'TRUE' ? 'true' : 'false'; + return [code, Order.ATOMIC]; +}; +``` + +### Summary + +- Value blocks return an array containing the value as a string and the precedence. +- `getFieldValue` finds the field with the specified name and returns its value. +- The type of the return value from `getFieldValue` depends on the type of the field. +- Each field type must document what its value represents. diff --git a/packages/docs/docs/codelabs/custom-renderer/change-connection-shapes.mdx b/packages/docs/docs/codelabs/custom-renderer/change-connection-shapes.mdx new file mode 100644 index 00000000000..e46cbbfbaf5 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/change-connection-shapes.mdx @@ -0,0 +1,156 @@ +--- +slug: /codelabs/custom-renderer/change-connection-shapes/index.html +description: How to change connection shapes. +--- + +# Build custom renderers + +## 7. Change connection shapes + +This step will define and use new shapes for previous/next connections and input/output connections. This takes three steps: + +1. Define new shape objects. +1. Override `init()` to store the new shape objects. +1. Override `shapeFor(connection)` to return the new objects. + +### Define a previous/next connection shape + +An outline path is drawn clockwise around the block, starting at the top left. As a result the previous connection is drawn from left-to-right, while the next connection is drawn from right-to-left. + +Previous and next connections are defined by the same object. The object has four properties: + +- `width`: The width of the connection. +- `height`: The height of the connection. +- `pathLeft`: The sub-path that describes the connection when drawn from left-to-right. +- `pathRight`: The sub-path that describes the connection when drawn from right-to-left. + +Define a new function called `makeRectangularPreviousConn()` and put it inside the `CustomConstantProvider` class definition. Note that `NOTCH_WIDTH` and `NOTCH_HEIGHT` have already been overridden in the `constructor()`, so they'll be reused: + +```js + /** + * @returns Rectangular notch for use with previous and next connections. + */ + makeRectangularPreviousConn() { + const width = this.NOTCH_WIDTH; + const height = this.NOTCH_HEIGHT; + + /** + * Since previous and next connections share the same shape you can define + * a function to generate the path for both. + * + * @param dir Multiplier for the horizontal direction of the path (-1 or 1) + * @returns SVGPath line for use with previous and next connections. + */ + function makeMainPath(dir) { + return Blockly.utils.svgPaths.line( + [ + Blockly.utils.svgPaths.point(0, height), + Blockly.utils.svgPaths.point(dir * width, 0), + Blockly.utils.svgPaths.point(0, -height), + ]); + } + const pathLeft = makeMainPath(1); + const pathRight = makeMainPath(-1); + + return { + width: width, + height: height, + pathLeft: pathLeft, + pathRight: pathRight, + }; + } +``` + +### Define an input/output connection shape + +Just as previous/next connection shapes are drawn from left-to-right and right-to-left, input/output connection shapes are drawn from top-to-bottom and bottom-to-top. + +Input and output connections are defined by the same object. The object has four properties: + +- `width`: The width of the connection. +- `height`: The height of the connection. +- `pathUp`: The sub-path that describes the connection when drawn from top-to-bottom. +- `pathDown`: The sub-path that describes the connection when drawn from bottom-to-top. + +Define a new function called `makeRectangularInputConn()` and put it inside the `CustomConstantProvider` class definition. Note that `TAB_WIDTH` and `TAB_HEIGHT` have already been overridden in the `constructor()` so they'll be reused: + +```js + /** + * @returns Rectangular puzzle tab for use with input and output connections. + */ + makeRectangularInputConn() { + const width = this.TAB_WIDTH; + const height = this.TAB_HEIGHT; + + /** + * Since input and output connections share the same shape you can define + * a function to generate the path for both. + * + * @param dir Multiplier for the vertical direction of the path (-1 or 1) + * @returns SVGPath line for use with input and output connections. + */ + function makeMainPath(dir) { + return Blockly.utils.svgPaths.line( + [ + Blockly.utils.svgPaths.point(-width, 0), + Blockly.utils.svgPaths.point(0, dir * height), + Blockly.utils.svgPaths.point(width, 0), + ]); + } + const pathUp = makeMainPath(-1); + const pathDown = makeMainPath(1); + + return { + width: width, + height: height, + pathUp: pathUp, + pathDown: pathDown, + }; + } +``` + +### Override init() + +Override the `init()` function in the `CustomConstantProvider` class definition and store the new shape objects as `RECT_PREV_NEXT` and `RECT_INPUT_OUTPUT`. Make sure to call the superclass `init()` function to store other objects that have not been overridden. + +```js + /** + * @override + */ + init() { + // First, call init() in the base provider to store the default objects. + super.init(); + + // Add calls to create shape objects for the new connection shapes. + this.RECT_PREV_NEXT = this.makeRectangularPreviousConn(); + this.RECT_INPUT_OUTPUT = this.makeRectangularInputConn(); + } +``` + +### Override shapeFor(connection) + +Next, override the `shapeFor(connection)` function in the `CustomConstantProvider` class definition and return the new custom objects: + +```js + /** + * @override + */ + shapeFor(connection) { + switch (connection.type) { + case Blockly.INPUT_VALUE: + case Blockly.OUTPUT_VALUE: + return this.RECT_INPUT_OUTPUT; + case Blockly.PREVIOUS_STATEMENT: + case Blockly.NEXT_STATEMENT: + return this.RECT_PREV_NEXT; + default: + throw Error('Unknown connection type'); + } + } +``` + +### The result + +Return to the browser, click on the `Loops` entry, and drag out a repeat block. The resulting block should have rectangular connections for all four connection types. + +![[Screenshot of a custom renderer with notches, corners, and tabs with fundamentally different shapes than the defaults.]](../../../static/images/codelabs/custom-renderer/custom_notches.png) diff --git a/packages/docs/docs/codelabs/custom-renderer/codelab-overview.mdx b/packages/docs/docs/codelabs/custom-renderer/codelab-overview.mdx new file mode 100644 index 00000000000..a17137c0e37 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/codelab-overview.mdx @@ -0,0 +1,35 @@ +--- +pagination_prev: null +slug: /codelabs/custom-renderer/codelab-overview/index.html +description: Overview of the "Build custom renderers" codelab. +--- + +# Build custom renderers + +## 1. Codelab overview + +### What you'll learn + +- How to define and register a custom renderer. +- How to override renderer constants. +- How to change the shape of connection notches. +- How to set a connection's shape based on its type checks. + +### What you'll build + +This codelab builds and uses four renderers: + +1. A minimal custom renderer that extends `Blockly.blockRendering.Renderer` but makes no modifications. + ![Screenshot of a renderer with an appearance matching the base renderer.](../../../static/images/codelabs/custom-renderer/custom_renderer.png) +1. A custom renderer which sets new values for the rendering-related constants `NOTCH_WIDTH`, `NOTCH_HEIGHT`,`CORNER_RADIUS`, and `TAB_HEIGHT` found in `Blockly.blockRendering.ConstantProvider`. + ![Screenshot of a custom renderer with notches, corners, and tabs that have similar shapes as the default but with different widths, heights, and radiuses.](../../../static/images/codelabs/custom-renderer/custom_constants.png) +1. A custom renderer which overrides the functions `Blockly.blockRendering.ConstantProvider.init()` and `Blockly.blockRendering.ConstantProvider.shapeFor(connection)` to define and return custom [SVG paths](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path). + ![Screenshot of a custom renderer with notches, corners, and tabs with fundamentally different shapes than the defaults.](../../../static/images/codelabs/custom-renderer/custom_notches.png) +1. A custom renderer which overrides the function `Blockly.blockRendering.ConstantProvider.shapeFor(connection)` to return different shapes for the input/output connections depending on whether the their type is a `Number`, `String`, or `Boolean`. + ![Screenshot of a custom renderer with rectangles for the Number input/outputs and a puzzle tab for the Boolean input/output attached to an "if" block](../../../static/images/codelabs/custom-renderer/typed_connection_shapes.png) + +### What you'll need + +- Basic understanding of renderers and toolboxes in Blockly. +- NPM installed ([instructions](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)). +- Comfort using the command line/terminal. diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/README.mdx b/packages/docs/docs/codelabs/custom-renderer/complete-code/README.mdx new file mode 100644 index 00000000000..1b3c36d82b8 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/README.mdx @@ -0,0 +1,50 @@ +# Blockly Sample App + +## Purpose + +This app illustrates how to use Blockly together with common programming tools like node/npm, webpack, typescript, eslint, and others. You can use it as the starting point for your own application and modify it as much as you'd like. It contains basic infrastructure for running, building, testing, etc. that you can use even if you don't understand how to configure the related tool yet. When your needs outgrow the functionality provided here, you can replace the provided configuration or tool with your own. + +## Quick Start + +1. [Install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) npm if you haven't before. +2. Run [`npx @blockly/create-package app `](https://www.npmjs.com/package/@blockly/create-package) to clone this application to your own machine. +3. Run `npm install` to install the required dependencies. +4. Run `npm run start` to run the development server and see the app in action. +5. If you make any changes to the source code, just refresh the browser while the server is running to see them. + +## Tooling + +The application uses many of the same tools that the Blockly team uses to develop Blockly itself. Following is a brief overview, and you can read more about them on our [developer site](https://developers.google.com/blockly/guides/contribute/get-started/development_tools). + +- Structure: The application is built as an npm package. You can use npm to manage the dependencies of the application. +- Modules: ES6 modules to handle imports to/exports from other files. +- Building/bundling: Webpack to build the source code and bundle it into one file for serving. +- Development server: webpack-dev-server to run locally while in development. +- Testing: Mocha to run unit tests. +- Linting: Eslint to lint the code and ensure it conforms with a standard style. +- UI Framework: Does not use a framework. For more complex applications, you may wish to integrate a UI framework like React or Angular. + +You can disable, reconfigure, or replace any of these tools at any time, but they are preconfigured to get you started developing your Blockly application quickly. + +## Structure + +- `package.json` contains basic information about the app. This is where the scripts to run, build, etc. are listed. +- `package-lock.json` is used by npm to manage dependencies +- `webpack.config.js` is the configuration for webpack. This handles bundling the application and running our development server. +- `src/` contains the rest of the source code. +- `dist/` contains the packaged output (that you could host on a server, for example). This is ignored by git and will only appear after you run `npm run build` or `npm run start`. + +### Source Code + +- `index.html` contains the skeleton HTML for the page. This file is modified during the build to import the bundled source code output by webpack. +- `index.js` is the entry point of the app. It configures Blockly and sets up the page to show the blocks, the generated code, and the output of running the code in JavaScript. +- `serialization.js` has code to save and load the workspace using the browser's local storage. This is how your workspace is saved even after refreshing or leaving the page. You could replace this with code that saves the user's data to a cloud database instead. +- `toolbox.js` contains the toolbox definition for the app. The current toolbox contains nearly every block that Blockly provides out of the box. You probably want to replace this definition with your own toolbox that uses your custom blocks and only includes the default blocks that are relevant to your application. +- `blocks/text.js` has code for a custom text block, just as an example of creating your own blocks. You probably want to delete this block, and add your own blocks in this directory. +- `generators/javascript.js` contains the JavaScript generator for the custom text block. You'll need to include block generators for any custom blocks you create, in whatever programming language(s) your application will use. + +## Serving + +To run your app locally, run `npm run start` to run the development server. This mode generates source maps and ingests the source maps created by Blockly, so that you can debug using unminified code. + +To deploy your app so that others can use it, run `npm run build` to run a production build. This will bundle your code and minify it to reduce its size. You can then host the contents of the `dist` directory on a web server of your choosing. If you're just getting started, try using [GitHub Pages](https://pages.github.com/). diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/package-lock.json b/packages/docs/docs/codelabs/custom-renderer/complete-code/package-lock.json new file mode 100644 index 00000000000..457f663c109 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/package-lock.json @@ -0,0 +1,8280 @@ +{ + "name": "renderer-sample-app", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "renderer-sample-app", + "version": "1.0.0", + "license": "Apache-2.0", + "dependencies": { + "blockly": "^12.0.0" + }, + "devDependencies": { + "css-loader": "^6.7.1", + "html-webpack-plugin": "^5.5.0", + "source-map-loader": "^4.0.1", + "style-loader": "^3.3.1", + "webpack": "^5.93.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.0.4" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.3.tgz", + "integrity": "sha512-XBG3talrhid44BY1x3MHzUx/aTG8+x/Zi57M4aTKK9RFB4aLlF3TTSzfzn8nWVHWL3FgAXAxmupmDd6VWww+pw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.9.tgz", + "integrity": "sha512-wILs5Zk7BU86UArYBJTPy/FMPPKVKHMj1ycCEyf3VUptol0JNRLFU/BZsJ4aiIHJEbSLiizzRrw8Pc1uAEDrXw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz", + "integrity": "sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz", + "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.37.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.16.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.11", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", + "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.6", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/batch": { + "version": "0.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blockly": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-12.0.0.tgz", + "integrity": "sha512-CrwxGjbgCh/zGg46VTlp26NYblSi/82n4VFsamyW5b4W6t3HXaf/b3CbMuu4/YnFvqlyJs+8zR4OKNTbIc28EA==", + "dependencies": { + "jsdom": "26.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clean-css": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "8.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "6.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.19", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-loader/node_modules/semver": { + "version": "7.5.0", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssstyle": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.1.tgz", + "integrity": "sha512-ZgW+Jgdd7i52AaLYCriF8Mxqft0gD/R9i9wi6RWBhs1pqdPEzPjym7rvRKi397WmQFf3SlyUsszhw+VVCbx79Q==", + "dependencies": { + "@asamuzakjp/css-color": "^3.1.2", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==" + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.1.tgz", + "integrity": "sha512-FKbOCOQ5QRB3VlIbl1LZQefWIYwszlBloaXcY2rbfpu9ioJnNh3TK03YtIDKDo3WKBi8u+YV4+Fn2CkEozgf4w==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "dev": true, + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "webpack": "^5.20.0" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "dependencies": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", + "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lower-case": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.4.tgz", + "integrity": "sha512-Xlj8b2rU11nM6+KU6wC7cuWcHQhVINWCUgdPS4Ar9nPxLaOya3RghqK7ALyDW2QtGebYAYs6uEdEVnwPVT942A==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.1.2", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz", + "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==" + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", + "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "node_modules/param-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz", + "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.11", + "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", + "dev": true, + "license": "MIT" + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", + "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "14 >=14.20 || 16 >=16.20 || >=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==" + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/sockjs": { + "version": "0.3.24", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/style-loader": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.31.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", + "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tslib": { + "version": "2.5.0", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utila": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.1.0", + "ws": "^8.16.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-driver/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + } + }, + "dependencies": { + "@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "requires": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + }, + "dependencies": { + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + } + } + }, + "@csstools/color-helpers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==" + }, + "@csstools/css-calc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.3.tgz", + "integrity": "sha512-XBG3talrhid44BY1x3MHzUx/aTG8+x/Zi57M4aTKK9RFB4aLlF3TTSzfzn8nWVHWL3FgAXAxmupmDd6VWww+pw==", + "requires": {} + }, + "@csstools/css-color-parser": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.9.tgz", + "integrity": "sha512-wILs5Zk7BU86UArYBJTPy/FMPPKVKHMj1ycCEyf3VUptol0JNRLFU/BZsJ4aiIHJEbSLiizzRrw8Pc1uAEDrXw==", + "requires": { + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.3" + } + }, + "@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "requires": {} + }, + "@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==" + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "dev": true + }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.3", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "requires": {} + }, + "@jsonjoy.com/json-pack": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz", + "integrity": "sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==", + "dev": true, + "requires": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + } + }, + "@jsonjoy.com/util": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz", + "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==", + "dev": true, + "requires": {} + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/eslint": { + "version": "8.37.0", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.4", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/html-minifier-terser": { + "version": "6.1.0", + "dev": true + }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "@types/http-proxy": { + "version": "1.17.11", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.11", + "dev": true + }, + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "@types/node": { + "version": "18.16.1", + "dev": true + }, + "@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "requires": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/ws": { + "version": "8.5.11", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", + "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "requires": {} + }, + "@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abab": { + "version": "2.0.6", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.8.2", + "dev": true + }, + "acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "requires": {} + }, + "agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==" + }, + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, + "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, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "ansi-html-community": { + "version": "0.0.8", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "dev": true + }, + "binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true + }, + "blockly": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-12.0.0.tgz", + "integrity": "sha512-CrwxGjbgCh/zGg46VTlp26NYblSi/82n4VFsamyW5b4W6t3HXaf/b3CbMuu4/YnFvqlyJs+8zR4OKNTbIc28EA==", + "requires": { + "jsdom": "26.1.0" + } + }, + "body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "boolbase": { + "version": "1.0.0", + "dev": true + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "requires": { + "fill-range": "^7.1.1" + } + }, + "browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "dev": true + }, + "bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "requires": { + "run-applescript": "^7.0.0" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "camel-case": { + "version": "4.1.2", + "dev": true, + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "caniuse-lite": { + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "dev": true + }, + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "dev": true + }, + "clean-css": { + "version": "5.3.2", + "dev": true, + "requires": { + "source-map": "~0.6.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "colorette": { + "version": "2.0.20", + "dev": true + }, + "commander": { + "version": "8.3.0", + "dev": true + }, + "compressible": { + "version": "2.0.18", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "bytes": { + "version": "3.0.0", + "dev": true + }, + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "connect-history-api-fallback": { + "version": "2.0.0", + "dev": true + }, + "content-disposition": { + "version": "0.5.4", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "dev": true + } + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true + }, + "cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-loader": { + "version": "6.7.3", + "dev": true, + "requires": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.19", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "dependencies": { + "semver": { + "version": "7.5.0", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "css-select": { + "version": "4.3.0", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "dev": true + }, + "cssstyle": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.1.tgz", + "integrity": "sha512-ZgW+Jgdd7i52AaLYCriF8Mxqft0gD/R9i9wi6RWBhs1pqdPEzPjym7rvRKi397WmQFf3SlyUsszhw+VVCbx79Q==", + "requires": { + "@asamuzakjp/css-color": "^3.1.2", + "rrweb-cssom": "^0.8.0" + } + }, + "data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "requires": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==" + }, + "default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "requires": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + } + }, + "default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true + }, + "default-gateway": { + "version": "6.0.3", + "dev": true, + "requires": { + "execa": "^5.0.0" + } + }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true + }, + "depd": { + "version": "2.0.0", + "dev": true + }, + "destroy": { + "version": "1.2.0", + "dev": true + }, + "detect-node": { + "version": "2.1.0", + "dev": true + }, + "dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "dom-converter": { + "version": "0.2.0", + "dev": true, + "requires": { + "utila": "~0.4" + } + }, + "dom-serializer": { + "version": "1.4.1", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "dev": true + }, + "domhandler": { + "version": "4.3.1", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dot-case": { + "version": "3.0.4", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "dev": true + }, + "electron-to-chromium": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.1.tgz", + "integrity": "sha512-FKbOCOQ5QRB3VlIbl1LZQefWIYwszlBloaXcY2rbfpu9ioJnNh3TK03YtIDKDo3WKBi8u+YV4+Fn2CkEozgf4w==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "dev": true + }, + "enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "2.2.0", + "dev": true + }, + "envinfo": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "dev": true + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-module-lexer": { + "version": "1.2.1", + "dev": true + }, + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "dev": true + }, + "etag": { + "version": "1.8.1", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "dev": true + }, + "events": { + "version": "3.3.0", + "dev": true + }, + "execa": { + "version": "5.0.0", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "dev": true + }, + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.16", + "dev": true + }, + "faye-websocket": { + "version": "0.11.4", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "find-up": { + "version": "4.1.0", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true + }, + "foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } + } + }, + "forwarded": { + "version": "0.2.0", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "dev": true + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.0", + "dev": true + }, + "glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.10", + "dev": true + }, + "handle-thing": { + "version": "2.0.1", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, + "he": { + "version": "1.2.0", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + } + } + }, + "html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "requires": { + "whatwg-encoding": "^3.1.1" + } + }, + "html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true + }, + "html-minifier-terser": { + "version": "6.1.0", + "dev": true, + "requires": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + } + }, + "html-webpack-plugin": { + "version": "5.5.1", + "dev": true, + "requires": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + } + }, + "htmlparser2": { + "version": "6.1.0", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-deceiver": { + "version": "1.2.7", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.8", + "dev": true + }, + "http-proxy": { + "version": "1.18.1", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "http-proxy-middleware": { + "version": "2.0.6", + "dev": true, + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "requires": { + "agent-base": "^7.1.2", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "dev": true + }, + "hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true + }, + "iconv-lite": { + "version": "0.6.3", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "icss-utils": { + "version": "5.1.0", + "dev": true, + "requires": {} + }, + "import-local": { + "version": "3.1.0", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "inherits": { + "version": "2.0.4", + "dev": true + }, + "interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dev": true, + "requires": { + "hasown": "^2.0.2" + } + }, + "is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "requires": { + "is-docker": "^3.0.0" + } + }, + "is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "3.0.0", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-stream": { + "version": "2.0.1", + "dev": true + }, + "is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "requires": { + "is-inside-container": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "dev": true + }, + "jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "requires": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + } + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true + }, + "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 + }, + "kind-of": { + "version": "6.0.3", + "dev": true + }, + "launch-editor": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", + "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", + "dev": true, + "requires": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "loader-runner": { + "version": "4.3.0", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "dev": true + }, + "lower-case": { + "version": "2.0.2", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "lru-cache": { + "version": "6.0.0", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true + }, + "memfs": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.4.tgz", + "integrity": "sha512-Xlj8b2rU11nM6+KU6wC7cuWcHQhVINWCUgdPS4Ar9nPxLaOya3RghqK7ALyDW2QtGebYAYs6uEdEVnwPVT942A==", + "dev": true, + "requires": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.1.2", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "dev": true + }, + "methods": { + "version": "1.1.2", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "1.6.0", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "dev": true + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, + "ms": { + "version": "2.1.2" + }, + "multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "dev": true + }, + "no-case": { + "version": "3.0.4", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true + }, + "node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "nwsapi": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz", + "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==" + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true + }, + "obuf": { + "version": "1.1.2", + "dev": true + }, + "on-finished": { + "version": "2.4.1", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "requires": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-retry": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", + "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "dev": true, + "requires": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + } + }, + "p-try": { + "version": "2.2.0", + "dev": true + }, + "package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "param-case": { + "version": "3.0.4", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "requires": { + "entities": "^6.0.0" + }, + "dependencies": { + "entities": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz", + "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==" + } + } + }, + "parseurl": { + "version": "1.3.3", + "dev": true + }, + "pascal-case": { + "version": "3.1.2", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-exists": { + "version": "4.0.0", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + } + } + }, + "path-to-regexp": { + "version": "0.1.7", + "dev": true + }, + "picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "postcss": { + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dev": true, + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "dev": true, + "requires": {} + }, + "postcss-modules-local-by-default": { + "version": "4.0.0", + "dev": true, + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "dev": true, + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.11", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "dev": true + }, + "pretty-error": { + "version": "4.0.0", + "dev": true, + "requires": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "dev": true + }, + "proxy-addr": { + "version": "2.0.7", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "dev": true + }, + "raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "requires": { + "resolve": "^1.20.0" + } + }, + "relateurl": { + "version": "0.2.7", + "dev": true + }, + "renderkid": { + "version": "3.0.0", + "dev": true, + "requires": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "dev": true + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "dev": true + }, + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true + }, + "rimraf": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", + "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==", + "dev": true, + "requires": { + "glob": "^10.3.7" + } + }, + "rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==" + }, + "run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2" + }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, + "select-hose": { + "version": "2.0.0", + "dev": true + }, + "selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "requires": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + } + }, + "send": { + "version": "0.18.0", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "dev": true + } + } + }, + "ms": { + "version": "2.1.3", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "dev": true + }, + "ms": { + "version": "2.0.0", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "dev": true + } + } + }, + "serve-static": { + "version": "1.15.0", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, + "setprototypeof": { + "version": "1.2.0", + "dev": true + }, + "shallow-clone": { + "version": "3.0.1", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "dev": true + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true + }, + "side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + } + }, + "signal-exit": { + "version": "3.0.7", + "dev": true + }, + "sockjs": { + "version": "0.3.24", + "dev": true, + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "source-map": { + "version": "0.6.1", + "dev": true + }, + "source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true + }, + "source-map-loader": { + "version": "4.0.1", + "dev": true, + "requires": { + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + } + }, + "source-map-support": { + "version": "0.5.21", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdy": { + "version": "4.0.2", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "statuses": { + "version": "2.0.1", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + } + } + }, + "strip-ansi": { + "version": "6.0.1", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "dev": true + }, + "style-loader": { + "version": "3.3.2", + "dev": true, + "requires": {} + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "tapable": { + "version": "2.2.1", + "dev": true + }, + "terser": { + "version": "5.31.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", + "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "dev": true + } + } + }, + "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==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "requires": {} + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "requires": { + "tldts-core": "^6.1.86" + } + }, + "tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "dev": true + }, + "tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "requires": { + "tldts": "^6.1.32" + } + }, + "tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "requires": { + "punycode": "^2.3.1" + } + }, + "tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "requires": {} + }, + "tslib": { + "version": "2.5.0", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "dev": true + }, + "update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "requires": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + } + }, + "uri-js": { + "version": "4.4.1", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "dev": true + }, + "utila": { + "version": "0.4.0", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "dev": true + }, + "vary": { + "version": "1.1.2", + "dev": true + }, + "w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "requires": { + "xml-name-validator": "^5.0.0" + } + }, + "watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wbuf": { + "version": "1.7.3", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "graceful-fs": { + "version": "4.2.11", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true + } + } + }, + "webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "requires": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + } + }, + "webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", + "dev": true, + "requires": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.1.0", + "ws": "^8.16.0" + }, + "dependencies": { + "ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true + } + } + }, + "webpack-merge": { + "version": "5.8.0", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.3", + "dev": true + }, + "websocket-driver": { + "version": "0.7.4", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "dev": true + } + } + }, + "websocket-extensions": { + "version": "0.1.4", + "dev": true + }, + "whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" + }, + "whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "requires": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + } + }, + "which": { + "version": "2.0.2", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wildcard": { + "version": "2.0.1", + "dev": true + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "requires": {} + }, + "xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "yallist": { + "version": "4.0.0", + "dev": true + } + } +} diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/package.json b/packages/docs/docs/codelabs/custom-renderer/complete-code/package.json new file mode 100644 index 00000000000..7bb0b001e2a --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/package.json @@ -0,0 +1,29 @@ +{ + "name": "renderer-sample-app", + "version": "1.0.0", + "description": "A sample app using Blockly and custom renderers", + "main": "index.js", + "private": true, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "webpack --mode production", + "start": "webpack serve --open --mode development" + }, + "keywords": [ + "blockly" + ], + "author": "", + "license": "Apache-2.0", + "devDependencies": { + "css-loader": "^6.7.1", + "html-webpack-plugin": "^5.5.0", + "source-map-loader": "^4.0.1", + "style-loader": "^3.3.1", + "webpack": "^5.93.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.0.4" + }, + "dependencies": { + "blockly": "^12.0.0" + } +} diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/src/blocks/text.js b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/blocks/text.js new file mode 100644 index 00000000000..83408ea00a1 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/blocks/text.js @@ -0,0 +1,40 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from 'blockly/core'; + +// Create a custom block called 'add_text' that adds +// text to the output div on the sample app. +// This is just an example and you should replace this with your +// own custom blocks. +const addText = { + type: 'add_text', + message0: 'Add text %1 with color %2', + args0: [ + { + type: 'input_value', + name: 'TEXT', + check: 'String', + }, + { + type: 'input_value', + name: 'COLOR', + check: 'Colour', + }, + ], + previousStatement: null, + nextStatement: null, + colour: 160, + tooltip: '', + helpUrl: '', +}; + +// Create the block definitions for the JSON-only blocks. +// This does not register their definitions with Blockly. +// This file has no side effects! +export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray([ + addText, +]); diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/src/generators/javascript.js b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/generators/javascript.js new file mode 100644 index 00000000000..f7508e36ef0 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/generators/javascript.js @@ -0,0 +1,34 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Order } from 'blockly/javascript'; + +// Export all the code generators for our custom blocks, +// but don't register them with Blockly yet. +// This file has no side effects! +export const forBlock = Object.create(null); + +forBlock['add_text'] = function (block, generator) { + const text = generator.valueToCode(block, 'TEXT', Order.NONE) || "''"; + const color = + generator.valueToCode(block, 'COLOR', Order.ATOMIC) || "'#ffffff'"; + + const addText = generator.provideFunction_( + 'addText', + `function ${generator.FUNCTION_NAME_PLACEHOLDER_}(text, color) { + + // Add text to the output area. + const outputDiv = document.getElementById('output'); + const textEl = document.createElement('p'); + textEl.innerText = text; + textEl.style.color = color; + outputDiv.appendChild(textEl); +}`, + ); + // Generate the function call for this block. + const code = `${addText}(${text}, ${color});\n`; + return code; +}; diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/src/index.css b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/index.css new file mode 100644 index 00000000000..f282700701f --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/index.css @@ -0,0 +1,40 @@ +body { + margin: 0; + max-width: 100vw; +} + +pre, +code { + overflow: auto; +} + +#pageContainer { + display: flex; + width: 100%; + max-width: 100vw; + height: 100vh; +} + +#blocklyDiv { + flex-basis: 100%; + height: 100%; + min-width: 600px; +} + +#outputPane { + display: flex; + flex-direction: column; + width: 400px; + flex: 0 0 400px; + overflow: auto; + margin: 1rem; +} + +#generatedCode { + height: 50%; + background-color: rgb(247, 240, 228); +} + +#output { + height: 50%; +} diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/src/index.html b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/index.html new file mode 100644 index 00000000000..36d8eeacd99 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/index.html @@ -0,0 +1,16 @@ + + + + + Blockly Sample App + + +
+
+
+
+
+
+
+ + diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/src/index.js b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/index.js new file mode 100644 index 00000000000..7694e44a4ff --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/index.js @@ -0,0 +1,66 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from 'blockly'; +import { blocks } from './blocks/text'; +import { forBlock } from './generators/javascript'; +import { javascriptGenerator } from 'blockly/javascript'; +import { save, load } from './serialization'; +import { toolbox } from './toolbox'; +import './renderers/custom'; +import './index.css'; + +// Register the blocks and generator with Blockly +Blockly.common.defineBlocks(blocks); +Object.assign(javascriptGenerator.forBlock, forBlock); + +// Set up UI elements and inject Blockly +const codeDiv = document.getElementById('generatedCode').firstChild; +const outputDiv = document.getElementById('output'); +const blocklyDiv = document.getElementById('blocklyDiv'); +const ws = Blockly.inject(blocklyDiv, { + renderer: 'custom_renderer', + toolbox, +}); + +// This function resets the code and output divs, shows the +// generated code from the workspace, and evals the code. +// In a real application, you probably shouldn't use `eval`. +const runCode = () => { + const code = javascriptGenerator.workspaceToCode(ws); + codeDiv.innerText = code; + + outputDiv.textContent = ''; + + eval(code); +}; + +// Load the initial state from storage and run the code. +load(ws); +runCode(); + +// Every time the workspace changes state, save the changes to storage. +ws.addChangeListener((e) => { + // UI events are things like scrolling, zooming, etc. + // No need to save after one of these. + if (e.isUiEvent) return; + save(ws); +}); + +// Whenever the workspace changes meaningfully, run the code again. +ws.addChangeListener((e) => { + // Don't run the code when the workspace finishes loading; we're + // already running it once when the application starts. + // Don't run the code during drags; we might have invalid state. + if ( + e.isUiEvent || + e.type == Blockly.Events.FINISHED_LOADING || + ws.isDragging() + ) { + return; + } + runCode(); +}); diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/src/renderers/custom.js b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/renderers/custom.js new file mode 100644 index 00000000000..14666ba79ee --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/renderers/custom.js @@ -0,0 +1,166 @@ +/** + * @license + * Copyright 2020 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview The full custom renderer built during custom renderer codelab. + */ + +import * as Blockly from 'blockly/core'; + +/** + * The ConstantProvider holds rendering-related constants such as colour + * and size information. + */ +class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider { + /** @override */ + constructor() { + // Set up all of the constants from the base provider. + super(); + + // Override a few properties. + /** + * The width of the notch used for previous and next connections. + * @type {number} + * @override + */ + this.NOTCH_WIDTH = 20; + + /** + * The height of the notch used for previous and next connections. + * @type {number} + * @override + */ + this.NOTCH_HEIGHT = 10; + + /** + * Rounded corner radius. + * @type {number} + * @override + */ + this.CORNER_RADIUS = 2; + + /** + * The height of the puzzle tab used for input and output connections. + * @type {number} + * @override + */ + this.TAB_HEIGHT = 8; + } + + /** + * @override + */ + init() { + // First, call init() in the base provider to store the default objects. + super.init(); + + // Add calls to create shape objects for the new connection shapes. + this.RECT_PREV_NEXT = this.makeRectangularPreviousConn(); + this.RECT_INPUT_OUTPUT = this.makeRectangularInputConn(); + } + + /** + * @override + */ + shapeFor(connection) { + const checks = connection.getCheck(); + switch (connection.type) { + case Blockly.INPUT_VALUE: + case Blockly.OUTPUT_VALUE: + if (checks && checks.includes('Number')) { + return this.RECT_INPUT_OUTPUT; + } + if (checks && checks.includes('String')) { + return this.RECT_INPUT_OUTPUT; + } + return this.PUZZLE_TAB; + case Blockly.PREVIOUS_STATEMENT: + case Blockly.NEXT_STATEMENT: + return this.NOTCH; + default: + throw Error('Unknown connection type'); + } + } + + /** + * @returns {Object} Rectangular notch for use with previous and next connections. + */ + makeRectangularPreviousConn() { + const width = this.NOTCH_WIDTH; + const height = this.NOTCH_HEIGHT; + + /** + * Since previous and next connections share the same shape you can define + * a function to generate the path for both. + * @param {number} dir Multiplier for the horizontal direction of the path (-1 or 1) + * @returns {Object} SVGPath line for use with previous and next connections. + */ + function makeMainPath(dir) { + return Blockly.utils.svgPaths.line([ + Blockly.utils.svgPaths.point(0, height), + Blockly.utils.svgPaths.point(dir * width, 0), + Blockly.utils.svgPaths.point(0, -height), + ]); + } + const pathLeft = makeMainPath(1); + const pathRight = makeMainPath(-1); + + return { + width: width, + height: height, + pathLeft: pathLeft, + pathRight: pathRight, + }; + } + + /** + * @returns {Object} Rectangular puzzle tab for use with input and output connections. + */ + makeRectangularInputConn() { + const width = this.TAB_WIDTH; + const height = this.TAB_HEIGHT; + + /** + * Since input and output connections share the same shape you can define + * a function to generate the path for both. + * @param {number} dir Multiplier for the vertical direction of the path (-1 or 1) + * @returns {Object} SVGPath line for use with input and output connections. + */ + function makeMainPath(dir) { + return Blockly.utils.svgPaths.line([ + Blockly.utils.svgPaths.point(-width, 0), + Blockly.utils.svgPaths.point(0, dir * height), + Blockly.utils.svgPaths.point(width, 0), + ]); + } + const pathUp = makeMainPath(-1); + const pathDown = makeMainPath(1); + + return { + width: width, + height: height, + pathUp: pathUp, + pathDown: pathDown, + }; + } +} + +/** The CustomRenderer class incorporates our custom ConstantProvider. */ +export class CustomRenderer extends Blockly.blockRendering.Renderer { + /** @override */ + constructor() { + super(); + } + + /** + * @override + */ + makeConstants_() { + return new CustomConstantProvider(); + } +} + +Blockly.blockRendering.register('custom_renderer', CustomRenderer); diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/src/serialization.js b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/serialization.js new file mode 100644 index 00000000000..685eaf2fd71 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/serialization.js @@ -0,0 +1,32 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as Blockly from 'blockly/core'; + +const storageKey = 'mainWorkspace'; + +/** + * Saves the state of the workspace to browser's local storage. + * @param {Blockly.Workspace} workspace Blockly workspace to save. + */ +export const save = function (workspace) { + const data = Blockly.serialization.workspaces.save(workspace); + window.localStorage?.setItem(storageKey, JSON.stringify(data)); +}; + +/** + * Loads saved state from local storage into the given workspace. + * @param {Blockly.Workspace} workspace Blockly workspace to load into. + */ +export const load = function (workspace) { + const data = window.localStorage?.getItem(storageKey); + if (!data) return; + + // Don't emit events during loading. + Blockly.Events.disable(); + Blockly.serialization.workspaces.load(JSON.parse(data), workspace, false); + Blockly.Events.enable(); +}; diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/src/toolbox.js b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/toolbox.js new file mode 100644 index 00000000000..7d88fba3269 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/src/toolbox.js @@ -0,0 +1,612 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/* +This toolbox contains nearly every single built-in block that Blockly offers, +in addition to the custom block 'add_text' this sample app adds. +You probably don't need every single block, and should consider either rewriting +your toolbox from scratch, or carefully choosing whether you need each block +listed here. +*/ + +export const toolbox = { + kind: 'categoryToolbox', + contents: [ + { + kind: 'category', + name: 'Logic', + categorystyle: 'logic_category', + contents: [ + { + kind: 'block', + type: 'controls_if', + }, + { + kind: 'block', + type: 'logic_compare', + }, + { + kind: 'block', + type: 'logic_operation', + }, + { + kind: 'block', + type: 'logic_negate', + }, + { + kind: 'block', + type: 'logic_boolean', + }, + { + kind: 'block', + type: 'logic_null', + }, + { + kind: 'block', + type: 'logic_ternary', + }, + ], + }, + { + kind: 'category', + name: 'Loops', + categorystyle: 'loop_category', + contents: [ + { + kind: 'block', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'controls_whileUntil', + }, + { + kind: 'block', + type: 'controls_for', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + BY: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'controls_forEach', + }, + { + kind: 'block', + type: 'controls_flow_statements', + }, + ], + }, + { + kind: 'category', + name: 'Math', + categorystyle: 'math_category', + contents: [ + { + kind: 'block', + type: 'math_number', + fields: { + NUM: 123, + }, + }, + { + kind: 'block', + type: 'math_arithmetic', + inputs: { + A: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + B: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'math_single', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 9, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'math_trig', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 45, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'math_constant', + }, + { + kind: 'block', + type: 'math_number_property', + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'math_round', + fields: { + OP: 'ROUND', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 3.1, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'math_on_list', + fields: { + OP: 'SUM', + }, + }, + { + kind: 'block', + type: 'math_modulo', + inputs: { + DIVIDEND: { + shadow: { + type: 'math_number', + fields: { + NUM: 64, + }, + }, + }, + DIVISOR: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'math_constrain', + inputs: { + VALUE: { + shadow: { + type: 'math_number', + fields: { + NUM: 50, + }, + }, + }, + LOW: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + HIGH: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'math_random_int', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'math_random_float', + }, + { + kind: 'block', + type: 'math_atan2', + inputs: { + X: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + Y: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Text', + categorystyle: 'text_category', + contents: [ + { + kind: 'block', + type: 'text', + }, + { + kind: 'block', + type: 'text_join', + }, + { + kind: 'block', + type: 'text_append', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'text_length', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'text_isEmpty', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'text_indexOf', + inputs: { + VALUE: { + block: { + type: 'variables_get', + }, + }, + FIND: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'text_charAt', + inputs: { + VALUE: { + block: { + type: 'variables_get', + }, + }, + }, + }, + { + kind: 'block', + type: 'text_getSubstring', + inputs: { + STRING: { + block: { + type: 'variables_get', + }, + }, + }, + }, + { + kind: 'block', + type: 'text_changeCase', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'text_trim', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'text_count', + inputs: { + SUB: { + shadow: { + type: 'text', + }, + }, + TEXT: { + shadow: { + type: 'text', + }, + }, + }, + }, + { + kind: 'block', + type: 'text_replace', + inputs: { + FROM: { + shadow: { + type: 'text', + }, + }, + TO: { + shadow: { + type: 'text', + }, + }, + TEXT: { + shadow: { + type: 'text', + }, + }, + }, + }, + { + kind: 'block', + type: 'text_reverse', + inputs: { + TEXT: { + shadow: { + type: 'text', + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Lists', + categorystyle: 'list_category', + contents: [ + { + kind: 'block', + type: 'lists_create_with', + }, + { + kind: 'block', + type: 'lists_create_with', + }, + { + kind: 'block', + type: 'lists_repeat', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'lists_length', + }, + { + kind: 'block', + type: 'lists_isEmpty', + }, + { + kind: 'block', + type: 'lists_indexOf', + inputs: { + VALUE: { + block: { + type: 'variables_get', + }, + }, + }, + }, + { + kind: 'block', + type: 'lists_getIndex', + inputs: { + VALUE: { + block: { + type: 'variables_get', + }, + }, + }, + }, + { + kind: 'block', + type: 'lists_setIndex', + inputs: { + LIST: { + block: { + type: 'variables_get', + }, + }, + }, + }, + { + kind: 'block', + type: 'lists_getSublist', + inputs: { + LIST: { + block: { + type: 'variables_get', + }, + }, + }, + }, + { + kind: 'block', + type: 'lists_split', + inputs: { + DELIM: { + shadow: { + type: 'text', + fields: { + TEXT: ',', + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'lists_sort', + }, + { + kind: 'block', + type: 'lists_reverse', + }, + ], + }, + { + kind: 'category', + name: 'Variables', + categorystyle: 'variable_category', + custom: 'VARIABLE', + }, + { + kind: 'category', + name: 'Functions', + categorystyle: 'procedure_category', + custom: 'PROCEDURE', + }, + ], +}; diff --git a/packages/docs/docs/codelabs/custom-renderer/complete-code/webpack.config.js b/packages/docs/docs/codelabs/custom-renderer/complete-code/webpack.config.js new file mode 100644 index 00000000000..1a095648fd7 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/complete-code/webpack.config.js @@ -0,0 +1,59 @@ +const path = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); + +// Base config that applies to either development or production mode. +const config = { + entry: './src/index.js', + output: { + // Compile the source files into a bundle. + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist'), + clean: true, + }, + // Enable webpack-dev-server to get hot refresh of the app. + devServer: { + static: './build', + }, + module: { + rules: [ + { + // Load CSS files. They can be imported into JS files. + test: /\.css$/i, + use: ['style-loader', 'css-loader'], + }, + ], + }, + plugins: [ + // Generate the HTML index page based on our template. + // This will output the same index page with the bundle we + // created above added in a script tag. + new HtmlWebpackPlugin({ + template: 'src/index.html', + }), + ], +}; + +module.exports = (env, argv) => { + if (argv.mode === 'development') { + // Set the output path to the `build` directory + // so we don't clobber production builds. + config.output.path = path.resolve(__dirname, 'build'); + + // Generate source maps for our code for easier debugging. + // Not suitable for production builds. If you want source maps in + // production, choose a different one from https://webpack.js.org/configuration/devtool + config.devtool = 'eval-cheap-module-source-map'; + + // Include the source maps for Blockly for easier debugging Blockly code. + config.module.rules.push({ + test: /(blockly[/\\].*\.js)$/, + use: [require.resolve('source-map-loader')], + enforce: 'pre', + }); + + // Ignore spurious warnings from source-map-loader + // It can't find source maps for some Closure modules and that is expected + config.ignoreWarnings = [/Failed to parse source map.*blockly/]; + } + return config; +}; diff --git a/packages/docs/docs/codelabs/custom-renderer/define-and-register-a-custom-renderer.mdx b/packages/docs/docs/codelabs/custom-renderer/define-and-register-a-custom-renderer.mdx new file mode 100644 index 00000000000..d3d9cecee0d --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/define-and-register-a-custom-renderer.mdx @@ -0,0 +1,55 @@ +--- +slug: /codelabs/custom-renderer/define-and-register-a-custom-renderer/index.html +description: How to register a custom renderer. +--- + +# Build custom renderers + +## 4. Define and register a custom renderer + +A **Renderer** is the interface between custom rendering code and the rest of Blockly. Blockly provides a base renderer with all required fields already set to usable values. + +To start, create a new directory at `src/renderers` and add a file inside named `custom.js`. + +At the top of the file, import `blockly/core`: + +```js +import * as Blockly from 'blockly/core'; +``` + +Then define a new custom renderer and have it extend the base renderer: + +```js +class CustomRenderer extends Blockly.blockRendering.Renderer { + constructor() { + super(); + } +} +``` + +After defining the renderer, register it with Blockly and give it the name `custom_renderer`: + +```js +Blockly.blockRendering.register('custom_renderer', CustomRenderer); +``` + +To use the custom renderer, import the new file at the top of `src/index.js`: + +```js +import './renderers/javascript'; +``` + +Now, add the the `renderer` property into the configuration struct passed to `Blockly.inject` so that it now looks like this: + +```js +const ws = Blockly.inject(blocklyDiv, { + renderer: 'custom_renderer', + toolbox, +}); +``` + +### The result + +If the server is already running, refresh the page to see the new changes. Otherwise, run `npm start` to start the server. Once the server is running, click on the `Loops` entry in the browser and drag out a repeat block. The resulting block will use the same values already defined in the base `Blockly.blockRendering.Renderer`. + +![Screenshot of a renderer with an appearance matching the base renderer.](../../../static/images/codelabs/custom-renderer/custom_renderer.png) diff --git a/packages/docs/docs/codelabs/custom-renderer/observe-the-built-in-renderers.mdx b/packages/docs/docs/codelabs/custom-renderer/observe-the-built-in-renderers.mdx new file mode 100644 index 00000000000..4f5afcf1194 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/observe-the-built-in-renderers.mdx @@ -0,0 +1,12 @@ +--- +slug: /codelabs/custom-renderer/observe-the-built-in-renderers/index.html +description: Introduction to the built-in renderers. +--- + +# Build custom renderers + +## 3. Observe the built-in renderers + +First, visit [the advanced playground](https://blockly-demo.appspot.com/static/tests/playgrounds/advanced_playground.html) to observe what the built-in renderers look like. + +Click on the "Loops" entry and drag out a repeat block. Now, change the selection in the "renderer" drop down to observe the look of each built-in renderer. By default, the renderer named "Geras" is used. diff --git a/packages/docs/docs/codelabs/custom-renderer/override-constants.mdx b/packages/docs/docs/codelabs/custom-renderer/override-constants.mdx new file mode 100644 index 00000000000..d08d596cb30 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/override-constants.mdx @@ -0,0 +1,75 @@ +--- +slug: /codelabs/custom-renderer/override-constants/index.html +description: How to override the constants in a renderer. +--- + +# Build custom renderers + +## 5. Override constants + +A **ConstantsProvider** holds all rendering-related constants. This includes sizing information and colours. Blockly provides a base **ConstantsProvider** with all required fields set to default values. + +The **ConstantsProvider** `constructor()` sets all static properties, such as `NOTCH_WIDTH` and `NOTCH_HEIGHT`. For a full list of properties, see [constants.ts](https://github.com/RaspberryPiFoundation/blockly/blob/main/core/renderers/common/constants.ts). + +Only override the necessary subset of the constants, rather than all of them. To do so: + +- Define a constants provider that extends the base `ConstantProvider`. +- Call the superclass `super()` in the `constructor()`. +- Set individual properties. + +Add this above the `CustomRenderer` definition in `src/renderers/custom.js`: + +```js +class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider { + constructor() { + // Set up all of the constants from the base provider. + super(); + + // Override a few properties. + /** + * The width of the notch used for previous and next connections. + * @type {number} + * @override + */ + this.NOTCH_WIDTH = 20; + + /** + * The height of the notch used for previous and next connections. + * @type {number} + * @override + */ + this.NOTCH_HEIGHT = 10; + + /** + * Rounded corner radius. + * @type {number} + * @override + */ + this.CORNER_RADIUS = 2; + + /** + * The height of the puzzle tab used for input and output connections. + * @type {number} + * @override + */ + this.TAB_HEIGHT = 8; + } +} +``` + +To use the new **CustomConstantProvider**, override `makeConstants_()` inside the `CustomRenderer` class. Below the `constructor()`, add: + +```js + /** + * @override + */ + makeConstants_() { + return new CustomConstantProvider(); + } +``` + +### The result + +Return to the browser, click on the `Loops` entry, and drag out a repeat block. The resulting block should have triangular previous and next connections, and skinny input and output connections. Note that the general shapes of the connections have not changed--only parameters such as width and height. + +![Screenshot of a custom renderer with notches, corners, and tabs that have similar shapes as the default but with different widths, heights, and radiuses.](../../../static/images/codelabs/custom-renderer/custom_constants.png) diff --git a/packages/docs/docs/codelabs/custom-renderer/setup.mdx b/packages/docs/docs/codelabs/custom-renderer/setup.mdx new file mode 100644 index 00000000000..e97707fcfb5 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/setup.mdx @@ -0,0 +1,30 @@ +--- +slug: /codelabs/custom-renderer/setup/index.html +description: Setting up the "Build custom renderers" codelab. +--- + +# Build custom renderers + +## 2. Setup + +This codelab will add code to the Blockly sample app to create and use a new custom renderer. + +### The application + +Use the Use the [`npx @blockly/create-package`](https://www.npmjs.com/package/@blockly/create-package) command to create a standalone application that contains a sample setup of Blockly, including custom blocks and a display of the generated code and output. + +1. Run `npx @blockly/create-package app custom-renderer-codelab`. This will create a blockly application in the folder `custom-renderer-codelab`. +1. `cd` into the new directory: `cd custom-renderer-codelab`. +1. Run `npm start` to start the server and run the sample application. +1. The sample app will automatically run in the browser window that opens. + +The initial application uses the default renderer and contains no code or definitions for a custom renderer. + +The complete code used in this codelab can be viewed in the `blockly` repository under [docs/docs/codelabs/custom-renderer](https://github.com/RaspberryPiFoundation/blockly/docs/docs/codelabs/custom-renderer/complete-code). + +Before setting up the rest of the application, change the storage key used for this codelab application. This will ensure that the workspace is saved in its own storage, separate from the regular sample app, so that it doesn't interfere with other demos. In `serialization.js`, change the value of `storageKey` to some unique string. `customRenderersWorkspace` will work: + +```js +// Use a unique storage key for this codelab +const storageKey = 'customRenderersWorkspace'; +``` diff --git a/packages/docs/docs/codelabs/custom-renderer/summary.mdx b/packages/docs/docs/codelabs/custom-renderer/summary.mdx new file mode 100644 index 00000000000..e397092890f --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/summary.mdx @@ -0,0 +1,16 @@ +--- +pagination_next: null +slug: /codelabs/custom-renderer/summary/index.html +description: Summary of the "Build custom renderers" codelab. +--- + +# Build custom renderers + +## 9. Summary + +Custom renderers are a powerful way to change the look and feel of Blockly. In this codelab you learned: + +- How to declare and register a custom renderer by extending `Blockly.blockRendering.Renderer`. +- How to override renderer constants such as `NOTCH_HEIGHT` in `Blockly.blockRendering.ConstantProvider`. +- How to modify connection shapes by creating custom [SVG paths](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path), storing them in `init()`, and finally returning them in `shapeFor(connection)`. +- How to update the mapping from connection to connection shape by adding logic in `shapeFor(connection)`. diff --git a/packages/docs/docs/codelabs/custom-renderer/typed-connection-shapes.mdx b/packages/docs/docs/codelabs/custom-renderer/typed-connection-shapes.mdx new file mode 100644 index 00000000000..8c575c3b6ac --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/typed-connection-shapes.mdx @@ -0,0 +1,54 @@ +--- +slug: /codelabs/custom-renderer/typed-connection-shapes/index.html +description: How to set connection shapes based on connection types. +--- + +# Build custom renderers + +## 8. Typed connection shapes + +This step will create a renderer that sets connection shapes at runtime based on a connection's type checks. It will use the default connection shapes and the shapes defined in the previous steps. + +### Override `shapeFor(connection)` + +Override the `shapeFor(connection)` function in the `CustomConstantProvider` class definition to return a different connection shape based on the `checks` returned from `connection.getCheck()`. Note the previous definition of `shapeFor(connection)` created in previous steps will need to be deleted. + +The new definition of `shapeFor(connection)` will: + +- Return a rectangular tab for inputs and outputs that accept `Number`s and `String`s. +- Return the default puzzle tab for all other inputs and outputs. +- Return the normal notch for all previous and next connections. + +```js +/** + * @override + */ +shapeFor(connection) { + var checks = connection.getCheck(); + switch (connection.type) { + case Blockly.INPUT_VALUE: + case Blockly.OUTPUT_VALUE: + if (checks && checks.includes('Number')) { + return this.RECT_INPUT_OUTPUT; + } + if (checks && checks.includes('String')) { + return this.RECT_INPUT_OUTPUT; + } + return this.PUZZLE_TAB; + case Blockly.PREVIOUS_STATEMENT: + case Blockly.NEXT_STATEMENT: + return this.NOTCH; + default: + throw Error('Unknown connection type'); + } +``` + +### The result + +Take these steps to fully test this change in the browser: + +1. Click on the `Loops` entry and drag out a repeat block. +1. Click on the `Logic` entry and drag the conditional `if` block into the repeat block that was placed on the workspace in the previous step. + +There should be an entry similar to the screenshot below, in which the `Number` inputs and outputs are rectangular, but the boolean input on the `if` block is a puzzle tab. +![Screenshot of a custom renderer with rectangles for the Number input/outputs and a puzzle tab for the Boolean input/output attached to an "if" block](../../../static/images/codelabs/custom-renderer/typed_connection_shapes.png) diff --git a/packages/docs/docs/codelabs/custom-renderer/understand-connection-shapes.mdx b/packages/docs/docs/codelabs/custom-renderer/understand-connection-shapes.mdx new file mode 100644 index 00000000000..5529740264a --- /dev/null +++ b/packages/docs/docs/codelabs/custom-renderer/understand-connection-shapes.mdx @@ -0,0 +1,68 @@ +--- +slug: /codelabs/custom-renderer/understand-connection-shapes/index.html +description: Introduction to connection shapes. +--- + +# Build custom renderers + +## 6. Understand connection shapes + +A common use case of a custom renderer is changing the shape of connections. This requires a more detailed understanding of how a block is drawn and how SVG paths are defined. + +### The block outline + +The outline of the block is a single [SVG path](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path). The outline is built out of many sub-paths (e.g. the path for a previous connection; the path for the top of the block; and the path for an input connection). + +Each sub-path is a string of [path commands](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#path_commands) that describe the appropriate shape. These commands must use relative (rather than absolute) coordinates. + +SVG path commands can be written as strings, but Blockly provides a set of [utility functions](/reference/blockly.utils_namespace.svgpaths_namespace) to make writing and reading paths easier. + +### `init()` + +A connection's shape is stored as an object with information about its width, height, and sub-path. These objects are created in the `ConstantProvider`s `init()` function. Here is the start of the default implementation. The complete definition can be found inside [`constants.ts`](https://github.com/RaspberryPiFoundation/blockly/blob/main/core/renderers/common/constants.ts). + +```js +/** + * Initialize shape objects based on the constants set in the constructor. + */ +init() { + /** + * An object containing sizing and path information about collapsed block + * indicators. + */ + this.JAGGED_TEETH = this.makeJaggedTeeth(); + + /** An object containing sizing and path information about notches. */ + this.NOTCH = this.makeNotch(); + + // Additional code has been removed for brevity. +} +``` + +**Properties that are primitives should be set in the `constructor()`, while objects should be set in `init()`**. This separation allows a subclass to override a constant such as `NOTCH_WIDTH` and see the change reflected in objects that depend on the constant. + +### `shapeFor(connection)` + +The `shapeFor(connection)` function maps from connection to connection shape. Here is the default implementation, which can be found inside [`constants.ts`](https://github.com/RaspberryPiFoundation/blockly/blob/main/core/renderers/common/constants.ts). It returns a puzzle tab for input/output connections and a notch for previous/next connections: + +```js +/** + * Get an object with connection shape and sizing information based on the + * type of the connection. + * + * @param connection The connection to find a shape object for + * @returns The shape object for the connection. + */ +shapeFor(connection: RenderedConnection): Shape { + switch (connection.type) { + case ConnectionType.INPUT_VALUE: + case ConnectionType.OUTPUT_VALUE: + return this.PUZZLE_TAB; + case ConnectionType.PREVIOUS_STATEMENT: + case ConnectionType.NEXT_STATEMENT: + return this.NOTCH; + default: + throw Error('Unknown connection type'); + } +} +``` diff --git a/packages/docs/docs/codelabs/custom-toolbox/add-an-icon-to-your-category.mdx b/packages/docs/docs/codelabs/custom-toolbox/add-an-icon-to-your-category.mdx new file mode 100644 index 00000000000..9a58f7dcb09 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/add-an-icon-to-your-category.mdx @@ -0,0 +1,126 @@ +--- +slug: /codelabs/custom-toolbox/add-an-icon-to-your-category/index.html +description: How to add an icon to your category. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Customizing a Blockly toolbox + +## 5. Add an icon to your category + +We are going to add an icon to our "Logic" category by adding an icon library to +our `index.html` file, and setting the appropriate CSS class on our category definition. + +To start, we are going to grab an icon library and add it to `index.html`: + +``` + +``` + +We are going to add a cog icon from this library to the "Logic" category. +To do this, we will add the appropriate CSS classes to our category definition. + +In `index.html` scroll down to your toolbox definition and change the below line: + +```xml + +``` + +to be: + +```xml + +``` + +All the classes used to create a category can be set similar to how we set the +icon class above. See the [Blockly toolbox documentation](/guides/configure/web/toolboxes/appearance#category-css) for more information. + +### Add some CSS + +If you open `index.html` you will notice that the gear icon is positioned +incorrectly and is a bit difficult to see. We will use the `customIcon` class to +change the color of the icon and use the `blocklyTreeRowContentContainer` class +to position the icon above the text. + +In your `toolbox_style.css` file add: + +```css +/* Changes color of the icon to white. */ +.customIcon { + color: white; +} +/* Stacks the icon on top of the label. */ +.blocklyTreeRowContentContainer { + display: flex; + flex-direction: column; + align-items: center; +} +.blocklyToolboxCategory { + height: initial; +} +``` + +### Update setSelected + +If you open `index.html` and click on the "Logic" category you will notice +that the white icon now blends into the white background. + +In order to fix this, we are going to update our `setSelected` method to set the +color of the icon to the category color when the category has been selected. + +Inside `custom_category.js` add the below line to `setSelected` if the category +has been selected: + +```js +this.iconDom_.style.color = this.colour_; +``` + +Add the below line to `setSelected` if the category has not been selected: + +```js +this.iconDom_.style.color = 'white'; +``` + +Your `setSelected` method should look similar to below: + +```js + /** @override */ + setSelected(isSelected){ + // We do not store the label span on the category, so use getElementsByClassName. + var labelDom = this.rowDiv_.getElementsByClassName('blocklyToolboxCategoryLabel')[0]; + if (isSelected) { + // Change the background color of the div to white. + this.rowDiv_.style.backgroundColor = 'white'; + // Set the colour of the text to the colour of the category. + labelDom.style.color = this.colour_; + this.iconDom_.style.color = this.colour_; + } else { + // Set the background back to the original colour. + this.rowDiv_.style.backgroundColor = this.colour_; + // Set the text back to white. + labelDom.style.color = 'white'; + this.iconDom_.style.color = 'white'; + } + // This is used for accessibility purposes. + Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_), + Blockly.utils.aria.State.SELECTED, isSelected); + } +``` + +### The result + +If you open your `index.html` file, you should see a white gear above your "Logic" +label, and it should change to blue when the category has been selected. + + + {' '} + ![A white gear above the word "Logic" on a blue + background.](../../../static/images/codelabs/custom-toolbox/category_gear.png){' '} + + + + {' '} + ![A blue gear above the word "Logic" on a white + background.](../../../static/images/codelabs/custom-toolbox/category_gear_selected.png){' '} + diff --git a/packages/docs/docs/codelabs/custom-toolbox/adding-a-custom-toolbox-item.mdx b/packages/docs/docs/codelabs/custom-toolbox/adding-a-custom-toolbox-item.mdx new file mode 100644 index 00000000000..03e2034c1b6 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/adding-a-custom-toolbox-item.mdx @@ -0,0 +1,189 @@ +--- +slug: /codelabs/custom-toolbox/adding-a-custom-toolbox-item/index.html +description: How to add a custom item to a toolbox. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Customizing a Blockly toolbox + +## 7. Adding a custom toolbox item + +In the previous sections we modified the toolbox by extending the base category class. +In this section we will make a completely new toolbox item and add it to our toolbox. + +For this example, we are going to create a toolbox label. + +### Setup + +In the same directory as `index.html` create a new file named `toolbox_label.js`. + +Include this file in `index.html`: + +```html + +``` + +Create a class in `toolbox_label.js` that extends `Blockly.ToolboxItem` +and register it. + +```js +class ToolboxLabel extends Blockly.ToolboxItem { + constructor(toolboxItemDef, parentToolbox) { + super(toolboxItemDef, parentToolbox); + } +} + +Blockly.registry.register( + Blockly.registry.Type.TOOLBOX_ITEM, + 'toolboxlabel', + ToolboxLabel, +); +``` + +By registering this toolbox item with the name "toolboxlabel" we can now use this +name in our toolbox definition to add our custom item to the toolbox. + +Navigate to `index.html`, and scroll down to the toolbox definition. Add a +`` element as the first item in your toolbox definition: + +```xml + +``` + +Your toolbox definition should now look something like: + +```xml + +``` + +### Initialize the toolbox item + +In order to create a toolbox item we must implement one of the toolbox item interfaces. + +For this example, we will be implementing the basic `IToolboxItem` interface. +There are three different types of toolbox item interfaces: +`IToolboxItem`, `ISelectableToobloxItem` and `ICollapsibleToolboxItem`. +Since we do not need our label to be selectable or collapsible, we can implement +the basic `IToolboxItem` interface. + +First, we are going to add an init method that will create the dom for our toolbox label: + +```js + /** @override */ + init() { + // Create the label. + this.label = document.createElement('label'); + // Set the name. + this.label.textContent = 'Label'; + } +``` + +Next, we are going to return this element: + +```js + /** @override */ + getDiv() { + return this.label; + } +``` + +If you open the `index.html` file you should see a label above your first category. + + + {' '} + ![The toolbox with a label at the + top.](../../../static/images/codelabs/custom-toolbox/toolbox_label.png){' '} + + +### Add attributes to the toolbox definition + +The above code is rather limiting since it only allows us to create a toolbox +label with the text "Label". +To make it possible to create different labels with different text and colour we +are going to add `name` and `colour` attributes to our toolbox definition. + +Open `index.html` and navigate to the toolbox definition. Change your +`toolboxlabel` element to look like the below line: + +```xml + +``` + +These values will get passed in to our `ToolboxLabel` class through the `toolboxItemDef`. +Navigate to `toolbox_label.js` and add the following lines to your `init` method: + +```js +// Set the name. +this.label.textContent = this.toolboxItemDef_['name']; +// Set the color. +this.label.style.color = this.toolboxItemDef_['colour']; +``` + +Remove the following line from your init method: + +```js +this.label.textContent = 'Label'; +``` + +All attributes on our toolbox definition get added to the `toolboxItemDef_`. +`this.toolboxItemDef_` is set in the `Blockly.ToolboxItem` constructor. + +Open your `index.html` in a browser to see the updated label. + + + {' '} + ![The toolbox with a label that now says "Custom + Toolbox".](../../../static/images/codelabs/custom-toolbox/custom_label.png){' '} + + +### Add some CSS + +Similar to how we added `colour` and `name` above, we are going to add a custom +class to our label. + +Navigate to your toolbox definition in `index.html` and modify it to look +like the below line. + +```xml + +``` + +Any item that begins with `css-` will be added to a `cssconfig` object stored on +the `toolboxItemDef`. + +To use this value navigate to `toolbox_label.js` and add the following lines to +your `init` method. + +```js +// Any attributes that begin with css- will get added to a cssconfig object. +const cssConfig = this.toolboxItemDef_['cssconfig']; +// Add the class. +if (cssConfig) { + this.label.classList.add(cssConfig['label']); +} +``` + +The above code will add the class to the label. Now, in `toolbox_style.css` add +the below CSS to make the label bold. + +```css +.customLabel { + font-weight: bold; +} +``` + +### The result + +If you open `index.html` you should now see a bold dark gray label at the +top of your toolbox. + + + {' '} + ![A toolbox with colored background and the blockly label above the category + text.](../../../static/images/codelabs/custom-toolbox/final_toolbox.png){' '} + diff --git a/packages/docs/docs/codelabs/custom-toolbox/change-the-category-HTML.mdx b/packages/docs/docs/codelabs/custom-toolbox/change-the-category-HTML.mdx new file mode 100644 index 00000000000..f4db3904cf1 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/change-the-category-HTML.mdx @@ -0,0 +1,45 @@ +--- +slug: /codelabs/custom-toolbox/change-the-category-HTML/index.html +description: How to change the HTML used by a category. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Customizing a Blockly toolbox + +## 6. Change the category HTML + +If you only need to change the CSS, like we did in the previous section, then using the cssConfig is a great choice. +However, if you need to change the html, maybe to add text, an image, or anything else, you can override +the corresponding method that creates the dom. In this example, we'll add an `` +to our category by overriding the `createIconDom_` method. + +### Change the element for our icon + +By default, the `createIconDom_` method adds a `` element for the category +icon. We can override this to return an `` element. + +Add the following methods to `custom_category.js`: + +```js +/** @override */ +createIconDom_() { + const img = document.createElement('img'); + img.src = './logo_only.svg'; + img.alt = 'Lamp'; + img.width='15'; + img.height='15'; + return img; +} +``` + +### The result + +If you open `index.html` you should now see the blockly logo on top of all your +categories + + + {' '} + ![A toolbox with the blockly logo on top of the category + label.](../../../static/images/codelabs/custom-toolbox/image_toolbox.png){' '} + diff --git a/packages/docs/docs/codelabs/custom-toolbox/change-the-look-of-a-category.mdx b/packages/docs/docs/codelabs/custom-toolbox/change-the-look-of-a-category.mdx new file mode 100644 index 00000000000..921b56d5038 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/change-the-look-of-a-category.mdx @@ -0,0 +1,94 @@ +--- +slug: /codelabs/custom-toolbox/change-the-look-of-a-category/index.html +description: How to change the look of a category. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Customizing a Blockly toolbox + +## 3. Change the look of a category + +### Change the background of the category + +In the default `ToolboxCategory` class, the `addColourBorder_` method adds a strip of color next +to the category name. We can override this method in order to add colour to the entire category div. + +Add the following code to your `CustomCategory` class. + +```js +/** @override */ +addColourBorder_(colour){ + this.rowDiv_.style.backgroundColor = colour; +} +``` + +The `colour` passed in is calculated from either the `categorystyle` or the `colour` +attribute set on the category definition. + +For example, the "Logic" category definition looks like: + +```xml + +... + +``` + +The logic_category style looks like: + +```json +"logic_category": { + "colour": "210" + } +``` + +For more information on Blockly styles please visit the [themes documentation](/guides/configure/web/appearance/themes#category-style). + +### Add some CSS + +Open `index.html` to see your updated toolbox. Your toolbox should look +similar to the below toolbox. + + + {' '} + ![A toolbox with colors that expand the across the entire + category.](../../../static/images/codelabs/custom-toolbox/colored_toolbox.png){' '} + + +We are going to add some CSS to make it easier to read, and to space out our categories. + +Create a file named `toolbox_style.css` in the same directory as `index.html` +and include it in `index.html`: + +``` + +``` + +Copy and paste the following CSS into your `toolbox_style.css` file. + +```css +/* Makes our label white. */ +.blocklyToolboxCategoryLabel { + color: white; +} +/* Adds padding around the group of categories and separators. */ +.blocklyToolboxCategoryGroup { + padding: 0.5em; +} +/* Adds space between the categories, rounds the corners and adds space around the label. */ +.blocklyToolboxCategory { + padding: 3px; + margin-bottom: 0.5em; + border-radius: 4px; +} +``` + +### The result + +Open `index.html` to see your toolbox. + + + {' '} + ![Toolbox with category corners that are rounded and white + text.](../../../static/images/codelabs/custom-toolbox/styled_toolbox.png){' '} + diff --git a/packages/docs/docs/codelabs/custom-toolbox/change-the-look-of-a-selected-category.mdx b/packages/docs/docs/codelabs/custom-toolbox/change-the-look-of-a-selected-category.mdx new file mode 100644 index 00000000000..f63cbf3d431 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/change-the-look-of-a-selected-category.mdx @@ -0,0 +1,57 @@ +--- +slug: /codelabs/custom-toolbox/change-the-look-of-a-selected-category/index.html +description: How to change the look of a selected category. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Customizing a Blockly toolbox + +## 4. Change the look of a selected category + +Open your `index.html` and click on a category. You will see that it +doesn't give any indication that it has been clicked. Worse than that, if you +click on the category a second time the background color will disappear. + +To fix this, we are going to override the `setSelected` method to change the look +of a category when it has been clicked. In the default category class this method +adds a colour to the entire row when a category is selected. Since we have already +expanded the colour over our entire div, we are going to change the background +color of the div to white, and the text to the color of the category when it has +been selected. + +Add the following code to `custom_category.js`: + +```js +/** @override */ +setSelected(isSelected){ + // We do not store the label span on the category, so use getElementsByClassName. + var labelDom = this.rowDiv_.getElementsByClassName('blocklyToolboxCategoryLabel')[0]; + if (isSelected) { + // Change the background color of the div to white. + this.rowDiv_.style.backgroundColor = 'white'; + // Set the colour of the text to the colour of the category. + labelDom.style.color = this.colour_; + } else { + // Set the background back to the original colour. + this.rowDiv_.style.backgroundColor = this.colour_; + // Set the text back to white. + labelDom.style.color = 'white'; + } + // This is used for accessibility purposes. + Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_), + Blockly.utils.aria.State.SELECTED, isSelected); +} +``` + +### The result + +Open `index.html` and click on the "Logic" category. You should now see a white +category with a colored label. + + + {' '} + ![A toolbox with all categories colored except for the first category that has + a white + background.](../../../static/images/codelabs/custom-toolbox/category_selected.png){' '} + diff --git a/packages/docs/docs/codelabs/custom-toolbox/codelab-overview.mdx b/packages/docs/docs/codelabs/custom-toolbox/codelab-overview.mdx new file mode 100644 index 00000000000..5e668c88b48 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/codelab-overview.mdx @@ -0,0 +1,48 @@ +--- +pagination_prev: null +slug: /codelabs/custom-toolbox/codelab-overview/index.html +description: Overview of the "Customizing a Blockly toolbox" codelab. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Customizing a Blockly toolbox + +## 1. Codelab overview + +### What you'll learn + +This codelab will focus on customizing the Blockly toolbox. + +In this codelab you will learn: + +1. How to add a background color to a toolbox category. +1. How to change the look of a selected category. +1. How to add a custom CSS classes to a toolbox category. +1. How to change the structure of your category HTML. +1. How to add a custom toolbox item. + +### What you'll build + +Over the course of this codelab you will customize your toolbox categories as well +as create a custom toolbox item. +The resulting toolbox is shown below. + + + {' '} + ![A toolbox with colored background and the blockly label above the category + text.](../../../static/images/codelabs/custom-toolbox/final_toolbox.png){' '} + + +The code samples are written in ES6 syntax. You can find the code for the [completed custom toolbox](https://github.com/RaspberryPiFoundation/blockly/docs/docs/codelabs/custom-toolbox/complete-code) on GitHub. + +### What you'll need + +- A browser. +- A text editor. +- Basic knowledge of HTML, CSS, and JavaScript. +- Basic understanding of the [Blockly toolbox](/guides/configure/web/toolboxes/toolbox). + +Throughout various parts of this codelab we will be talking about [toolbox definitions](/guides/configure/web/toolboxes/category?tab=xml). +The toolbox definition can be written in XML or JSON. We will be using an XML +toolbox definition that can be found in the provided code. diff --git a/packages/docs/docs/codelabs/custom-toolbox/complete-code/custom_category_es6.js b/packages/docs/docs/codelabs/custom-toolbox/complete-code/custom_category_es6.js new file mode 100644 index 00000000000..c9c15ec34fd --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/complete-code/custom_category_es6.js @@ -0,0 +1,82 @@ +/** + * @license + * Copyright 2020 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview The toolbox category built during the custom toolbox codelab, in es6. + * @author aschmiedt@google.com (Abby Schmiedt) + */ + +class CustomCategory extends Blockly.ToolboxCategory { + /** + * Constructor for a custom category. + * @override + */ + constructor(categoryDef, toolbox, opt_parent) { + super(categoryDef, toolbox, opt_parent); + } + + /** + * Adds the colour to the toolbox. + * This is called on category creation and whenever the theme changes. + * @override + */ + addColourBorder_(colour) { + this.rowDiv_.style.backgroundColor = colour; + } + + /** + * Sets the style for the category when it is selected or deselected. + * @param {boolean} isSelected True if the category has been selected, + * false otherwise. + * @override + */ + setSelected(isSelected) { + // We do not store the label span on the category, so use getElementsByClassName. + const labelDom = this.rowDiv_.getElementsByClassName( + 'blocklyToolboxCategoryLabel', + )[0]; + if (isSelected) { + // Change the background color of the div to white. + this.rowDiv_.style.backgroundColor = 'white'; + // Set the colour of the text to the colour of the category. + labelDom.style.color = this.colour_; + this.iconDom_.style.color = this.colour_; + } else { + // Set the background back to the original colour. + this.rowDiv_.style.backgroundColor = this.colour_; + // Set the text back to white. + labelDom.style.color = 'white'; + this.iconDom_.style.color = 'white'; + } + // This is used for accessibility purposes. + Blockly.utils.aria.setState( + /** @type {!Element} */ (this.htmlDiv_), + Blockly.utils.aria.State.SELECTED, + isSelected, + ); + } + + /** + * Creates the dom used for the icon. + * @returns {HTMLElement} The element for the icon. + * @override + */ + createIconDom_() { + const iconImg = document.createElement('img'); + iconImg.src = './logo_only.svg'; + iconImg.alt = 'Blockly Logo'; + iconImg.width = '25'; + iconImg.height = '25'; + return iconImg; + } +} + +Blockly.registry.register( + Blockly.registry.Type.TOOLBOX_ITEM, + Blockly.ToolboxCategory.registrationName, + CustomCategory, + true, +); diff --git a/packages/docs/docs/codelabs/custom-toolbox/complete-code/index.html b/packages/docs/docs/codelabs/custom-toolbox/complete-code/index.html new file mode 100644 index 00000000000..ddd57a89a9a --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/complete-code/index.html @@ -0,0 +1,359 @@ + + + + + Toolbox Customization Codelab + + + + + + + + + + + +

Toolbox Customization Codelab

+
+ + + + + diff --git a/packages/docs/docs/codelabs/custom-toolbox/complete-code/index.js b/packages/docs/docs/codelabs/custom-toolbox/complete-code/index.js new file mode 100644 index 00000000000..adddf0322c4 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/complete-code/index.js @@ -0,0 +1,10 @@ +'use strict'; + +let workspace = null; + +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: document.getElementById('toolbox-categories'), + }); +} diff --git a/packages/docs/docs/codelabs/custom-toolbox/complete-code/logo_only.svg b/packages/docs/docs/codelabs/custom-toolbox/complete-code/logo_only.svg new file mode 100644 index 00000000000..4616ee99f98 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/complete-code/logo_only.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + logo-only + + + + + + + + logo-only + + + + + diff --git a/packages/docs/docs/codelabs/custom-toolbox/complete-code/toolbox_label_es6.js b/packages/docs/docs/codelabs/custom-toolbox/complete-code/toolbox_label_es6.js new file mode 100644 index 00000000000..401ffa42aac --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/complete-code/toolbox_label_es6.js @@ -0,0 +1,63 @@ +/** + * @license + * Copyright 2020 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview The toolbox label built during the custom toolbox codelab, in es6. + * @author aschmiedt@google.com (Abby Schmiedt) + */ + +class ToolboxLabel extends Blockly.ToolboxItem { + /** + * Constructor for a label in the toolbox. + * @param {!Blockly.utils.toolbox.ToolboxItemInfo} toolboxItemDef The toolbox + * item definition. This comes directly from the toolbox definition. + * @param {!Blockly.IToolbox} parentToolbox The toolbox that holds this + * toolbox item. + * @override + */ + constructor(toolboxItemDef, parentToolbox) { + super(toolboxItemDef, parentToolbox); + /** + * The button element. + * @type {?HTMLLabelElement} + */ + this.label = null; + } + + /** + * Init method for the label. + * @override + */ + init() { + // Create the label. + this.label = document.createElement('label'); + // Set the name. + this.label.textContent = this.toolboxItemDef_['name']; + // Set the color. + this.label.style.color = this.toolboxItemDef_['colour']; + // Any attributes that begin with css- will get added to a cssconfig. + const cssConfig = this.toolboxItemDef_['cssconfig']; + // Add the class. + if (cssConfig) { + this.label.classList.add(cssConfig['label']); + } + } + + /** + * Gets the div for the toolbox item. + * @returns {HTMLLabelElement} The label element. + * @override + */ + getDiv() { + return this.label; + } +} + +Blockly.registry.register( + Blockly.registry.Type.TOOLBOX_ITEM, + 'toolboxlabel', + ToolboxLabel, +); diff --git a/packages/docs/docs/codelabs/custom-toolbox/complete-code/toolbox_style.css b/packages/docs/docs/codelabs/custom-toolbox/complete-code/toolbox_style.css new file mode 100644 index 00000000000..067e90aba74 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/complete-code/toolbox_style.css @@ -0,0 +1,27 @@ +/* Makes our label white. */ +.blocklyToolboxCategoryLabel { + color: #fff; +} +/* Adds padding around the group of categories and separators. */ +.blocklyToolboxCategoryGroup { + padding: 0.5em; +} +/* Adds space between the categories, rounds the corners and adds space around the label. */ +.blocklyToolboxCategory { + padding: 3px; + margin-bottom: 0.5em; + border-radius: 4px; +} +/* Changes color of the icon to white. */ +.customIcon { + color: #fff; +} +/* Stacks the icon on top of the label. */ +.blocklyTreeRowContentContainer { + display: flex; + flex-direction: column; + align-items: center; +} +.blocklyToolboxCategory { + height: initial; +} diff --git a/packages/docs/docs/codelabs/custom-toolbox/setup.mdx b/packages/docs/docs/codelabs/custom-toolbox/setup.mdx new file mode 100644 index 00000000000..e24003bde61 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/setup.mdx @@ -0,0 +1,100 @@ +--- +slug: /codelabs/custom-toolbox/setup/index.html +description: Setting up the "Customizing a Blockly toolbox" codelab. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Customizing a Blockly toolbox + +## 2. Setup + +### Download the sample code + +You can get the sample code for this codelab by either downloading the zip here: + +[Download zip](https://github.com/RaspberryPiFoundation/blockly/archive/main.zip) + +or by cloning this git repo: + +```bash +git clone https://github.com/RaspberryPiFoundation/blockly.git +``` + +If you downloaded the source as a zip, unpacking it should give you a root folder named `blockly-main`. + +The relevant files are in `docs/docs/codelabs/custom-toolbox`. There are two versions of the app: + +- `starter-code/`: The starter code that you'll build upon in this codelab. +- `complete-code/`: The code after completing the codelab, in case you get lost or want to compare to your version. + +Each folder contains: + +- `index.js` - The codelab's logic. To start, it just injects a simple workspace. +- `index.html` - A web page containing a simple blockly workspace. + +To run the code, simply open `starter-code/index.html` in a browser. You should see a Blockly workspace with a toolbox. + +![A web page with the text "Toolbox Customization Codelab" and a Blockly workspace.](../../../static/images/codelabs/custom-toolbox/starter_workspace.png) + +### Define and register a custom category + +To start, create a file named `custom_category.js` in the `starter-code` +directory. Include your new file by adding a script tag to `index.html`. + +```html + +``` + +In order to create a custom category we will create a new category that extends +the default `Blockly.ToolboxCategory` class. Add the following code to your +`custom_category.js` file. + +```js +class CustomCategory extends Blockly.ToolboxCategory { + /** + * Constructor for a custom category. + * @override + */ + constructor(categoryDef, toolbox, opt_parent) { + super(categoryDef, toolbox, opt_parent); + } +} +``` + +After defining your category you need to tell Blockly that it exists. +Register your category by adding the below code to the end of `custom_category.js`. + +```js +Blockly.registry.register( + Blockly.registry.Type.TOOLBOX_ITEM, + Blockly.ToolboxCategory.registrationName, + CustomCategory, + true, +); +``` + +By registering our `CustomCategory` with `Blockly.ToolboxCategory.registrationName` +we are overriding the default category in Blockly. Because we are overriding a +toolbox item instead of adding a new one, we must pass in `true` as the last +argument. If this flag is `false`, `Blockly.registry.register` will throw +an error because we are overriding an existing class. + +### The result + +To test, open `index.html` in a browser. Your toolbox should look the same as it +did before. + + + {' '} + ![The default toolbox. A list of categories with a strip of colour to the + left.](../../../static/images/codelabs/custom-toolbox/base_toolbox.png){' '} + + +However, if you run the below commands in your console you will see that +your toolbox is now using the `CustomCategory` class. + +```js +var toolbox = Blockly.common.getMainWorkspace().getToolbox(); +toolbox.getToolboxItems()[0]; +``` diff --git a/packages/docs/docs/codelabs/custom-toolbox/starter-code/index.html b/packages/docs/docs/codelabs/custom-toolbox/starter-code/index.html new file mode 100644 index 00000000000..6e1d8f8dc87 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/starter-code/index.html @@ -0,0 +1,349 @@ + + + + + Toolbox Customization Codelab + + + + + + + +

Toolbox Customization Codelab

+
+ + + + + diff --git a/packages/docs/docs/codelabs/custom-toolbox/starter-code/index.js b/packages/docs/docs/codelabs/custom-toolbox/starter-code/index.js new file mode 100644 index 00000000000..adddf0322c4 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/starter-code/index.js @@ -0,0 +1,10 @@ +'use strict'; + +let workspace = null; + +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: document.getElementById('toolbox-categories'), + }); +} diff --git a/packages/docs/docs/codelabs/custom-toolbox/starter-code/logo_only.svg b/packages/docs/docs/codelabs/custom-toolbox/starter-code/logo_only.svg new file mode 100644 index 00000000000..4616ee99f98 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/starter-code/logo_only.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + logo-only + + + + + + + + logo-only + + + + + diff --git a/packages/docs/docs/codelabs/custom-toolbox/summary.mdx b/packages/docs/docs/codelabs/custom-toolbox/summary.mdx new file mode 100644 index 00000000000..19c454f28a3 --- /dev/null +++ b/packages/docs/docs/codelabs/custom-toolbox/summary.mdx @@ -0,0 +1,19 @@ +--- +pagination_next: null +slug: /codelabs/custom-toolbox/summary/index.html +description: Summary of the "Customizing a Blockly toolbox" codelab. +--- + +# Customizing a Blockly toolbox + +## 8. Summary + +The toolbox can be customized in a variety of ways to make it work for your application. In this codelab you learned: + +- How to create a custom category. +- What method to override to change how the colour of the category is applied. +- What method to override to change the look of the category when selected. +- How to add an icon by adding a custom CSS class to the icon div. +- How to change what HTML Elements are used for different parts of a category. +- How to create a custom toolbox item. + You can find the code for the [completed custom toolbox](https://github.com/RaspberryPiFoundation/blockly/docs/docs/codelabs/custom-toolbox/complete-code) on GitHub. diff --git a/packages/docs/docs/codelabs/getting-started/add-blockly-libraries.mdx b/packages/docs/docs/codelabs/getting-started/add-blockly-libraries.mdx new file mode 100644 index 00000000000..04664a3d004 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/add-blockly-libraries.mdx @@ -0,0 +1,47 @@ +--- +slug: /codelabs/getting-started/add-blockly-libraries/index.html +description: How to add Blockly libraries to an app. +--- + +# Getting started with Blockly + +## 4. Add Blockly libraries + +Now that you know what you'll be building, you need to add Blockly dependencies to your app. + +Blockly releases are [published on npm](https://www.npmjs.com/package/blockly) on a quarterly basis. For this codelab you will import blockly using [unpkg](https://unpkg.com), which lets you import all of the files you need with a single script tag. + +### Add the script tag + +Open `starter-code/index.html` in a text editor and scroll to the end. You can see two script tags: + +```html + + +``` + +Add Blockly just before these two scripts. The order is important, because you will use Blockly objects later in `main.js`. Your imports should now look like this: + +```html + + + + + + +``` + +### Default imports + +Importing Blockly this way loads four default modules. + +- Blockly core: The main Blockly library, which defines the basic Blockly UI and logic. +- Built-in block definitions: Common blocks such as loops, logic, math, and string manipulation. +- The JavaScript generator: Converts blocks into JavaScript, and contains block generators for all built-in blocks. +- English language files: String tables for all messages on built-in blocks and the Blockly UI, in English. + +### Alternate imports + +There are many ways to import a library in JavaScript, and this tutorial does not cover all of them. For samples that show how to integrate Blockly in your project, look at the `examples` folder in [blockly-samples](https://github.com/RaspberryPiFoundation/blockly-samples). + +You can also define your imports more carefully to get [different generators](https://www.npmjs.com/package/blockly#blockly-generators) and [locales](https://www.npmjs.com/package/blockly#blockly-languages). diff --git a/packages/docs/docs/codelabs/getting-started/codelab-overview.mdx b/packages/docs/docs/codelabs/getting-started/codelab-overview.mdx new file mode 100644 index 00000000000..f55fe04cf46 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/codelab-overview.mdx @@ -0,0 +1,45 @@ +--- +pagination_prev: null +slug: /codelabs/getting-started/codelab-overview/index.html +description: Overview of the "Getting started with Blockly" codelab. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Getting started with Blockly + +## 1. Codelab overview + +### What you'll learn + +This codelab will teach you how to modify a simple web app to include the [Blockly](/blockly) visual programming library. + +### What is Blockly? + +Blockly is a library for building block programming apps. + +Block programming allows users to create scripts and programs by using visual blocks, even if they do not know any programming language. + +Blockly includes everything you need for defining and rendering blocks in a drag-n-drop editor. Each block represents a chunk of code that can be easily stacked and translated into code. + +### What you'll build + +MusicMaker, a web app where you can program buttons to play different sounds, using Blockly. + + + {' '} + ![image](../../../static/images/codelabs/getting-started/play_mode.png){' '} + + + + {' '} + ![image](../../../static/images/codelabs/getting-started/d4_three_times.png){' '} + + +### What you'll need + +- A browser +- A text editor +- Basic knowledge of HTML, CSS and JavaScript + +This codelab is focused on Blockly. The app structure, non-relevant concepts and code are glossed over and are provided for you to simply copy and paste. diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/index.html b/packages/docs/docs/codelabs/getting-started/complete-code/index.html new file mode 100644 index 00000000000..cbed5e45d64 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/complete-code/index.html @@ -0,0 +1,63 @@ + + + + + + + + Blockly for the Web Codelab + + + + + + +
+

Music Maker

+

Music Maker Configuration

+
+ +
+ + + +

+ Tap any button to edit its code.
When complete, press Done. +

+ +
+
+
1
+
2
+
3
+
+
+
4
+
5
+
6
+
+
+
7
+
8
+
9
+
+
+ +
+
+
+
+ + + + + + + + + + diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/scripts/main.js b/packages/docs/docs/codelabs/getting-started/complete-code/scripts/main.js new file mode 100644 index 00000000000..e1a54cd71d2 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/complete-code/scripts/main.js @@ -0,0 +1,102 @@ +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ +(function () { + let currentButton; + + function handlePlay(event) { + loadWorkspace(event.target); + let code = javascript.javascriptGenerator.workspaceToCode( + Blockly.getMainWorkspace(), + ); + code += 'MusicMaker.play();'; + // Eval can be dangerous. For more controlled execution, check + // https://github.com/NeilFraser/JS-Interpreter. + try { + eval(code); + } catch (error) { + console.log(error); + } + } + + function loadWorkspace(button) { + const workspace = Blockly.getMainWorkspace(); + if (button.blocklySave) { + Blockly.serialization.workspaces.load(button.blocklySave, workspace); + } else { + workspace.clear(); + } + } + + function save(button) { + button.blocklySave = Blockly.serialization.workspaces.save( + Blockly.getMainWorkspace(), + ); + } + + function handleSave() { + document.body.setAttribute('mode', 'edit'); + save(currentButton); + } + + function enableEditMode() { + document.body.setAttribute('mode', 'edit'); + document.querySelectorAll('.button').forEach((btn) => { + btn.removeEventListener('click', handlePlay); + btn.addEventListener('click', enableBlocklyMode); + }); + } + + function enableMakerMode() { + document.body.setAttribute('mode', 'maker'); + document.querySelectorAll('.button').forEach((btn) => { + btn.addEventListener('click', handlePlay); + btn.removeEventListener('click', enableBlocklyMode); + }); + } + + function enableBlocklyMode(e) { + document.body.setAttribute('mode', 'blockly'); + currentButton = e.target; + loadWorkspace(currentButton); + } + + document.querySelector('#edit').addEventListener('click', enableEditMode); + document.querySelector('#done').addEventListener('click', enableMakerMode); + document.querySelector('#save').addEventListener('click', handleSave); + + enableMakerMode(); + + const toolbox = { + kind: 'flyoutToolbox', + contents: [ + { + kind: 'block', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'play_sound', + }, + ], + }; + + Blockly.inject('blocklyDiv', { + toolbox: toolbox, + scrollbars: false, + horizontalLayout: true, + toolboxPosition: 'end', + }); +})(); diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/scripts/music_maker.js b/packages/docs/docs/codelabs/getting-started/complete-code/scripts/music_maker.js new file mode 100644 index 00000000000..7959de10a83 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/complete-code/scripts/music_maker.js @@ -0,0 +1,21 @@ +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ +const MusicMaker = { + queue_: [], + player_: new Audio(), + queueSound: function (soundUrl) { + this.queue_.push(soundUrl); + }, + play: function () { + const next = this.queue_.shift(); + if (next) { + this.player_.src = next; + this.player_.play(); + } + }, +}; + +MusicMaker.player_.addEventListener('ended', MusicMaker.play.bind(MusicMaker)); diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/scripts/sound_blocks.js b/packages/docs/docs/codelabs/getting-started/complete-code/scripts/sound_blocks.js new file mode 100644 index 00000000000..81101c1051f --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/complete-code/scripts/sound_blocks.js @@ -0,0 +1,34 @@ +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +Blockly.defineBlocksWithJsonArray([ + // Block for colour picker. + { + type: 'play_sound', + message0: 'Play %1', + args0: [ + { + type: 'field_dropdown', + name: 'VALUE', + options: [ + ['C4', 'sounds/c4.m4a'], + ['D4', 'sounds/d4.m4a'], + ['E4', 'sounds/e4.m4a'], + ['F4', 'sounds/f4.m4a'], + ['G4', 'sounds/g4.m4a'], + ], + }, + ], + previousStatement: null, + nextStatement: null, + colour: 355, + }, +]); + +javascript.javascriptGenerator.forBlock['play_sound'] = function (block) { + const value = "'" + block.getFieldValue('VALUE') + "'"; + return 'MusicMaker.queueSound(' + value + ');\n'; +}; diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/sounds/c4.m4a b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/c4.m4a new file mode 100644 index 00000000000..33941cfae15 Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/c4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/sounds/c5.m4a b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/c5.m4a new file mode 100644 index 00000000000..49721cd31df Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/c5.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/sounds/d4.m4a b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/d4.m4a new file mode 100644 index 00000000000..51bcad6c2f1 Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/d4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/sounds/e4.m4a b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/e4.m4a new file mode 100644 index 00000000000..d910052ef9f Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/e4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/sounds/f4.m4a b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/f4.m4a new file mode 100644 index 00000000000..c80a0bfd3b2 Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/f4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/sounds/g4.m4a b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/g4.m4a new file mode 100644 index 00000000000..45ea4483021 Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/complete-code/sounds/g4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/complete-code/styles/index.css b/packages/docs/docs/codelabs/getting-started/complete-code/styles/index.css new file mode 100644 index 00000000000..988bb49ecb8 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/complete-code/styles/index.css @@ -0,0 +1,75 @@ +main { + width: 400px; + position: relative; + margin: 0 auto; + overflow: hidden; + height: 600px; +} + +header { + background-color: green; + width: 100%; +} + +h1 { + width: 400px; + position: relative; + margin: 0 auto; + color: #fff; + font-size: 1.8em; + line-height: 2.4em; +} + +.mode-edit, +.mode-maker, +.mode-blockly { + display: none; +} + +[mode='maker'] .mode-maker, +[mode='edit'] .mode-edit, +[mode='blockly'] .mode-blockly { + display: block; +} + +.blockly-editor { + position: absolute; + top: 64px; + left: -400px; + transition: left 0.4s; + height: 460px; + width: 400px; + background-color: #eee; +} + +[mode='blockly'] .blockly-editor { + left: 0; +} + +.maker { + display: flex; + flex-flow: column; + justify-content: space-between; + height: 460px; + width: 400px; +} + +.maker > div { + display: flex; + justify-content: space-between; +} + +.button { + width: 120px; + height: 140px; + color: #fff; + font-size: 3em; + text-align: center; + vertical-align: middle; + line-height: 140px; +} + +.mdl-button { + margin: 1em 0; + float: right; +} diff --git a/packages/docs/docs/codelabs/getting-started/create-a-blockly-workspace.mdx b/packages/docs/docs/codelabs/getting-started/create-a-blockly-workspace.mdx new file mode 100644 index 00000000000..89ee1921210 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/create-a-blockly-workspace.mdx @@ -0,0 +1,106 @@ +--- +slug: /codelabs/getting-started/create-a-blockly-workspace/index.html +description: How to add a workspace to your app. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Getting started with Blockly + +## 5. Create a Blockly workspace + +In this section you will learn how to add a workspace to your app, including how to define a toolbox. + +### Parts of Blockly + +A Blockly workspace has two main components: + +- The area where the user assembles their blocks (the white area). +- A toolbox that contains all blocks that are available to the user (the grey area). + + + {' '} + ![image](../../../static/images/codelabs/getting-started/d4_three_times.png){' '} + + +The toolbox may be organized into categories, and may contain both single blocks and groups of blocks. A well-organized toolbox helps the user to explore the available blocks and understand the capabilities of the underlying system. + +A toolbox is defined as a JavaScript object and passed into the workspace constructor through an options struct. + +For more information on this JSON format and toolbox configuration, including category creation, please see our toolbox documentation. + +### Define the toolbox + +Open up `scripts/main.js` and scroll down to the end of the file. Then add the code for your `toolbox` definition just after the call to `enableMakerMode()`: + +```js +const toolbox = { + kind: 'flyoutToolbox', + contents: [ + { + kind: 'block', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, + }, + }, + }, + }, + }, + ], +}; +``` + +This JavaScript object defines a toolbox with a single "repeat loop" block. + +### Injection + +Adding a Blockly workspace to a page is called _injection_, because the workspace is injected into a `div` that already exists on the page. + +To do this you call the function `Blockly.inject(container, options)`, which takes two arguments: + +- `container` is where the Blockly workspace should be placed on the page. It can be an `Element`, an ID string, or a CSS selector. +- `options` is a dictionary of configuration options. + +For this codelab we will inject into a div with the id `"blocklyDiv"`, which you can find in `index.html`: + +```html +
+``` + +### Create the workspace + +Now add code to inject the Blockly editor just after the code you used to define your toolbox: + +```js +Blockly.inject('blocklyDiv', { + toolbox: toolbox, + scrollbars: false, + horizontalLayout: true, + toolboxPosition: 'end', +}); +``` + +Let's look at the options we used to initialize your blockly editor: + +- `toolbox`: A JavaScript object which defines the toolbox for the editor. +- `scrollbars`: Whether to show scrollbars in the workspace. +- `horizontalLayout`: Whether to display the toolbox horizontally or vertically in the workspace. +- `toolboxPosition`: Whether to show the toolbox at the top or bottom of the workspace. + +The `options` struct gives you significant control over your Blockly instance. You can pass options to set Blockly's theme, modify scrolling behaviour, set the renderer, and more. For more information, head over to Blockly's developer site and check out the [configuration](/guides/configure/web/configuration_struct#the-options-dictionary) section. + +### Check your work + +Now refresh the page. Select the EDIT mode, then tap on one of the buttons. You should see a Blockly editor: + + + {' '} + ![image](../../../static/images/codelabs/getting-started/workspace_with_loop.png){' '} + + +Drag and drop the available loop block to the workspace to test it out. diff --git a/packages/docs/docs/codelabs/getting-started/create-a-custom-block.mdx b/packages/docs/docs/codelabs/getting-started/create-a-custom-block.mdx new file mode 100644 index 00000000000..9effdeba928 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/create-a-custom-block.mdx @@ -0,0 +1,111 @@ +--- +slug: /codelabs/getting-started/create-a-custom-block/index.html +description: How to create a custom block. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Getting started with Blockly + +## 6. Create a custom block + +Since this is a music maker app, we want a block that plays sounds. We could create one block per sound, but instead we will create a single block with a dropdown to select which note to play: + + + {' '} + ![image](../../../static/images/codelabs/getting-started/play_sound_block.png){' '} + + +In Blockly, a _block definition_ describes how a block looks and behaves. This includes its text, colour, and shape. It may also include which other blocks it can connect to. + +Blocks can be defined in either JavaScript or JSON. The developer site has a full article on [how to define a block](/guides/create-custom-blocks/define/block-definitions#how-to-create-block-definitions). + +In this codelab we will simply provide the block definition for you to copy and use. + +### Define the sound block + +Create a JS file to define a new "play sound" block: + +1. Add `sound_blocks.js` file in the `scripts` directory. +1. Add the following code to `sound_blocks.js`: + +```js +Blockly.common.defineBlocksWithJsonArray([ + { + type: 'play_sound', + message0: 'Play %1', + args0: [ + { + type: 'field_dropdown', + name: 'VALUE', + options: [ + ['C4', 'sounds/c4.m4a'], + ['D4', 'sounds/d4.m4a'], + ['E4', 'sounds/e4.m4a'], + ['F4', 'sounds/f4.m4a'], + ['G4', 'sounds/g4.m4a'], + ], + }, + ], + previousStatement: null, + nextStatement: null, + colour: 355, + }, +]); +``` + +Add a script tag to `index.html` to include your new block definition: + +```html + +``` + +Your sound block definitions must come after importing Blockly and before the other imports, since you will use Blockly functions in this file, and you will be using functions from this file in later files. Your imports should now look like this: + +```html + + + + +``` + +### Add the sound block to the toolbox + +Now we can update the toolbox to include the new sound block, by adding `{'kind': 'block', 'type': 'play_sound'}` to our `toolbox` definition: + +```js +const toolbox = { + kind: 'flyoutToolbox', + contents: [ + { + kind: 'block', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'play_sound', + }, + ], +}; +``` + +Run the app one more time, and play around with the new `Play (sound)` block. It should look like this: + + + {' '} + ![image](../../../static/images/codelabs/getting-started/workspace_with_toolbox.png){' '} + + +### The block factory + +This step discussed how to manually define custom blocks in Blockly. Once you've completed the entire codelab, we recommend that you check out our [block factory tool](/guides/create-custom-blocks/blockly-developer-tools), which helps automate part of this process. diff --git a/packages/docs/docs/codelabs/getting-started/explore-the-app.mdx b/packages/docs/docs/codelabs/getting-started/explore-the-app.mdx new file mode 100644 index 00000000000..b2302c063a5 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/explore-the-app.mdx @@ -0,0 +1,32 @@ +--- +slug: /codelabs/getting-started/explore-the-app/index.html +description: Explore Blockly's getting started app. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Getting started with Blockly + +## 3. Explore the app + +To run the app, simply open `starter-code/index.html` in a browser. + +### Play Mode + +By default, the app launches in "**Play Mode**". In this mode, you can see 9 buttons. None of them can do anything yet. The idea is to let the user define custom behaviors for each button, using Blockly. + + + {' '} + ![image](../../../static/images/codelabs/getting-started/play_mode.png){' '} + + +### Edit mode + +By tapping the **EDIT** button, you can switch to edit mode. In this mode, tapping a button will display an editor, which is where you can program how sounds should play for that button. For now, the editor screen is empty. + + + {' '} + ![image](../../../static/images/codelabs/getting-started/edit_mode_unimplemented.png){' '} + + +You can go back to the play mode by tapping **SAVE** and then **DONE** buttons. diff --git a/packages/docs/docs/codelabs/getting-started/generate-javaScript-code.mdx b/packages/docs/docs/codelabs/getting-started/generate-javaScript-code.mdx new file mode 100644 index 00000000000..bf8f9e7d614 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/generate-javaScript-code.mdx @@ -0,0 +1,50 @@ +--- +slug: /codelabs/getting-started/generate-javaScript-code/index.html +description: How to generate JavaScript code. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Getting started with Blockly + +## 8. Generate JavaScript code + +Now that each button can be configured with its own Blockly workspace, the next thing we want to do is to generate JavaScript code from each workspace. + +This generated code will be run by the browser, effectively executing the blocks set up in the Blockly workspace. + +### The language generator + +Blockly can generate code from blocks for different languages, e.g. JavaScript, Python, or PHP. + +A _language generator_ defines the rules for generating a specific language (such as indentation). Because we are using the default imports, we don't need to add any new code to get the JavaScript generator. + +As previously mentioned, you can define your imports more carefully to get a [different generator](https://www.npmjs.com/package/blockly#blockly-generators). + +### Add a block generator + +When Blockly generates JavaScript code for blocks in a workspace, it translates each block into code. By default, it knows how to translate all library-provided default blocks into JavaScript code. However, for any custom blocks, we need to specify our own translation functions. These are called _block generators_. + +Add the following code to the bottom of `scripts/sound_blocks.js`: + +```js +javascript.javascriptGenerator.forBlock['play_sound'] = function (block) { + let value = "'" + block.getFieldValue('VALUE') + "'"; + return 'MusicMaker.queueSound(' + value + ');\n'; +}; +``` + +With this translation function, the following `play_sound` block: + + + {' '} + ![image](../../../static/images/codelabs/getting-started/play_sound_block.png){' '} + + +translates into the JavaScript code: + +```javascript +MusicMaker.queueSound('Sounds/c4.m4a'); +``` + +For more information on block generators, read the [generating code](/guides/create-custom-blocks/code-generation/overview#block-code-generators) page on the developer site. diff --git a/packages/docs/docs/codelabs/getting-started/run-generated-code.mdx b/packages/docs/docs/codelabs/getting-started/run-generated-code.mdx new file mode 100644 index 00000000000..a3b8000ff94 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/run-generated-code.mdx @@ -0,0 +1,73 @@ +--- +slug: /codelabs/getting-started/run-generated-code/index.html +description: How to run generated code. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Getting started with Blockly + +## 9. Run generated code + +Most of your work so far has been in the **Edit** mode. Now you will update the **Play** mode to actually execute the custom code associated with each block. + +The function `handlePlay` is already defined in `scripts/main.js`, but it's empty. Load the workspace content associated with the pressed button: + +```js +loadWorkspace(event.target); +``` + +Next, you need to generate the code out of that workspace, which you can do with a call to `javascript.javascriptGenerator.workspaceToCode`. + +The user's code will consist of many `MusicMaker.queueSound` calls. At the end of our generated script, add a call to `MusicMaker.play` to play all the sounds added to the queue: + +```js +let code = javascript.javascriptGenerator.workspaceToCode( + Blockly.getMainWorkspace(), +); +code += 'MusicMaker.play();'; +``` + +Finally, execute the script with the `eval` function. Wrap it in a `try/catch` so that any runtime errors are logged to the console, instead of failing quietly: + +```js +try { + eval(code); +} catch (error) { + console.log(error); +} +``` + +### The full code + +The end result should look like this: + +```js +function handlePlay(event) { + loadWorkspace(event.target); + let code = javascript.javascriptGenerator.workspaceToCode( + Blockly.getMainWorkspace(), + ); + code += 'MusicMaker.play();'; + try { + eval(code); + } catch (error) { + console.log(error); + } +} +``` + +### A note on eval + +Executing scripts with eval is not always the safest option - we use it here for simplicity. If you intend to run the user's blocks in production, check out the JS Interpreter project. This project is separate from Blockly, but was specifically written for Blockly. + +### Test it + +Run the app and try it out! Edit one of the buttons to play a D4 sound 3 times: + + + {' '} + ![image](../../../static/images/codelabs/getting-started/d4_three_times.png){' '} + + +Save and exit the edit mode. Now if you tap this button, you should hear the D4 sound played 3 times. diff --git a/packages/docs/docs/codelabs/getting-started/save-load-workspace.mdx b/packages/docs/docs/codelabs/getting-started/save-load-workspace.mdx new file mode 100644 index 00000000000..89fe5254028 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/save-load-workspace.mdx @@ -0,0 +1,54 @@ +--- +slug: /codelabs/getting-started/save-load-workspace/index.html +description: How to save and load your workspace. +--- + +# Getting started with Blockly + +## 7. Save/load workspace + +You now have a Blockly workspace that appears when editing a button. The user can use this to write code, but there's no link between the code the user has written and an individual button on the page. + +Once the button behavior is defined by the user, it needs to be saved for later use. The saved code must be per button, since buttons can be programmed to play different sounds. + +### Add the save method + +Open `scripts/main.js`. Add the following code to the `save()` method: + +```js +button.blocklySave = Blockly.serialization.workspaces.save( + Blockly.getMainWorkspace(), +); +``` + +`workspaces.save` takes the Blockly workspace, exports its state to a JavaScript object and stores it in a `blocklySave` property on the button. This way the exported state for the block sequence gets associated with a particular button. + +### Add the load method + +Similarly, when a user opens the editor, the blocks previously associated with this button should get loaded into the workspace. + +In the `scripts/main.js `file, add `loadWorkspace` function: + +``` +function loadWorkspace(button) { + const workspace = Blockly.getMainWorkspace(); + if (button.blocklySave) { + Blockly.serialization.workspaces.load(button.blocklySave, workspace); + } else { + workspace.clear(); + } +} +``` + +This loads the blocks stored on the button that was clicked back into the workspace. + +Call this function from the end of the function `enableBlocklyMode`: + +``` +function enableBlocklyMode(e) { + ... + loadWorkspace(currentButton); +} +``` + +Now, test the code. Edit the workspace for one of the buttons, add some blocks, save it, and reopen it. The workspace should still contain the blocks you added. diff --git a/packages/docs/docs/codelabs/getting-started/setup.mdx b/packages/docs/docs/codelabs/getting-started/setup.mdx new file mode 100644 index 00000000000..d07921bacbe --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/setup.mdx @@ -0,0 +1,36 @@ +--- +slug: /codelabs/getting-started/setup/index.html +description: Setting up the "Getting started with Blockly" codelab. +--- + +# Getting started with Blockly + +## 2. Setup + +### Download the sample code + +You can get the sample code for this code by either downloading the zip here: + +[Download zip](https://github.com/RaspberryPiFoundation/blockly/archive/main.zip) + +or by cloning this git repo: + +```bash +git clone https://github.com/RaspberryPiFoundation/blockly.git +``` + +If you downloaded the source as a zip, unpacking it should give you a root folder named `blockly-main`. + +The relevant files are in `docs/docs/codelabs/getting-started`. There are two versions of the app: + +- `starter-code/`: The starter code that you'll build upon in this codelab. +- `complete-code/`: The code after completing the codelab, in case you get lost or want to compare to your version. + +Each folder contains: + +- `scripts/` + - `main.js` - The main logic for the app. In the starter project it has all the code needed to navigate and switch between views in the basic app. + - `music_maker.js` - A small library to play sounds. We will use it to actually play sounds in the browser. +- `sounds/` - Sound files for various notes +- `styles/` - The app's CSS +- `index.html` - The app's index page. diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/index.html b/packages/docs/docs/codelabs/getting-started/starter-code/index.html new file mode 100644 index 00000000000..c821256a3be --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/starter-code/index.html @@ -0,0 +1,58 @@ + + + + + + + + Blockly for the Web Codelab + + + + + + +
+

Music Maker

+

Music Maker Configuration

+
+ +
+ + + +

+ Tap any button to edit its code.
When complete, press Done. +

+ +
+
+
1
+
2
+
3
+
+
+
4
+
5
+
6
+
+
+
7
+
8
+
9
+
+
+ +
+
+
+
+ + + + + diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/scripts/main.js b/packages/docs/docs/codelabs/getting-started/starter-code/scripts/main.js new file mode 100644 index 00000000000..33cf91446d2 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/starter-code/scripts/main.js @@ -0,0 +1,48 @@ +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ +(function () { + let currentButton; + + function handlePlay(event) { + // Add code for playing sound. + } + + function save(button) { + // Add code for saving the behavior of a button. + } + + function handleSave() { + document.body.setAttribute('mode', 'edit'); + save(currentButton); + } + + function enableEditMode() { + document.body.setAttribute('mode', 'edit'); + document.querySelectorAll('.button').forEach((btn) => { + btn.removeEventListener('click', handlePlay); + btn.addEventListener('click', enableBlocklyMode); + }); + } + + function enableMakerMode() { + document.body.setAttribute('mode', 'maker'); + document.querySelectorAll('.button').forEach((btn) => { + btn.addEventListener('click', handlePlay); + btn.removeEventListener('click', enableBlocklyMode); + }); + } + + function enableBlocklyMode(e) { + document.body.setAttribute('mode', 'blockly'); + currentButton = e.target; + } + + document.querySelector('#edit').addEventListener('click', enableEditMode); + document.querySelector('#done').addEventListener('click', enableMakerMode); + document.querySelector('#save').addEventListener('click', handleSave); + + enableMakerMode(); +})(); diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/scripts/music_maker.js b/packages/docs/docs/codelabs/getting-started/starter-code/scripts/music_maker.js new file mode 100644 index 00000000000..7959de10a83 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/starter-code/scripts/music_maker.js @@ -0,0 +1,21 @@ +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ +const MusicMaker = { + queue_: [], + player_: new Audio(), + queueSound: function (soundUrl) { + this.queue_.push(soundUrl); + }, + play: function () { + const next = this.queue_.shift(); + if (next) { + this.player_.src = next; + this.player_.play(); + } + }, +}; + +MusicMaker.player_.addEventListener('ended', MusicMaker.play.bind(MusicMaker)); diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/sounds/c4.m4a b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/c4.m4a new file mode 100644 index 00000000000..33941cfae15 Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/c4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/sounds/c5.m4a b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/c5.m4a new file mode 100644 index 00000000000..49721cd31df Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/c5.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/sounds/d4.m4a b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/d4.m4a new file mode 100644 index 00000000000..51bcad6c2f1 Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/d4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/sounds/e4.m4a b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/e4.m4a new file mode 100644 index 00000000000..d910052ef9f Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/e4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/sounds/f4.m4a b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/f4.m4a new file mode 100644 index 00000000000..c80a0bfd3b2 Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/f4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/sounds/g4.m4a b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/g4.m4a new file mode 100644 index 00000000000..45ea4483021 Binary files /dev/null and b/packages/docs/docs/codelabs/getting-started/starter-code/sounds/g4.m4a differ diff --git a/packages/docs/docs/codelabs/getting-started/starter-code/styles/index.css b/packages/docs/docs/codelabs/getting-started/starter-code/styles/index.css new file mode 100644 index 00000000000..988bb49ecb8 --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/starter-code/styles/index.css @@ -0,0 +1,75 @@ +main { + width: 400px; + position: relative; + margin: 0 auto; + overflow: hidden; + height: 600px; +} + +header { + background-color: green; + width: 100%; +} + +h1 { + width: 400px; + position: relative; + margin: 0 auto; + color: #fff; + font-size: 1.8em; + line-height: 2.4em; +} + +.mode-edit, +.mode-maker, +.mode-blockly { + display: none; +} + +[mode='maker'] .mode-maker, +[mode='edit'] .mode-edit, +[mode='blockly'] .mode-blockly { + display: block; +} + +.blockly-editor { + position: absolute; + top: 64px; + left: -400px; + transition: left 0.4s; + height: 460px; + width: 400px; + background-color: #eee; +} + +[mode='blockly'] .blockly-editor { + left: 0; +} + +.maker { + display: flex; + flex-flow: column; + justify-content: space-between; + height: 460px; + width: 400px; +} + +.maker > div { + display: flex; + justify-content: space-between; +} + +.button { + width: 120px; + height: 140px; + color: #fff; + font-size: 3em; + text-align: center; + vertical-align: middle; + line-height: 140px; +} + +.mdl-button { + margin: 1em 0; + float: right; +} diff --git a/packages/docs/docs/codelabs/getting-started/the-end.mdx b/packages/docs/docs/codelabs/getting-started/the-end.mdx new file mode 100644 index 00000000000..10e5305ce8d --- /dev/null +++ b/packages/docs/docs/codelabs/getting-started/the-end.mdx @@ -0,0 +1,15 @@ +--- +pagination_next: null +slug: /codelabs/getting-started/the-end/index.html +description: Summary of the "Getting started with Blockly" codelab. +--- + +# Getting started with Blockly + +## 10. The End + +And with that, you're done with the Blockly codelab! If you'd like to continue playing with the app, we suggest adding or changing the available blocks. There are sample sound files in the `sounds` folder - try hooking them up to a new block! + +For more documentation, visit the [Blockly developer site](/guides/get-started/what-is-blockly). + +Additionally, Blockly has an active [developer forum](https://groups.google.com/g/blockly). Please drop by and say hello. We're happy to answer any questions or give advice on best practices for building an app with Blockly. Feel free to show us your prototypes early; collectively we have a lot of experience and can offer hints which will save you time. diff --git a/packages/docs/docs/codelabs/index.mdx b/packages/docs/docs/codelabs/index.mdx new file mode 100644 index 00000000000..cda1d7a1aa5 --- /dev/null +++ b/packages/docs/docs/codelabs/index.mdx @@ -0,0 +1,94 @@ +--- +title: Welcome to the Blockly Codelabs +pagination_next: null +pagination_prev: null +slug: /codelabs/index +--- + +import { CodelabGrid, CodelabCard } from '@site/src/components/CodelabCards'; +import Image from '@site/src/components/Image'; + +Blockly Codelabs provide a guided, tutorial, hands-on coding experience of Blockly. + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/codelab-overview.mdx b/packages/docs/docs/codelabs/theme-extension-identifier/codelab-overview.mdx new file mode 100644 index 00000000000..630615778ec --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/codelab-overview.mdx @@ -0,0 +1,29 @@ +--- +pagination_prev: null +slug: /codelabs/theme-extension-identifier/codelab-overview/index.html +description: Overview of the "Customizing your themes" codelab. +--- + +# Customizing your themes + +## 1. Codelab overview + +### What you'll learn + +In this codelab you will learn how to: + +- Add component styles. +- Add a category style. +- Add a block style. + +### What you'll build + +A very simple Blockly workspace with customized themes. + +### What you'll need + +- A browser +- Basic knowledge of HTML, CSS, and JavaScript. + +This codelab is focused on Blockly's theme extension. Non-relevant concepts +are glossed over and provided for you to simple copy and paste. diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/complete-code/index.html b/packages/docs/docs/codelabs/theme-extension-identifier/complete-code/index.html new file mode 100644 index 00000000000..f43e1187827 --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/complete-code/index.html @@ -0,0 +1,40 @@ + + + + + Theme Extension Codelab + + + + + + + + +

Theme Extension Codelab

+
+ + diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/complete-code/index.js b/packages/docs/docs/codelabs/theme-extension-identifier/complete-code/index.js new file mode 100644 index 00000000000..45cdc22e1b9 --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/complete-code/index.js @@ -0,0 +1,64 @@ +'use strict'; + +let workspace = null; + +Blockly.Themes.Halloween = Blockly.Theme.defineTheme('halloween', { + base: Blockly.Themes.Classic, + categoryStyles: { + list_category: { + colour: '#4a148c', + }, + logic_category: { + colour: '#8b4513', + }, + loop_category: { + colour: '#85E21F', + }, + text_category: { + colour: '#FE9B13', + }, + }, + blockStyles: { + list_blocks: { + colourPrimary: '#4a148c', + colourSecondary: '#AD7BE9', + colourTertiary: '#CDB6E9', + }, + logic_blocks: { + colourPrimary: '#8b4513', + colourSecondary: '#ff0000', + colourTertiary: '#C5EAFF', + }, + loop_blocks: { + colourPrimary: '#85E21F', + colourSecondary: '#ff0000', + colourTertiary: '#C5EAFF', + }, + text_blocks: { + colourPrimary: '#FE9B13', + colourSecondary: '#ff0000', + colourTertiary: '#C5EAFF', + }, + }, + componentStyles: { + workspaceBackgroundColour: '#ff7518', + toolboxBackgroundColour: '#F9C10E', + toolboxForegroundColour: '#fff', + flyoutBackgroundColour: '#252526', + flyoutForegroundColour: '#ccc', + flyoutOpacity: 1, + scrollbarColour: '#ff0000', + insertionMarkerColour: '#fff', + insertionMarkerOpacity: 0.3, + scrollbarOpacity: 0.4, + cursorColour: '#d0d0d0', + blackBackground: '#333', + }, +}); +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxCategories, + theme: Blockly.Themes.Halloween, + }); +} diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/customize-block-styles.mdx b/packages/docs/docs/codelabs/theme-extension-identifier/customize-block-styles.mdx new file mode 100644 index 00000000000..b90c3852b8e --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/customize-block-styles.mdx @@ -0,0 +1,76 @@ +--- +slug: /codelabs/theme-extension-identifier/customize-block-styles/index.html +description: How to use a theme to set the colours of blocks. +--- + +# Customizing your themes + +## 6. Customize Block Styles + +A block style currently only holds three different colour properties. They are 'colourPrimary', +'colourSecondary' and 'colourTertiary'. This value can either be defined as a hex value or as a hue. +For more information on block styles visit our themes [documentation](/guides/configure/web/appearance/themes#block-style) + +Update the Theme definition to have the block styles as below. + +```js +Blockly.Themes.Halloween = Blockly.Theme.defineTheme('halloween', { + base: Blockly.Themes.Classic, + categoryStyles: { + list_category: { + colour: '#4a148c', + }, + logic_category: { + colour: '#8b4513', + }, + loop_category: { + colour: '#85E21F', + }, + text_category: { + colour: '#FE9B13', + }, + }, + blockStyles: { + list_blocks: { + colourPrimary: '#4a148c', + colourSecondary: '#AD7BE9', + colourTertiary: '#CDB6E9', + }, + logic_blocks: { + colourPrimary: '#8b4513', + colourSecondary: '#ff0000', + colourTertiary: '#C5EAFF', + }, + loop_blocks: { + colourPrimary: '#85E21F', + colourSecondary: '#ff0000', + colourTertiary: '#C5EAFF', + }, + text_blocks: { + colourPrimary: '#FE9B13', + colourSecondary: '#ff0000', + colourTertiary: '#C5EAFF', + }, + }, + componentStyles: { + workspaceBackgroundColour: '#ff7518', + toolboxBackgroundColour: '#F9C10E', + toolboxForegroundColour: '#fff', + flyoutBackgroundColour: '#252526', + flyoutForegroundColour: '#ccc', + flyoutOpacity: 1, + scrollbarColour: '#ff0000', + insertionMarkerColour: '#fff', + insertionMarkerOpacity: 0.3, + scrollbarOpacity: 0.4, + cursorColour: '#d0d0d0', + blackBackground: '#333', + }, +}); +``` + +### Test it + +Click on different blocks in the component and you should see the colours that you applied show up. + +![Customized Block colors on the components](../../../static/images/codelabs/theme-extension/block_styles.png) diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/customize-category-styles.mdx b/packages/docs/docs/codelabs/theme-extension-identifier/customize-category-styles.mdx new file mode 100644 index 00000000000..72485084272 --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/customize-category-styles.mdx @@ -0,0 +1,56 @@ +--- +slug: /codelabs/theme-extension-identifier/customize-category-styles/index.html +description: How to use a theme to set the colours of categories. +--- + +# Customizing your themes + +## 5. Customize Category Styles + +A category style currently only holds a colour property. It is the colour of the category on the toolbox. +This value can either be defined as a hex value or as a hue. Usually these colours should be the same as +the colourPrimary on the majority of blocks in the category making it easy for users to tell what blocks +belong in what category. + +Update the Theme definition to have the category styles as below. + +```js +Blockly.Themes.Halloween = Blockly.Theme.defineTheme('halloween', { + base: Blockly.Themes.Classic, + categoryStyles: { + list_category: { + colour: '#4a148c', + }, + logic_category: { + colour: '#8b4513', + }, + loop_category: { + colour: '#85E21F', + }, + text_category: { + colour: '#FE9B13', + }, + }, + componentStyles: { + workspaceBackgroundColour: '#ff7518', + toolboxBackgroundColour: '#F9C10E', + toolboxForegroundColour: '#fff', + flyoutBackgroundColour: '#252526', + flyoutForegroundColour: '#ccc', + flyoutOpacity: 1, + scrollbarColour: '#ff0000', + insertionMarkerColour: '#fff', + insertionMarkerOpacity: 0.3, + scrollbarOpacity: 0.4, + cursorColour: '#d0d0d0', + blackBackground: '#333', + }, +}); +``` + +### Test it + +The colour displayed next to the toolbox category should display your new colours. +Clicking on a category will highlight the row with your new colour. + +![Customized Block colors on the components](../../../static/images/codelabs/theme-extension/customized_categories.png) diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/customize-components.mdx b/packages/docs/docs/codelabs/theme-extension-identifier/customize-components.mdx new file mode 100644 index 00000000000..752be022e18 --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/customize-components.mdx @@ -0,0 +1,36 @@ +--- +slug: /codelabs/theme-extension-identifier/customize-components/index.html +description: How to use a theme to set the colours of components. +--- + +# Customizing your themes + +## 4. Customize Components + +Within the Halloween theme definition, you can customize the colours of multiple components: + +```js +Blockly.Themes.Halloween = Blockly.Theme.defineTheme('halloween', { + base: Blockly.Themes.Classic, + componentStyles: { + workspaceBackgroundColour: '#ff7518', + toolboxBackgroundColour: '#F9C10E', + toolboxForegroundColour: '#fff', + flyoutBackgroundColour: '#252526', + flyoutForegroundColour: '#ccc', + flyoutOpacity: 1, + scrollbarColour: '#ff0000', + insertionMarkerColour: '#fff', + insertionMarkerOpacity: 0.3, + scrollbarOpacity: 0.4, + cursorColour: '#d0d0d0', + blackBackground: '#333', + }, +}); +``` + +### Test it + +Reload your web page. You should see a themed workspace! + +![Fun with colours.](../../../static/images/codelabs/theme-extension/theme_components_workspace.png) diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/setup.mdx b/packages/docs/docs/codelabs/theme-extension-identifier/setup.mdx new file mode 100644 index 00000000000..36e4dc1c652 --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/setup.mdx @@ -0,0 +1,36 @@ +--- +slug: /codelabs/theme-extension-identifier/setup/index.html +description: Setting up the "Customizing your themes" codelab. +--- + +# Customizing your themes + +## 2. Setup + +### Download the sample code + +You can get the sample code for this code by either downloading the zip here: + +[Download zip](https://github.com/RaspberryPiFoundation/blockly/archive/main.zip) + +or by cloning this git repo: + +```bash +git clone https://github.com/RaspberryPiFoundation/blockly.git +``` + +If you downloaded the source as a zip, unpacking it should give you a root folder named `blockly-main`. + +The relevant files are in `docs/docs/codelabs/theme-extension-identifier`. There are two versions of the app: + +- `starter-code/`: The starter code that you'll build upon in this codelab. +- `complete-code/`: The code after completing the codelab, in case you get lost or want to compare to your version. + +Each folder contains: + +- `index.js` - The codelab's logic. To start, it just injects a simple workspace. +- `index.html` - A web page containing a simple blockly workspace. + +To run the code, simple open `starter-code/index.html` in a browser. You should see a Blockly workspace with a flyout. + +![A web page with the text "Theme Extension Codelab" and a Blockly workspace.](../../../static/images/codelabs/theme-extension/starter_workspace.png) diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/starter-code/index.html b/packages/docs/docs/codelabs/theme-extension-identifier/starter-code/index.html new file mode 100644 index 00000000000..f43e1187827 --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/starter-code/index.html @@ -0,0 +1,40 @@ + + + + + Theme Extension Codelab + + + + + + + + +

Theme Extension Codelab

+
+ + diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/starter-code/index.js b/packages/docs/docs/codelabs/theme-extension-identifier/starter-code/index.js new file mode 100644 index 00000000000..b8313f48d43 --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/starter-code/index.js @@ -0,0 +1,10 @@ +'use strict'; + +let workspace = null; + +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxCategories, + }); +} diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/summary.mdx b/packages/docs/docs/codelabs/theme-extension-identifier/summary.mdx new file mode 100644 index 00000000000..c07901a62f1 --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/summary.mdx @@ -0,0 +1,17 @@ +--- +pagination_next: null +slug: /codelabs/theme-extension-identifier/summary/index.html +description: Summary of the "Customizing your themes" codelab. +--- + +# Customizing your themes + +## 7. Summary + +In this codelab you have learned how to extend and customize themes for the blocks component. + +### Additional information + +- [Themes documentation](/guides/configure/web/appearance/themes) + +- You can also customize the font styles. Details are available in the [documentation](/guides/configure/web/appearance/themes#font-styles). diff --git a/packages/docs/docs/codelabs/theme-extension-identifier/workspace-theme.mdx b/packages/docs/docs/codelabs/theme-extension-identifier/workspace-theme.mdx new file mode 100644 index 00000000000..5d86693c2c2 --- /dev/null +++ b/packages/docs/docs/codelabs/theme-extension-identifier/workspace-theme.mdx @@ -0,0 +1,40 @@ +--- +slug: /codelabs/theme-extension-identifier/workspace-theme/index.html +description: How to create a theme. +--- + +# Customizing your themes + +## 3. Workspace Theme + +In this section you will create a very basic halloween theme, then inject it to display in the workspace. + +### Themes + +Themes are a way to customize the look and feel of Blockly. Currently, we support customizing block colours, category colours and certain components through the Themes class. + +A theme can be created using the constructor or by using defineTheme. Using `defineTheme` makes it easy to extend a pre existing theme and set all values with a single object. + +Add the below code in `index.js` right before function start() + +```js +Blockly.Themes.Halloween = Blockly.Theme.defineTheme('halloween', { + base: Blockly.Themes.Classic, +}); +``` + +And then add a line to inject this theme in function start() in `index.js` + +```js +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxCategories, + theme: Blockly.Themes.Halloween, + }); +} +``` + +:::note +At this point, we have just created a new theme. But it does not have any customizations. We will do that next. +::: diff --git a/packages/docs/docs/codelabs/validation-and-warnings/codelab-overview.mdx b/packages/docs/docs/codelabs/validation-and-warnings/codelab-overview.mdx new file mode 100644 index 00000000000..9144ad97156 --- /dev/null +++ b/packages/docs/docs/codelabs/validation-and-warnings/codelab-overview.mdx @@ -0,0 +1,37 @@ +--- +pagination_prev: null +slug: /codelabs/validation-and-warnings/codelab-overview/index.html +description: Overview of the "Block validation and warnings" codelab. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Block validation and warnings + +## 1. Codelab overview + +### What you'll learn + +This codelab will show you how to ensure that custom blocks either: + +1. have everything they need to be able to generate valid code, or +1. display a visual warning to the user that the block is currently invalid. + +### What you'll build + +In this codelab, you'll create a new custom block type that generates a list of numbers counting up within a given range. The block will validate itself and display a warning if the first number in the range is greater than the last number: + + + ![Two instances of a custom block, one with a validation + warning.](../../../static/images/codelabs/validation-and-warnings/final_range_blocks.png) + + +You can find the code for the [completed custom block](https://github.com/RaspberryPiFoundation/blockly/docs/docs/codelabs/validation-and-warnings/complete-code/index.js) on GitHub. + +### What you'll need + +- A browser. +- A text editor. +- Basic knowledge of JavaScript. +- Basic understanding of the [Blockly toolbox](/guides/configure/web/toolboxes/toolbox). +- Basic understanding of [using JSON to define custom blocks](/guides/create-custom-blocks/define/structure-json). diff --git a/packages/docs/docs/codelabs/validation-and-warnings/complete-code/index.html b/packages/docs/docs/codelabs/validation-and-warnings/complete-code/index.html new file mode 100644 index 00000000000..f6ca51f2a12 --- /dev/null +++ b/packages/docs/docs/codelabs/validation-and-warnings/complete-code/index.html @@ -0,0 +1,55 @@ + + + + + Validation and Warnings Codelab + + + + + + + +

Validation and Warnings Codelab

+
+ +
+ +
+ + diff --git a/packages/docs/docs/codelabs/validation-and-warnings/complete-code/index.js b/packages/docs/docs/codelabs/validation-and-warnings/complete-code/index.js new file mode 100644 index 00000000000..cdd841fc2c5 --- /dev/null +++ b/packages/docs/docs/codelabs/validation-and-warnings/complete-code/index.js @@ -0,0 +1,138 @@ +// Use Blockly's custom block JSON API to define a new block type. +Blockly.common.defineBlocksWithJsonArray([ + { + type: 'list_range', + message0: 'create list of numbers from %1 up to %2', + args0: [ + { + type: 'field_number', + name: 'FIRST', + value: 0, + min: 0, + precision: 2, + }, + { + type: 'field_number', + name: 'LAST', + value: 5, + min: 0, + precision: 1, + }, + ], + output: 'Array', + style: 'list_blocks', + extensions: ['list_range_validation'], + }, +]); + +Blockly.Extensions.register('list_range_validation', function () { + // Add custom validation. + this.getField('LAST').setValidator(function (newValue) { + // Force an odd number. + return Math.round((newValue - 1) / 2) * 2 + 1; + }); + + // Validate the entire block whenever any part of it changes, + // and display a warning if the block cannot be made valid. + this.setOnChange(function (event) { + const first = this.getFieldValue('FIRST'); + const last = this.getFieldValue('LAST'); + const valid = first < last; + this.setWarningText( + valid + ? null + : `The first number (${first}) must be smaller than the last number (${last}).`, + ); + + // Disable invalid blocks (unless it's in a toolbox flyout, + // since you can't drag disabled blocks to your workspace). + if (!this.isInFlyout) { + const initialGroup = Blockly.Events.getGroup(); + // Make it so the move and the disable event get undone together. + Blockly.Events.setGroup(event.group); + this.setDisabledReason(!valid, 'Invalid range'); + Blockly.Events.setGroup(initialGroup); + } + }); +}); + +// Define how to generate JavaScript from the custom block. +javascript.javascriptGenerator.forBlock['list_range'] = function (block) { + const first = this.getFieldValue('FIRST'); + const last = this.getFieldValue('LAST'); + const numbers = []; + for (let i = first; i <= last; i++) { + numbers.push(i); + } + const code = '[' + numbers.join(', ') + ']'; + return [code, javascript.Order.NONE]; +}; + +// Define which blocks are available in the toolbox. +const toolbox = { + kind: 'categoryToolbox', + contents: [ + { + kind: 'category', + name: 'Blocks', + categorystyle: 'list_category', + contents: [ + { + kind: 'block', + type: 'list_range', + }, + { + kind: 'block', + type: 'controls_forEach', + }, + { + kind: 'block', + type: 'math_on_list', + }, + { + kind: 'block', + type: 'text_print', + }, + { + kind: 'block', + type: 'controls_flow_statements', + }, + ], + }, + { + kind: 'category', + name: 'Variables', + categorystyle: 'variable_category', + custom: 'VARIABLE', + }, + ], +}; + +let workspace = null; + +/** + * Initialize a Blockly workspace, and add a change listener to update the display of generated code. + * + * Called from index.html when the page initially loads. + */ +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolbox, + }); + + workspace.addChangeListener((event) => { + const code = javascript.javascriptGenerator.workspaceToCode(workspace); + document.getElementById('generatedCodeContainer').value = code; + }); +} + +/** + * Generate JavaScript code from the Blockly workspace, and execute it. + * + * Called from index.html when the execute button is clicked. + */ +function executeCode() { + const code = javascript.javascriptGenerator.workspaceToCode(workspace); + eval(code); +} diff --git a/packages/docs/docs/codelabs/validation-and-warnings/displaying-warnings.mdx b/packages/docs/docs/codelabs/validation-and-warnings/displaying-warnings.mdx new file mode 100644 index 00000000000..1d5d6041530 --- /dev/null +++ b/packages/docs/docs/codelabs/validation-and-warnings/displaying-warnings.mdx @@ -0,0 +1,57 @@ +--- +slug: /codelabs/validation-and-warnings/displaying-warnings/index.html +description: How to display a warning when a block fails validation. +--- + +# Block validation and warnings + +## 4. Displaying warnings + +Both Blockly's built-in validators and custom validators are nice because they immediately correct any errors so that there should never be any interruption in the validity of the blocks in the workspace or in the validity of the code that it generates. This results in a smooth, pleasant experience for the user, and you should take advantage of these validators whenever possible. + +However, there may be invalid conditions that can't be corrected automatically because it's ambiguous what the desired result is. For example, it doesn't make much sense for our custom block to have a `FIRST` field with a greater value than the `LAST` field, but it's not obvious which of the two fields is "wrong." The best we can do is warn the user about the problem, and let them decide how to fix it. + +In the case of our custom block, we want our extension to be notified whenever either field is updated, so that it can check both of the fields to determine whether the block is currently valid. We can set that up with a general change listener by adding this code inside the extension function after the custom validator: + +```js +// Validate the entire block whenever any part of it changes, +// and display a warning if the block cannot be made valid. +this.setOnChange(function (event) { + const first = this.getFieldValue('FIRST'); + const last = this.getFieldValue('LAST'); + const valid = first < last; + this.setWarningText( + valid + ? null + : `The first number (${first}) must be smaller than the last number (${last}).`, + ); +}); +``` + +This change listener function will get called whenever any part of the block is updated. It has access to all of the block's current field values, as well as the block's parents and children, if any. In this case, it reads both field values and compares them to determine whether the block is valid. Then it calls `this.setWarningText(...)`, which can accept either `null` indicating that there is nothing wrong or a string describing the problem. + +Reload `index.html`, drag the custom block into the workspace, then edit the fields to make the `FIRST` field greater than the `LAST` field. You should see a warning indicator, and you can click on it to see the warning message: + +![A Blockly workspace containing a custom range block with a warning message.](../../../static/images/codelabs/validation-and-warnings/warning_message.png) + +Depending on the severity of the issue, this might be sufficient for your custom block's needs. However, if the validity issue is severe enough that it wouldn't make sense to even try to generate code from the block, you should disable the block in addition to displaying a warning, because disabling a block makes code generators pretend the block doesn't exist. For example, most languages only allow `break` or `continue` statements inside of loops, so Blockly's corresponding built-in blocks are automatically disabled when used outside of loops: + +![A Blockly workspace with disabled break and continue blocks.](../../../static/images/codelabs/validation-and-warnings/disabled_break.png) + +You can disable a block using `this.setDisabledReason(true, 'reason')`, although there are some caveats: disabled blocks can't be dragged out of the toolbox flyout, and the act of disabling a block usually adds an event to Blockly's undo history. That's probably not the behavior you want when validating a block, so you can avoid both of these effects with the following code, which you should put inside the change listener function after setting the warning text: + +```js +// Disable invalid blocks (unless it's in a toolbox flyout, +// since you can't drag disabled blocks to your workspace). +if (!this.isInFlyout) { + const initialGroup = Blockly.Events.getGroup(); + // Make it so the move and the disable event get undone together. + Blockly.Events.setGroup(event.group); + this.setDisabledReason(!valid, 'Invalid range'); + Blockly.Events.setGroup(initialGroup); +} +``` + +Reload `index.html` one last time, drag out the custom block, and edit the fields to make the `FIRST` field greater than the `LAST` field again. This time, the block should be disabled, and it won't generate code even if it is combined with other blocks: + +![A Blockly workspace with disabled custom blocks.](../../../static/images/codelabs/validation-and-warnings/disabled_block.png) diff --git a/packages/docs/docs/codelabs/validation-and-warnings/setup.mdx b/packages/docs/docs/codelabs/validation-and-warnings/setup.mdx new file mode 100644 index 00000000000..2711ebe24ba --- /dev/null +++ b/packages/docs/docs/codelabs/validation-and-warnings/setup.mdx @@ -0,0 +1,112 @@ +--- +slug: /codelabs/validation-and-warnings/setup/index.html +description: Setting up the "Block validation and warnings" codelab. +--- + +import CodelabImage from '@site/src/components/CodelabImage'; + +# Block validation and warnings + +## 2. Setup + +### Download the sample code + +You can get the sample code for this codelab by either downloading the zip here: + +[Download zip](https://github.com/RaspberryPiFoundation/blockly/archive/main.zip) + +or by cloning this git repo: + +```bash +git clone https://github.com/RaspberryPiFoundation/blockly.git +``` + +If you downloaded the source as a zip, unpacking it should give you a root folder named `blockly-main`. + +The relevant files are in `docs/docs/codelabs/validation-and-warnings`. There are two versions of the app: + +- `starter-code/`: The starter code that you'll build upon in this codelab. +- `complete-code/`: The code after completing the codelab, in case you get lost or want to compare to your version. + +Each folder contains: + +- `index.js` - The codelab's logic. To start, it just injects a simple workspace. +- `index.html` - A web page containing a simple blockly workspace, an empty space where generated code will be displayed, and a button to execute the generated code. + +Open the file `starter-code/index.html` in a browser to see what it looks like. You should see a Blockly workspace with a toolbox, and space below it for generated code. + +![A web page with the text "Validation and Warnings Codelab" and a Blockly workspace.](../../../static/images/codelabs/validation-and-warnings/starter_workspace.png) + +Next, open the file `starter-code/index.js` in a text editor. You will be making changes to this file, but first let's take a look at the contents. The code in this file already does a few things: + +1. It uses Blockly's toolbox JSON API to define a toolbox containing a few built-in blocks that will be useful for testing our custom block. +1. In a function called `start()`, it initializes a Blockly workspace with the above toolbox, and adds a change event listener that displays the generated JavaScript code whenever a block is moved or updated in the workspace. +1. In a function called `executeCode()`, it executes the generated JavaScript code. + +### Define a custom block type + +To prepare for adding validation, let's define a new custom block type named `list_range` with two number fields called `FIRST` and `LAST`. Copy the following code to the beginning of `index.js`: + +```js +// Use Blockly's custom block JSON API to define a new block type. +Blockly.common.defineBlocksWithJsonArray([ + { + type: 'list_range', + message0: 'create list of numbers from %1 up to %2', + args0: [ + { + type: 'field_number', + name: 'FIRST', + value: 0, + }, + { + type: 'field_number', + name: 'LAST', + value: 5, + }, + ], + output: 'Array', + style: 'list_blocks', + }, +]); +``` + +Then, to make this block available from the toolbox, find the toolbox definition in `index.js` and insert this code at the beginning of the list of available blocks, right before the one named `controls_forEach`: + +```js + { + 'kind': 'block', + 'type': 'list_range', + }, +``` + +Now, if you reload `index.html` and open the toolbox, you should see the new block at the top: + + + ![A Blockly toolbox containing range, for-each, sum, print, and break + blocks.](../../../static/images/codelabs/validation-and-warnings/completed_toolbox.png) + + +### Generating JavaScript code for the custom block + +You can drag this block out from the toolbox into the workspace, but if you try to use it, you'll find that Blockly doesn't know how to generate JavaScript code from this block yet and error messages will appear in the browser console when it tries to update the display of the generated code. To fix this, add the following code below the custom block definition: + +```js +// Define how to generate JavaScript from the custom block. +javascript.javascriptGenerator['list_range'] = function (block) { + const first = this.getFieldValue('FIRST'); + const last = this.getFieldValue('LAST'); + const numbers = []; + for (let i = first; i <= last; i++) { + numbers.push(i); + } + const code = '[' + numbers.join(', ') + ']'; + return [code, javascript.Order.NONE]; +}; +``` + +Reload `index.html` once again and try adding the new block to the workspace. You should be able to see it successfully generate JavaScript code this time. Try combining it with other blocks to see what the code might look like, and click the button labeled "Execute the JavaScript code below" to see what happens when you run it: + +![A Blockly workspace with some blocks, the generated code, and the output.](../../../static/images/codelabs/validation-and-warnings/generated_javascript.png) + +Now we are ready to start adding validation! diff --git a/packages/docs/docs/codelabs/validation-and-warnings/starter-code/index.html b/packages/docs/docs/codelabs/validation-and-warnings/starter-code/index.html new file mode 100644 index 00000000000..f6ca51f2a12 --- /dev/null +++ b/packages/docs/docs/codelabs/validation-and-warnings/starter-code/index.html @@ -0,0 +1,55 @@ + + + + + Validation and Warnings Codelab + + + + + + + +

Validation and Warnings Codelab

+
+ +
+ +
+ + diff --git a/packages/docs/docs/codelabs/validation-and-warnings/starter-code/index.js b/packages/docs/docs/codelabs/validation-and-warnings/starter-code/index.js new file mode 100644 index 00000000000..58c4706fc76 --- /dev/null +++ b/packages/docs/docs/codelabs/validation-and-warnings/starter-code/index.js @@ -0,0 +1,64 @@ +// Define which blocks are available in the toolbox. +const toolbox = { + kind: 'categoryToolbox', + contents: [ + { + kind: 'category', + name: 'Blocks', + categorystyle: 'list_category', + contents: [ + { + kind: 'block', + type: 'controls_forEach', + }, + { + kind: 'block', + type: 'math_on_list', + }, + { + kind: 'block', + type: 'text_print', + }, + { + kind: 'block', + type: 'controls_flow_statements', + }, + ], + }, + { + kind: 'category', + name: 'Variables', + categorystyle: 'variable_category', + custom: 'VARIABLE', + }, + ], +}; + +let workspace = null; + +/** + * Initialize a Blockly workspace, and add a change listener to update the display of generated code. + * + * Called from index.html when the page initially loads. + */ +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolbox, + }); + + workspace.addChangeListener((event) => { + const code = javascript.javascriptGenerator.workspaceToCode(workspace); + document.getElementById('generatedCodeContainer').value = code; + }); +} + +/** + * Generate JavaScript code from the Blockly workspace, and execute it. + * + * Called from index.html when the execute button is clicked. + */ +function executeCode() { + const code = javascript.javascriptGenerator.workspaceToCode(workspace); + eval(code); +} diff --git a/packages/docs/docs/codelabs/validation-and-warnings/summary.mdx b/packages/docs/docs/codelabs/validation-and-warnings/summary.mdx new file mode 100644 index 00000000000..2973ca75200 --- /dev/null +++ b/packages/docs/docs/codelabs/validation-and-warnings/summary.mdx @@ -0,0 +1,32 @@ +--- +pagination_next: null +slug: /codelabs/validation-and-warnings/summary/index.html +description: Summary of the "Block validation and warnings" codelab. +--- + +# Block validation and warnings + +## 5. Summary + +In this codelab, you learned: + +- How to use the field validators in Blockly's JSON API. +- How to create an extension that adds functionality to a block. +- How to create custom field validators. +- How to validate the entire block when any part of it changes. +- How to display a warning message on the block. +- How to disable a block (without adding an event to the undo history). + +You can find the code for the [completed custom block](https://github.com/RaspberryPiFoundation/blockly/docs/docs/codelabs/validation-and-warnings/complete-code/index.js) on GitHub. + +### Resources + +For more information related topics, check out the documentation: + +- [Defining the toolbox](/guides/configure/web/toolboxes/toolbox) +- [Defining custom blocks](/guides/create-custom-blocks/overview) +- [Generating code from blocks](/guides/create-custom-blocks/code-generation/overview) +- [Creating extensions](/guides/create-custom-blocks/define/extensions#extensions) +- [Listening for change events](/guides/configure/web/events) +- [Custom validators](/guides/create-custom-blocks/fields/validators) +- [Custom block style guide](/guides/design/blocks) diff --git a/packages/docs/docs/codelabs/validation-and-warnings/validating-blocks.mdx b/packages/docs/docs/codelabs/validation-and-warnings/validating-blocks.mdx new file mode 100644 index 00000000000..c656d67784a --- /dev/null +++ b/packages/docs/docs/codelabs/validation-and-warnings/validating-blocks.mdx @@ -0,0 +1,94 @@ +--- +slug: /codelabs/validation-and-warnings/validating-blocks/index.html +description: How to validate the fields in a block. +--- + +# Block validation and warnings + +## 3. Validating blocks + +When you're designing custom blocks, you may find that it doesn't make sense to use the block in certain ways. Depending on the intended purpose of your block, you may want to add constraints on the possible values that can be assigned to its fields, or on where it is used. + +### Basic field constraints + +Blockly generally allows users to enter negative values and decimal values for number fields, but for this custom block, let's make sure that only positive whole numbers are allowed. Add `'min': 0` and `'precision': 1` to the fields in the custom block definition so that they look like this: + +```js + 'args0': [ + { + 'type': 'field_number', + 'name': 'FIRST', + 'value': 0, + 'min': 0, + 'precision': 1, + }, + { + 'type': 'field_number', + 'name': 'LAST', + 'value': 5, + 'min': 0, + 'precision': 1, + }, + ], +``` + +Then reload `index.html`, drag the custom block to your workspace, and try entering various values such as negative numbers or decimals. Notice how invalid values are immediately converted to the nearest valid value! + +If you want, you can also add a `'max'` constraint to a number field. + +### Adding custom validation to a field + +The built-in constraints are very convenient, but sometimes you might need to add custom constraints. For example, let's say that our custom block needs the first number of the range to be even, and the last number to be odd. We can easily implement the even constraint by setting the `'precision'` constraint of the `FIRST` field to `2`, but the odd constraint requires a custom validator. + +So far, we've been using Blockly's JSON API for defining custom blocks, but Blockly also has a JavaScript API with more advanced features, and one of those features is defining custom validators. Fortunately, we don't have to convert our entire custom block definition to the JavaScript API in order to take advantage of these advanced features, because Blockly has a system for adding JavaScript extensions to blocks that were defined with the JSON API. + +Let's give our custom block a new extension called `list_range_validation`. Add `'extensions': ['list_range_validation']` to the end of the custom block definition in `index.js` like so: + +```js +Blockly.common.defineBlocksWithJsonArray([ + { + 'type': 'list_range', + ... + 'style': 'list_blocks', + 'extensions': [ + 'list_range_validation', + ], + }, +]); +``` + +Then copy the following code to `index.js` underneath the custom block definition to register an implementation of that extension: + +```js +Blockly.Extensions.register('list_range_validation', function () { + // Validation code to be added here... +}); +``` + +The extension's function will be executed every time the custom block is instantiated, and the block instance itself will be implicitly available inside the function using JavaScript's `this` keyword. We can use it to access Blockly's JavaScript API for blocks, including validators. To add a validator on the `LAST` field, put the following code inside the extension function: + +```js +this.getField('LAST').setValidator(function (newValue) { + // Validation of newValue for LAST field to be added here... +}); +``` + +Blockly validator functions are called whenever the user enters a new value for that field, and the new value is passed to the function as a parameter. The parameter might be an invalid value, but validator function can return a valid value to override the user input. To force the `LAST` field to be an odd number, put the following code inside the validator function: + +```js +return Math.round((newValue - 1) / 2) * 2 + 1; +``` + +Afterwards, your extension code should look something like this: + +```js +Blockly.Extensions.register('list_range_validation', function () { + // Add custom validation. + this.getField('LAST').setValidator(function (newValue) { + // Force an odd number. + return Math.round((newValue - 1) / 2) * 2 + 1; + }); +}); +``` + +Reload `index.html` now, then drag the custom block to your workspace and try setting the `LAST` field to various values. Notice how it always turns into an odd number! diff --git a/packages/docs/docs/guides/app-integration/attribution.mdx b/packages/docs/docs/guides/app-integration/attribution.mdx new file mode 100644 index 00000000000..4f7df2e8109 --- /dev/null +++ b/packages/docs/docs/guides/app-integration/attribution.mdx @@ -0,0 +1,354 @@ +--- +description: How to properly attribute Blockly. +title: Attribute Blockly +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + + + + + +# Attribute Blockly + +Blockly's code is open source and free to use without attribution. + +However, we do encourage developers who are using Blockly to reference the +product in their website, app, or product. This page describes the best +practices for referring to Blockly and attributing it as well as appropriate +uses of the logo. + + + Download all assets + + +## How to refer to Blockly + +### Describing and attributing Blockly in text + +Upon first reference in a paragraph, use the primary one-line description: + +> Blockly is an open-source developer library from the Raspberry Pi Foundation, originally developed at Google. +> It creates a visual programming interface that uses drag-and-drop blocks. + +When referring to Blockly in the context of another app which uses Blockly +you should use the phrase "Built with Blockly". + +When giving Blockly attribution, this phrase should be used for blog posts, +press interviews, the app, and on your website. + +### Reference do's and don'ts + +

+ Do — Call Blockly "beginner friendly" + instead of "kid friendly." Blockly is used for a variety of applications, not + all of which are kid focused. +

+ +

+ Don't — Refer to Blockly as a language + (for example, as a "block-based programming language"). Blockly is not a + language, it's a library that developers use to make a block-based visual + programming interface. +

+ +## How to visually represent Blockly + +### Attributing Blockly with a logo + +To give Blockly attribution in your app or website, please use one of the +following logos, depending on background color: + +
+ + + + + + + + + + + + + + + + +
+ Built on Blockly white + + Built on Blockly black +
+ For light backgrounds with overlapping shapes or varied patterns, and + for solid dark backgrounds (no shapes or patterns) with high contrast. + For dark backgrounds with overlapping shapes or varied patterns.
+ + PNG + + + SVG + + + + PNG + + + SVG + +
+ +Please hyperlink the badge to Blockly's home page: [https://www.blockly.com](https://www.blockly.com) + +### Badge sizing and spacing + +
+
+

+ To ensure legibility, badges should not be used with a height smaller than + 24px. +

+

+ For lockups, provide at least x-height and width x1 white space around the + logo. Never crowd or overlap the logo with other elements. +

+
+
+ Blockly Badge + Blockly Badge +
+
+ +### Other uses of the Blockly logo + +Do not use the Blockly mark or any variant of the Blockly mark in conjunction +with the overall name of your application, product, service, or website without +permission from the Blockly team (please email support@blockly.com to +request permission). Do not alter or use the Blockly mark in a way that may be +confusing or misleading, and never use Blockly branding as the most prominent +element on your page. + + + + + + +
+ Standard Blockly logo + +

Standard lockup

+

The standard lockup can be used in slide decks and blog posts.

+

+ Whenever possible, the logo should be represented as a horizontal lockup + with a full color logomark and neutral 700 (#5F6368) or solid white + logotype. +

+ + PNG + + + SVG + +
+ + + + + + + + + + + + + + + + + + + +
+ Blockly vertical logo + + Blockly logomark + + Blockly knockout logo +
+ When there is limited horizontal space, a vertical lockup can be used + with the full color logomark and neutral 700 (#5F6368) or solid white + logotype. + + When there is limited vertical and horizontal space, the logomark can be + used by itself without the logotype. + + When the color of the logomark has poor contrast with the background, a + solid white knockout version can be used. +
+ + PNG + + + SVG + + + + PNG + + + SVG + + + + PNG + + + SVG + +
+ +### Logo colours + + + + + + + + + + + + + + +
+ Blockly blue +

#4285f4 or hsla(217, 89%, 61%, 1)

+
+ Blockly gray +

#c8d1db or hsla(212, 21%, 82%, 1)

+
+ Neutral 700 +

#5f6368 or hsla(213, 5%, 39%, 1)

+
+ +
+
+

Sizing and spacing

+

+ To ensure legibility, the logo should not be used with a height smaller + than 24px. +

+

+ For lockups, provide at least x-height x2 white space around the logo. + Never crowd or overlap the logo with other elements. +

+

Common errors

+ Do not... +
    +
  • Alter or distort the logo in any way
  • +
  • Use the white knockout in any color but white
  • +
  • Alter color, shape, or angles
  • +
  • Rotate or flip in any direction
  • +
  • Alter proportions, positioning, or placement
  • +
  • Replace the logotype with a different typeface
  • +
  • + Use the old Blockly logo (existing uses should be updated when + convenient) +
  • +
  • + Use the logo on a poorly contrasting background (e.g. the knockout logo + on a light gray background) +
  • +
  • Overlap or crowd the logo with other elements
  • +
  • Redraw the logo
  • +
+
+
+ Height references for padding the logo +
+
diff --git a/packages/docs/docs/guides/app-integration/run-code.mdx b/packages/docs/docs/guides/app-integration/run-code.mdx new file mode 100644 index 00000000000..a13e75dd1ea --- /dev/null +++ b/packages/docs/docs/guides/app-integration/run-code.mdx @@ -0,0 +1,151 @@ +--- +description: How to generate and run code for all blocks. +title: Generate and run code +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Generate and run code + +Your application can generate code at any time. For example, it might generate +code when the end user clicks a button or every time the user makes a change. + +For an overview of code generation, see [Code +generation](/guides/create-custom-blocks/code-generation/overview). + +## Import a language code generator + +To generate code, you need a language code generator. You can import language +code generators with any of the following methods. + + + + ```js + import {javascriptGenerator} from 'blockly/javascript'; + import {pythonGenerator} from 'blockly/python'; + import {phpGenerator} from 'blockly/php'; + import {luaGenerator} from 'blockly/lua'; + import {dartGenerator} from 'blockly/dart'; + + // Generate code for all the blocks in the workspace. + const jsCode = javascriptGenerator.workspaceToCode(workspace); + const pythonCode = pythonGenerator.workspaceToCode(workspace); + const phpCode = phpGenerator.workspaceToCode(workspace); + const luaCode = luaGenerator.workspaceToCode(workspace); + const dartCode = dartGenerator.workspaceToCode(workspace); + ``` + + + You must include the generator after you include Blockly. + + ```html + + + + + + + ``` + + ```js + // Generate code for all the blocks in the workspace. + const jsCode = javascript.javascriptGenerator.workspaceToCode(workspace); + const pythonCode = python.pythonGenerator.workspaceToCode(workspace); + const phpCode = php.phpGenerator.workspaceToCode(workspace); + const luaCode = lua.luaGenerator.workspaceToCode(workspace); + const dartCode = dart.dartGenerator.workspaceToCode(workspace); + ``` + + + You must include the generator after you include Blockly. + + ```html + + + + + + + ``` + + ```js + // Generate code for all the blocks in the workspace. + const jsCode = javascript.javascriptGenerator.workspaceToCode(workspace); + const pythonCode = python.pythonGenerator.workspaceToCode(workspace); + const phpCode = php.phpGenerator.workspaceToCode(workspace); + const luaCode = lua.luaGenerator.workspaceToCode(workspace); + const dartCode = dart.dartGenerator.workspaceToCode(workspace); + ``` + + +## Generate code + +To generate code, use the generator's `workspaceToCode` function. + +```js +const code = javascriptGenerator.workspaceToCode(workspace); +``` + +### Continuous updates + +Continuous updates allow you to show or run the code whenever the user makes a +change. Generating code is a fast operation, so there's little performance +impact for doing this. This is done using an [event listener][event]. + +```js +const supportedEvents = new Set([ + Blockly.Events.BLOCK_CHANGE, + Blockly.Events.BLOCK_CREATE, + Blockly.Events.BLOCK_DELETE, + Blockly.Events.BLOCK_MOVE, +]); + +function updateCode(event) { + if (workspace.isDragging()) return; // Don't update while changes are happening. + if (!supportedEvents.has(event.type)) return; + + const code = javascriptGenerator.workspaceToCode(workspace); + document.getElementById('textarea').value = code; +} + +workspace.addChangeListener(updateCode); +``` + +## Add preamble or postscript code + +After you've generated your code you can optionally include code before the +start or after the end of the generated code. + +```js +let code = javascriptGenerator.workspaceToCode(workspace); +// Add a preamble and a postscript to the code. +const preamble = 'import {MyLibrary} from \'/path/to/my/library\';\n' +const postscript = 'MyLibrary.myKickoffFunction();\n'; +code = preamble + code + postscript; +``` + +Preamble code is usually used to include external definitions at the beginning +of the code. Postscript code is usually used to call functions to kick off +behavior at the end of the code. + +If your generated code is runnable as-is, then there's no need to include a +preamble or a postscript. + +## Execute code + +After you've generated the code, you need to figure out how to execute it. +Deciding how to execute it is very application-specific, and outside the scope +of Blockly. + +If you want to execute JavaScript code, see [Generate and run +JavaScript](/guides/app-integration/running-javascript). This discusses +some special features of the JavaScript code generator, as well as +[JSInterpreter][jsinterpreter], which the Blockly team recommends as a way to +safely execute JavaScript. + +Other languages require other tools. + +[event]: /guides/configure/web/events +[jsinterpreter]: https://github.com/NeilFraser/JS-Interpreter diff --git a/packages/docs/docs/guides/app-integration/running-javascript.mdx b/packages/docs/docs/guides/app-integration/running-javascript.mdx new file mode 100644 index 00000000000..dfec8d90c58 --- /dev/null +++ b/packages/docs/docs/guides/app-integration/running-javascript.mdx @@ -0,0 +1,221 @@ +--- +description: Advanced methods for evaluating generated JavaScript code. +title: Generate and run JavaScript +image: images/blockly_banner.png +--- + +# Generate and run JavaScript + +Blockly applications often generate JavaScript as their output language, +generally to run within a web page (possibly the same, or a embedded WebView). +Like any generator, the first step is to include the JavaScript generator. + +```js +import { javascriptGenerator } from 'blockly/javascript'; +``` + +To generate JavaScript from the workspace, call: + +```js +javascriptGenerator.addReservedWords('code'); +var code = javascriptGenerator.workspaceToCode(workspace); +``` + +The resulting code can be executed right in the destination web page: + +:::warning +Executing JavaScript with `eval` is a [serious security +risk](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) +and should be done only during prototyping. In a production application, use a +sandboxed JavaScript interpreter such as [JS-interpreter](#js-interpreter). +::: + +```js +try { + eval(code); +} catch (e) { + alert(e); +} +``` + +Basically, the above snippet just generates the code and evals it. However, +there are a couple of refinements. One refinement is that the eval is wrapped in +a `try`/`catch` so that any runtime errors are visible, instead of failing +quietly. Another refinement is that `code` is added to the list of reserved +words so that if the user's code contains a variable of that name it will be +automatically renamed instead of colliding. Any local variables should be +reserved in this way. + +## Highlight Blocks + +Highlighting the currently executing block as the code runs helps users +understand their program's behaviour. Highlighting may be done on a +statement-by-statement level by setting `STATEMENT_PREFIX` prior to +generating the JavaScript code: + +```js +javascriptGenerator.STATEMENT_PREFIX = 'highlightBlock(%1);\n'; +javascriptGenerator.addReservedWords('highlightBlock'); +``` + +Define `highlightBlock` to mark the block on the workspace. + +```js +function highlightBlock(id) { + workspace.highlightBlock(id); +} +``` + +This results in the statement `highlightBlock('123');` being added to before +every statement, where `123` is the serial number of the block to be +highlighted. + +## Infinite Loops + +Although the resulting code is guaranteed to be syntactically correct at all +times, it may contain infinite loops. Since solving the +[Halting problem](https://en.wikipedia.org/wiki/Halting_problem) is beyond +Blockly's scope (!) the best approach for dealing with these cases is to +maintain a counter and decrement it every time an iteration is performed. +To accomplish this, just set `javascriptGenerator.INFINITE_LOOP_TRAP` to a code +snippet which will be inserted into every loop and every function. Here is an +example: + +```js +window.LoopTrap = 1000; +javascriptGenerator.INFINITE_LOOP_TRAP = + 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n'; +var code = javascriptGenerator.workspaceToCode(workspace); +``` + +## Example + +Here is [a live +demo](https://raspberrypifoundation.github.io/blockly-samples/examples/generator-demo/) of +generating and executing JavaScript. + +## JS-Interpreter + +If you are serious about running the user's blocks properly, then the +[JS-Interpreter project](https://github.com/NeilFraser/JS-Interpreter) is the way to go. +This project is separate from Blockly, but was specifically written for Blockly. + +- Execute code at any speed. +- Pause/resume/step-through execution. +- Highlight blocks as they execute. +- Completely isolated from browser's JavaScript. + +### Run the Interpreter + +First, download the JS-Interpreter from GitHub: + +- [Download zip file](https://github.com/NeilFraser/JS-Interpreter/zipball/master) +- [Download tar file](https://github.com/NeilFraser/JS-Interpreter/tarball/master) +- [View on GitHub](https://github.com/NeilFraser/JS-Interpreter) + +Then add it to your page: + +```html + +``` + +The simplest method of calling it is to generate the JavaScript, create the +interpreter, and run the code: + +```js +var code = javascriptGenerator.workspaceToCode(workspace); +var myInterpreter = new Interpreter(code); +myInterpreter.run(); +``` + +### Step the Interpreter + +In order to execute the code slower, or in a more controlled manner, replace the +call to `run` with a loop that steps (in this case one step every 10ms): + +```js +function nextStep() { + if (myInterpreter.step()) { + setTimeout(nextStep, 10); + } +} +nextStep(); +``` + +Note that each step is not a line or a block, it is a semantic unit in +JavaScript, which may be extremely fine-grained. + +### Add an API + +The JS-Interpreter is a sandbox that is completely isolated from the browser. +Any blocks that perform actions with the outside world require an API added to +the interpreter. For a full description, see the +[JS-Interpreter documentation](https://neil.fraser.name/software/JS-Interpreter/docs.html). +But to start with, here is the API needed to support the alert and prompt blocks: + +```js +function initApi(interpreter, globalObject) { + // Add an API function for the alert() block. + var wrapper = function (text) { + return alert(arguments.length ? text : ''); + }; + interpreter.setProperty( + globalObject, + 'alert', + interpreter.createNativeFunction(wrapper), + ); + + // Add an API function for the prompt() block. + wrapper = function (text) { + return prompt(text); + }; + interpreter.setProperty( + globalObject, + 'prompt', + interpreter.createNativeFunction(wrapper), + ); +} +``` + +Then modify your interpreter initialization to pass in the initApi function: + +```js +var myInterpreter = new Interpreter(code, initApi); +``` + +The alert and prompt blocks are the only two blocks in the default set of blocks +that require a custom API for the interpreter. + +### Connecting `highlightBlock()` + +When running in JS-Interpreter, `highlightBlock()` should be executed +immediately, outside the sandbox, as the user steps through the program. To do +this, create a wrapper function `highlightBlock()` to capture the function +argument, and register it as a native function. + +```js +function initApi(interpreter, globalObject) { + // Add an API function for highlighting blocks. + var wrapper = function (id) { + return workspace.highlightBlock(id); + }; + interpreter.setProperty( + globalObject, + 'highlightBlock', + interpreter.createNativeFunction(wrapper), + ); +} +``` + +More sophisticated applications might wish to repeatedly execute steps without +pause until a highlight command is reached, then pause. This strategy simulates +line-by-line execution. The example below uses this approach. + +### JS-Interpreter Example + +Here is [a live +demo](https://raspberrypifoundation.github.io/blockly-samples/examples/interpreter-demo/step-execution.html) +of interpreting JavaScript step by step. And [this +demo](https://raspberrypifoundation.github.io/blockly-samples/examples/interpreter-demo/async-execution.html) +includes a wait block, a good example to use for other asynchronous behavior +(e.g., speech or audio, user input). diff --git a/packages/docs/docs/guides/configure/web/appearance/block-colour.mdx b/packages/docs/docs/guides/configure/web/appearance/block-colour.mdx new file mode 100644 index 00000000000..c1047a22777 --- /dev/null +++ b/packages/docs/docs/guides/configure/web/appearance/block-colour.mdx @@ -0,0 +1,63 @@ +--- +description: How to apply colours to a block. +title: Block colours +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Block colours + +Most Blockly apps use a variety of block colours to visually group the blocks +into categories. The blocks shipped with Blockly include several categories, +with the colours mirrored by the various toolbar categories in the demos: + +![A screenshot of a workspace with an example of each block +colour.](/images/standard-block-colors.png) + +Additional colours on the block are derived from the main colour. For example, +[shadow blocks](/guides/configure/web/toolboxes/preset#shadow-blocks) +are a desaturated version of the main colour, and border colours are a darker +version. + +:::tip +If you want more control over shadow block or border colours, learn about +[defining a theme](/guides/configure/web/appearance/themes). +::: + +## Set block colour + +The primary colour of a block can be defined in either JSON or JavaScript. You +can pass the hue (preferred), RGB value, or color name; for more information, +see [Colour formats](/guides/configure/web/appearance/colour-formats). + + + + ```js + { + // ..., + "colour": 160, + } + ``` + + + ```js + init: function() { + // ... + this.setColour(160); + } + ``` + + +Note the British spelling. Failure to set the colour results in a black block. + +You can also set the block color using the +[`Block.setColour(..)`](/reference/blockly.block_class.setcolour_1_method) +function, or by using [themes](/guides/configure/web/appearance/themes) +and defining a block style. + +## Accessibility + +For information about how colour affects accessibility, see [Colour and +accessibility](/guides/configure/web/colour-a11y) diff --git a/packages/docs/docs/guides/configure/web/appearance/colour-formats.mdx b/packages/docs/docs/guides/configure/web/appearance/colour-formats.mdx new file mode 100644 index 00000000000..49025227ddf --- /dev/null +++ b/packages/docs/docs/guides/configure/web/appearance/colour-formats.mdx @@ -0,0 +1,95 @@ +--- +description: Describes Blockly's colour formats and how to reference them. +title: Colour formats +image: images/blockly_banner.png +--- + +# Colour formats + +Colour values can be given in HSV or RGB format or using a colour name. + +## Hue-Saturation-Value + +The simplest way to define a colour is a number between 0-360, defining +the hue in the +[hue-saturation-value](https://en.wikipedia.org/wiki/HSL_and_HSV) (HSV) colour +model. + +![HSV colour spectrum](/images/hsv.png) + +Using HSV with saturation and value fixed for all block colours lets you select +a block colour while ensuring all blocks share a cohesive palette. + +The saturation and values can be adapted for each application by calling the +following functions: + +```js +Blockly.utils.colour.setHsvSaturation(0.45); // 0 (inclusive) to 1 (exclusive), defaulting to 0.45 +Blockly.utils.colour.setHsvValue(0.65); // 0 (inclusive) to 1 (exclusive), defaulting to 0.65 +``` + +Several colour pickers offer the HSV colour space, such as [HSV +picker](http://www.rapidtables.com/web/color/color-picker.htm). Enter Blockly's +saturation and value constants (the defaults are 45% and 65% respectively), then +slide the hue to a chosen colour. Use this hue number as the `colour` value. + +## RGB + +Using the HSV colour space is highly recommended, but Blockly does support +colours specified as `#RRGGBB` hexadecimal strings. While this can facilitate +coordination with other application colours (e.g., styles in CSS) and design +applications (e.g., Photoshop), it is a design risk that could lead to +uncoordinated blocks if not chosen carefully. + +![An example of poorly selected colours.](/images/fruit-salad.png) + +Unless you have dedicated visual design resources, working within the +constraints of the HSV colour space is recommended. If attempting to redefine +all colours in this manner, consider [Google's Material Design resources on +colour](https://material.io/guidelines/style/color.html). + +## Colour names + +You can also specify colours using the [colour names defined by the +W3C](https://www.w3.org/TR/css-color-3/#html4). + +## Colour references + +Often, multiple blocks share the same colour, and centralizing the colour +definitions simplifies managing the colours and adding new blocks of the correct +colour. Block colours and toolbox categories can use [localization +tokens](/guides/configure/web/translations#use-localization-tokens-in-json) +to do exactly that. + +Blockly includes nine colour constants in the string table, corresponding to the +toolbox categories, plus a distinct colour for dynamic variables: + +```js +'%{BKY_LOGIC_HUE}'; +'%{BKY_LOOPS_HUE}'; +'%{BKY_MATH_HUE}'; +'%{BKY_TEXTS_HUE}'; +'%{BKY_LISTS_HUE}'; +'%{BKY_COLOUR_HUE}'; +'%{BKY_VARIABLES_HUE}'; +'%{BKY_VARIABLES_DYNAMIC_HUE}'; +'%{BKY_PROCEDURES_HUE}'; +``` + +These string values can be used in both the JSON definitions and +[`block.setColour(..)`](/reference/blockly.block_class.setcolour_1_method). + +You can add your own colour constants by adding to `Blockly.Msg`: + +```js +// Define the colour +Blockly.Msg['EVERYTHING_HUE'] = '42'; +// Use in a block or block definition: +block.setColour('%{BKY_EVERYTHING_HUE}'); +``` + +Storing the colours in the localization string table may seem unusual, but it +is convenient given the JSON notation already has support for the references. It +also allows [colours to be +localized](https://web.archive.org/web/20220905211610/http://translation-blog.multilizer.com/color-localization-infographics/), +if needed. diff --git a/packages/docs/docs/guides/configure/web/appearance/css.mdx b/packages/docs/docs/guides/configure/web/appearance/css.mdx new file mode 100644 index 00000000000..942d61e8a5d --- /dev/null +++ b/packages/docs/docs/guides/configure/web/appearance/css.mdx @@ -0,0 +1,368 @@ +--- +description: Customizing the look and feel of your application with CSS. +title: Style with CSS +image: images/blockly_banner.png +--- + +# Style with CSS + +Blockly applications are constructed of HTML and SVG elements. These elements +are labeled with CSS classes that identify what they represent (e.g. +`blocklyBlock`, `blocklyField`) as well as their state (e.g. `blocklyEditing`, +`blocklySelected`). Blockly also provides a default set of CSS rules. + +You can use CSS to style your application: + +- Override Blockly's CSS rules with your own rules. +- Add your own CSS classes to Blockly components for additional specificity. +- Use CSS classes and rules to style custom components. + +For a practical introduction to using CSS in blockly, see the [Use CSS in Blockly](/codelabs/css/codelab-overview/index.html) + +:::note +The easiest way to style Blockly is with [themes](/guides/configure/web/appearance/themes). If you need finer-grained control, use CSS. +::: + +## CSS classes + +Blockly applications use CSS classes to identify elements to be styled. This +provides finer-grained control than type (element) selectors. + +### Blockly CSS classes + +Blockly uses CSS classes to provide the following kinds of information about the +HTML and SVG elements it uses. + +- **Type.** Most Blockly CSS classes identify what an element represents. For + example, the root element of a block is labeled `blocklyBlock`. Some + elements are labeled with multiple classes, each more specific than the + last. For example, the root element of a text input field is labeled + `blocklyField`, `blocklyInputField`, and `blocklyTextInputField`. Type + classes remain the same for the life of a component. + +- **State.** Blockly also uses CSS classes to specify the state of a + component. For example, when the cursor is on a text input field, its root + element is labeled with the `blocklyEditing` class. When the cursor is moved + away, this class is removed. + +- **Additional information.** Blockly uses a few CSS classes to provide + additional information. For example, the injection `
` has classes that + provide the name of the workspace's current renderer and theme. These + classes generally remain the same for the life of the application. + +The easiest way to discover what CSS classes Blockly uses is to open your +browser's developer tools and inspect the elements used by your application. + +### Custom CSS classes + +You can use custom CSS classes to provide more specificity to Blockly +components. + +#### Workspaces + +To add or remove a CSS class from a workspace's injection `
`, call +`WorkspaceSvg.addClass` or `WorkspaceSvg.removeClass`. + +#### Toolboxes + +To add a CSS class to a button or a label in a toolbox, use the `web-class` key +in your JSON definition of the toolbox. For more information, see [Buttons and +labels](/guides/configure/web/toolboxes/buttons). + +To override the CSS classes used for the various parts of a category, use the +`cssConfig` key in your JSON definition of the category. This allows you to +style individual categories. For more information, see [Category +CSS](/guides/configure/web/toolboxes/appearance#category-css). + +#### Blocks + +To add CSS classes to a custom block, pass a string or array of strings to the +`classes` key. + +```js +Blockly.common.defineBlocksWithJsonArray([ + { + type: 'string_length', + message0: 'length of %1', + args0: [ + { + type: 'input_value', + name: 'VALUE', + check: 'String', + }, + ], + classes: 'myStringLengthBlock', + output: 'Number', + colour: 160, + }, +]); +``` + +You can also add or remove a CSS class from a block's `` element by calling +`BlockSvg.addClass` or `BlockSvg.removeClass`. + +#### Label fields + +To add or remove a CSS class from the `` element used by a label field or +serializable label field, call `FieldLabel.setClass`. You can also pass a class +name to the label's constructor. + +### CSS classes and custom components + +When constructing a custom component, use one of the following methods to add +custom CSS classes: + +- If your component is a subclass of `Field` or `Icon`, override the + `initView` method. For example: + + ```js + class MyCustomField extends Blockly.FieldTextInput { + ... + + initView() { + super.initView(); + + // Add custom CSS class so we can style the field. + if (this.fieldGroup_) { + Blockly.utils.dom.addClass(this.fieldGroup_, 'myCustomField'); + } + } + } + ``` + + For more information, see [Customizing fields with + CSS](/guides/create-custom-blocks/fields/customizing-fields/creating#customizing-with-css) + or [Create the icon's + view](/guides/create-custom-blocks/icons/creating-custom-icons/basic-implementation#create-the-icons-view). + +- When constructing an SVG element, pass your class to + `Blockly.utils.dom.createSvgElement`: + + ```js + this.svgRoot = Blockly.utils.dom.createSvgElement(Svg.G, { + class: 'myCustomComponent', + }); + ``` + +- When constructing an HTML element, use `Blockly.utils.dom.addClass`: + + ```js + const myDiv = document.createElement('div'); + Blockly.utils.dom.addClass(myDiv, 'myInformation'); + ``` + +To add or remove classes after construction, use `Blockly.utils.dom.addClass` or +`Blockly.utils.dom.removeClass`. + +```js +setMyHighlight(highlight) { + if (highlight) { + Blockly.utils.dom.addClass(this.svgRoot, 'myHighlight'); + } else { + Blockly.utils.dom.removeClass(this.svgRoot, 'myHighlight'); + } +} +``` + +:::warning +Do not use `dom.addClass` or `dom.removeClass` to add classes to or +remove classes from components written by others, including Blockly. This might +lead to unpredictable results. +::: + +## CSS rules background + +If you understand SVG styling properties and the CSS cascade, you can +[skip](#css-rules) this section. + +### SVG styling properties versus CSS properties \{#svg-style\} + +SVG elements are styled with [SVG styling +properties](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute#presentation_attributes). +These can be used as attributes on SVG elements (aka **presentation +attributes**) or in CSS rules. Thus, all of the following do the same thing. + +```svg + + +``` + +```svg + + + +``` + +```css +/* External CSS file.*/ +circle { + fill: red; +} +``` + +```svg + + +``` + +The list of SVG styling properties is related to but different from the list of +CSS properties: + +- **Same concept, same name.** For example, both SVG and CSS use `direction` + to specify whether text is LTR or RTL. +- **Same concept, different name.** For example, SVG uses `fill` to specify + fill color; CSS uses `background-color`. +- **CSS only.** CSS has many properties that are not in SVG, such as `margin` + and `padding`. +- **SVG only.** SVG has a few properties that are not in CSS, such as `x` and + `y`. + +Thus, if you're styling an SVG element, use [SVG styling +properties](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute#presentation_attributes). +If you're styling an HTML element, use [CSS +properties](https://www.w3schools.com/CSSref/index.php). + +### CSS cascade + +The [CSS +cascade](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Cascade#cascading_order) +determines the _priorities_ of CSS rules, which determine which rule to use if +more than one rule applies to a given property and element. The following +simplified cascade covers the parts of the cascade most commonly used by Blockly +and may help you resolve the question, "Why doesn't my CSS work?" + +#### Simplified cascade \{#simplified\} + +To determine which rule applies to a particular element and property, follow +these steps and stop when only one rule remains: + +1. Gather all the rules that apply to the property and element. +1. If any rules have an `!important` annotation, discard all rules that don't + have an `!important` annotation. +1. Choose the rules with the highest + [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity). + - [SVG presentation attributes](#svg-style) have a specificity of zero. + - Rules in a ` +``` + +You may specify a CSS class name to apply to your button or label. +In the above example, the first label uses a custom style, while the second +label uses the default style. + +Buttons should have callback functions; labels should not. To set the callback +for a given button click, use + +```js +yourWorkspace.registerButtonCallback(yourCallbackKey, yourFunction). +``` + +Your function should accept as an argument the button that was clicked. +The "Create variable..." button in the variable category is a good example of a +button with a callback. diff --git a/packages/docs/docs/guides/configure/web/toolboxes/category.mdx b/packages/docs/docs/guides/configure/web/toolboxes/category.mdx new file mode 100644 index 00000000000..87977baca8b --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/category.mdx @@ -0,0 +1,95 @@ +--- +description: How to define a category toolbox, which arranges sets of blocks into categories. +title: Define a category toolbox +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Define a category toolbox + +A category toolbox has multiple sets of blocks that are arranged into different +categories. + +![A category toolbox with Control and Logic categories. The Logic category is +open and the flyout toolbox contains comparison, and-or, and true-false +blocks.](/images/toolbox-categories.png) + +To create a category toolbox, pass JSON or XML describing the toolbox to the +`toolbox` property of the [configuration +options](/guides/configure/web/configuration_struct#the-options-dictionary). + + + + ```js + var toolbox = { + "kind": "categoryToolbox", + "contents": [ + { + "kind": "category", + "name": "Control", + "contents": [ + { + "kind": "block", + "type": "controls_if" + }, + ] + }, + { + "kind": "category", + "name": "Logic", + "contents": [ + { + "kind": "block", + "type": "logic_compare" + }, + { + "kind": "block", + "type": "logic_operation" + }, + { + "kind": "block", + "type": "logic_boolean" + } + ] + } + ] + }; + var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox}); + ``` + + + ```xml + + + ``` + + + ```js + var toolbox = ''; + var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox}); + ``` + + diff --git a/packages/docs/docs/guides/configure/web/toolboxes/disable-categories.mdx b/packages/docs/docs/guides/configure/web/toolboxes/disable-categories.mdx new file mode 100644 index 00000000000..870fafdde60 --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/disable-categories.mdx @@ -0,0 +1,85 @@ +--- +description: How to disable, hide, or expand categories in a category toolbox. +title: Disable, hide, or expand categories +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Disable, hide, or expand categories + +You can disable, hide, or expand categories. + +## Disable categories + +A disabled category will not allow a user to open the category and it will be +skipped during keyboard navigation. + +```js +var category = toolbox.getToolboxItems()[0]; +category.setDisabled('true'); +``` + +When a category is disabled, a `'disabled'` property is added to the DOM +element, which allows you to control the look of a disabled category. + +```css +.blocklyToolboxCategoryContainer[disabled='true'] { + opacity: 0.5; +} +``` + +## Hide categories + +A hidden category will not be shown as part of the toolbox. + + + + ```js + { + "kind": "category", + "name": "...", + "hidden": "true", + } + ``` + + + ```xml + + ``` + + +Hidden categories can later be shown via JavaScript. + +```js +var category = toolbox.getToolboxItems()[0]; +category.hide(); +// etc... +category.show(); +``` + +## Expand categories + +This only applies to categories which contain other [nested +categories](/guides/configure/web/toolboxes/nested). + +An expanded category will show you its sub categories. By default, nested +categories are collapsed, and need to be clicked to be expanded. + + + + ```js + { + "kind": "category", + "name": "...", + "expanded": "true", + } + ``` + + + ```xml + + ``` + + diff --git a/packages/docs/docs/guides/configure/web/toolboxes/dynamic.mdx b/packages/docs/docs/guides/configure/web/toolboxes/dynamic.mdx new file mode 100644 index 00000000000..b45ced377dd --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/dynamic.mdx @@ -0,0 +1,136 @@ +--- +description: How to create dynamic categories in a toolbox. +title: Dynamic categories +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Dynamic categories + +Dynamic categories are categories that are dynamically repopulated based on a +function each time they are opened. + +Blockly supports this by allowing you to associate a category with a function +via a registered string key. The function should return a definition of a +category's contents (including blocks, buttons, labels, etc). The contents can +be specified as JSON or XML, although JSON is recommended. + +Also note that the function is provided the target workspace as a parameter, so +the blocks in your dynamic category can be based on the state of the workspace. + + + + ```js + // Returns an array of objects. + var coloursFlyoutCallback = function(workspace) { + // Returns an array of hex colours, e.g. ['#4286f4', '#ef0447'] + var colourList = getPalette(); + var blockList = []; + for (var i = 0; i < colourList.length; i++) { + blockList.push({ + 'kind': 'block', + 'type': 'colour_picker', + 'fields': { + 'COLOUR': colourList[i] + } + }); + } + return blockList; + }; + + // Associates the function with the string 'COLOUR_PALETTE' + myWorkspace.registerToolboxCategoryCallback( + 'COLOUR_PALETTE', coloursFlyoutCallback); + ``` + + + ```js + // Returns an array of XML nodes. + var coloursFlyoutCallback = function(workspace) { + // Returns an array of hex colours, e.g. ['#4286f4', '#ef0447'] + var colourList = getPalette(); + var blockList = []; + for (var i = 0; i < colourList.length; i++) { + var block = document.createElement('block'); + block.setAttribute('type', 'colour_picker'); + var field = document.createElement('field'); + field.setAttribute('name', 'COLOUR'); + field.innerText = colourList[i]; + block.appendChild(field); + blockList.push(block); + } + return blockList; + }; + + // Associates the function with the string 'COLOUR_PALETTE' + myWorkspace.registerToolboxCategoryCallback( + 'COLOUR_PALETTE', coloursFlyoutCallback); + ``` + + +After the dynamic category functions are associated with a string key (aka +registered) you can assign this string key to the `custom` property of +your category definition to make the category dynamic. + + + + ```js + { + "kind": "category", + "name": "Colours", + "custom": "COLOUR_PALETTE" + } + ``` + + + ```xml + + ``` + + +## Built-in dynamic categories + +Blockly provides three built-in dynamic categories. + +- `'VARIABLE'` creates a category for [_untyped_ variables][untyped-variable]. +- `'VARIABLE_DYNAMIC'` creates a category for + [_typed_ variables][typed-variable]. It has buttons to create strings, + numbers, and colours. +- `'PROCEDURE'` creates a category for function blocks. + + + + ```js + { + "kind": "category", + "name": "Variables", + "custom": "VARIABLE" + }, + { + "kind": "category", + "name": "Variables", + "custom": "VARIABLE_DYNAMIC" + }, + { + "kind": "category", + "name": "Functions", + "custom": "PROCEDURE" + } + ``` + + + ```xml + + + + ``` + + +_Note: The word 'procedure' is used throughout the Blockly codebase, but the +word 'function' has found to be more understandable by students. +Sorry for the mismatch._ + +[untyped-variable]: /guides/create-custom-blocks/variables#untyped-variable-blocks +[typed-variable]: /guides/create-custom-blocks/variables#typed-variable-blocks diff --git a/packages/docs/docs/guides/configure/web/toolboxes/flyout.mdx b/packages/docs/docs/guides/configure/web/toolboxes/flyout.mdx new file mode 100644 index 00000000000..09f2647304c --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/flyout.mdx @@ -0,0 +1,61 @@ +--- +description: How to define a flyout toolbox, which displays a single set of blocks. +title: Define a flyout toolbox +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Define a flyout toolbox + +A flyout toolbox has a single set of blocks that are displayed at all times. + +![A workspace with a flyout toolbox containing two +blocks.](/images/toolbox-minimal.png) + +To create a flyout toolbox, pass JSON or XML describing the toolbox to the +`toolbox` property of the [configuration +options](/guides/configure/web/configuration_struct#the-options-dictionary). + + + + ```js + var toolbox = { + "kind": "flyoutToolbox", + "contents": [ + { + "kind": "block", + "type": "controls_if" + }, + { + "kind": "block", + "type": "controls_whileUntil" + } + ] + }; + var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox}); + ``` + + + ```xml + + + ``` + + + ```js + var toolbox = '' + + '' + + '' + + ''; + var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox}); + ``` + + diff --git a/packages/docs/docs/guides/configure/web/toolboxes/modify.mdx b/packages/docs/docs/guides/configure/web/toolboxes/modify.mdx new file mode 100644 index 00000000000..6a27fda92aa --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/modify.mdx @@ -0,0 +1,37 @@ +--- +description: How to modify a toolbox programmatically. +title: Modify toolboxes +image: images/blockly_banner.png +--- + +# Modify toolboxes + +The application may change the blocks available in the toolbox at any time with +a single function call: + +```js +workspace.updateToolbox(newTree); +``` + +As was the case during initial configuration, `newTree` may either be a tree of +nodes, a string representation, or a JSON object. The only restriction is that +the mode cannot be changed; that is if there were categories in the +initially-defined toolbox then the new toolbox must also have categories +(though the categories may change). Likewise, if the initially-defined toolbox +did not have any categories, then the new toolbox may not have any categories. + +The contents of a single category can be updated by: + +```js +var category = workspace.getToolbox().getToolboxItems()[0]; +category.updateFlyoutContents(flyoutContents); +``` + +Where `flyoutContents` can be a list of blocks defined using JSON, a tree of nodes, +or a string representation. + +Be aware that at this time updating the toolbox causes some minor UI resets: + +- In a toolbox without categories, any fields changed by the user (such as a dropdown) will revert to the default. + +Here is [a live demo](https://raspberrypifoundation.github.io/blockly-samples/examples/toolbox-demo/) of a tree with categories and block groups. diff --git a/packages/docs/docs/guides/configure/web/toolboxes/nested.mdx b/packages/docs/docs/guides/configure/web/toolboxes/nested.mdx new file mode 100644 index 00000000000..f8fa89eb1a1 --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/nested.mdx @@ -0,0 +1,93 @@ +--- +description: How to nest toolbox categories. +title: Nested categories +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Nested categories + +Categories may be nested within other categories. Here are two top-level +categories ('Core' and 'Custom'), the second of which contains two sub-categories, +each of which contain blocks: + +Note that it is possible for a category to contain both sub-categories _and_ +blocks. In the following example, `Custom` has two sub-categories (`Move` and +`Turn`), as well as a block of its own (`start`). + + + + ```js + { + "kind": "categoryToolbox", + "contents": [ + { + "kind": "category", + "name": "Core", + "contents": [ + { + "kind": "block", + "type": "controls_if" + }, + { + "kind": "block", + "type": "logic_compare" + }, + ] + }, + { + "kind": "category", + "name": "Custom", + "contents": [ + { + "kind": "block", + "type": "start" + }, + { + "kind": "category", + "name": "Move", + "contents": [ + { + "kind": "block", + "type": "move_forward" + } + ] + }, + { + "kind": "category", + "name": "Turn", + "contents": [ + { + "kind": "block", + "type": "turn_left" + } + ] + } + ] + } + ] + } + ``` + + + ```xml + + ``` + + diff --git a/packages/docs/docs/guides/configure/web/toolboxes/preset.mdx b/packages/docs/docs/guides/configure/web/toolboxes/preset.mdx new file mode 100644 index 00000000000..595361d8d20 --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/preset.mdx @@ -0,0 +1,310 @@ +--- +description: How to preset the configuration of blocks in the toolbox +title: Preset blocks +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Preset blocks + +You can configure (preset) the state of blocks in a toolbox. For example, you +can set a field to a default value or connect two blocks together. You can also +create [shadow blocks](#shadow-blocks), which serve as defaults for child +blocks. + +## Examples + +Here are some examples of preset blocks. + +### Block with a preset field value + +Here is a `math_number` block whose field displays the number 42 instead of the +default of 0: + +![A number block whose value is preset to 42.](/images/42.png) + +And here is a toolbox that sets this field: + + + + ```json + { + "kind": "flyoutToolbox", + "contents": [ + { + "kind": "block", + "type": "math_number", + "fields": { + "NUM": 42 + } + }, + ] + } + ``` + + + ```xml + + ``` + + +### Preconnected blocks + +Here is a `controls_for` block that has three `math_number` blocks connected to +it: + +![A "count with i from value to value by value" block. The three value inputs +are connected to number blocks with the values 1, 10, and +1.](/images/count-with.png) + +And here is a toolbox that preconnects these blocks: + + + + ```json + { + "kind": "flyoutToolbox", + "contents": [ + { + "kind": "block", + "type": "controls_for", + "inputs": { + "FROM": { + "block": { + "type": "math_number", + "fields": { + "NUM": 1 + } + } + }, + "TO": { + "block": { + "type": "math_number", + "fields": { + "NUM": 10 + } + } + }, + "BY": { + "block": { + "type": "math_number", + "fields": { + "NUM": 1 + } + } + }, + } + }, + ] + } + ``` + + + ```xml + + ``` + + +### Disabled blocks + +Disabled blocks cannot be dragged from the toolbox. Blocks can be individually +disabled using the optional `disabled` property. + +![A flyout menu with three blocks. The third block is disabled and is greyed +out.](/images/toolbox-disabled.png) + + + + ```json + { + "kind": "flyoutToolbox", + "contents": [ + { + "kind": "block", + "type":"math_number" + }, + { + "kind": "block", + "type": "math_arithmetic" + }, + { + "kind": "block", + "type": "math_single", + "disabled": "true" + } + ] + } + ``` + + + ```xml + + ``` + + +You can also programmatically disable or enable a block by using +[`setDisabledReason`](/reference/blockly.block_class.setdisabledreason_1_method). + +## Configure your blocks + +You can configure a block in a toolbox in any way that you can configure it in a +workspace. For example, you can set field values, connect blocks to value or +statement inputs, add comments, and collapse or disable blocks. This is possible +because toolboxes use the same code to configure blocks that workspaces use to +serialize them. + +It also means that it is easy to create a block configuration. Just load your +block into a workspace, configure it how you want, and serialize it by running +the following code in the console. + + + + ```js + console.log(Blockly.serialization.workspaces.save(Blockly.getMainWorkspace())); + ``` + + + ```xml console.log(Blockly.Xml.workspaceToDom(Blockly.getMainWorkspace())); + ``` + + +You can then copy the configuration code and paste it into your toolbox. Be sure +to remove the `x`, `y` and `id` properties, which are ignored by the toolbox. + +### Variable fields + +Variable fields may need to be specified differently when they are in a toolbox +versus when they are serialized. + +In particular, when variable fields are normally serialized to JSON, they only +contain the ID of the variable they represent, because the variable's name and +type are serialized separately. However, toolboxes do not contain that +information, so it needs to be included in the variable field directly. + +```js +{ + "kind": "flyoutToolbox", + "content": [ + { + "kind": "block", + "type": "controls_for", + "fields": { + "VAR": { + "name": "index", + "type": "Number" + } + } + } + ] +} +``` + +## Shadow blocks + +Shadow blocks are placeholder blocks that perform several functions: + +- They indicate the default values for their parent block. +- They allow users to type values directly without needing to fetch a number or string block. +- Unlike a regular block, they get replaced if the user drops a block on top of them. +- They inform the user of the type of value expected. + +:::note +Shadow blocks may not include a variable field or have children that are +not also shadows. +::: + +To create a shadow block, use `shadow` property (JSON) or the `` tag +(XML) instead of the `block` property or the `` tag. For example, here is +a `math_arithmetic` block that has two `math_number` shadow blocks connected to +it: + +![A `math_arithmetic` block with two value inputs separated by an operator +dropdown on which the plus operator is chosen. Each value input contains a +shadow number block, which is greyed out to show another block can replace +it.](/images/1plus1.png) + +And here is a toolbox that uses these shadow blocks: + + + + ```json + { + "kind": "flyoutToolbox", + "contents": [ + { + "kind": "block", + "type": "math_arithmetic", + "fields": { + "OP": "ADD" + }, + "inputs": { + "A": { + "shadow": { + "type": "math_number", + "fields": { + "NUM": 1 + } + } + }, + "B": { + "shadow": { + "type": "math_number", + "fields": { + "NUM": 1 + } + } + } + } + }, + ] + } + ``` + + + ```xml + + ``` + + diff --git a/packages/docs/docs/guides/configure/web/toolboxes/programmatic.mdx b/packages/docs/docs/guides/configure/web/toolboxes/programmatic.mdx new file mode 100644 index 00000000000..0a2fda33741 --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/programmatic.mdx @@ -0,0 +1,42 @@ +--- +description: How to access categories programmatically. +title: Programmatic access +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Programmatic access + +There are two ways you can access a category programmatically. You can either +access it by index (where 0 is the top category): + +```js +var category = toolbox.getToolboxItems()[0]; +``` + +Or by ID: + +```js +var category = toolbox.getToolboxItemById('categoryId'); +``` + +Where the ID is specified in the toolbox definition: + + + + ```js + { + "kind": "category", + "name": "...", + "toolboxitemid": "categoryId" + } + ``` + + + ```xml + + ``` + + diff --git a/packages/docs/docs/guides/configure/web/toolboxes/separators.mdx b/packages/docs/docs/guides/configure/web/toolboxes/separators.mdx new file mode 100644 index 00000000000..3ab7b1452ca --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/separators.mdx @@ -0,0 +1,98 @@ +--- +description: How to add separators to flyout and category toolboxes. +title: Separators +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Separators + +Adding a separator between any two categories will create a line and extra space +between the two categories. + +![A category menu with a vertical gap between two +categories.](/images/toolbox-separator.png) + +You can change the class for the separator in your JSON or XML toolbox definition. + + + + ```js + { + "kind": "sep", + "cssConfig": { + "container": "yourClassName" + } + } + ``` + + + ```xml + + ``` + + +Adding a separator between any two blocks will create a gap between the blocks. +By default every block is separated from its lower neighbour by 24 pixels. +This separation may be changed using the 'gap' attribute, which will replace the +default gap. + +This allows you to create logical groups of blocks in the toolbox. + +![A flyout toolbox with a vertical gap between a number block and a group of two +arithmetic blocks.](/images/toolbox-gap.png) + + + + ```js + { + "kind": "flyoutToolbox", + "contents": [ + { + "kind": "block", + "type":"math_number" + }, + { + "kind": "sep", + "gap": "32" + }, + { + "kind": "block", + "type"" "math_arithmetic" + "fields": { + "OP": "ADD" + }, + }, + { + "kind": "sep", + "gap": "8" + }, + { + "kind": "block", + "type"" "math_arithmetic" + "fields": { + "OP": "MINUS" + }, + } + ] + } + ``` + + + ```xml + + ``` + + diff --git a/packages/docs/docs/guides/configure/web/toolboxes/toolbox.mdx b/packages/docs/docs/guides/configure/web/toolboxes/toolbox.mdx new file mode 100644 index 00000000000..fdc9ce6dbce --- /dev/null +++ b/packages/docs/docs/guides/configure/web/toolboxes/toolbox.mdx @@ -0,0 +1,28 @@ +--- +description: Defining the toolbox, which allows users to access your blocks. +title: Toolboxes +image: images/blockly_banner.png +--- + +# Toolboxes + +The toolbox is the place where users get blocks. Usually it is displayed on one +side of the workspace. + +A [flyout toolbox](/guides/configure/web/toolboxes/flyout) has a single +set of blocks that are displayed at all times. A [category +toolbox](/guides/configure/web/toolboxes/category) has multiple sets of +blocks that are arranged into different categories. + +Toolboxes can be defined using JSON (as of the [September 2020 +release](https://github.com/RaspberryPiFoundation/blockly/releases/tag/3.20200924.0)) or XML. +The JSON format is preferred. + +This section mainly focuses on how to specify the _structure_ of your toolbox +(i.e. what categories it has, and what blocks they contain). If you want more +details about how to change the _appearance_ of your toolbox, see [Category +appearance](/guides/configure/web/toolboxes/appearance), the +[Customizing a Blockly toolbox +codelab](/codelabs/custom-toolbox/codelab-overview/index.html), +and the [2021 Toolbox APIs +talk](https://www.youtube.com/watch?v=JJVX_YuKDbo&list=PLSIUOFhnxEiCjoIwJ0jAdwpTZET73CK7d&index=9&t=1s). diff --git a/packages/docs/docs/guides/configure/web/translations.mdx b/packages/docs/docs/guides/configure/web/translations.mdx new file mode 100644 index 00000000000..c1af5436c41 --- /dev/null +++ b/packages/docs/docs/guides/configure/web/translations.mdx @@ -0,0 +1,393 @@ +--- +title: Localization +description: Enabling localizations of Blockly. +image: images/blockly_banner.png +--- + +# Localization + +Blockly provides a system for localizing the text in an application, such as +tooltips, context menus, and the text on blocks. It uses this system to localize +its own text; you can use it to localize text unique to your application. + +:::note +Localization is the same as translation, except that it allows +translations to be different for different countries, such as different +translations into Portuguese in Portugal and Brazil. +::: + +## How the localization system works + +The localization system consists of localization tokens, localization tables, +and functions that use the tables to replace tokens with localized strings. + +### Localization tokens + +A **localization token** is a short string that represents text that needs to be +localized. For example, a tooltip in a custom date block might use the token +`MY_DATE_TOOLTIP`. Localization tokens are used in code in place of text. At +runtime, Blockly replaces these tokens with localized strings. + +### Localization tables + +A **localization table**, also known as a string table or message table, is an +object that maps localization tokens to localized strings. You need a different +table for each locale. For example, if you want to support English and Spanish, +your English table might contain: + +```js +enTable.MY_DATE_TOOLTIP = 'Enter a date.'; +``` + +and your Spanish table might contain: + +```js +esTable.MY_DATE_TOOLTIP = 'Introduzca una fecha.'; +``` + +Blockly includes localization tables for its own text. They are available in the +Blockly distribution as files named `blockly/msg/xx.js`, where `xx` is the +locale code. + +You need to create localization tables for your own text. At run time, you load +the localization tables -- Blockly's and yours -- for the chosen locale into +`Blockly.Msg`, which is the localization table that Blockly uses internally. + +## Use the localization system + +Before using the localization system, you need to decide how many locales you +want to support and whether you plan to support more locales in the future. + +- If you only ever want to support a single locale, enter your text directly + in your code. You don't need to use localization tokens. + - If your locale is English (`en`), you don't need to do anything else. + The Blockly localization table for the `en` locale is loaded by default. + - If your locale is not `en`, [load the Blockly localization table](#load-blockly) + for that locale. + +- If you want to support multiple locales now or in the future: + 1. [Define and use localization tokens](#define) for your custom text. + 1. Decide how users will [choose a locale](#choose). + 1. [Load the Blockly localization table](#load-blockly) for the locale. + 1. [Load your localization table](#load-custom) for the locale. + +## Define and use localization tokens \{#define\} + +When supporting multiple locales, you need to define and use localization tokens +for all of your custom text. + +### Define localization tokens + +For each string that needs to be localized, define a token. You may want to use +a custom prefix with your tokens to avoid collisions with any tokens Blockly +adds in the future. + +For example, if you have a single custom block and a single custom category, you +might define the following tokens: + +```js +MY_DATE_BLOCK_TEXT; +MY_DATE_TOOLTIP; +MY_DATE_HELPURL; +MY_DATE_CATEGORY; +``` + +### Define localization tables + +For each locale you want to support, define a localization table. For example: + +```js +// English localization table: my_tokens_en.js +export const myEnTable = { + MY_DATE_BLOCK_TEXT: 'Date %1', + MY_DATE_TOOLTIP: 'Enter a date.', + MY_DATE_HELPURL: 'https://myownpersonaldomain.com/help/en/dateblock' + MY_DATE_CATEGORY: 'Dates', +} + +// Spanish localization table: my_tokens_es.js +export const myEsTable = { + MY_DATE_BLOCK_TEXT: 'Fecha %1', + MY_DATE_TOOLTIP: 'Introduzca una fecha.', + MY_DATE_HELPURL: 'https://myownpersonaldomain.com/help/es/dateblock' + MY_DATE_CATEGORY: 'Fechas', +} +``` + +### Use localization tokens in JSON + +To use localization tokens in JSON, replace the string to be localized with a +**token reference**. A token reference has the form `%{BKY_TOKEN}`. For example: + +```js +Blockly.common.defineBlocksWithJsonArray([ + { + type: 'my_date', + message0: '%{BKY_MY_DATE_BLOCK_TEXT}', + args0: [ + { + type: 'field_input', + name: 'DATE', + }, + ], + output: 'Date', + colour: '%{BKY_MY_DATE_COLOUR}', + tooltip: '%{BKY_MY_DATE_TOOLTIP}', + helpUrl: '%{BKY_MY_DATE_HELPURL}', + extensions: ['validate_date'], + }, +]); +``` + +When the JSON is processed -- in this case, when the block is instantiated -- +Blockly looks up the tokens in `Blockly.Msg` and replaces them with localized +strings. If it doesn't find a token, it leaves the reference in place and emits +a warning. + +For a complete list of where token references can be used, see the +[appendix](#where). + +#### JSON message interpolation + +The `message` keys in a JSON block definition define the inputs and fields +(including labels) in a block. The use of token references in these keys allows +a single block definition to adapt to the vocabulary, word ordering, and +direction of multiple locales. For example, here is Blockly's `lists_repeat` +block in four different languages: + +![lists_repeat block in English](/images/createlist-en.png) \ +![lists_repeat block in Spanish](/images/createlist-es.png) \ +![lists_repeat block in Korean](/images/createlist-ko.png) \ +![lists_repeat block in right-to-left Arabic](/images/createlist-ar.png) + +All of these blocks share the same block definition, whose `message0` key is: + +```js +message0: %{BKY_LISTS_REPEAT_TITLE}, +``` + +The value of this token in the English localization table is: + +```js +Blockly.Msg['LISTS_REPEAT_TITLE'] = + 'create list with item %1 repeated %2 times'; +``` + +The interpolation markers (`%1` and `%2`) correspond to the block's defined +inputs and fields, and the text between the markers is converted into unnamed +label fields. Because the text for `message0` is stored in localization tables +and not the block definition, a single block definition in JSON can support +different orderings of inputs and fields: + +```js +// In Spanish: label, input, label, input, label +Blockly.Msg['LISTS_REPEAT_TITLE'] = + 'crear lista con el elemento %1 repetido %2 veces'; +// In Korean: input, label, input, label, input (dummy) +Blockly.Msg['LISTS_REPEAT_TITLE'] = '%1을 %2번 넣어, 리스트 생성'; +``` + +This is not possible for block definitions in JavaScript, where different +orderings of inputs and fields require different sequences of function calls. + +When using right-to-left languages, write the message string in visual order, +and do not include Unicode direction commands: + +```js +// In Arabic. Note how %2 is left of %1, since it reads right to left. +Blockly.Msg['LISTS_REPEAT_TITLE'] = 'إنشئ قائمة مع العنصر %1 %2 مرات'; +``` + +For more information about how Blockly converts `message` keys into inputs and +fields, see [Define block structure in +JSON](/guides/create-custom-blocks/define/structure-json). + +### Use localization tokens in JavaScript + +To use localization tokens in JavaScript, replace the string to be localized +with `Blockly.Msg['TOKEN']`. For example: + +```js +// Return the text for a localized context menu item. +displayText: () => Blockly.Msg['MY_CONTEXT_MENU_ITEM']; +``` + +Except as noted in the [appendix](#where), Blockly doesn't parse token +references in JavaScript: + +```js +// Doesn't work. Returns '%{BKY_MY_CONTEXT_MENU_ITEM}'. +displayText: () => '%{BKY_MY_CONTEXT_MENU_ITEM}'; +``` + +## Choose a locale \{#choose\} + +How to choose a locale is application-specific and outside the scope of Blockly. +For example, your application might always use the same locale, determine the +locale from the URL or URL parameters, or let users choose a locale from a list. + +As a general rule, you should choose a locale and load the corresponding +localization tables before you create a workspace. If you choose a different +locale and load new tables after creating a workspace, you'll have to re-create +the workspace: Blockly does not update the existing toolbox or blocks to use the +new locale automatically. To preserve the user's work (if any), save the state +before you re-create the workspace and re-load it after. + +## Load a Blockly localization table \{#load-blockly\} + +Blockly provides localization tables for all of its own text, such as the text +on built-in blocks. Unless you are using the `en` locale, which is loaded by +default, you need to load the Blockly localization table for your locale. + +Blockly's localization tables are stored in files named `blockly/msg/xx.js`, +where `xx` is the locale code. For a list of supported locales, see the files in +[`blockly/msg/json`](https://github.com/RaspberryPiFoundation/blockly/tree/main/msg/json). + +### Load a Blockly localization table with npm + +When you import Blockly with `import * as Blockly from 'blockly';` you'll get +the default modules: Blockly core, Blockly built-in blocks, the JavaScript +generator, and the Blockly localization table for the English (`en`) locale. + +To load the Blockly localization table for a different locale using npm: + +1. Import Blockly default modules: + + ```js + import * as Blockly from 'blockly/core'; + import 'blockly/blocks'; + import 'blockly/javascript'; // Or the generator of your choice + ``` + +1. Import the Blockly localization table for your locale. For example, to + import the table for the Spanish (`es`) locale: + + ```js + import * as Es from 'blockly/msg/es'; + ``` + +1. Load the table with `Blockly.setLocale`. This function copies the table into + the `Blockly.Msg` object. + + ```js + Blockly.setLocale(Es); + ``` + + `setLocale` is only included in the npm release of Blockly. + +### Load a Blockly localization table without npm + +To load a Blockly localization table without using npm, use a ` + + +``` + +The localization table is loaded automatically. + +## Load your own localization table \{#load-custom\} + +If you define your own localization tables, you need to load the table for your +chosen locale. + +- If you are using npm, you can do this with `Blockly.setLocale`: + + ```js + import * as Es from 'blockly/msg/es'; + import { myEsTable } from '../my_tokens_es'; + Blockly.setLocale(Es); + Blockly.setLocale(myEsTable); + ``` + + `setLocale` copies each key-value pair from the input object into + `Blockly.Msg`. You can call it multiple times with distinct keys, but + calling it a second time with a duplicate key overwrites the first. + +- If you are not using npm, you must copy your table into `Blockly.Msg` by + hand. (`setLocale` is only included in the npm release of Blockly.) The + easiest way to do this is to define your own version of `setLocale`. + + ```js + function mySetLocale(locale) { + Object.keys(locale).forEach(function (k) { + Blockly.Msg[k] = locale[k]; + } + } + + mySetLocale(myEsTable); + ``` + +## Functions to resolve token references + +Blockly provides two functions for resolving token references: +`Blockly.utils.parsing.replaceMessageReferences` (commonly used) and +`Blockly.utils.parsing.tokenizeInterpolation` (rarely used). In most cases, you +don't need to call either of these functions. This is because Blockly already +calls them in the [places it supports token references](#where). For example, +Blockly uses these functions to resolve token references in the `messageN`, +`tooltip`, and `helpUrl` keys in a JSON block definition. + +One place you might need to use `replaceMessageReferences` is in custom fields. +If your custom field accepts token references in any of its options, use +`replaceMessageReferences` to resolve them. For more information, see [JSON and +registration](/guides/create-custom-blocks/fields/customizing-fields/creating#json-and-registration). + +## Related topics + +- Right-to-left languages: See the [RTL + demo](https://raspberrypifoundation.github.io/blockly-samples/examples/rtl-demo/). +- Help localize Blockly's text: See + [Translating](/guides/contribute/core/translating) in the section on + contributing to Blockly. + +## Appendix: Where token references are allowed \{#where\} + +You can use [token references](#use-localization-tokens-in-json) in the +following JSON keys: + +- In category toolbox definitions: + - `name` + - `colour` +- In block definitions: + - `messageN` + - `tooltip` + - `helpUrl` + - `colour` +- In the options passed to all fields: + - `tooltip` +- In the [nested arrays](/guides/create-custom-blocks/fields/built-in-fields/dropdown#creation) + passed to `options` in `field_dropdown`: + - The first element, when the first element is a string + - The value of `alt`, when the first element is an object describing an + image +- In the options passed to `field_variable`: + - `variable` +- In the options passed to `field_label` and `field_label_serializable`: + - `text` +- In the options passed to `field_image`: + - `height` + - `width` + - `src` + - `alt` +- In themes: + - `colour` in category styles + - `colourPrimary`, `colourSecondary`, and `colourTertiary` in block styles + +And as argument values in the following methods: + +- `Block.setColour` +- `Blockly.utils.extensions.buildTooltipForDropDown` +- `Blockly.utils.extensions.buildTooltipWithFieldText` +- `Blockly.utils.parsing.parseBlockColour` + +And in the XML definition of a toolbox in the following attributes of +``: + +- `name` +- `colour` + +For more information about using token references as colour values, see [Colour +references](/guides/configure/web/appearance/colour-formats#colour-references). diff --git a/packages/docs/docs/guides/configure/web/workspace_comment.mdx b/packages/docs/docs/guides/configure/web/workspace_comment.mdx new file mode 100644 index 00000000000..89add5bd55c --- /dev/null +++ b/packages/docs/docs/guides/configure/web/workspace_comment.mdx @@ -0,0 +1,212 @@ +--- +description: What workspace comments are and how to use them. +title: Workspace comments +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Workspace comments + +A workspace comment is a graphical element that you can enter text into. Usually +it's used to document things about your code, just like comments in a text-based +programming language. + +Workspace comment + +:::note +workspace comments cannot be added to the [flyout][flyout]. +::: + +## Enable workspace comments + +To enable workspace comments in your application, you need to give users some +way to create them. One way to do this is to add a context menu item that +creates a workspace comment. You can register default context menu items to +create, delete, and duplicate workspace comments with the following code: + +```js +// This should be called on page load. It can be called before or after +// you inject your workspace. +Blockly.ContextMenuItems.registerCommentOptions(); +``` + +You could also create your own context menu options, or add another way for the +user to add workspace comments. For more information about context menu options, +see [Context menus][context-menus]. + +## Visually customize comments + +There are several ways for you to customize the look of workspace comments. +These use CSS and not [themes][themes]. It is possible to control most of the +colours and sizes of different parts of the comment, but not how they are +positioned. + +### Colour CSS variables + +You can set the `commentFillColour` css variable to change the background colour +of the text area. You can set the `commentBorderColour` css variable to change +the colour of the comment top bar and the border of the comment. + +```css +.blocklyWorkspace { + --commentFillColour: blue; + --commentBorderColour: red; +} +``` + +A workspace comment with the colours changed + +### CSS classes + +There are different css classes assigned to different elements of the comment +view, which allow you to modify the elements' styling. + +| CSS class(es) | Image | +| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | +| `blocklyComment`, `blocklyDraggable` | Workspace comment | +| `blocklySelected`, `blocklyCommentHighlight` | Selected comment Selected collapsed comment | : | +| `blocklyCollapsed` | Collapsed workspace comment | +| `blocklyCommentTopbar` | Workspace comment topbar | +| `blocklyFoldoutIcon` | Foldout icon | +| `blocklyCommentPreview`, `blocklyText` | Comment preview | +| `blocklyDeleteIcon` | Delete icon | +| `blocklyText` | Text | +| `blocklyResizeHandle` | Resize icon | + +#### Basic CSS use + +In most cases you can apply your custom attributes with the appropriate CSS +class: + +```css +.blocklyCommentTopbarBackground { + height: 50px; +} +``` + +A workspace comment with a taller top bar + +#### CSS for text + +However, for text you need to be more specific to override the CSS generated by +the renderer. + +```css +/* Modifies the preview text. */ +.blocklyComment .blocklyCommentPreview.blocklyText { + fill: blue; +} + +/* Modifies the input text. */ +.blocklyComment .blocklyText { + color: blue; +} +``` + +A workspace comment with blue preview text + +A workspace comment with blue input text + +#### CSS for selected highlights + +And for highlighting the comment when its selected, the object the CSS should be +applied to changes depending on whether the comment is collapsed or not. When +it's collapsed, you apply the CSS to the `blocklyCommentTopbarBackground`, +otherwise apply it to the `blocklyCommentHighlight`. + +```css +/* Highlight when expanded. */ +.blocklySelected .blocklyCommentHighlight { + stroke: #fc3; + stroke-width: 3px; +} + +/* Hide normal highlight when collapsed. */ +.blocklyCollapsed.blocklySelected .blocklyCommentHighlight { + stroke: none; +} + +/* Instead apply the collapsed highlight to the top bar. */ +.blocklyCollapsed.blocklySelected .blocklyCommentTopbarBackground { + stroke: #fc3; + stroke-width: 3px; +} +``` + +### Icons + +The `blocklyFoldoutIcon`, `blocklyDeleteIcon`, and `blocklyResizeHandle` classes +are all applied to [``][svg-image-element] elements. This means that if +you want to change the colour or shape of an icon, you can include a different +image in your [media folder][media]. + +| Image name | Image | +| ------------------- | -------------------------------------------------------------------------------------------------- | +| `foldout-icon.svg` | Foldout icon | +| `delete-icon.svg` | Delete icon | +| `resize-handle.svg` | Resize icon | + +#### Delete icon + +The delete icon is hidden by default. If you want to enable it, you need to use +CSS to make it visible: + +```css +.blocklyDeleteIcon { + display: block; +} +``` + +### Default size + +To set the default comment size, set the static property +`Blockly.comments.CommentView.defaultCommentSize`: + +```js +Blockly.comments.CommentView.defaultCommentSize = new Blockly.utils.Size( + 200, + 200, +); +``` + +[context-menus]: /guides/configure/web/context-menus +[flyout]: /guides/get-started/workspace-anatomy#flyout-toolbox +[themes]: /guides/configure/web/appearance/themes +[svg-image-element]: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image +[media]: /guides/configure/web/media +[workspace-comment-image]: /images/workspace-comments/workspace-comment.png +[coloured-workspace-comment-image]: /images/workspace-comments/coloured-comment.png +[workspace-comment-outline-image]: /images/workspace-comments/workspace-comment-outline.png +[collapsed-outline-image]: /images/workspace-comments/collapsed-outline.png +[top-bar-outline-image]: /images/workspace-comments/top-bar-outline.png +[foldout-icon-outline-image]: /images/workspace-comments/foldout-icon-outline.png +[preview-text-outline-image]: /images/workspace-comments/preview-text-outline.png +[delete-icon-outline-image]: /images/workspace-comments/delete-icon-outline.png +[text-outline-image]: /images/workspace-comments/text-input-outline.png +[resize-handle-outline-image]: /images/workspace-comments/resize-handle-outline.png +[taller-top-bar-image]: /images/workspace-comments/tall-top-bar.png +[blue-input-text-image]: /images/workspace-comments/blue-text.png +[blue-preview-text-image]: /images/workspace-comments/blue-preview-text.png +[selected-comment]: /images/workspace-comments/selected-comment.png +[selected-collapsed]: /images/workspace-comments/selected-collapsed.png diff --git a/packages/docs/docs/guides/configure/web/zoom.mdx b/packages/docs/docs/guides/configure/web/zoom.mdx new file mode 100644 index 00000000000..b4b4b526112 --- /dev/null +++ b/packages/docs/docs/guides/configure/web/zoom.mdx @@ -0,0 +1,70 @@ +--- +description: Configuration options for how the workspace can be zoomed. +title: Zoom option +image: images/blockly_banner.png +--- + +# Zoom option + +Blockly's main workspace may be scalable, either dynamically by the user, +or statically by the developer. + +The zoom settings are defined by an object that is part of Blockly's +[configuration +options](/guides/configure/web/configuration_struct#the-options-dictionary). +Here is an example: + +```js +var workspace = Blockly.inject('blocklyDiv', { + toolbox: document.getElementById('toolbox'), + zoom: { + controls: true, + wheel: true, + startScale: 1.0, + maxScale: 3, + minScale: 0.3, + scaleSpeed: 1.2, + pinch: true, + }, + trashcan: true, +}); +``` + +## controls + +Set to `true` to show zoom-centre, zoom-in, and zoom-out buttons. +Defaults to `false`. + +![The zoom-centre, zoom-in, and zoom-out +buttons.](/images/zoom-controls.png) + +## wheel + +Set to `true` to allow the mouse wheel to zoom. Defaults to `false`. + +## startScale + +Initial magnification factor. For applications with multiple levels, +`startScale` is often set to a higher value on the first level, then +incrementally decreased as subsequent levels become more complex. +Defaults to `1.0`. + +## maxScale + +Maximum multiplication factor for how far one can zoom in. Defaults to `3`. + +## minScale + +Minimum multiplication factor for how far one can zoom out. Defaults to `0.3`. + +## scaleSpeed + +For each zooming in-out step the scale is multiplied or divided respectively by +the scale speed, this means that: `scale = scaleSpeed ^ steps`. Note that in +this formula steps of zoom-out are subtracted and zoom-in steps are added. +Defaults to `1.2`. + +## pinch + +Set to `true` to enable pinch to zoom support on touch devices. Defaults to +`true` if either the `wheel` or `controls` option is set to `true`. diff --git a/packages/docs/docs/guides/contribute/core-architecture/render-management.mdx b/packages/docs/docs/guides/contribute/core-architecture/render-management.mdx new file mode 100644 index 00000000000..9ead0931cbf --- /dev/null +++ b/packages/docs/docs/guides/contribute/core-architecture/render-management.mdx @@ -0,0 +1,121 @@ +--- +description: What the render management system is, and how it works. +title: Render management +image: images/blockly_banner.png +--- + +# Render management + +The render management system tells the [renderer][renderer] when to rerender the +blocks. It makes sure that when a block is modified (e.g. field values are set, +or inputs are added) the shape of the block gets updated to match. + +## When to care + +You need to interact with this system if you are: + +- Adding methods to Blockly that modify the shape of the block. +- Adding methods to Blockly that rely on updated size or positioning + information about a block. + +## How it works + +1. **Automatically queue.** Whenever a block gets modified, Blockly "queues" a + render for that block. Some examples of modifications that queue a render + are: + - Setting a field's value + - Adding or removing an input + - Connecting or disconnecting a child block + +2. **Create a set.** When a block gets queued, the render management system + adds it, and all of its parent blocks, to a set of blocks that need to be + rerendered. + +3. **Request a callback.** Then the render management system requests a + callback using [`requestAnimationFrame`][requestFrame]. This callback gets + called by the browser _right_ before the current frame is drawn. + +4. **Rerender the set (as a tree).** When the `requestAnimationFrame` callback + gets called, the render management system renders every block in the set + from leaf blocks to root blocks. This makes sure that child blocks have + accurate size information before their parent blocks are rendered so the + parent blocks can stretch around their children. + +:::note +modifications that only affect the color of the block and not its shape +(e.g. disabling the block) _don't_ queue a render. The colors are updated +independently using `BlockSvg.prototype.applyColour`. +::: + +## Why it works how it does + +Waiting to rerender blocks until right before the current frame is drawn allows +the render management system to deduplicate rendering requests. If blocks were +always rendered immediately, the same block might unnecessarily be rendered +multiple times in a row. Instead the render requests are batched, and each +changed block only gets drawn once at the end of the frame, after its state is +finalized. Deduping rendering operations makes Blockly much more efficient. + +For example, inserting one block between two others queues 11 renders, but only +3 actually occur (one for each block). That's a 3.6x performance boost. + +## How to use it + +You shouldn't usually have to care about the render management system, because +it works automatically when you modify a block. But there are a few cases where +you have to interact with it directly. + +### Queue renders + +If you are adding a new method to Blockly that should update the shape of a +block, you need to call `BlockSvg.prototype.queueRender` to queue rendering the +block. + +### Wait for renders to finish + +If you are adding a new method to Blockly that requires having updated sizing or +positioning information about a block, you should await the +`renderManagement.finishQueuedRenders()` promise. This promise resolves after +any queued renders are completed, or immediately if there are no queued renders. + +```js +import * as renderManagement from './renderManagement.js'; + +function async myNewMethod() { + block.somethingThatModifiesTheShape(); + // Await the promise. + await renderManagement.finishQueuedRenders(); + myThingThatReliesOnPositioningInfo(); +} +``` + +### Trigger queued renders immediately + +If you are adding a new method to Blockly that requires having updated sizing or +positioning information about a block, _and_ you cannot wait until the next +frame for any renders to complete, you can call +`renderManagement.triggerQueuedRenders` to force any queued renders to happen +immediately. + +```js +import * as renderManagement from './renderManagement.js'; + +function async myNewMethod() { + block.somethingThatModifiesTheShape(); + // Trigger an immediate render. + renderManagement.triggerQueuedRenders(); + myThingThatReliesOnPositioningInfo(); +} +``` + +In general, you don't want to do this because it's less performant. It's only +necessary in cases where a delay causes a bad user experience. For example, +insertion markers need positioning information, and it's important that +insertion markers give users immediate feedback, so they trigger an immediate +render. + +There are also a few places in core where it triggers immediate renders for +backwards compatibility reasons. These are planned to be removed in v11. + +[renderer]: /guides/create-custom-blocks/renderers/overview +[requestFrame]: https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame diff --git a/packages/docs/docs/guides/contribute/core/add_localization_token.mdx b/packages/docs/docs/guides/contribute/core/add_localization_token.mdx new file mode 100644 index 00000000000..bbc63691854 --- /dev/null +++ b/packages/docs/docs/guides/contribute/core/add_localization_token.mdx @@ -0,0 +1,135 @@ +--- +description: How to add a new localization token to Blockly core. +title: Add a new localization token to Blockly core +image: images/blockly_banner.png +--- + +# Add a new localization token to Blockly core + +If you add a feature to Blockly core that requires new user-visible strings, you +must add those strings to `Blockly.Msg` so that they can be [translated by +Translatewiki][translatewiki]. (For information about adding localization tokens +for your own application, see [Localization][localization].) + +1. Add your new string with an appropriate name and description to the + `msg/messages.js` file. +1. Run `npm run messages` to automatically add your translation to the + `msg/json/qqq.json` and `msg/json/en.js` files. This step may also change + `msg/json/constants.js` or `msg/json/synonyms.js` in some cases. +1. Inspect the automatically-generated files for correctness. Note that the + script may remove the `@metadata` section at the beginning of `qqq.json`. If + this happens, you should carefully revert that change so that your new + string is added but the `@metadata` is not removed. +1. In your feature code, reference the new string with + `Blockly.Msg['MY_NEW_MESSAGE']`. +1. Commit all of the changes to the `msg` files alongside your feature code. + +For example, if you add this code to `msg/messages.js`: + +```js +/** @type {string} */ +/// This is a hint to translators about the context for the message. +Blockly.Msg.MY_NEW_MESSAGE = 'This is a string that users will see!'; +``` + +Then run `npm run messages`, you should see the following changes in +`msg/en.json`: + +```js +// ... + "MY_NEW_MESSAGE": "This is a message that users will see!", +// ... +``` + +and in `msg/qqq.json`: + +```js +// ... + "MY_NEW_MESSAGE": "This is a hint to translators about the context for the message.", +// ... +``` + +Then you can reference this string in code with `Blockly.Msg['MY_NEW_MESSAGE']`. + +## Translation hints + +The triple-slash comment in `msg/messages.js` is shown to TranslateWiki users as +supplementary information when translating. Provide context for where the +message will be shown to users. If the message includes parameters (e.g., `%1`), +explain what the parameters mean. + +Here is an example of a good translation hint that explains the parameters and +provides a link to more information. + +```js +/** @type {string} */ +/// block text - Repeatedly counts a variable (%1) +/// starting with a (usually lower) number in a range (%2), +/// ending with a (usually higher) number in a range (%3), and counting the +/// iterations by a number of steps (%4). As in +/// [https://github.com/RaspberryPiFoundation/blockly/wiki/Loops#count-with +/// https://github.com/RaspberryPiFoundation/blockly/wiki/Loops#count-with]. +Blockly.Msg.CONTROLS_FOR_TITLE = 'count with %1 from %2 to %3 by %4'; +``` + +### Context types + +Many of the hints use a prefix to explain the context of a message. The common +prefixes include: + +- block text +- button text +- context menu +- dropdown +- math +- toast notification +- tooltip + +If your message appears in one of these context, use the appropriate prefix. + +## Synonyms + +Sometimes a message key needs to be changed, but the translations don't. In that +case, you can set the old message as a synonym of the new message, like so: + +```js +/** @type {string} */ +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO; +``` + +## Optional messages + +Some message strings are unlikely to need translation except in certain +circumstances, for example, proper nouns or symbols. In Blockly, help URLs are +often marked optional. + +Languages are only committed to the Blockly repository if they are at least 25% +complete. Thus, marking messages that are unlikely to need translating as +optional will help those languages meet the threshold without needing to +complete the optional translations. + +```js +/** @type {string} */ +/// {{Optional}} math - The symbol for the binary operation addition. +Blockly.Msg.MATH_ADDITION_SYMBOL = '+'; +``` + +## Notranslate items + +The colours used for default block categories are marked `{{notranslate}}`. These colours are not intended to be +localized, but are in the localization system so that developers can easily +[change the colours][block-colour] of blocks in the default categories. If you +add new block categories, use the `{{notranslate}}` +directive. If you add a different type of message that you think should never be +translated, consider whether the localization system is the right place for the +string. + +```js +/** @type {string} */ +/// {{Notranslate}} Hue value for all logic blocks. +Blockly.Msg.LOGIC_HUE = '210'; +``` + +[translatewiki]: /guides/contribute/core/translating +[localization]: /guides/configure/web/translations +[block-colour]: /guides/configure/web/appearance/block-colour#set-block-colour diff --git a/packages/docs/docs/guides/contribute/core/advanced.mdx b/packages/docs/docs/guides/contribute/core/advanced.mdx new file mode 100644 index 00000000000..6d707386843 --- /dev/null +++ b/packages/docs/docs/guides/contribute/core/advanced.mdx @@ -0,0 +1,133 @@ +--- +description: Reducing the size of Blockly using Closure Compiler. +title: Advanced compilation +image: images/blockly_banner.png +--- + +# Advanced compilation + +The regular [build process](/guides/contribute/core/building) uses Google's online JavaScript compiler to reduce Blockly to a half a dozen files totaling about 720kb (160kb zipped). Alternatively one can use the Google's offline JavaScript compiler in "advanced compilation" mode which has a number of advantages: + +- Total Blockly size reduced to 300kb (100kb zipped) due to tree shaking. +- Faster build times and no network traffic due to local compiler execution. +- Unlimited compilations (the online compiler is rate-limited). + +## Setup + +For the purposes of this minimal tutorial, start by creating a new directory in the Blockly root directory. + +### Download Closure Compiler. + +Download [`compiler.jar`](https://unpkg.com/google-closure-compiler-java/compiler.jar), rename it to `closure-compiler.jar`, and place it in your directory. + +Verify that your Java Runtime Environment can run the compiler by running this +on the command line: + +```shell +java -jar closure-compiler.jar --version +``` + +### Boiler Plate + +First, create an HTML file which defines a minimal Blockly toolbox and a `div` +in which to inject it. To do so, create a file in your directory called +`index.html` that contains this code: + +```html + + + + + Blockly: Advanced Compilation + + + + +

Blockly: Advanced Compilation

+
+ + + +``` + +Be sure to edit the language path (`../msg/en.js`) as required for +your path to Blockly and for your desired language. + +Second, create a JavaScript file that loads Blockly and any necessary message +files or block definitions, then injects Blockly into the provided `div`. +To do so, create a file in your directory called `main.js` that contains +this code: + +```js +goog.provide('Main'); +// Core +goog.require('Blockly.requires'); +// Blocks +goog.require('Blockly.Constants.Logic'); +goog.require('Blockly.Constants.Loops'); +goog.require('Blockly.Constants.Math'); +goog.require('Blockly.Constants.Text'); + +Main.init = function () { + Blockly.inject('blocklyDiv', { + toolbox: document.getElementById('toolbox'), + }); +}; +window.addEventListener('load', Main.init); +``` + +### Compile + +Compile `main.js`, Blockly, and Closure Library together by running the +Closure Compiler from the command line: + +```shell +java -jar closure-compiler.jar --js='main.js' \ + --js='../blocks/**.js' \ + --js='../core/**.js' \ + --js='../generators/**.js' \ + --generate_exports \ + --externs ../externs/svg-externs.js \ + --compilation_level ADVANCED_OPTIMIZATIONS \ + --dependency_mode=PRUNE --entry_point=Main \ + --js_output_file main_compressed.js +``` + +Or by using our advanced compilation script: + +``` +npm run test:compile:advanced +``` + +Point a browser at `index.html` to verify everything worked. + +### Even More Advanced + +For even greater reductions in size, you can include only the Blockly components +that your application actually uses. For example, if your application isn't +configured to have a trashcan, then you can remove the trashcan from the list +of components that are compiled in. To do so, delete the requirement for +`Blockly.requires` from your code: + +```js +// Core +goog.require('Blockly.requires'); +``` + +In its place, open `core/requires.js` and copy all the require statements into +your code. You can then comment out the ones you don't need. + +Note that the Closure Compiler preserves licences in the compiled output. +Feel free to strip the Apache licenses from this output file to reduce the +size further. + +The Closure Compiler has a lot of features and options, do check out their +[documentation](https://developers.google.com/closure/compiler/docs/gettingstarted_app). diff --git a/packages/docs/docs/guides/contribute/core/building.mdx b/packages/docs/docs/guides/contribute/core/building.mdx new file mode 100644 index 00000000000..ceda5223992 --- /dev/null +++ b/packages/docs/docs/guides/contribute/core/building.mdx @@ -0,0 +1,202 @@ +--- +description: The process for building Blockly. +title: Build scripts +image: images/blockly_banner.png +--- + +# Build scripts + +:::warning +Unless you are modifying the Blockly source code directly, you probably +don't need to build Blockly run any of the scripts documented below yourself. +Instead, follow the instructions in [the "Get the Code" +section](/guides/get-started/get-the-code#get-the-code-1) of the [Get Started](/guides/get-started/get-the-code) page to install [the `blockly` NPM package](https://www.npmjs.com/package/blockly) or download the `.tgz` file attached to +[the latest release on GitHub](https://github.com/RaspberryPiFoundation/blockly/releases/latest). +::: + +Blockly is made up of over a hundred TypeScript files. These must be compiled +by the TypeScript compiler, `tsc`, into JavaScript before they can be +used. This creates an equally large number of `.js` files which are suitable +for local testing, but loading such a large number of files over the Internet +is a sluggish experience for end users. To make Blockly load faster, the +[Closure Compiler](https://developers.google.com/closure/compiler) is used to +compress (minify) and combine them into a half a dozen files ("bundles" or +"chunks") with total size less than half that of uncompressed files. + +In the process, code using the latest ECMAScript features—ones which may not +be compatible with all browsers—are transpiled down to ES6, +which is generally compatible with most widely-used browsers. Thus, it's +important that you serve only the minified code to your end users. + +The [RaspberryPiFoundation/blockly repository](https://github.com/RaspberryPiFoundation/blockly) contains +only the source code. It previously also contained the build products, +but since 2019 the minified bundles have been published as [the +`blockly` NPM package](https://www.npmjs.com/package/blockly) and since +2022 also attached as a `.tgz` file to [each GitHub release](https://github.com/RaspberryPiFoundation/blockly/releases), so there is no need +to build Blockly unless you are hacking on Blockly itself—in particular on +files in the `core`, `blocks`, `generators`, or `msg` directories. + +The process of building, testing, and publishing Blockly is automated using +[npm scripts](https://docs.npmjs.com/cli/v9/using-npm/scripts) to run [Gulp +tasks](https://gulpjs.com/). This page documents the principle scripts and +what each does. + +## Compressed and Uncompressed Mode + +Loading Blockly directly from the individual `.js` files generated by the +TypeScript compiler is referred to as "uncompressed mode". Because it avoids +several slow build steps, this facilitates a quick edit-compile-run cycle; +it also facilitates debugging as the JavaScript code being executed is nearly +as readable as the original TypeScript sources, obviating the need to depend +on sourcemaps. + +Loading Blockly from the minified bundles is referred to as "compressed mode". +This is the best way to test changes to Blockly when using it as a dependency +of another package, because it tests (an unpublished version of) the `blockly` +npm package. + +N.B.: There are some places in the blockly repository where the terms +"uncompiled mode" and "compiled mode" are used as synonyms for "uncompressed +mode" and "compressed mode" respectively. This usage made sense in the past +as Closure Compiler was used to compress (minify) the code, but now the +the TypeScript compiler is always needed, even in uncompressed mode, so +this alternative terminology is potentially confusing and discouraged. + +## Quick Start + +:::warning +Unless you are modifying the Blockly source code directly, you probably +don't need to build Blockly run any of the scripts documented below yourself. +Instead, follow the instructions in [the "Get the Code" +section](/guides/get-started/get-the-code#get-the-code-1) of the [Get Started](/guides/get-started/get-the-code) page to install [the `blockly` NPM package](https://www.npmjs.com/package/blockly) or download the `.tgz` file attached to +[the latest release on GitHub](https://github.com/RaspberryPiFoundation/blockly/releases/latest). +::: + +- If you've made local changes and want to make sure they've not broken the + build or any tests, run + + ```shell + npm test + ``` + + to build Blockly and run its test suite. + +- If you want to test local changes in the browser, run + + ```shell + npm start + ``` + + This compiles Blockly and opens a web browser pointing at the Blockly + playground running Blockly in uncompressed mode. + + Any files in `core/`, `blocks/` and `generators/` that are modified are + automatically recompiled; reload the browser tab to see the changes. + +- To build your locally-modified version of Blockly and test it, in compressed + mode, as a dependency of another npm package, run + + ```shell + npm run package + ``` + + to build Blockly package, then + + ```shell + cd dist && npm link + ``` + + to tell npm where to find the compiled files, and then `cd` to your project's + directory before running + + ```shell + npm link blockly + ``` + + to have your package use the freshly-compiled version of Blockly in + place of the published `blockly` package. + +## Detailed Script Reference + +This section lists the principle `scripts` in Blockly's `package.json` file +with an explanation of what they do. + +These scripts generate files in two places: + +- Files in the `build/` subdirectory are intermediary files used for local + testing or ingested by later parts of the build pipeline. +- Files in the `dist/` subdirectory form the contents of the published npm + package. + +Neither directory is tracked in the blockly git repository. + +### `clean` + +`npm run clean` cleans up any previous builds by deleting the `build/` and +`dist/` directories. Useful for fixing arcane build failures, particularly +ones caused by renaming a source file. + +### `messages` + +`npm run messages` updates the messages files in `msg/json/` with any changes +that have been made to `msg/messages.js`, and should be run after each time +that file is modified. + +### `langfiles` + +`npm run langfiles` generates the compiled language files in `build/msg/` +from the messages files in `msg/json`. + +### `tsc` + +`npm run tsc` runs the TypeScript compiler on the contents of the `core/`, +`blocks/` and `generators/` directories, and outputs individual `.js` files +to `build/src/`. + +### `minify` + +`npm run minify` runs `closure-make-deps` and `closure-calculate-chunks` +to determine how to divide up the compiled `.js` files into chunks (minified +bundles), after which it runs `closure-compiler` to create the chunks as +follows: + +- The contents of `build/src/core/` become `dist/blockly_compressed.js`. +- The contents of `build/src/blocks/` become `dist/blocs_compressed.js`. +- The contents of `build/src/generators/javascript/` (plus + `build/src/generators/javascript.js`) become `dist/javascript_compressed.js`. +- And likewise for `dart`, `lua`, `php`, and `python`. + +The generated chuks use a wrapper to ensure compatibility with the [Universal +Module Definition](https://github.com/umdjs/umd) so no extra processing is +needed before they are included in the package. + +### `build` + +`npm run build` runs the `minify` and `langfiles` tasks. This should do +everything that's needed to load the Blockly playground in either compressed +or uncompressed mode. + +### `package` + +`npm run package` runs the `clean` and `build` tasks and then: + +- Applies a [UMD](https://github.com/umdjs/umd) wrapper the files in + `build/msg/`, placing the wrapped versions in `dist/msg/`. +- Adds various additional support files to `dist/`, with UMD wrappers where + applicable. + +### `publish` + +`npm run publish` is used by the Blockly team to publish the `blockly` npm +package. It depends on Google-internal infrastructure so is not useful to external developers. + +### `lint` + +`npm run lint` runs [ESLint](https://eslint.org/), performing static analysis +of the Blockly source code to find problems. + +### `test` + +`npm test` (or `npm run test`) runs the `package` task and then runs various +automated tests (including running ESLint). This should be run—and pass—on +any code submitted as a pull request against the blockly repository. diff --git a/packages/docs/docs/guides/contribute/core/index.mdx b/packages/docs/docs/guides/contribute/core/index.mdx new file mode 100644 index 00000000000..36750cf537d --- /dev/null +++ b/packages/docs/docs/guides/contribute/core/index.mdx @@ -0,0 +1,61 @@ +--- +description: Learn how to contribute changes to Blockly Core. +title: Contribute to core +image: images/blockly_banner.png +slug: /guides/contribute/core/index +--- + +# Contribute to core + +The [Blockly](https://github.com/RaspberryPiFoundation/blockly) core repository contains the +code that is needed to run any Blackly-based application. It also contains the documentation, including codelabs. + +## Need to Know + +Here is a quick overview of facts about Blockly core you need to know in order +to create a PR. + +- The working branch is **main** and all PRs should be made against + main. +- You must fill out the pull request template with the requested information. +- Code must conform to Google's [TypeScript Style + Guide](https://google.github.io/styleguide/tsguide.html). +- Use [conventional commits](/guides/contribute/get-started/commits) + in your commit messages and pull request titles. +- User-visible strings must be in the `/msg/messages.js` file so they may be + translated. Less than 6% of the world speaks English natively. +- Text on blocks should generally be all lowercase (just like the keywords in + most programming languages). +- Maintain backwards compatibility. There are a _lot_ of Blockly apps out + there, don't break everyone else. +- Any new code files must be prefixed with the Apache License v2.0: + + ```js + /** + * @license + * Copyright Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + ``` + +## Make and Verify a Change + +1. Run `npm install` to install dependencies. +1. Run `npm run start` to start up a server running the playground. You can use + this page to test the existing behavior. See the + [playground](/guides/contribute/get-started/playground) page for + more information. +1. Make any necessary changes to the code. +1. If you've left the server running, refresh to see your changes. Otherwise, + restart the server and verify the code behaves as expected and there are no + errors or warnings in the console. +1. Run `npm run build` and ensure there are no build errors. +1. Write automated tests. Usually, these will be mocha tests in the + `tests/mocha` directory, but we may ask you for other types of tests. +1. Run `npm run format` to format the code and automatically fix some lint + problems. +1. Run `npm test` to run the automated tests. This also runs `eslint`. +1. If there are lint errors, run `npm run lint:fix` to fix the problems that + are autofixable. Address any remaining lint warnings or errors. +1. If all tests pass, you are ready to open a PR against **main** with your + changes. diff --git a/packages/docs/docs/guides/contribute/core/klingon.mdx b/packages/docs/docs/guides/contribute/core/klingon.mdx new file mode 100644 index 00000000000..0dd15d08d36 --- /dev/null +++ b/packages/docs/docs/guides/contribute/core/klingon.mdx @@ -0,0 +1,64 @@ +--- +title: Klingon +image: images/blockly_banner.png +--- + +# Klingon + +On 1 April 2014 we released a +[Klingon translation of Blockly](https://blockly-demo.appspot.com/static/demos/code/index.html?lang=tlh#ortpyd). +Klingon is an unusual choice for a translation, and on this page we wanted to +give some context on the hows and whys, as well as how you can help. + +![A stack of blocks in Klingon.](/images/klingon.png) + +## Why? + +Blockly has been translated into over 40 languages, including RTL languages such +as Arabic and Hebrew. We feel that it is important that novice programmers are +able to learn the fundamentals of programming in their own language, before +making the transition to conventional English-based programming languages. + +Klingon is a real language in every sense of the word. It is not just a +collection of made-up words thrown together for a movie. Instead, it has been +crafted by linguists over the course of decades. The Klingon language has a +complicated grammar that is completely unique. + +Consider word order. English follows the Subject-Verb-Object order ("The cat +eats the food."). Hungarian follows the Object-Subject-Verb order ("The food +the cat eats."). Hebrew follows the Verb-Subject-Object order ("Eats the cat +the food."). Klingon is the most bizarre, with Object-Verb-Subject order ("The +food eats the cat."). Supporting Klingon is the ultimate test of Blockly's +flexibility. Block inputs need to be reordered, suffix groups need to be added, +rules for plurals need to be rethought. Infrastructure improvements made during +the course of translating to Klingon help us support all languages. + +## Who? + +The number of Google employees who are fluent in Klingon is larger than one +might expect. Google's Klingon language group maintains +a style guide for terminology so that different applications use a consistent +vocabulary. + +We are always pleased when volunteers come forward to contribute new +translations or corrections -- whether for Klingon, or other languages. + +## How? + +Most of [Blockly's translations](/guides/contribute/core/translating) are done by volunteers +using Translatewiki. Unfortunately, Klingon is not in their language matrix. +As a result, Klingon contributors need to edit two files manually: + +[msg/json/tlh.json](https://github.com/RaspberryPiFoundation/blockly/blob/main/msg/json/tlh.json) +and +[demos/code/msg/tlh.js](https://github.com/RaspberryPiFoundation/blockly/blob/main/demos/code/msg/tlh.js) + +See the `en` files in each directory for the English phrases (including +those not yet translated to Klingon). +We actively do not want tooltip messages or help URLs translated since they +offer useful context for those new to Klingon. + +All phrases _must_ be manually translated. Bing Translate produces such +translations as `"Library" -> "be'nI''a'wI', Datu'"` which actually means +`"discover my big sister"`. +Clearly this would be an inadvisable phrase to use in a Klingon environment. diff --git a/packages/docs/docs/guides/contribute/core/style_guide.mdx b/packages/docs/docs/guides/contribute/core/style_guide.mdx new file mode 100644 index 00000000000..a463105f9ce --- /dev/null +++ b/packages/docs/docs/guides/contribute/core/style_guide.mdx @@ -0,0 +1,134 @@ +--- +description: The style guide for code contributions to Blockly. +title: Style guide +image: images/blockly_banner.png +--- + +# Style guide + +Follow the [Google TypeScript style +guide](https://google.github.io/styleguide/tsguide.html). + +## Migration to TypeScript & ES6 + +Blockly was originally written in ES5.1 in compliance with an [older, +then-current version of the Google JavaScript style +guide](https://google.github.io/styleguide/javascriptguide.xml). Newly-written +code should comply with the current style guide and use ES6 language features +like `let`, `const`, `class`, destructuring assignment where applicable. +Existing code may be updated or may be left out of compliance. The Blockly team +tries to make the best decision taking into account code consistency and the +experience for users of the library - for example, we may opt not to rename +public functions that no longer comply with the style guide. + +## Do + +- Use linting and formatting tools. + - We use [eslint](http://eslint.org/) and have an [`eslint.config.mjs` + file](https://github.com/RaspberryPiFoundation/blockly/blob/main/eslint.config.mjs) + set up with rules for our preferred style. + - We use [prettier](https://prettier.io/) for automatic formatting. + - Run `npm run lint` to run the linter and `npm run format` to run the + formatter. +- Indent with spaces, not tabs. +- Use [semicolons][semicolons-rule]. +- Use `camelCase` for variables and functions. +- Use `TitleCase` for classes. +- Use `ALL_CAPS` for constants. +- [Use braces](https://google.github.io/styleguide/jsguide.html#formatting-braces-all) + for all control structures. + - Exception: You may omit the braces for single-line `if` statements. +- Use single quotes (except when writing JSON). +- Redeclare variables in `for` loops. That is, always write `for (const i = 0; +...)` instead of `for (i = 0; ...)`. + - Not doing so raises the risk that after a refactor higher up in the + function the variable will be orphaned and become a surprise global. +- Start comments with capital letters and end them with periods. +- Create GitHub issues with TODOs and link them using `TODO(#issueNumber)`. +- Annotate everything with [TSDoc](#tsdoc). + +## Don't + +- Indent with tabs. +- Use underlines at the ends of variable or function names. + - Some earlier code uses underscores for private or internal properties or + functions. While these may continue to exist, no new code should be + added following this convention. +- Use `snake_case`. +- Use double quotes (except when writing JSON). +- Use malformed TSDoc. + - Our TSDoc is automatically published as part of our documentation. +- Write `TODO (username)`. + - Instead create GitHub issues with TODOs and link them using + `TODO(#issueNumber)`. +- Use `string.startsWith`. Use `Blockly.utils.string.startsWith` instead. + +## TSDoc + +The Blockly team uses [TSDoc](https://tsdoc.org/) to annotate our code and +generate documentation. We expect TSDoc for all public properties of classes, +and for all exported functions. + +TSDoc comments must start with `/**` and end with `*/` to be parsed correctly. + +### Types + +Types are omitted from TSDoc because that information is in the TypeScript code +directly. If you are editing one of the few remaining JavaScript files, include +type annotations according to the [Closure Compiler +documentation](https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler). + +### Visibility + +Functions or properties that should only be accessed within the Blockly library +should be annotated with `@internal`. This prevents these properties from +appearing in the public documentation. Other [visibility +modifiers](/guides/programming/using_blockly_apis) should be placed in +the TypeScript code directly, not in the TSDoc. + +### Properties + +TSDoc for properties should include a description of the property. The +description may be omitted for self-explanatory properties. + +```ts +/** + * The location of the top left of this block (in workspace coordinates) + * relative to either its parent block, or the workspace origin if it has no + * parent. + * + * @internal + */ +relativeCoords = new Coordinate(0, 0); +``` + +### Functions + +Annotations for functions should include + +- A description of the function +- One [`@param`](https://tsdoc.org/pages/tags/param/) tag per parameter, + including + - Name + - Description +- A [`@returns`](https://tsdoc.org/pages/tags/returns/) tag if the function + will return a value, with a description of the returned value. + +Descriptions may omitted for functions, parameters, or return values if they are +self-explanatory. + +For example: + +```ts +/** + * Find the workspace with the specified ID. + * + * @param id ID of workspace to find. + * @returns The sought after workspace or null if not found. + */ +export function getWorkspaceById(id: string): Workspace | null { + return WorkspaceDB_[id] || null; +} +``` + +[semicolons-rule]: https://google.github.io/styleguide/jsguide.html#formatting-semicolons-are-required diff --git a/packages/docs/docs/guides/contribute/core/translating.mdx b/packages/docs/docs/guides/contribute/core/translating.mdx new file mode 100644 index 00000000000..c3030f8ab3e --- /dev/null +++ b/packages/docs/docs/guides/contribute/core/translating.mdx @@ -0,0 +1,35 @@ +--- +description: How to contribute translations to Blockly. +title: Translate text +image: images/blockly_banner.png +--- + +# Translate text + +Students shouldn't have to struggle with learning English at the same time as +they're learning computer science concepts. If you are a native speaker of a +language other than English, we'd appreciate your assistance in reaching the 95% +of the world that doesn't speak English natively. + +## Translatewiki + +Translations for both Blockly and Blockly Games are handled by Translatewiki. + +1. Sign up to become a translator at + [translatewiki.net](https://translatewiki.net/). +1. Do some [test + translations](https://translatewiki.net/wiki/Special:TranslationStash) to + get permission to translate (choose a language in the upper-right). +1. Briefly read over the [style + guide](https://translatewiki.net/wiki/Translating:Blockly) for Blockly's + translations. +1. Go to Blockly's [message group](https://translatewiki.net/w/i.php?title=Special:Translate&group=out-blockly-0-all) + (choose a language in the upper-right), and start translating! + +New translations may take a few months to show up on the live site. + +![A photo showing three Vietnamese girls in front of a +computer.](/images/vietnam.jpg) + +Note that [Klingon](klingon) is not supported by Translatewiki, so that language +needs to be handled separately. diff --git a/packages/docs/docs/guides/contribute/core/unit_testing.mdx b/packages/docs/docs/guides/contribute/core/unit_testing.mdx new file mode 100644 index 00000000000..168b1dc4368 --- /dev/null +++ b/packages/docs/docs/guides/contribute/core/unit_testing.mdx @@ -0,0 +1,247 @@ +--- +description: Blockly's unit testing setup and requirements. +title: Unit tests +image: images/blockly_banner.png +--- + +# Unit tests + +After changing or adding code, you should run existing unit tests and consider +writing more. All tests are executed on the uncompressed versions of the code. + +There are two sets of unit tests: JS tests and block generator tests. + +## JS Tests + +The JS tests confirm the operation of internal JavaScript functions in Blockly's +core. We use [Mocha](https://mochajs.org/) to run unit tests, +[Sinon](https://sinonjs.org/) to stub dependencies, and +[Chai](https://www.chaijs.com/) to make assertions about the code. + +### Running Tests + +In both blockly and blockly-samples, `npm run test` will run the unit tests. In +blockly, this will also run other tests such as linting and compilation. You can +also open `tests/mocha/index.html` in a browser to interactively run all mocha +tests. + +### Writing Tests + +We use the Mocha TDD interface to run tests. Tests are organized into suites, +which can contain both additional sub-suites and/or tests. Generally, each +component of Blockly (such as `toolbox` or `workspace`) has its own test file +which contains one or more suites. Each suite can have a `setup` and `teardown` +method that will be called before and after, respectively, each test in that +suite. + +#### Test Helpers + +We have a number of helper functions specific to Blockly that may be useful when +writing tests. These can be found in +[core](https://github.com/RaspberryPiFoundation/blockly/blob/main/tests/mocha/test_helpers/) +and in +[blockly-samples](https://github.com/RaspberryPiFoundation/blockly-samples/blob/main/plugins/dev-tools/src/test_helpers.mocha.js). + +The helper functions include `sharedTestSetup` and `sharedTestTeardown` which +are **required** to be called before and after your tests (see Requirements +section). + +##### `sharedTestSetup`: + +- Sets up sinon fake timers (in some tests you will need to use + `this.clock.runAll`). +- Stubs Blockly.Events.fire to fire immediately (configurable). +- Sets up automatic cleanup of blockTypes defined though + `defineBlocksWithJsonArray`. +- Declares a few properties on the `this` context that are meant to be + accessible: + - `this.clock` (but should not be restored else it will cause issues in + `sharedTestTeardown`) + - `this.eventsFireStub` + - `this.sharedCleanup` (to be used with `addMessageToCleanup` and + `addBlockTypeToCleanup`) (NOTE: you don't need to use + `addBlockTypeToCleanup` if you defined the block using + `defineBlocksWithJsonArray`) + +The function has one optional `options` parameter to configure setup. Currently, +it's only used to determine whether to stub `Blockly.Events.fire` to fire +immediately (will stub by default). + +##### `sharedTestTeardown`: + +- Disposes of workspace `this.workspace` (depending on where it was defined, + see Test Requirements section for more information). +- Restores all stubs. +- Cleans up all block types added though `defineBlocksWithJsonArray` and + `addBlockTypeToCleanup`. +- Cleans up all messages added though `addMessageToCleanup`. + +#### Test Requirements + +- Each test must call `sharedTestSetup.call(this);` as the first line in the + setup of the outermost suite and `sharedTestTeardown.call(this);` as the + last line in the teardown of the outermost suite for a file. +- If you need a workspace with a generic toolbox, you can use one of the + [preset toolboxes](https://github.com/RaspberryPiFoundation/blockly/blob/c12be77701cf34434274351f40356f5ad8e7b469/tests/mocha/index.html#L117) + on the test `index.html`. See below for an example. +- You must properly dispose of `this.workspace`. In most tests, you will + define `this.workspace` in the outermost suite and use it for all subsequent + tests, but in some cases you might define or redefine it in an inner suite + (for example, one of your tests requires a workspace with different options + than you originally set up). It must be disposed of at the end of the test. + - If you define `this.workspace` in the outermost suite and never redefine + it, no further action is needed. It will be automatically disposed of by + `sharedTestTeardown`. + - If you define `this.workspace` for the first time in an inner suite + (i.e. you did not define it in the outermost suite), you must manually + dispose of it by calling `workspaceTeardown.call(this, this.workspace)` + in the teardown of that suite. + - If you define `this.workpace` in the outermost suite, but then redefine + it in an inner test suite, you must first call + `workspaceTeardown.call(this, this.workspace)` **before redefining it** + to tear down the original workspace defined in the top level suite. You + must also manually dispose the new value by calling + `workspaceTeardown.call(this, this.workspace)` again in the teardown of + this inner suite. + +#### Test Structure + +Unit tests generally follow a set structure, which can be summarized as +_arrange, act, assert._ + +1. **Arrange**: Set up the state of the world and any necessary conditions for + the behavior under test. +1. **Act**: Call the code under test to trigger the behavior being tested. +1. **Assert**: Make assertions about the return value or interactions with + mocked objects in order to verify correctness. + +In a simple test, there may not be any behavior to arrange, and the act and +assert stages can be combined by inlining the call to the code under test in the +assertion. For more complex cases, your tests will be more readable if you stick +to these 3 stages. + +Here is an example test file (simplified from the real thing). + +```js +suite('Flyout', function () { + setup(function () { + sharedTestSetup.call(this); + this.toolboxXml = document.getElementById('toolbox-simple'); + this.workspace = Blockly.inject('blocklyDiv', { + toolbox: this.toolboxXml, + }); + }); + + teardown(function () { + sharedTestTeardown.call(this); + }); + + suite('simple flyout', function () { + setup(function () { + this.flyout = this.workspace.getFlyout(); + }); + test('y is always 0', function () { + // Act and assert stages combined for simple test case + chai.assert.equal( + this.flyout.getY(), + 0, + 'y coordinate in vertical flyout is 0', + ); + }); + test('x is right of workspace if flyout at right', function () { + // Arrange + sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({ + viewWidth: 100, + }); + this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_RIGHT; + this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_RIGHT; + + // Act + var x = this.flyout.getX(); + + // Assert + chai.assert.equal(x, 100, 'x is right of workspace'); + }); + }); +}); +``` + +Things to note from this example: + +- A suite can contain other suites that have additional `setup` and `teardown` + methods. +- Each suite and test has a descriptive name. +- Chai assertions are used to make assertions about the code. + - You can supply an optional string argument that will be displayed if the + test fails. This makes it easier to debug broken tests. + - The order of the parameters is `chai.assert.equal(actualValue, +expectedValue, optionalMessage)`. If you swap `actual` and `expected`, + the error messages won't make sense. +- Sinon is used to stub methods when you don't want to call the real code. In + this example, we don't want to call the real metrics function because it + isn't relevant to this test. We only care about how the results are used by + the method under test. Sinon stubs the `getMetrics` function to return a + canned response which we can easily check for in our test assertions. +- The `setup` methods for each suite should contain only generic setup that + applies to all tests. If a test for a particular behavior relies on a + certain condition, that condition should clearly be stated in the relevant + test. + +### Debugging Tests + +- You can open the tests in a browser and use the developer tools to set + breakpoints and investigate if your tests are unexpectedly failing (or + unexpectedly passing!). +- Set `.only()` or `.skip()` on a test or suite to run only that set of tests, + or skip a test. For example: + + ```js + suite.only('Workspace', function () { + suite('updateToolbox', function () { + test('test name', function () { + // ... + }); + test.skip('test I don’t care about', function () { + // ... + }); + }); + }); + ``` + + Remember to remove these before committing your code. + +## Block Generator Tests + +Each block has its own unit tests. These tests verify that blocks generate +code than functions as intended. + +1. Load `tests/generators/index.html` in Firefox or Safari. Note that Chrome and Opera + have security restrictions that prevent loading the tests from the local "file://" + system (Issues [41024](https://code.google.com/p/chromium/issues/detail?id=41024) + and [47416](https://code.google.com/p/chromium/issues/detail?id=47416)). +1. Choose the relevant part of the system to test from the drop-down menu, and + click "Load". Blocks should appear in the workspace. +1. Click on "JavaScript".
+ Copy and run the generated code in a JavaScript console. If the output ends + with "OK", the test has passed. +1. Click on "Python".
+ Copy and run the generated code in a [Python interpreter](https://repl.it/languages/python). + If the output ends with "OK", the test has passed. +1. Click on "PHP".
+ Copy and run the generated code in a [PHP interpreter](https://repl.it/languages/php). + If the output ends with "OK", the test has passed. +1. Click on "Lua".
+ Copy and run the generated code in a [Lua interpreter](https://repl.it/languages/lua). + If the output ends with "OK", the test has passed. +1. Click on "Dart".
+ Copy and run the generated code in a [Dart interpreter](https://dartpad.dev/). + If the output ends with "OK", the test has passed. + +## Editing Block Generator Tests + +1. Load `tests/generators/index.html` in a browser. +1. Choose the relevant part of the system from the drop-down menu, and click + "Load". Blocks should appear in the workspace. +1. Make any changes or additions to the blocks. +1. Click on "XML". +1. Copy the generated XML into the appropriate file in `tests/generators/`. diff --git a/packages/docs/docs/guides/contribute/core/write_a_codelab.mdx b/packages/docs/docs/guides/contribute/core/write_a_codelab.mdx new file mode 100644 index 00000000000..bb0c81700f9 --- /dev/null +++ b/packages/docs/docs/guides/contribute/core/write_a_codelab.mdx @@ -0,0 +1,107 @@ +--- +description: Steps and recommendations for writing a good codelab. +title: Write a codelab +image: images/blockly_banner.png +--- + +# Write a codelab + +## Introduction + +Codelabs are interactive tutorials written in Markdown syntax. They are +published as [part of our documentation](/codelabs/index). Codelabs use +a mix of natural language, code samples, and screenshots to create a more +interesting tutorial experience. The target user of a codelab is following along +and running the code as they read. + +![screenshots of the custom renderers codelabs](/images/structure-codelabs.png) + +Writing a codelab is a great way to contribute to the community. It's a way to +share your knowledge and make life easier for the next developer who runs into +the same problem. + +### What makes a great codelab? + +A great codelab is focused and readable. It clearly tell the user what they will +build and what they will learn, and it walks the user through writing and +understanding code to complete a specific task. + +### Process + +If you have an idea for a codelab, you can tell us about it by making a +[feature request](/guides/contribute/get-started/write_a_good_issue#feature-request) +in the blockly repository. Include a description of what you want to +teach and what you will build in the codelab. We'll discuss and refine the idea. +Then you can write it up and +[submit a pull request](/guides/contribute/get-started/write_a_good_pr) for +it. Once it's been through +[review](/guides/contribute/get-started/pr_review_process), a member of the +Blockly team will publish it. + +## Directory structure + +The [codelabs directory](https://github.com/RaspberryPiFoundation/blockly/tree/main/docs/docs/codelabs) +has one folder per codelab. Each codelab folder contains the codelab's Markdown +files and usually contain `starter-code/` and `complete-code/` subdirectories. +Assets (PNGs, GIFs, etc.) are stored in subdirectories of the +[`docs/static/images/codelabs`](https://github.com/RaspberryPiFoundation/blockly/tree/main/docs/static/images/codelabs). + +## Writing tips + +The rest of this page is a set of tips and questions to guide you through +writing a codelab. + +Check out [Technical Writing +One](https://developers.google.com/tech-writing/one) for a quick introduction to +technical writing. + +### Audience + +- Who is the target reader? +- What do they already know about using Blockly? +- What are they trying to learn? + +### Setup + +- What is the minimum setup required for the user to run your code? + +### Structure + +As with any writing, start with an outline. This is a good structure for most +codelabs: + +- Codelab overview + - What you'll learn + - What you'll build + - What you need to know +- Setup + - Download the repository code + - Additional setup instructions +- Step one: [Title goes here] + - Explanation/motivation + - Code sample + - Expected results + - (Optional) More explanation +- ... +- Step ten: [Title goes here] +- Summary + - What you learned + - What you built + - Additional resources + - Link to completed code + +Most codelabs have five to ten steps. If you have more than that, you should +consider breaking it into two codelabs. + +### Writing style + +- Use a conversational writing style. +- Use headings to make the organization clear. +- Use bulleted lists to break up walls of texts. +- Use images and gifs! + +### Code style + +- You can write in ES5, ES6, or TypeScript, but tell the reader which it is at + the beginning. +- Follow the [Google style guide](https://google.github.io/styleguide/jsguide.html) diff --git a/packages/docs/docs/guides/contribute/get-started/commits.mdx b/packages/docs/docs/guides/contribute/get-started/commits.mdx new file mode 100644 index 00000000000..08942df5d2b --- /dev/null +++ b/packages/docs/docs/guides/contribute/get-started/commits.mdx @@ -0,0 +1,94 @@ +--- +description: How commit messages should be structured. +title: Commit message guide +image: images/blockly_banner.png +--- + +# Commit message guide + +## Commit messages + +Clear commit messages make pull requests easier to review, and release notes +easier to generate. The Blockly project uses +[conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) to help +with this. + +Each commit should have the format: + +```none +: + +[optional body] + +[optional footer(s)] +``` + +Note that the core Blockly repo has a commit linter to help enforce this. If +your pull request has multiple commits, the linter will check the title. If it +has a single commit, it will check that commit. It is best if both your +individual commits and the pull request title follow these guidelines. + +### Type + +The type must be non-empty, and all lower case. The following is a list of +accepted types. + +- **`chore`:** For commits that complete routine/automated tasks such as upgrading + dependencies. + +- **`deprecate`:** For commits that deprecate functionality. + +- **`feat`:** For commits that add new functionality to Blockly. + +- **`fix`:** For commits that fix bugs/errors in Blockly. + +- **`release`:** For commits that relate to the release of a new version. + +#### Breaking changes + +Commits that make breaking changes should append a `!` after the type of the +commit. Breaking changes are changes that may break developers using Blockly in +their apps, causing them to have to do extra work. + +For example: + +```none +fix!: return type of workspace.paste +``` + +Breaking changes could have any of the above valid types. + +### Description + +The description must be non-empty, and must be under 256 characters. + +### Body + +The body is optional. If it is provided there should be a blank line between it +and the description. It must be broken into lines of no more than 256 +characters. + +Note that usually, it is advisable to put this kind of information in your +pull request description, in addition to/rather than directly in the commit. + +### Footer + +The footer is optional. If it is provided there should be a blank line between +it and the body. It must be broken into lines of no more than 256 characters. + +## Fixing non-conventional commits + +If you did not use [conventional commits](#commit-messages) when making your +modifications, there are two options for fixing the messages depending on how +many commits you have: + +1. If your pull request has multiple commits, edit the pull request title to + conform to the requirements. + When the pull request is merged, your other commits will be + [squashed](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-pull-request-commits) + so that the title becomes the commit message. + +2. If your pull request has a single commit, amend your commit message using + `git commit --amend`, then force push your changes to your fork of Blockly. + This will automatically updated any open pull requests associated with this + branch. `git push --force origin my-branch`. diff --git a/packages/docs/docs/guides/contribute/get-started/development_tools.mdx b/packages/docs/docs/guides/contribute/get-started/development_tools.mdx new file mode 100644 index 00000000000..969cc18052a --- /dev/null +++ b/packages/docs/docs/guides/contribute/get-started/development_tools.mdx @@ -0,0 +1,98 @@ +--- +description: Tools used to contribute code to Blockly. +title: Development tools +image: images/blockly_banner.png +--- + +# Development tools + +Blockly uses some tools and libraries for development, including Git, npm, and +the Closure Compiler. This section will provide some basic descriptions of each +tool, as well as links to where you can find more information about each tool. + +We use many of these tools through scripts. You may not need to ever run +them directly. Knowing the names may still be helpful for debugging or filing +issues or feature requests. + +### Git + +[Git](https://git-scm.com/) is a version control system that we use to track and +manage changes to files. + +### GitHub + +[GitHub](https://github.com/) is a hosting platform for version control, +collaboration, and distribution of open-source code. Git tracks the files; +GitHub provides smooth interfaces for reviewing code, tracking issues, and +viewing change history. + +**Getting started**: If you're new to Git and GitHub, work through GitHub's +[quickstart](https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/quickstart) +tutorials to get comfortable with the basics. + +### Node + +[Node.js](https://nodejs.org/) is a way to run JavaScript on the server (rather +than in a browser). npm (see below) runs on Node. + +### npm + +[npm](https://www.npmjs.com/) is two things: + +- A command-line tool that we use to install dependencies and run scripts. +- An online registry where we publish our code, which makes it easy for + other developers to use Blockly. + +**Getting started**: [Install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) +Node and npm. + +### Closure Compiler + +The [Closure Compiler](https://github.com/google/closure-compiler) is a tool for +making JavaScript download and run faster. We use it to combine all of our +JavaScript files into a single library; we also use it to check syntax and +types. + +**Getting started**: You don't need to install or run the Closure Compiler +directly: we install and run it through npm. + +**Read more**: Closure compiler documentation on [JavaScript types](https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System) +and [type annotations](https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler). + +### ESLint + +[ESLint](https://eslint.org/) is a static analyzer that finds problems with +JavaScript code. We use it to define and enforce a consistent style across our +codebase. Small problems with code (missing semicolons, inconsistent spacing, +etc.) are often called _lint_. ESLint automatically runs when you send us a pull +request. You can also run it locally. + +**Getting started**: In both Blockly core and blockly-samples, you can run +ESLint with `npm run lint`. Many code editors also have ESLint integrations to +show problems as you type. + +**Read more**: Each ESLint rule has a [documentation page](https://eslint.org/docs/rules/no-unreachable) +that describes the rule and gives examples of correct and incorrect code. + +### Mocha + +[Mocha](https://mochajs.org/) is a JavaScript test framework. We use it to run +tests in the browser and on Node.js (for headless use cases). + +**Getting started**: In both Blockly core and blockly-samples, you can run our +Mocha tests with `npm run test`. In Blockly core this will also run other tests. +Blockly core's Mocha tests are defined in the [tests/mocha](https://github.com/RaspberryPiFoundation/blockly/tree/main/tests/mocha) +directory. + +**Read more**: Mocha allows developers to define [hooks](https://mochajs.org/#hooks), +which allow you to define centralized setup and teardown functions for your +tests. + +### Chai + +[Chai](https://www.chaijs.com/) is an assertion library that we use in our Mocha +tests. + +**Read more**: Chai has multiple "flavors" of syntax, to make it easy to +integrate with existing projects. Blockly uses the +[assert](https://www.chaijs.com/api/assert/) flavor. diff --git a/packages/docs/docs/guides/contribute/get-started/index.mdx b/packages/docs/docs/guides/contribute/get-started/index.mdx new file mode 100644 index 00000000000..f3f62b46367 --- /dev/null +++ b/packages/docs/docs/guides/contribute/get-started/index.mdx @@ -0,0 +1,64 @@ +--- +description: Learn about contributing to Blockly. +title: Get started contributing to Blockly +image: images/blockly_banner.png +slug: /guides/contribute/get-started/index +--- + +# Get started contributing to Blockly + +Blockly is open source and is primarily maintained by a small team. We welcome +contributions from developers outside the core team; there is no way for us to +build every requested feature or fix every reported bug without our community. +This section contains general guides that may be helpful to you especially if +you are new to open source development. + +For information specific to Blockly that you should read before making a +contribution, see the +[Contributing to Core](/guides/contribute/core/index) and +[Contributing to Samples](/guides/contribute/samples/index) sections. + +## Which repository? + +A **repository** contains all the files for a single project. Blockly has two +repositories: blockly core and blockly-samples. + +**Blockly core** is the repository for the Blockly library. Use this repository +if you want to make a change to core Blockly behaviour in a way that will apply +to all users of the library. Blockly core also contains the documentation, including +the codelabs and codelab solutions. + +**Blockly samples** is the repository for samples and plugins. Use +this repository if you want to create or modify a plugin or a sample. + +## Step by step + +These are the general steps you will follow any time you make a change. + +1. **Install** Git and Node, following the links in the [Tools](/guides/contribute/get-started/development_tools) + section. +1. **Fork and clone the repository.** GitHub has a wonderful tutorial about + [forking a repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository). + To apply it to blockly, just replace every instance of + **octocat/Spoon-Knife** with **RaspberryPiFoundation/blockly** or + **RaspberryPiFoundation/blockly-samples**, depending on which repository you want to work + in. +1. **Sync your fork.** GitHub provides a tutorial for + [syncing a fork](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/syncing-a-fork) + as well. +1. **Check out the main branch.** In blockly core and blockly-samples, this branch is named `main`. +1. **Install** dependencies and build tools by running `npm install` in the + root directory. +1. **Create a new branch** by running `git checkout -b myBranchName` in a + terminal. The name should help you remember what you're working on. +1. **Make your changes.** +1. **Validate your changes,** following the guide for + [core](/guides/contribute/core/index) or + [samples](/guides/contribute/samples/index). +1. **Save your changes** with `git commit -am "fix: My commit message"`. + [Read more about commit messages](#). +1. **Push your changes** to GitHub with `git push origin myBranchName`. +1. **Open a pull request** when your code is ready. A member of the Blockly + team will review your changes and merge them into Blockly if they are + approved. For more information see + [PR Review Process](/guides/contribute/get-started/pr_review_process). diff --git a/packages/docs/docs/guides/contribute/get-started/issue_labels.mdx b/packages/docs/docs/guides/contribute/get-started/issue_labels.mdx new file mode 100644 index 00000000000..a1e68effdab --- /dev/null +++ b/packages/docs/docs/guides/contribute/get-started/issue_labels.mdx @@ -0,0 +1,148 @@ +--- +description: Issue labels used in blocky and blockly-samples. +title: Issue labels +image: images/blockly_banner.png +--- + +# Issue labels + +Labels are a cool feature of GitHub that allow you to filter issues and pull +requests. They help you find something fun to work on that fits with your level +of experience. + +For our repositories, adding new labels to issues is handled exclusively by the +core Blockly team, to make sure that things don't end up in the wrong spot. + +:::note +For more information about using labels, see +[Filtering issues and pull requests](https://help.github.com/en/github/managing-your-work-on-github/filtering-issues-and-pull-requests-by-labels). +::: + +### Size + +Some issues are bite-sized and beautiful, while others could take weeks to +defeat. These labels help you tell how much work an issue will probably take. + +- **[Good first issue](https://github.com/RaspberryPiFoundation/blockly-samples/labels/good%20first%20issue):** + These issues are great for people who are new to the repository. They should + take less than half a day's work and require limited familiarity with the + code base. You can start work on these issues immediately, without approval + from the team. + +### Jurisdiction + +Working on a widely-used repo can be a sensitive process, and some issues can be +more sensitive than others. These labels help you tell which issues are open for +contribution, and which issues to steer clear of. + +- **[Help wanted](https://github.com/RaspberryPiFoundation/blockly-samples/labels/help%20wanted):** + These issues are reserved for contributors. Often they are features the core + team think would be useful, but don't have time to implement. They may need + either discussion or implementation, so check the status label to see what + work is needed. This is a good place to find fun creative projects! +- **[Internal](https://github.com/RaspberryPiFoundation/blockly-samples/labels/internal):** + These issues are reserved for members of the core team. Often they are + sensitive or complex bugs that need special discussion. It's best to steer + clear of these because the situation around them could change rapidly! +- **[Neither](https://github.com/RaspberryPiFoundation/blockly-samples/issues?q=is%3Aissue+is%3Aopen+-label%3A%22help+wanted%22+-label%3A%22internal%22):** + Issues that have neither label can be fixed by contributors _and_ members of + the core team. If you see an unlabeled issue that seems interesting to you, + go ahead and take it! + +### Status + +Certain issues (particularly feature requests) go through a few different stages +before they can be considered "closed". These labels tell you what stage an +issue is currently in, so you can know what needs to be done next. + +- **[Discussion](https://github.com/RaspberryPiFoundation/blockly-samples/labels/status%3A%20discussion):** + These issues are in the + [discussion phase](/guides/contribute/samples/add_a_plugin#discussion), + which means there are still questions that need to be answered before + implementation. If you have any thoughts related to this issue, feel free to + leave a comment! We're always looking for more input. +- **[Implementation](https://github.com/RaspberryPiFoundation/blockly-samples/labels/status%3A%20implementation):** + These issues have had enough discussion that they are clearly defined, and + have moved into the [implementation phase](/guides/contribute/samples/add_a_plugin#implementation). + They are either waiting for implementation, or already being implemented. If + you're interested in working on one of these, read through the whole issue + and then leave a comment saying which part you want to work on, then go + ahead and dive in! +- **[Neither](https://github.com/RaspberryPiFoundation/blockly-samples/issues?q=is%3Aissue+is%3Aopen+-label%3A%22status%3A+discussion%22+-label%3A%22status%3A+implementation%22+):** + Issues that have neither label could be in either state. If you have an + opinion about how the issue should be implemented, go ahead and leave a + comment! Alternatively if you're interested in _working_ on the issue, it is + best to leave a comment asking if it is ready to be implemented. + +### Type + +Different issues require different responses. Some only require editing a few +lines of code, while others need lots of design and discussion. These labels +tell you what type of action an issue will need. + +- **[Bug](https://github.com/RaspberryPiFoundation/blockly-samples/labels/type%3A%20bug):** + These issues document a problem with the codebase. They often take some + debugging to diagnose what's causing the problem, but some can be fixed in a + wink. If you like digging deep to learn how the code ticks, these will be + great issues for you. You can help either by fixing the bug or by digging to + understand the issue and writing a clear explanation of the root cause. +- **[Feature request](https://github.com/RaspberryPiFoundation/blockly-samples/labels/type%3A%20feature%20request):** + These issues document a feature that someone would like to have added. This + can apply to the repository as a whole, or to an individual project. If you + like fleshing out design ideas and adding new functionality, these could be + the perfect issues for you. +- **[Question](https://github.com/RaspberryPiFoundation/blockly-samples/labels/type%3A%20question):** + These issues document a question someone has about the codebase. Generally + these questions are redirected to the + [developer forum](https://groups.google.com/g/blockly), but if + you see a question you feel you could help with, feel free to jump in and + respond. + +### Category + +This repository contains a few different kinds of projects, with a few different +kinds of target audiences. If you are passionate about tutorials, or love +working on plugins, these labels can help you find issues you're interested in. + +- **[Codelab](https://github.com/RaspberryPiFoundation/blockly/labels/category%3A%20codelab):** + These issues relate to Blockly + [codelabs](/guides/contribute/core/write_a_codelab/), + a suite of interactive tutorials. +- **[Example](https://github.com/RaspberryPiFoundation/blockly-samples/labels/category%3A%20example):** + These issues relate to Blockly + [examples](/guides/contribute/samples/repository_structure#examples), + a set of self-contained demos showcasing how to include and extend Blockly. +- **[Plugin](https://github.com/RaspberryPiFoundation/blockly-samples/labels/category%3A%20plugin):** + These issues relate to Blockly + [plugins](/guides/contribute/samples/repository_structure#plugins), + a collection of extensions that add functionality Blockly. + +### Project + +And if you want to get even more fine-grained there are also tags for individual +projects. These are usually created for plugins, which tend to have more issues +related to them, but they can also be created for codelabs and examples. If you +have a particular project you are interested in, these labels can help you find +issues related to that project. + +To see if there is a label for the project you are interested in, see the full list of labels: + +- [`blockly` repository labels](https://github.com/RaspberryPiFoundation/blockly/labels) +- [`blockly-samples` repository labels](https://github.com/RaspberryPiFoundation/blockly-samples/labels) + +### Other + +As with any collection of things, there are a few odd-balls you should also know +about. These labels may not be as helpful when you're looking for an issue to +work on, but they can still be informative. + +- **[Triage](https://github.com/RaspberryPiFoundation/blockly-samples/labels/triage):** These + issues have yet to be properly labeled by the core team. Issues with this + label may already include another simple label like + [bug](https://github.com/RaspberryPiFoundation/blockly-samples/labels/type%3A%20bug) or + [feature request](https://github.com/RaspberryPiFoundation/blockly-samples/labels/type%3A%20feature%20request), + but it is likely that more labels will be added soon. +- **[Duplicate](https://github.com/RaspberryPiFoundation/blockly-samples/labels/duplicate):** + These issues document a problem, request, or question that is already + covered by another issue. This label tells you that you should not reply to + this issue, but instead reply to the original issue. diff --git a/packages/docs/docs/guides/contribute/get-started/playground.mdx b/packages/docs/docs/guides/contribute/get-started/playground.mdx new file mode 100644 index 00000000000..5f33413330f --- /dev/null +++ b/packages/docs/docs/guides/contribute/get-started/playground.mdx @@ -0,0 +1,126 @@ +--- +description: The best way to develop with Blockly. +title: Use the playground +image: images/blockly_banner.png +--- + +# Use the playground + +When hacking in Blockly's core or developing a plugin, the playground is a +tremendously useful tool. It has a preconfigured instance of Blockly that you +can use for testing, debugging, or prototyping. At the Raspberry Pi Foundation, virtually all of +Blockly's development occurs using the playground. As a preview, here is the +[simple playground on the demo server](https://blockly-demo.appspot.com/static/tests/playground.html). + +There are 3 types of playgrounds for core Blockly: simple, advanced, and multi. +In blockly-samples, typically only the advanced playground is used. + +## Prerequisites + +Blockly now uses the Closure module system. Because of the way they are loaded, +uncompiled Closure modules must be fetched from an `http:` or `https:` URL and +cannot be fetched directly from `file:` URLs. Consequently, to load the +playground in uncompiled mode, you must load it from a local web server. + +We have created a script that starts up a local server and loads all of the code +required to load the Blockly modules. You will need to have +[npm installed on your machine](/guides/contribute/get-started/development_tools#npm) +and run `npm install` from the root of Blockly in order to install all +dependencies. + +### Using Internet Explorer + +Blockly now uses advanced features in its codebase that may not be compatible +with Internet Explorer. In the compressed (compiled) code, these features are +transpiled to work with IE, but loading the uncompressed code may not work. If +you load the playground in IE, even via a local http server, the playground will +therefore automatically load the compressed Blockly code in an effort to ensure +compatibility. See the "Accessing playgrounds directly" section for more details +about testing changes in the playground in compressed mode. + +## Simple Playground + +The simple playground is what the other two playgrounds are based on. It +displays a toolbox and workspace, and allows you to adjust a limited number of +settings. + +To open the playground, run + +```shell +npm run start +``` + +from the root of Blockly. Make sure there is nothing else listening on port 8080. This command will start a server hosting the Blockly modules and +automatically open your browser to the playground page. When you're ready to +shut the playground down, end the process (ctrl-c in Mac and Linux +environments). + +The playground features: + +- All code is uncompressed for rapid development. +- All the default blocks (except for some deprecated ones). +- All the language generators (JavaScript, Python, PHP, Lua, and Dart). +- Serialize and deserialize workspace state (JSON or XML). +- Switch between LTR and RTL layout. +- Switch between toolbox layouts. +- Stress tests for the renderer. +- Log all events in the console. + +## Advanced playground + +The advanced playground contains additional features to make debugging Blockly +even easier. This is also the default playground used in blockly-samples for all +plugins. + +This playground features all of the simple playground features plus: + +- Additional settings can be configured, such as grid size, zoom/move + controls, renderer, theme, and more. +- Settings and blocks used are cached and used automatically next time the + playground is loaded. +- See the output of each generator in the same window. + +To start the advanced playground for any plugin in blockly-samples, run `npm run +start` from the plugin's root directory. Currently, only one plugin can run at a +time, and it uses port 3000. If you have trouble getting the plugin to start, +first make sure nothing else is listening on that port. + +To start the advanced playground in core, run `npm run start` from Blockly's +root, and then click the "Advanced" link under the title. + +You can also create your own test page that includes the advanced playground by +using [Blockly's dev-tools package](https://www.npmjs.com/package/@blockly/dev-tools). + +## Multi playground + +The multi playground contains several playgrounds in different configurations +for LTR mode and location of the toolbox. This is mainly used to quickly check +that Blockly hasn't broken anything related to LTR before a release. To open +this playground, follow the steps for the simple playground, and then change the +URL to `/tests/multi_playground.html`. + +## Testing changes + +When running any of the playgrounds from a local server, all you need to do to +see your changes in Blockly in most cases is refresh the page. If you've added a +new file or added a new dependency to a file, you may need to first run `npm run +build` which will update the `test/deps.js` file to ensure dependencies are +loaded correctly, and then refresh the page. + +If you're running a plugin's advanced playground, you don't even need to refresh +the page. Changes are hotloaded automatically! + +## Accessing playgrounds directly + +Previously, the simple playground was accessed locally by directly navigating to +the `test/playground.html` file in your browser. This is still possible with the +simple and multi playgrounds, but it is no longer recommended. If you do this, +the playground will detect that you are not running a local server and +automatically use compressed Blockly files (see the +[Building Blockly page](/guides/contribute/core/building) for more +info) and whenever you change something in core Blockly, you will have to +rebuild core and stage the changes. You can still access these pages if hosted +on a remote server, such as our example hosted on our demo site. The background +will be bright blue whenever you are in compressed mode. + +The advanced playground is not available via `file:` access. diff --git a/packages/docs/docs/guides/contribute/get-started/pr_review_process.mdx b/packages/docs/docs/guides/contribute/get-started/pr_review_process.mdx new file mode 100644 index 00000000000..7ae0e5c96a0 --- /dev/null +++ b/packages/docs/docs/guides/contribute/get-started/pr_review_process.mdx @@ -0,0 +1,101 @@ +--- +description: The process a pull request goes through before being merged. +title: Code review process +image: images/blockly_banner.png +--- + +# Code review process + +### Goals + +Our review process has several goals: + +- **Ensure high quality code**, in both functionality and readability. +- **Catch bugs**, because bugs happen. +- **Maintain consistent style** so that it's easy to start working in any part + of the codebase. + +All of the code that goes into +[blockly-samples](https://www.github.com/RaspberryPiFoundation/blockly-samples) and +[core Blockly](https://www.github.com/RaspberryPiFoundation/blockly) goes through review, +whether it's written by community contributors or Blockly team members. + +As reviewers, we aim to work with you to make your change as good as possible. +We ask that you, as contributors, engage in conversation with us to get your +pull requests through review and merged. + +# The Process + +The PR review process goes through a few stages: + +1. [Assignment](#assignment) +2. [Feedback](#feedback) +3. [Discussion](#discussion) +4. [Revision](#revision) +5. [Repetition](#repetition) +6. [Merge!](#merge) + +## Assignment + +When your pull request comes in, the on-call member of the Blockly team assigns +a reviewer. + +Reviewers are chosen based on expertise and to evenly distribute workload. + +It may take a few days to get a reviewer assigned, and a few more days to get a +review. Don't worry, this is normal. + +## Feedback + +During the feedback stage a reviewer leaves suggestions for changes on your PR. +These could be simple things to make your code conform to the +[Google JavaScript style guide](https://google.github.io/styleguide/jsguide.html). +Or they could be larger things like asking you to reorganize your function +definitions. + +Reviewers are encouraged to use [GitHub's code +reviews](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/reviewing-proposed-changes-in-a-pull-request#starting-a-review) (rather +than making individual comments) so that you receive a single notification +instead of several. + +## Discussion + +The discussion phase is your chance to respond to the feedback. Maybe one +of the review comments wasn't clear: now is your chance to ask for +clarification. Or maybe your reviewer requested a change, but you think it will +have repercussions: now is your chance to find a compromise. + +:::note +For this to work, both parties need to go into the discussion with a +spirit of **collaboration**. The goal is not to "win" but to make something +you're both proud of. +::: + +## Revision + +The revision phase is where you get to make changes to your PR. Usually these +changes are a result of something your reviewer has said in the feedback phase. + +Once you have completed your revisions it can be helpful to [tag](https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax#mentioning-people-and-teams) +your reviewer asking them to take another look. + +:::note +discussion and revision may happen at the same time. +::: + +## Repetition + +After the revision phase your reviewer has another chance to give +[feedback](#feedback), and the process starts from the beginning. + +Often a second review is simple and focuses on nits such as punctuation and code +style. But sometimes a second review can be quite big. Your first reviewer may +even ask someone else to take a look, to get a fresh perspective. + +## Merge! + +The merge phase is your chance to **celebrate**. You've created a change, +discussed and revised it, and finally gotten it merged! This is a grand +achievement that many people never start, let alone complete! + +Thank you for all of your hard work to make Blockly better. And congratulations! diff --git a/packages/docs/docs/guides/contribute/get-started/write_a_good_issue.mdx b/packages/docs/docs/guides/contribute/get-started/write_a_good_issue.mdx new file mode 100644 index 00000000000..fef42fdfecb --- /dev/null +++ b/packages/docs/docs/guides/contribute/get-started/write_a_good_issue.mdx @@ -0,0 +1,208 @@ +--- +description: Steps and recommendations for writing a good issue. +title: Write a good issue +image: images/blockly_banner.png +--- + +# Write a good issue + +All great projects are built on user feedback. Blockly uses GitHub issues to +track feedback. This page details how to write an issue that is easy for a +developer to read and respond to, which makes it more likely that your bug +report/feature request will be addressed! + +## Pre-work + +### Got Questions? + +We love hearing your questions! But GitHub issues aren't a very good medium for +them. If you have a question, head over to our [developer +forum](https://groups.google.com/g/blockly) instead. If you ask your +question there you're more likely to get a timely and thorough response because +it is filled with developers that have been using Blockly for years! + +### Check for Duplicates + +Before you go about writing _any_ type of issue, it is always good to see if a +matching one already exists. If one does, this saves you the effort of having to +write it up yourself! So before you get started writing, do some searches for +duplicates or related issues. + +- Search in [blockly-samples](https://github.com/RaspberryPiFoundation/blockly-samples/issues?q=is%3Aissue+mySearchHere) +- Search in [Blockly core](https://github.com/RaspberryPiFoundation/blockly/issues?q=is%3Aissue+mySearchHere) +- Search the [forum](https://groups.google.com/g/blockly/search?q=mySearchHere) + +If you find a matching issue, give it a thumbs up or add a comment +detailing your thoughts. This is especially important for bug reports and +feature requests. If developers see that an issue is getting a lot of attention, +it is more likely to get worked on! + +## Report a Bug + +So you think you've discovered a bug? Great! We love hearing bug reports because +we want this project to be as stable as possible. Here are some steps you can +follow to help your bug get fixed. + +1. [Check for Duplicates](#check-for-duplicates) +1. [Gather Evidence](#gather-evidence) +1. [Locate the Issue](#locate-the-issue) +1. [Solidify your Reproduction](#solidify-your-reproduction) +1. [Suggest a Cause](#suggest-a-cause) +1. [Write your Issue!](#write-your-issue) + +### Gather Evidence + +Generally, the more information your bug has, the better. Here are a few things +you might want to provide: + +- **Screenshots or Gifs** can be really helpful if a bug causes a visual + problem. +- **Sample Code** is useful if a bug only affects certain kinds of blocks, or + configurations of workspaces. +- **A Hosted Site** is great if you're having trouble reproducing your bug + outside your specific environment. + +### Locate the Issue + +Between the core library, the plugins, the examples, and the codelabs, we've got +a lot of Blockly code. Help us out by telling us exactly where the issue is. + +If the problem is in core, which component or codelab is it in? For instance, it could be an issue +with the toolbox, or with the zoom controls, or with the library blocks. Be as +specific as possible. + +If the problem is in blockly-samples, figure out which plugin or +example it's in. If you find the same bug in multiple places, tell us that too. + +### Solidify your Reproduction + +A bug is only fixable if it is reproducible, so before you submit an issue, make +sure you have a solid way of getting your bug to occur. + +You should end up with a numbered list of steps that tell a developer how to +reproduce the bug. For example: + +1. Open X codelab. +1. Go to Y page. +1. Run Z example code. +1. Observe the bad behavior, which looks like W. + +If your issue is in Blockly core, try to reproduce it in the +[playground](https://blockly-demo.appspot.com/static/tests/playground.html). + +### Suggest a Cause + +If you think you know why the bug is happening, include that information as +well. Again, be as specific as possible. + +### Write your Issue! + +The time has come to write your bug report. Select your repository: + +- [Blockly core](https://github.com/RaspberryPiFoundation/blockly/issues/new?assignees=&labels=issue%3A+bug%2C+issue%3A+triage&template=bug_report.yaml) +- [Blockly-samples](https://github.com/RaspberryPiFoundation/blockly-samples/issues/new?assignees=&labels=type%3A+bug%2C+triage&template=bug_report.yaml) + +Be sure to fill out all of the sections of the issue template, even the ones +not detailed here. + +Thank you for your interest in reporting a bug, and happy issue writing! + +### What's Next? + +- Your bug report is automatically tagged for triage. +- The on-call member of the Blockly team will take a look and possibly ask + clarifying questions. They will also add labels, which we use to keep our bugs + organized. +- The issue may be marked "Help Wanted", in which case you can claim it and + start working on it. +- The issue may be assigned to a member of the Blockly team for a fix. +- The issue may be marked with a quarterly milestone, to indicate when it will + be done. +- The issue may be placed in the Icebox milestone, meaning that we do not intend + to work on it in the foreseeable future. + - This may happen for low-frequency issues or bugs with known workarounds. + - You can still work on Iceboxed issues. +- The issue may be placed in the Bug Bash Backlog milestone, meaning that it is + non-urgent but we still want to fix it. + - At the end of every quarter the team spends a few weeks working on bugs + pulled from the Bug Bash Backlog milestone. +- The issue may be moved from Blockly core to blockly-samples (or the + opposite direction) if needed. +- The issue may be closed. + +## Feature Request + +Is there something you want to change to make Blockly better? Do you have an +idea for a plugin, example, or codelab? Maybe there's already one you like, and +you've come up with a way to improve it. If so then you've come to the right +place! Here are steps to help you create a great feature request that gets a +response. + +1. [Check for Duplicates](#check-for-duplicates) +1. [Check the Requirements](#check-the-requirements) +1. [Gather your Thoughts](#gather-your-thoughts) +1. [Write your Feature Request!](#write-your-feature-request) + +### Check the Requirements + +We would love to allow every single idea to enter this repository! But sadly +we're only human, so we have some guidelines in place about what kinds of +requests we will pursue. + +Here are the guidelines for each of the different categories of projects: + +- [Blockly core](/guides/contribute/index) +- [Plugins](/guides/contribute/samples/add_a_plugin#first-party-criteria) +- Examples: Show how to use only one or two Blockly features. +- Codelabs: Show how to complete a single task or implement a single behaviour. + +But these aren't hard and fast rules. They're just meant to give you an idea of +what we're looking for before you put time into building your feature request. + +If you're unsure whether something fits, try posting it on our [developer +forums](https://groups.google.com/g/blockly). And remember, even if +your idea doesn't get accepted, we would still love for you to build it as a +third party plugin or tutorial! + +### Gather your Thoughts + +Your idea doesn't need to be 100% fleshed out with tinsel and diagrams before +you go ahead and submit, but you should have a solid idea of what you're looking +for. These are some good questions to ponder before you start to write: + +- Why do I want this feature? +- Does this feature solve a problem? +- Who is the intended audience for this feature? +- Why does this feature serve them? +- What are some alternative options that could achieve the same thing? + +Once you have those things figured out, you'll be most of the way to a good +feature request! + +### Write your Feature Request! + +Now you're ready to write your feature request. Select your repository: + +- [Blockly core](https://github.com/RaspberryPiFoundation/blockly/issues/new?assignees=&labels=issue%3A+feature+request%2C+issue%3A+triage&template=feature_request.yaml) +- [Blockly-samples](https://github.com/RaspberryPiFoundation/blockly-samples/issues/new?assignees=&labels=type%3A+feature+request%2C+triage&template=feature_request.yaml) + +Be sure to fill out all of the sections of the issue template, even the ones +not detailed here. + +Thank you for your interest in submitting a feature request, and happy issue +writing! + +### What's Next? + +- Your feature request is automatically tagged for triage. +- The on-call member of the Blockly team will take a look and possibly ask + clarifying questions. They will also add labels, which we use to keep our bugs + organized. +- The feature may be marked "Help Wanted", in which case you can claim it and + start working on it. +- The feature may be assigned to a member of the Blockly team for + implementation. +- The feature request may be moved from Blockly core to blockly-samples (or the + opposite direction) if needed. +- The feature request may be closed, in which case you still have the option to + implement it as a third-party plugin. diff --git a/packages/docs/docs/guides/contribute/get-started/write_a_good_pr.mdx b/packages/docs/docs/guides/contribute/get-started/write_a_good_pr.mdx new file mode 100644 index 00000000000..85301103162 --- /dev/null +++ b/packages/docs/docs/guides/contribute/get-started/write_a_good_pr.mdx @@ -0,0 +1,98 @@ +--- +description: Steps and recommendations for writing a good pull request. +title: Write a good pull request +image: images/blockly_banner.png +--- + +# Write a good pull request + +Pull requests are like the life blood of a repository. They keep everything +healthy and moving. This page details how to create a PR that is complete and +easy to review, which makes it more likely that your PR will get merged. + +Here are steps you can take to make sure you create the best PR possible. + +1. [Communicate](#communicate) +1. [Get Set Up](#get-set-up) +1. [Keep it Small](#keep-it-small) +1. [Keep it Clean](#keep-it-clean) +1. [Test your Change](#test-your-change) +1. [Communicate (pt2)](#communicate-1) + +### Communicate + +Before you jump in and start writing code, it's helpful to communicate with the +core team so they know what you're interested in. + +If there is an issue you are interested in, put a comment on the issue saying +you're going to start to work on it. This makes sure that we don't have multiple +people working on the same thing. A team member will respond to confirm that +it's yours. + +If you have an idea which is not covered by an issue, please [write one +up](/guides/contribute/get-started/write_a_good_issue) before you begin work. +This gives the team a chance to discuss how best to build out the change +_before_ you start building, which saves you work in the long run. + +### Get Set Up + +If this is your first time contributing to Blockly or blockly-samples, start at +the [development setup](/guides/contribute/get-started/development_tools) page. + +### Keep it Small + +Always try to keep your changes small and focused. We would much rather review +multiple smaller PRs than review one giant PR. Some good rules of thumb are: + +- **Fix one problem.** Don't try to tackle multiple issues at once. +- **Limit the scope.** Usually a PR should take < 8hrs (depending on your + familiarity with the codebase). +- **Use commits.** If your PR feels a little big, split the changes into + logical groups using git commits. + +### Keep it Clean + +Why care about code style? We're in it for the long term, and consistent style +makes maintenance easier. Style refers to how you name your variables, but also +covers how you structure your code, write comments, and more. Where possible we +use tools such as eslint to automate style checks. + +In addition to eslint, please follow these guides: + +- [Google JavaScript style + guide](https://google.github.io/styleguide/jsguide.html). +- [Commit Message Guide](/guides/contribute/get-started/commits) +- [API visibility](/guides/programming/using_blockly_apis) +- [Codelab style guide](/guides/contribute/core/write_a_codelab#writing-tips) + +### Test your Change + +Before you put up a PR you should always test that your changes are working, so +that you don't have to go back and fix things later. Here are some ideas for +testing the different categories of projects: + +- For **plugins**: write automated mocha tests covering your changes. +- For **examples**: manually test all of your demonstrated functionality. +- For **codelabs**: run through the entire tutorial in a clean environment and + test any example code you provide. + +### Communicate + +This is the last and arguably the most important part of creating a PR: writing +the summary. + +Writing a great PR summary helps other developers review your changes, making it +more likely that it will get accepted faster! + +Your summary should include things like: + +- What issue your PR is related to. +- What change your PR adds. +- How you tested your change. +- Anything you want reviewers to scrutinize. +- Any other information you think reviewers need. + +If you follow the PR template when your create your request you should be good +to go. Just remember to be as **concise** and **complete** as possible. + +Happy Coding! diff --git a/packages/docs/docs/guides/contribute/index.mdx b/packages/docs/docs/guides/contribute/index.mdx new file mode 100644 index 00000000000..4ed12daad09 --- /dev/null +++ b/packages/docs/docs/guides/contribute/index.mdx @@ -0,0 +1,44 @@ +--- +description: How to contribute (not just code!) to Blockly. +title: Contribute to Blockly +image: images/blockly_banner.png +slug: /guides/contribute/index +--- + +# Contribute to Blockly + +Blockly is an open-source project with a strong community, and we welcome your +contributions. + +## How you can help + +- [File bugs](/guides/contribute/get-started/write_a_good_issue) +- [File feature requests](/guides/contribute/get-started/write_a_good_issue#feature-request) +- [Fix bugs](/guides/contribute/get-started/write_a_good_pr) +- [Add tests](/guides/contribute/core/unit_testing) +- [Write codelabs](/guides/contribute/core/write_a_codelab) +- [Write plugins](/guides/contribute/samples/add_a_plugin) +- [Answer questions](https://groups.google.com/g/blockly) + +## Where to start + +- If you're new to open source development, or you want to get more background + knowledge, head over to the + [Getting Started contributing](/guides/contribute/get-started/index) + guides. +- If you are ready to jump in, check out the + [Contributing to Core](/guides/contribute/core/index) or + [Contributing to Samples](/guides/contribute/samples/index) guides. + +### Talk to us! + +Help us focus our development efforts by telling us +[what you are doing with Blockly](https://goo.gl/forms/kZTsO9wGLmpoPXC02). The +questionnaire only takes a few minutes and will help us better support the +Blockly community. + +Or join our +[newsgroup for developers](https://groups.google.com/g/blockly) and +say hello. Show us your prototypes early; collectively we have a lot of +experience and can offer hints which will save you time. Plus, we always love to +hear about new projects and use cases for Blockly! diff --git a/packages/docs/docs/guides/contribute/samples/add_a_plugin.mdx b/packages/docs/docs/guides/contribute/samples/add_a_plugin.mdx new file mode 100644 index 00000000000..e1d36245ca7 --- /dev/null +++ b/packages/docs/docs/guides/contribute/samples/add_a_plugin.mdx @@ -0,0 +1,151 @@ +--- +description: The process for creating a plugin. +title: Add a plugin +image: images/blockly_banner.png +--- + +# Add a plugin + +This document discusses how to create a new plugin. While the process it +describes is for creating first-party plugins, you can use it as a guideline for +creating third-party plugins. + +For an overview of plugins, +see [Plugins](/guides/programming/plugin_overview). + +For a quick introduction to creating a plugin, see our [How to Build a Plugin +talk +(2021)](https://www.youtube.com/watch?v=cZlZrTk2aQU&list=PLSIUOFhnxEiCjoIwJ0jAdwpTZET73CK7d&index=7). + +## First-party vs third-party + +The target user for a plugin is a developer who finds and uses the plugin +through npm. + +First-party plugins are supported by the Blockly team and published under the +`@blockly` scope on npm. They are designed to be usable in a wide range of +Blockly applications and are stable and easy to use. They are stored in the +[blockly-samples](https://github.com/RaspberryPiFoundation/blockly-samples). A field for +setting motor speed could be used in many robotics projects and is a good +candidate for a first-party plugin. + +Third-party plugins are maintained and published independently. They may be more +complex, more experimental, or targeted to a narrower range of Blockly +applications. A field for editing a specific object defined by your database +schema is better as a third-party plugin. + +### First party criteria + +First party plugins **must** meet these requirements: + +- Work on all major platforms, unless granted an exemption by the Blockly + team. + - Chrome, Firefox, Safari, Edge +- Have an author who is willing to handle bugs for the first year. +- Do not monkeypatch Blockly. +- Have a clearly defined and documented API. +- Do not call private or package functions from Blockly core, unless granted + an exemption by the Blockly team. + - Overriding package functions on a subclass that you define is allowed. + - If you want an exemption, ask us in an issue on blockly-samples. +- Have tests. + +## The process + +Plugins go through four stages: [suggestion](#suggestion), +[discussion](#discussion), [implementation](#implementation), and +[publishing](#publishing). + +## Suggestion + +A plugin starts as a **suggestion**. You can suggest a plugin by creating a new +issue with the [Feature +Request](https://github.com/RaspberryPiFoundation/blockly-samples/issues/new?assignees=&labels=type%3A+feature+request%2C+triage&template=feature_request.yaml) +template. For more information, read about [how to write a feature +request](/guides/contribute/get-started/write_a_good_issue#feature-request). + +In addition to the basic feature request information, a plugin suggestion should +include: + +- The API the plugin would expose. +- APIs that need to be added or changed in core Blockly to support the plugin. +- Screenshots, GIFs, or mock-ups if the plugin includes UI features. +- An explanation of why it should be a first-party plugin rather than a + third-party plugin. + +The Blockly team reviews suggestions as they come in and either closes the issue +or agrees that it would be a good first-party plugin. + +## Discussion + +Next, a plugin goes into the **discussion** phase. This phase includes: + +- Clarification of the desired functionality. +- Clarification of the plugin's API. +- Planning for implementation. +- Planning for tests. +- Discussion of API changes in core Blockly. +- Breaking large plugins into implementation steps. +- Plugin naming, based on our [naming + conventions](/guides/contribute/samples/naming). +- Confirming all [first party criteria](#first-party-criteria) will be met. + +This discussion generally happens on the GitHub issue. The smaller the scope of +the plugin, the faster the discussion phase can be. Larger plugins may attract +community attention and strong opinions about the Right Solution. If this +happens on your issue, congratulations! You have found something that people +care about. + +The goal is that at the end of the discussion phase, all major design decisions +have been made and there is a clear list of implementation steps. Both should be +documented in comments on the issue. + +During discussion we may decide that a plugin should be a third-party plugin, +and not be published under the `@blockly` scope. In that case we will explain +why and close the issue. + +When discussion is complete a Blockly team member notes that it is ready to be +implemented. + +## Implementation + +**Implementation** steps include: + +- Running `npx @blockly/create-package` to set up the plugin and its directory + from a template. [Learn + more...](https://github.com/RaspberryPiFoundation/blockly-samples/tree/main/plugins/dev-create) +- Implementing core logic for the plugin. +- Implementing a UI, if needed. +- Testing the plugin, using Mocha. +- Documenting the plugin, including the `README`. + +If a suggested plugin has been approved for implementation and you would like to +work on it, comment on the issue and ask if it's still open for contributions. + +Implementation may be done by multiple contributors in parallel. You may +implement a plugin collaboratively on your own fork, or through pull requests +against this repository. If you want to collaborate on a plugin in this +repository, ask the Blockly team to create a feature branch for you. + +Plugins should be added to the [`gh-pages/_index.html`](https://github.com/RaspberryPiFoundation/blockly-samples/blob/main/gh-pages/_index.html) +file in the `main` branch of blockly-samples. This will cause them to appear +on our [Plugins site](https://raspberrypifoundation.github.io/blockly-samples/). First-party +plugins should point to their test page. Third-party plugins can also be added +to this page, and can point to a link of their owner's choosing, such as a +hosted demo or the npm page. + +## Publishing + +Finally, **publishing**. The Blockly team uses [Lerna](https://lerna.js.org/) to +manage versioning and publishing for all plugins. + +Every Thursday, any plugins that have changed since their last release are +published. If you need a change to be published sooner, please note it on your +pull request. + +The Plugins site is also updated whenever plugins are published. + +Plugins that are not ready for publishing should be marked `private` in their +`package.json`. This may happen if a plugin relies on a not-yet-published change +in [core Blockly](https://github.com/RaspberryPiFoundation/blockly). Core Blockly is published +in the last week of each quarter (once every three months). diff --git a/packages/docs/docs/guides/contribute/samples/block_factory.mdx b/packages/docs/docs/guides/contribute/samples/block_factory.mdx new file mode 100644 index 00000000000..f130dea28ad --- /dev/null +++ b/packages/docs/docs/guides/contribute/samples/block_factory.mdx @@ -0,0 +1,242 @@ +--- +description: How to add a plugin field to Block Factory. +title: Add a plugin field to Block Factory +image: images/blockly_banner.png +--- + +# Add a plugin field to Block Factory + +[Blockly Developer +Tools](https://raspberrypifoundation.github.io/blockly-samples/examples/developer-tools/index.html) +lets you create custom blocks using blocks! It has support for fields that are +published as plugins in addition to the fields that come with core Blockly. If +you've created a custom field, you can add support for it to the Block Factory +by following this guide. The custom field must be published on npm before you +can add support for it. You also need to commit to updating your field to keep +up with changes in Blockly, otherwise we may need to remove it from Block +Factory in the future. + +## Development on the Block Factory + +The source code for the Block Factory is located in the blockly-samples +repository in the [`examples/developer-tools`][source-developer-tools] +directory. + +To submit a change to the Developer Tools in blockly-samples, you'll need to +follow the [typical steps][blockly-samples-development] for developing in +blockly-samples. Unlike working with plugins however, you'll need to run `npm +install` from the `examples/developer-tools` directory directly, rather than at +the root level of blockly-samples. + +## Install the plugin + +In order for the Block Factory to show your custom field in the preview, it +needs to install the custom field. Add your field as an npm dependency of +developer-tools. Then, register it or do any other setup work necessary in +[`developer-tools/src/blocks/index.ts`][source-blocks-index]. + +## Create a block for the field + +Since the Block Factory uses blocks to create custom blocks, you'll need a block +that represents your custom field. + +### Create the block definition + +You need to design the block for your field; if you want to get meta, you can +even design it using Block Factory! The block should allow the user to configure +the setup required by your field, such as default values, and a name. Add this +block definition to +[`developer-tools/src/blocks/fields.ts`][source-blocks-fields], and import it in +[`developer-tools/src/blocks/index.ts`][source-blocks-index]. + +### Add block to toolbox + +Next, you need to add this block to the toolbox definition to make it accessible +to users. The toolbox definition is located in +[`developer-tools/src/toolbox.ts`][source-toolbox]. Your block should be added +to the "Fields" category. + +## Code Generators + +The Block Factory works by using the Code Generator system you are already +familiar with from Blockly. Each block has a block-code generator for each type +of output generated by the Block Factory, and the parent blocks assemble the +code for the child blocks into the correct output. To add support for a custom +field, you'll need to add block-code generator functions for each of the Code +Generator classes. + +Create a file for your field block in the +[`output-generators/fields`][source-output-generators] directory. You'll add the +block-code generators for each of the following Generators to this file. Import +this file in the [`blocks/index.ts`][source-blocks-index] file so that the +block-code generator functions are loaded into the application. + +### JavaScript definition + +The `javascriptDefinitionGenerator` creates the code that will be included in +the JavaScript definition for a block that includes your custom field. Usually, +this means the block-code generator should return a line of code that looks like +`.appendField(new YourFieldConstructor(arg1, arg2), 'userSpecifiedName')`. Note +that this line of code does _not_ include a semicolon, because an input that +contains multiple fields will have several calls to `appendField` chained +together. The arguments in the constructor are pulled from the values the user +set on the field block. Here's an example of this block-code generator for +`FieldAngle`: + +```ts +javascriptDefinitionGenerator.forBlock['field_angle'] = function ( + block: Blockly.Block, + generator: JavascriptDefinitionGenerator, +): string { + const name = generator.quote_(block.getFieldValue('FIELDNAME')); + const angle = block.getFieldValue('ANGLE'); + return `.appendField(new FieldAngle(${angle}), ${name})`; +}; +``` + +The angle block that the user dragged from the "Fields" category of the Block +Factory toolbox has two fields on it: + +- `FIELDNAME`: user can set the name of the field on their custom block +- `ANGLE`: user can set the default angle value + +In this block-code generator, we get the default angle value and pass it as the +only argument to the `FieldAngle` constructor. The field name is always passed +as the second argument to `appendField`. + +:::note +For any place you would need quotation marks around a field value, such as +when passing the name of the field to `appendField`, you should use +`generator.quote_` rather than manually wrapping in quotation marks. +::: + +### JSON definition + +The `jsonDefinitionGenerator` is similar, but this outputs the part of the JSON +block definition that corresponds to your field. Typically, this code is a JSON +object that includes: + +- `type`: corresponds to the name of your field in the Blockly field registry +- `name`: user can set the name of the field on their custom block +- any other custom properties needed by your field's json initialization + method. + +Here's an example from the `FieldAngle` again: + +```ts +jsonDefinitionGenerator.forBlock['field_angle'] = function ( + block: Blockly.Block, + generator: JsonDefinitionGenerator, +): string { + const code = { + type: 'field_angle', + name: block.getFieldValue('FIELDNAME'), + angle: block.getFieldValue('ANGLE'), + }; + return JSON.stringify(code); +}; +``` + +:::note +Block-code generators always return strings, so stringify the object +before returning it. +::: + +### Code headers + +The Code Header Generator creates the Code Headers output shown in the Block +Factory. This output can be toggled between esmodule imports and script tags, +depending on how the user wishes to load the code, so there are actually two +different generator instances: one for each case. You need to add a block-code +generator for each of them. Here's an example for `FieldAngle`: + +```ts +importHeaderGenerator.forBlock['field_angle'] = function ( + block: Blockly.Block, + generator: CodeHeaderGenerator, +): string { + generator.addHeaderLine( + `import {registerFieldAngle, FieldAngle} from '@blockly/field-angle';`, + ); + generator.addHeaderLine(`registerFieldAngle();`); + return ''; +}; + +scriptHeaderGenerator.forBlock['field_angle'] = function ( + block: Blockly.Block, + generator: CodeHeaderGenerator, +): string { + generator.addHeaderLine( + ``, + ); + generator.addHeaderLine(`registerFieldAngle();`); + return ''; +}; +``` + +These generators have a method called `addHeaderLine` that lets you specify a +line of code that should be called before your field is used in code. Commonly, +this includes work such as importing the field or loading it through a script +tag, and perhaps calling a function that will register the field with Blockly's +field registry. + +:::tip +If your package is published on npm, it should automatically be available +on unpkg, which is a convenient place that script tags can load from. +::: + +For these two block-code generators, all the code should be added through calls +to `addHeaderLine`. This function will ensure each header line is only shown +once, even if your custom field block is used multiple times in one custom +block. The block-code generator should return the empty string. + +### Generator stub + +Lastly, we have the generator that creates the generator stub for the field. In +this block-code generator, you'll be writing code that generates code that helps +the user write code that generates code. Confused yet? It's easier than it +sounds! + +The generator stub for a custom block includes a premade variable +representing every field on the block. Then there's a `TODO` the user must +finish to assemble all of these variables into the final code string their +custom block will return. That means typically all your block-code generator +needs to do is return the line that creates this custom variable. Say the user +is making a custom block that will add rays of sunlight to their canvas. They +add an angle field to the block and name it `"SUN_DIRECTION"`. The generator +stub for this block would include the line `const angle_sun_direction = +block.getFieldValue("SUN_DIRECTION");`. That is the line of code our block-code +generator for the angle field needs to return: + +```ts +generatorStubGenerator.forBlock['field_angle'] = function ( + block: Blockly.Block, + generator: GeneratorStubGenerator, +): string { + const name = block.getFieldValue('FIELDNAME'); + const fieldVar = generator.createVariableName('angle', name); + return `const ${fieldVar} = block.getFieldValue(${generator.quote_( + name, + )});\n`; +}; +``` + +To get a standardized name for the variable, you can call +`generator.createVariableName` and pass in the type of your field (such as +`angle`, `number`, etc.) along with what the user named their field. + +## Test it + +After you've written all of these pieces, you should be able to start the Block +Factory by running `npm start` in the `blockly-samples/examples/developer-tools` +directory. You should be able to drag your block from the field category, add it +to an input on a block, and watch the output change. Check that the preview of +the block looks right, and that the code for each of the output sections is +correct. + +[blockly-samples-development]: /guides/contribute/samples/index +[source-developer-tools]: https://github.com/RaspberryPiFoundation/blockly-samples/blob/main/examples/developer-tools +[source-blocks-index]: https://github.com/RaspberryPiFoundation/blockly-samples/blob/main/examples/developer-tools/src/blocks/index.ts +[source-blocks-fields]: https://github.com/RaspberryPiFoundation/blockly-samples/blob/main/examples/developer-tools/src/blocks/fields.ts +[source-toolbox]: https://github.com/RaspberryPiFoundation/blockly-samples/blob/main/examples/developer-tools/src/toolbox.ts +[source-output-generators]: https://github.com/RaspberryPiFoundation/blockly-samples/tree/main/examples/developer-tools/src/output-generators/fields diff --git a/packages/docs/docs/guides/contribute/samples/block_libraries.mdx b/packages/docs/docs/guides/contribute/samples/block_libraries.mdx new file mode 100644 index 00000000000..2c414147aa9 --- /dev/null +++ b/packages/docs/docs/guides/contribute/samples/block_libraries.mdx @@ -0,0 +1,128 @@ +--- +description: Guidance for publishing plugins that contain block libraries. +title: Publish block libraries +image: images/blockly_banner.png +--- + +import Head from '@docusaurus/Head'; +import CompareBlock from '@site/src/components/CompareBlock'; + + + + + + +# Publish block libraries + +Plugins that provide libraries of block definitions are a great way to share +your reusable blocks with the Blockly community. To make your block library as +versatile and useful as possible, we've developed these guidelines. + +## Guidelines + +- Make it **easy** for users to install all of your blocks, and make it + **possible** for users to install only certain blocks or pieces of blocks + they choose. + - Make it easy to install everything: You can do this by providing a + function that installs every piece a single block definition requires + (such as mutators, extensions, mixins, fields, etc.). You can also + provide a function that will install all of the blocks offered by your + plugin at once. + - Make it possible to choose specific parts: You should export all of the + pieces of a block definition separately, so that it is possible for a + user to import only the pieces they need in order to create their own + similar custom block. +- Avoid using side effects in your plugin. + - Blocks, fields, extensions, and other pieces shouldn't be installed as a + side effect of loading your plugin. Users should maintain control over + which things are installed and when. This allows users to import the + pieces they need without worrying that pieces they don't will be + installed. +- Use the JSON field registry instead of instantiating new fields directly. + + - + Not Recommended - Instantiating a new field directly: + + ```js + const myCustomBlock = { + init: function() { + this.appendDummyInput() + .appendField(new Blockly.FieldNumber(123), 'NAME'); + } + } + ``` + + + - + Recommended - JSON field registry: + + ```js + export const myCustomBlock = { + init: function() { + this.appendDummyInput() + .appendField(Blockly.fieldRegistry.fromJson({ + name: 'field_number', + value: 123, + }), 'NAME'); + } + } + ``` + + + - Using the field registry makes it easier for a user to replace the + implementation of the field used in your block without having to change + the block definition. +- Don't make assumptions about what the user has already installed. + - If your plugin requires a custom field or another plugin, register those + fields yourself in your provided `install` function. + - Soon, Blockly will provide tools that let you register + already-registered items without error. Until then, you may want to + check what has already been registered before registering an extension, + mutator, mixin, or field yourself. + - Be clear about any prerequisites or dependencies that are required by + your plugin or block definitions. +- Consider providing generator functions for each of the blocks you provide. + - Providing generator functions that work out of the box makes it easier + for users to use your blocks without having to understand their + structure and design. If they have to write their own generator + functions, this may lead to redundant work being done by each user. + - JavaScript is the most commonly used language in Blockly, so if you only + pick one language to provide, we recommend JavaScript, unless your blocks + are built for a specific language such as implementing a Python library. + - Consider posting 'help wanted' issues for languages for which you are + unable to implement generator functions, and accept pull requests for + these if a user contributes them. + - If you provide an install function for your block, you can accept an + optional `generators` parameter. If a user passes a generator instance + that you support, you can automatically install the block-code generator + function and do related work such as adding reserved words: + + ```js + // Your plugin's install function + export const installMyCustomBlock(generators = {}) { + Blockly.common.defineBlocks({my_custom_block: myCustomBlock}); + if (generators.javascript) { + generators.javascript.forBlock['my_custom_block'] = myCustomGeneratorFunction; + generators.javascript.addReservedWords('specialReservedWord'); + } + } + + // How a user may install your block + import {javascriptGenerator} from 'blockly/javascript'; + import {installMyCustomBlock} from 'blockly-cool-blocks-plugin'; + // installs the block definition and the javascript block-code generator + installMyCustomBlock({javascript: javascriptGenerator}); + ``` + +## Feedback + +If you have questions about how to best follow these guidelines in your plugin, +let us know in the forum! We'd love to see your block libraries and provide +feedback on them. + +Note that not all first-party plugins that provide block definitions currently +follow these guidelines, but new plugins will and we plan to migrate existing +plugins. diff --git a/packages/docs/docs/guides/contribute/samples/debugging.mdx b/packages/docs/docs/guides/contribute/samples/debugging.mdx new file mode 100644 index 00000000000..fed54024271 --- /dev/null +++ b/packages/docs/docs/guides/contribute/samples/debugging.mdx @@ -0,0 +1,48 @@ +--- +description: How to test changes in blockly-samples that depend on changes in Blockly core. +title: Debug plugins +image: images/blockly_banner.png +--- + +# Debug plugins + +Sometimes when developing a plugin in blockly-samples, you'll need to make +corresponding changes in Blockly itself. Most plugins are set up to fetch +Blockly from the npm registry, so you'd only be able to use code that has +already been released on npm. This would make debugging your Blockly changes +difficult. When you want to make and test changes in both blockly and blockly- +samples, you can use `npm link` to test your unreleased changes together. + +## npm link + +You can tell npm to use a package from your machine instead of fetching the +package from the npm registry. Using this method, you should have access to +sourcemaps that make debugging blockly easier. You can use this method with +changes in core that haven't yet been pushed to GitHub. + +1. In your fork of blockly: + + ```shell + $ npm run package + $ cd dist + $ npm link + ``` + + These steps build core Blockly, package it, then create a symlink to the + packaged files. + +1. In your fork of blockly-samples, at root: + + ```shell + $ npm link blockly + ``` + + This step tells npm to look for the symlink you created earlier instead of + fetching the package from npm. + +1. `npm run start` from the plugin's directory to test your plugin. + +When you make changes in core, you'll have to rebuild and repackage it. + +When you're finished testing, run `npm ci` at the root level of blockly-samples +to reset the state of your repository. diff --git a/packages/docs/docs/guides/contribute/samples/index.mdx b/packages/docs/docs/guides/contribute/samples/index.mdx new file mode 100644 index 00000000000..759f27372c3 --- /dev/null +++ b/packages/docs/docs/guides/contribute/samples/index.mdx @@ -0,0 +1,63 @@ +--- +description: Learn how to contribute changes to Blockly Samples. +title: Contribute to samples +image: images/blockly_banner.png +slug: /guides/contribute/samples/index +--- + +# Contribute to samples + +[Blockly samples](https://github.com/RaspberryPiFoundation/blockly-samples) contains extra +content related to Blockly that isn't part of the core repository, including +plugins and example code. For more details about each of these, see +the [Repository +Structure](/guides/contribute/samples/repository_structure) page. + +## Need to Know + +Here is a quick overview of facts about blockly-samples you need to know in +order to create a PR. + +- The working branch is **main** and all PRs should be made against main. +- **Run `npm install` at the root level of blockly-samples,** not at the + individual plugin level. Blockly-samples is a monorepo, meaning it contains + multiple packages in the same repository, and installing at the root level + is part of the workflow for managing the monorepo with Lerna. +- Code must conform to either Google's [JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html) + or [TypeScript Style + Guide](https://google.github.io/styleguide/tsguide.html) depending on the + language used. +- Use [conventional commits](/guides/contribute/get-started/commits) + in your commit messages and pull request titles. +- Any new code files must be prefixed with the Apache License v2.0: + + ```js + /** + * @license + * Copyright Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + ``` + +## Make and Verify a Change + +1. Run `npm install` at the root level of blockly-samples to install + dependencies. +1. Run `npm run start` in a plugin's directory to build and start up a server + running the plugin's test page. You can use this page to see the existing + behavior of a plugin, or if you're adding a new plugin you will need to make + this a useful test page so that others can see what your plugin does. See + the [playground](/guides/contribute/get-started/playground) page for + more information. +1. Make any necessary changes to the plugin's code. +1. If you've left the server running, your changes will load automatically. + Otherwise, restart the server and verify the plugin behaves as expected and + there are no errors or warnings in the console. +1. Run `npm run build` and ensure there are no build errors. +1. Write automated mocha tests in the `test/` directory. +1. Run `npm run test` to run the automated tests. +1. Run `npm run lint:fix` to fix lint errors. Address any remaining warnings or + errors. +1. Run `npm run format` to run the autoformatter. +1. If all tests pass, you are ready to open a PR against **main** with your + changes. diff --git a/packages/docs/docs/guides/contribute/samples/naming.mdx b/packages/docs/docs/guides/contribute/samples/naming.mdx new file mode 100644 index 00000000000..386e916c3e0 --- /dev/null +++ b/packages/docs/docs/guides/contribute/samples/naming.mdx @@ -0,0 +1,98 @@ +--- +description: How to name your plugins consistently. +title: Plugin naming conventions +image: images/blockly_banner.png +--- + +# Plugin naming conventions + +## Overview + +Consistent plugin names are helpful for organizing and searching plugins, and +for finding published plugins on npm. + +This page lists our standard plugin naming conventions. If your plugin doesn't +fit in any of the categories, use the generic plugin naming format at the end of +the page. + +We recommend you add the suggested tags in your `package.json` to make it easier +to find your plugin on npm. + +## Plugin types + +### Field + +A field plugin publishes a single [custom +field](/guides/create-custom-blocks/fields/customizing-fields/overview). + +Loading a field plugin registers a new field type that can be used in all +Blockly workspaces on the page. + +| First Party | Third Party | Example | Suggested tags | +| ------------------ | ----------------- | ------------------------- | ------------------------- | +| `@blockly/field-*` | `blockly-field-*` | [`@blockly/field-slider`] | `blockly-plugin`, `field` | + +[`@blockly/field-slider`]: https://raspberrypifoundation.github.io/blockly-samples/plugins/field-slider/test/ + +### Theme + +A theme plugin publishes a single Blockly +[theme](/guides/configure/web/appearance/themes). + +Loading a theme plugin defines a new theme that can then be used in all Blockly +workspaces on the page. + +| First Party | Third Party | Example | Suggested tags | +| ------------------ | ----------------- | ------------------------- | ------------------------- | +| `@blockly/theme-*` | `blockly-theme-*` | [`@blockly/theme-modern`] | `blockly-plugin`, `theme` | + +[`@blockly/theme-modern`]: https://www.npmjs.com/package/@blockly/theme-modern + +### Block + +A block plugin publishes one or more [block +definitions](/guides/create-custom-blocks/overview). + +Loading a block plugin defines those blocks for all Blockly workspaces on the +page. + +| First Party | Third Party | Example | Suggested tags | +| --------------------- | -------------------- | ------------------------------ | ----------------------------------- | +| `@blockly/block(s)-*` | `blockly-block(s)-*` | [`@blockly/blocks-plus-minus`] | `blockly-plugin`, `block`, `blocks` | + +[`@blockly/blocks-plus-minus`]: https://raspberrypifoundation.github.io/blockly-samples/plugins/block-plus-minus/test/ + +### Block Extension + +A block extension plugin publishes one or more [block +extensions](/guides/create-custom-blocks/define/extensions), which can +be used to programmatically share behaviour between blocks. + +Loading a block extension plugin registers the extensions for use on all Blockly +workspaces on the page. + +| First Party | Third Party | Example | Suggested tags | +| ---------------------- | --------------------- | -------- | ---------------------------------- | +| `@blockly/extension-*` | `blockly-extension-*` | None yet | `blockly-plugin`,`block-extension` | + +### Workspace + +A workspace plugin adds behaviour to a single workspace. + +Loading a workspace plugin does nothing until it is initialized on a Blockly +workspace. + +| First Party | Third Party | Example | Suggested tags | +| ---------------------- | --------------------- | -------- | ---------------------------- | +| `@blockly/workspace-*` | `blockly-workspace-*` | None yet | `blockly-plugin`,`workspace` | + +### Generic plugin + +This is the most general plugin type. Use this naming convention if your plugin +doesn't meet the requirements of any other plugin type. + +| First Party | Third Party | Example | Suggested tags | +| ------------------- | ------------------ | ------------------------- | ---------------- | +| `@blockly/plugin-*` | `blockly-plugin-*` | [`@blockly/plugin-modal`] | `blockly-plugin` | + +[`@blockly/plugin-modal`]: https://raspberrypifoundation.github.io/blockly-samples/plugins/modal/test/ diff --git a/packages/docs/docs/guides/contribute/samples/repository_structure.mdx b/packages/docs/docs/guides/contribute/samples/repository_structure.mdx new file mode 100644 index 00000000000..b6e990b3a6b --- /dev/null +++ b/packages/docs/docs/guides/contribute/samples/repository_structure.mdx @@ -0,0 +1,57 @@ +--- +description: The types of content available in blockly-samples. +title: Repository structure +image: images/blockly_banner.png +--- + +# Repository structure + +The blockly-samples repository contains a few different categories of projects. +This page is meant to help you understand where the different categories live, +and what each project in a category might contain. + +### Examples + +Examples are self-contained sample projects demonstrating techniques to include +and extend the Blockly library. They usually consist of a demo web page, and +some supporting code. While codelab walk you through building something +step-by-step, Examples show you a finished product, and allow you to explore it +at your own pace. + +![Screenshot of the blockly-react example](/images/structure-examples.png) + +Example code is meant to be extremely well-commented so that it is easy to copy. +The target user may be reading the code, running it locally, or copying code +snippets. + +The +[examples directory](https://github.com/RaspberryPiFoundation/blockly-samples/tree/main/examples) +has one folder per example. Each example can be run with `npm install && npm run +start`, and has a `README.md` file with additional context or instructions. + +### Plugins + +Plugins are self-contained pieces of code that add functionality to Blockly. +Plugins can add fields, define themes, create renderers, and much more. The +target user is a developer who finds and uses the plugin through npm. Plugins +defined in this repository are _first-party_ plugins, which means that they are +supported by the Blockly team. + +![Screenshot of the "typed variable modal" plugin](/images/structure-plugin.png) + +The +[plugins directory](https://github.com/RaspberryPiFoundation/blockly-samples/tree/main/plugins) +has one folder per plugin. Each plugin has a `src` directory, where the code is +contained, and a `test` directory, where a demo page lives. They also contain a +`README.md` file, which gives developers information about what the plugin does, +and how to use it. + +### Github Pages + +Blockly-samples has a [webpage](https://raspberrypifoundation.github.io/blockly-samples/) where +many of the plugins and demos are available in a playground environment. This +page is hosted on GitHub pages, and the code for this site is in the +[gh-pages](https://github.com/RaspberryPiFoundation/blockly-samples/tree/main/gh-pages) +directory of blockly-samples. This directory contains templates for the pages on +the site. The actual site content is generated based on these templates and +metadata from each plugin or example hosted. diff --git a/packages/docs/docs/guides/create-custom-blocks/blockly-developer-tools.md b/packages/docs/docs/guides/create-custom-blocks/blockly-developer-tools.md new file mode 100644 index 00000000000..f6a1bf780f9 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/blockly-developer-tools.md @@ -0,0 +1,188 @@ +--- +description: How to use Blockly's tools for defining blocks. +title: Blockly Developer Tools +image: images/blockly_banner.png +--- + +# Blockly Developer Tools + +[Blockly Developer +Tools](https://raspberrypifoundation.github.io/blockly-samples/examples/developer-tools/index.html) +is a web-based developer tool that can help you build +[custom blocks][add-custom-blocks] and include them in your application. + +:::note +This document is about the newer version of Blockly Developer Tools that +is compatible with Blockly v10+. If you are looking for the legacy tool, see the +[legacy documentation][legacy-block-factory]. +::: + +![Screenshot of the Block Factory showing the toolbox and various output +areas](/images/block-factory/block_factory_overview.png) + +## Define a block + +The Block Factory workspace will start with an empty configuration block. You +can add [inputs][inputs] and [fields][fields] to the block by dragging blocks +from the respective categories in the toolbox. You can also set the tooltip +text, help URL, colour, and connection check(s) for the block by modifying the +configuration block. + +The Block Factory can only create one type of block at a time. If you want to +design several blocks that are connected together, you'll have to design the +blocks separately and connect them in the [toolbox definition][toolbox-preset]. +Additionally, blocks can have advanced features like [mutators][mutators], but +these advanced features can't be created in the Factory. You'll have to modify +the block definition according to the documentation after you've built the basic +form of the block. + +As you modify the configuration block in the workspace, the preview for the +block will update automatically. The code you will need to add to your +application will also update automatically. + +## Output configuration + +Blockly supports different methods of defining blocks and of loading Blockly +itself, as well as having multiple built-in code generator languages. The way +you define your blocks and block-code generators depends on these factors, so +you can set them in the Block Factory to change the code output. + +![Screenshot of the output configuration panel, with selectors for the blockly +import format, block definition format, and code generator +language](/images/block-factory/block_factory_configuration.png) + +### Blockly import format + +You can load Blockly through ` + + + + + +```` + +```js +// Add block-code generators for the custom_if block. +javascript.javascriptGenerator.forBlock['custom_if'] = function ( + block, + generator, +) { + /* ... */ +}; +python.pythonGenerator.forBlock['custom_if'] = function (block, generator) { + /* ... */ +}; +php.phpGenerator.forBlock['custom_if'] = function (block, generator) { + /* ... */ +}; +lua.luaGenerator.forBlock['custom_if'] = function (block, generator) { + /* ... */ +}; +dart.dartGenerator.forBlock['custom_if'] = function (block, generator) { + /* ... */ +}; +``` + + + +You must include the generator after you include Blockly. + +```html + + + + + + +``` + +```js +// Add block-code generators for the custom_if block. +javascript.javascriptGenerator.forBlock['custom_if'] = function ( + block, + generator, +) { + /* ... */ +}; +python.pythonGenerator.forBlock['custom_if'] = function (block, generator) { + /* ... */ +}; +php.phpGenerator.forBlock['custom_if'] = function (block, generator) { + /* ... */ +}; +lua.luaGenerator.forBlock['custom_if'] = function (block, generator) { + /* ... */ +}; +dart.dartGenerator.forBlock['custom_if'] = function (block, generator) { + /* ... */ +}; +``` + + + + +## Get field values + +Fields allow users to enter values like strings, numbers, and colours. To get a +field's value, call `getFieldValue`. What is returned is different from field to +field. For example, text fields return the exact text entered by the user, but +dropdown fields return a language-neutral string associated with the item the +user selected. For more information, see the [documentation for built-in +fields](/guides/create-custom-blocks/fields/built-in-fields/overview). + +Depending on the field, you may need to transform the returned value before +using it in code. + + + +```js +javascriptGenerator.forBlock['custom_compare'] = function (block, generator) { + // Use the value of the OPERATOR dropdown to look up the actual operator. + const OPERATORS = { + EQUALS: '==', + LESS: '<', + GREATER: '>', + }; + const operator = OPERATORS[block.getFieldValue('OPERATOR')]; + // The value of the RIGHT field is a number and can be used directly when + // building the block's code string. + const right = block.getFieldValue('RIGHT'); + ... +} +``` + + +```js +javascriptGenerator.forBlock['custom_if'] = function (block, generator) { + // Use the value of the NOT field to get the negation operator (if any). + const checkbox = block.getFieldValue('NOT'); + const negate = checkbox === 'TRUE' ? '!' : ''; + ... +} +``` + + + +For more information, see [Transform field +values](/guides/create-custom-blocks/code-generation/fields). + +## Get code from inner blocks + +Inner blocks are the blocks attached to a block's value and statement inputs. +For example, the `custom_if` block has a value inner block for the if condition, +and statement inner blocks for the code that is executed if the condition is +true. + +Unlike field values, the code you get from inner blocks is ready to go and does +not need to be transformed. + +:::note +A block attached to a next connection is not an inner block and your +block-code generator should ignore it. The language code generator gets the code +for next blocks. +::: + +### Inner value blocks + +To get code from an inner block attached to a value input, call `valueToCode`. +This method calls the inner block's code generator. + + + +```js +import {javascriptGenerator, Order} from 'blockly/javascript'; + +javascriptGenerator.forBlock['custom_compare'] = function (block, generator) { +... +const order = operator === '==' ? Order.EQUALITY : Order.RELATIONAL; +const left = generator.valueToCode(block, 'LEFT', order); +... +} + +```` + + +```js +import {javascriptGenerator, Order} from 'blockly/javascript'; + +javascriptGenerator.forBlock['custom_if'] = function (block, generator) { + ... + const order = checkbox === 'TRUE' ? Order.LOGICAL_NOT : Order.NONE; + const condition = generator.valueToCode(block, 'CONDITION', order) || 'false'; + ... +} +```` + + + + +When you call `valueToCode`, you need to tell it about the strongest operator in +your code that will apply to the inner block's code. This allows `valueToCode` +to determine whether it needs to wrap the inner block's code in parentheses. + +For example, checking the `NOT` box in `custom_if` applies a logical not +operator (`!`) to the condition. In this case, you pass the not operator's +precedence (`Order.LOGICAL_NOT`) to `valueToCode` and `valueToCode` compares +this to the precedence of the weakest operator in the inner block. It then wraps +the inner block's code as needed: + +- If `CONDITION` is a variable block, `valueToCode` doesn't add parentheses + because the not operator can be applied directly to a variable + (`!myBoolean`). +- If `CONDITION` is a comparison block, `valueToCode` adds parentheses so the + not operator applies to the entire comparison (`!(a < b)`) instead of the + left-hand value (`!a < b`). + +You don't actually need to know whether `valueToCode` added parentheses. All you +need to do is pass the precedence to `valueToCode` and add the returned code to +your code string. For more information, see [valueToCode +precedence](/guides/create-custom-blocks/code-generation/operator-precedence#valuetocode-precedence). + +### Inner statement blocks + +To get code from an inner block attached to a statement input, call +`statementToCode`. This method calls the inner block's code generator and +handles indenting code. + + + +The `custom_compare` block does not have any statement inputs. + + +```js +javascriptGenerator.forBlock['custom_if'] = function (block, generator) { + ... + const statements = generator.statementToCode(block, 'THEN'); + ... +} +``` + + + +You only need to call `statementToCode` for the inner block directly connected +to a statement input. `statementToCode` handles any additional blocks attached +to the first block. + +## Build and return your code string + +After you have gotten the code for the fields and inner blocks, build and return +the code string for your block. Exactly what you return depends on your block +type: + +- **Value blocks:** Return an array containing the code string and the + precedence of the weakest operator in your code. `valueToCode` uses this to + decide if your code needs to be wrapped in parentheses when your block is + used as an inner block. For more information, see [Return + precedence](/guides/create-custom-blocks/code-generation/operator-precedence#return-precedence). + +- **Statement blocks:** Return the code string. + + + +```js +import {javascriptGenerator, Order} from 'blockly/javascript'; + +javascriptGenerator.forBlock['custom_compare'] = function (block, generator) { +... +const order = operator === '==' ? Order.EQUALITY : Order.RELATIONAL; +... +const code = left + ' ' + operator + ' ' + right; +return [code, order]; +} + +```` + + +```js +javascriptGenerator.forBlock['custom_if'] = function (block, generator) { + ... + const code = 'if (' + negate + condition + ') {\n' + statements + '}\n'; + return code; +} +```` + + + + +If you use the code of an inner value block multiple times in your code string, +you should [cache the code from that +block](/guides/create-custom-blocks/code-generation/caching-arguments) +to avoid subtle bugs and unwanted side-effects. + +## Complete code generators + +For reference, here are the complete code generators for each block: + + + +```js +import {javascriptGenerator, Order} from 'blockly/javascript'; + +javascriptGenerator.forBlock['custom_compare'] = function (block, generator) { +const OPERATORS = { +EQUALS: '==', +LESS: '<', +GREATER: '>', +}; +const operator = OPERATORS[block.getFieldValue('OPERATOR')]; +const order = operator === '==' ? Order.EQUALITY : Order.RELATIONAL; +const left = generator.valueToCode(block, 'LEFT', order); +const right = block.getFieldValue('RIGHT'); +const code = left + ' ' + operator + ' ' + right; +return [code, order]; +} + +```` + + +```js +import {javascriptGenerator, Order} from 'blockly/javascript'; + +javascriptGenerator.forBlock['custom_if'] = function (block, generator) { + const checkbox = block.getFieldValue('NOT'); + const negate = checkbox === 'TRUE' ? '!' : ''; + const order = checkbox === 'TRUE' ? Order.LOGICAL_NOT : Order.NONE; + const condition = generator.valueToCode(block, 'CONDITION', order) || 'false'; + const statements = generator.statementToCode(block, 'THEN'); + const code = 'if (' + negate + condition + ') {\n' + statements + '}\n'; + return code; +} +```` + + + diff --git a/packages/docs/docs/guides/create-custom-blocks/code-generation/caching-arguments.mdx b/packages/docs/docs/guides/create-custom-blocks/code-generation/caching-arguments.mdx new file mode 100644 index 00000000000..01fa1a53128 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/code-generation/caching-arguments.mdx @@ -0,0 +1,189 @@ +--- +description: How to cache code from inner value blocks referenced multiple times. +title: Cache inner value block code +image: images/blockly_banner.png +--- + +# Cache inner value block code + +Value blocks correspond to expressions. When you use a value block as an inner +block, you may need to use the expression it generates more than once in your +block's code. For example, a block that gets the last element of a list uses the +expression that creates the list twice. + +```js +// Incorrect block-code generator. +javascriptGenerator.forBlock['last_element'] = function (block, generator) { + // Get the expression that creates the list. + const listCode = generator.valueToCode(block, 'LIST', Order.MEMBER); + + // listCode is used twice. + const code = `${listCode}[${listCode}.length - 1]`; + + return [code, Order.MEMBER]; +}; +``` + +This causes problems if the inner block's code generates different values each +time it is executed, or if the code has side effects. For example, if the inner +block's code is actually a function call, this particular code can cause an out +of range condition: + +```js +randomList()[randomList().length - 1]; +``` + +To avoid this problem, your code should execute an inner block's code exactly +once. There are two ways to do this: + +- [Temporary variables](#temporary-variables): Cache the result of evaluating + the inner block's code in a temporary variable and use the temporary + variable instead. You can use this method only if your block is a statement + block. + +- [Utility functions](#utility-functions): Create a function that performs the + work you need to do and pass the result of evaluating the inner block's code + as an argument to this function. You can use this method for both value and + statement blocks. + +## Temporary variables + +A temporary variable stores the value of an inner block's code string so that +the code is only _evaluated_ once, and then the value can be referenced multiple +times. + +Temporary variables cannot be used in value blocks because value blocks +must return a single line of code. Use a [utility function](#utility-functions) +instead. + +```js +import { javascriptGenerator, Order } from 'blockly/javascript'; + +// Correct block-code generator for a statement block that prints the last element of a list. +javascriptGenerator.forBlock['print_last_element'] = function ( + block, + generator, +) { + // Get the expression that creates the list. + const listCode = generator.valueToCode(block, 'LIST', Order.MEMBER); + // Get the name of a temporary variable. + const listVar = generator.nameDB_.getDistinctName( + 'temp_list', + Blockly.names.NameType.VARIABLE, + ); + + // Evaluate listCode once and assign the result to the temporary variable. + const code = `var ${listVar} = ${listCode};\n`; + // Print the last element of the list. + code += `print(${listVar}[${listVar}.length - 1]);\n`; + return code; +}; +``` + +For example, if the inner block's code is the function call `randomList()`, the +generated code is: + +```js +var temp_list = randomList(); +print(temp_list[temp_list.length - 1]); +``` + +The `getDistinctName` call takes in the variable name you want, and returns a +name that doesn't conflict with any user-defined variables. + +### Reduce redundant code + +The downside of temporary variables is that if the inner block's code is a value +and not a function or expression, you get code that's redundant: + +```js +// Assigning to temp_list is unnecessary. +var temp_list = foo; +print(temp_list[temp_list.length - 1]); +``` + +To produce cleaner code you can check if the inner block's code is a value, and +only include the temporary variable if it's not. + +```js +if (listCode.match(/^\w+$/)) { + const code = `print(${listCode}[${listCode}.length - 1]);\n`; +} else { + const listVar = generator.nameDB_.getDistinctName( + 'temp_list', + Blockly.names.NameType.VARIABLE, + ); + const code = `var ${listVar} = ${listCode};\n`; + code += `print(${listVar}[${listVar}.length - 1]);\n`; +} +``` + +## Utility functions + +A utility function is a developer-defined function included as part of the +generated code string. You can use them to make sure that inner-block code is +only _evaluated_ once, and then the value can be referenced multiple times. + +Utility functions can be used in value blocks and statement blocks. +However, statement blocks should generally use [temporary +variables](#temporary-variables), which are usually more readable. + +```js +import { javascriptGenerator, Order } from 'blockly/javascript'; + +// Correct block-code generator for a value block that gets the last element of a list. +javascriptGenerator.forBlock['last_element'] = function (block, generator) { + // Get the expression that creates the list. + const listCode = generator.valueToCode(block, 'LIST', Order.NONE); + // Create a function that accepts a list and returns its last element. The + // language generator adds this function to your code. + const functionName = generator.provideFunction_('list_lastElement', [ + `function ${generator.FUNCTION_NAME_PLACEHOLDER_}(list) {`, + ` return list[list.length - 1];`, + `}`, + ]); + + // Create an expression that calls the function with listCode as its argument. + // This evaluates listCode once and passes the resulting list to the function. + const code = `${functionName}(${listCode})`; + return [code, Order.FUNCTION_CALL]; +}; +``` + +For example, if the inner block's code is the function call `randomList()`, the +generated code is: + +```js +// This code is added to the overall code returned by the code generator. +function list_lastElement(list) { + return list[list.length - 1]; +} + +// This code is returned by your inner block. +list_lastElement(randomList()); +``` + +### Provide the function + +You can define utility functions inside block-code generators using +`provideFunction_`. It takes in the name you want for your utility function, and +an array of code strings that contain the function's definition. It returns the +resulting name of your utility function, after (possibly) modifying it to not +conflict with user-defined functions. + +`provideFunction_` also dedupes utility function definitions, so that each +utility function only exists once, even if the block type that defines it exists +multiple times. + +### Update precedences + +When you define a utility function, you should also update the precedences +(which define how [parentheses][parentheses] are inserted) included in the +block-code generator. + +The precedence is always based on the code string returned by the block-code +generator. It does not care about operators inside utility functions. So in the +previous example the `valueToCode` call was changed to `Order.NONE` and the +return tuple was changed to `Order.FUNCTION_CALL`. + +[parentheses]: /guides/create-custom-blocks/code-generation/operator-precedence diff --git a/packages/docs/docs/guides/create-custom-blocks/code-generation/fields.mdx b/packages/docs/docs/guides/create-custom-blocks/code-generation/fields.mdx new file mode 100644 index 00000000000..4da5cc24deb --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/code-generation/fields.mdx @@ -0,0 +1,71 @@ +--- +description: How to transform field values for use in generated code strings. +title: Transform field values +image: images/blockly_banner.png +--- + +# Transform field values + +Most field values are ready to be concatenated to your code string immediately. +However, some field values require extra work before they are usable. + +## Strings + +Strings need to be quoted with either `quote_` or `multiline_quote_` before they +can be concatenated. These functions perform language-specific character +escaping, such as replacing `'` with `\'` in JavaScript. + +```js +// For a single line text field. +const str = generator.quote_(block.getFieldValue('STR')); + +// For a multiline text field. +const str = generator.multiline_quote_(block.getFieldValue('STR')); +``` + +:::note +the `quote_` and `multiline_quote_` methods follow an earlier naming +convention with underscores, but they are public. +::: + +## Variables + +For the built-in variable field, `getFieldValue` returns a variable ID, not a +variable name. To get an actual variable name, call `getVariableName` in the +code generator. This returns a name that is both unique and legal. Among other +things, `getVariableName`: + +- Converts the non-ASCII characters to ASCII. This is necessary because users + can enter variable names in their own language. For example, it converts + "`متغير`" to "`_D9_85_D8_AA_D8_BA_D9_8A_D8_B1`". +- Ensures variable names follow the rules set forth by programming languages. + For example, it converts spaces to underscores and adds the prefix `my_` to + variable names that start with a digit. +- Resolves conflicts with reserved words or other variable or function names. + For example, it converts `for` to `for2`. + +```js +const identifier = generator.getVariableName(block.getFieldValue('VAR')); +``` + +## Dropdowns + +For the built-in dropdown field, `getFieldValue` returns a language-neutral +string that might not be directly usable in code. For example, a dropdown +containing comparison operators might return `'EQUALS'`, `'LESS'`, or +`'GREATER'`. This can be used to look up a string that is used in code. + +```js +const OPERATORS = { + EQUALS: '==', + LESS: '<', + GREATER: '>', +}; +const operator = OPERATORS[block.getFieldValue('OPERATOR')]; +``` + +## Checkboxes + +For the built-in checkbox field, `getFieldValue` returns `'TRUE'` or `'FALSE'`. +How you use this depends on the meaning of the checkbox. For example, you might +use it for branching while generating code. diff --git a/packages/docs/docs/guides/create-custom-blocks/code-generation/operator-precedence.mdx b/packages/docs/docs/guides/create-custom-blocks/code-generation/operator-precedence.mdx new file mode 100644 index 00000000000..2394231a068 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/code-generation/operator-precedence.mdx @@ -0,0 +1,179 @@ +--- +description: How parentheses are inserted during code generation. +title: Add parentheses +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Add parentheses + +Blocks imply parentheses. For example, when you see the following blocks, you +assume it means `-(5 + 2)` not `-5 + 2` because the `5` and the `2` are part of +one block, and the `-` is part of another block. + +blocks representing -(5 + 2) + +But if you put parentheses around every block, it makes the code much less +readable. Compare `(((5) * (2)) + (3))` with `5 * 2 + 3`. Both of these +expressions evaluate to the same thing (`13`) but the second one is much easier +to read. + +Blockly's operator precedence rules help you generate code with the minimum +number of parentheses, for maximum readability. + +## Generate "correct" output + +If you don't need your generated code to be human-readable, then there's no need +to worry about minimizing parentheses. Wrapping every block is a fine approach, +and it ensures that your generated code is always evaluated correctly. + +To ensure correctness, always pass `Order.ATOMIC` to `valueToCode` calls, and +always return `Order.NONE` from your block-code generator. + +## Generate optimal parentheses + +Parentheses only need to be inserted if the generated code is incorrect without +them. This happens when the precedence of an operator in the outer block is +stronger than the precedence of an operator in the inner block. + +:::note +Precedence is the order operators get evaluated in. For example, in basic +arithmetic precedence is specified by +[`PEMDAS`](https://en.wikipedia.org/wiki/Order_of_operations#Mnemonics). +::: + +For example, in the following blocks there is a unary negation operator and an +addition operator. The unary negation has a stronger precedence than the +addition operator. + +negate-and-addition + +So if you don't add parentheses you get `-5 + 2`, and the `-` is evaluated +before the `+`, which is doesn't match the blocks. + +You can tell the generator when to insert parentheses by telling it how strong +your different operators are. If it sees that the outer operator is stronger +than the inner operator, it inserts parentheses to protect the inner operator. + +`valueToCode` takes in the precedence of the outer operator, and the return +tuple specifies the precedence of the inner operator. + +Here is an example for a block that includes two operators: + +A block with a unary negation operator, and an addition operator, and a child block. + +```js +import { javascriptGenerator, Order } from 'blockly/javascript'; + +javascriptGenerator.forBlock['negate_plus_two'] = function (block, generator) { + // valueToCode takes in the precedence of the outer operator. + const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION); + const code = `-${innerCode} + 2`; + // The return tuple specifies the precedence of the inner operator. + return [code, Order.ADDITION]; +}; +``` + +### valueToCode precedence + +When you call `valueToCode` to generate the code of an inner block, you pass it +the precedence of the _strongest operator_ acting on the code of the inner +block. This is the operator the inner block's code needs to be protected from. + +For example, in the following blocks both the unary negation operator and the +addition operator are acting on the code of the inner block. The unary negation +is stronger, so that is the precedence you should pass to `valueToCode`. + +A block with a unary negation operator, and an addition operator, and a child block. + +```js +// The - is the strongest operator acting on the inner code. +const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION); +const code = `-${innerCode} + 2`; +``` + +### Return precedence + +When you return a precedence from your block-code generator, return the +precedence of the _weakest operator_ within the code of the block. This is the +operator that needs protecting. + +For example, the following block contains both a unary negation operator and an +addition operator. The addition is weaker, so that is the precedence you should +return from the block-code generator. + +A block with a unary negation operator, and an addition operator, and no child block + +```js +const code = `-${innerCode} + 2`; +// The + is the weakest operator in the block. +return [code, Order.ADDITION]; +``` + +## Order enum + +Every language generator module defines an `Order` enum which includes all of +the precedences for that language. + +Stronger precedences have lower backing values, and weaker precedences have +higher backing values. You can think of strong precedences as being "ranked +higher" in strength, and weaker precedences as being "ranked lower" - as if they +were competitive fighters. + +Here is where you can find the `Order` enums for all of the built-in languages: + +- [Dart order][dart-order] +- [JavaScript order][javascript-order] +- [Lua order][lua-order] +- [PHP order][php-order] +- [Python order][python-order] + +### Special precedences + +Most of the precedences in the generators' `Order` enums match the precedences +defined by their respective text-based languages. But there are two special +precedences, `Order.ATOMIC` and `Order.NONE`. + +`Order.ATOMIC` is the strongest precedence. It is used when: + +- You want to [ensure code is always parenthesized](#generate-correct-output), + so you pass it to `valueToCode`. +- Your block doesn't include any operators, so you return it from your + block-code generator. + +`Order.NONE` is the weakest precedence. It is used when: + +- You want to [ensure code is always parenthesized](#generate-correct-output), + so you return it from your block-code generator. +- There are no operators acting on an inner block, so you pass it to + `valueToCode`. + +[negate-and-addition]: /images/code-generation/parentheses/negation-and-addition.png +[negate-plus-two-with-child]: /images/code-generation/parentheses/negate-plus-two-with-child.png +[negate-plus-two]: /images/code-generation/parentheses/negate-plus-two.png +[dart-order]: https://github.com/RaspberryPiFoundation/blockly/blob/dcd2d0e539f2b7aa34b58969d5dc812e7848800c/generators/dart/dart_generator.ts#L27 +[javascript-order]: https://github.com/RaspberryPiFoundation/blockly/blob/dcd2d0e539f2b7aa34b58969d5dc812e7848800c/generators/javascript/javascript_generator.ts#L27 +[lua-order]: https://github.com/RaspberryPiFoundation/blockly/blob/dcd2d0e539f2b7aa34b58969d5dc812e7848800c/generators/lua/lua_generator.ts#L28 +[php-order]: https://github.com/RaspberryPiFoundation/blockly/blob/dcd2d0e539f2b7aa34b58969d5dc812e7848800c/generators/php/php_generator.ts#L26 +[python-order]: https://github.com/RaspberryPiFoundation/blockly/blob/dcd2d0e539f2b7aa34b58969d5dc812e7848800c/generators/python/python_generator.ts#L27 diff --git a/packages/docs/docs/guides/create-custom-blocks/code-generation/overview.mdx b/packages/docs/docs/guides/create-custom-blocks/code-generation/overview.mdx new file mode 100644 index 00000000000..0363a726119 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/code-generation/overview.mdx @@ -0,0 +1,86 @@ +--- +description: What code generation is, and how to implement it. +title: Code generation +image: images/blockly_banner.png +--- + +# Code generation + +Code generation is the process of turning the blocks on a workspace into a +string of code that can be executed. + +Code generation is extremely important, because it is what allows your blocks to +actually _do_ things, like evaluate arithmetic expressions, move a character +through a maze, or configure an online shop! + +You can't "run" blocks directly. Instead you generate code strings, and then +execute those. + +## Language code generators + +To generate code, you have to pick what text-based language you want to +generate. This is because each language has its own code generator. + +A **language code generator** (commonly called a **code generator**) is a class +that handles the rules for generating code that are specific to a given +language, but not specific to an individual block. For example, it handles +things like formatting comments, indenting statements, and quoting strings. + +Blockly provides 5 built-in code generators: + +- JavaScript ES5 +- Python 3 +- Lua 5.1 +- Dart 2 +- PHP 7 + +If this list doesn't include the language you want to generate code for, you can +create a custom language code generator. For a simple example, see the [Build a +custom generator][custom-code-generator] codelab, which creates a JSON language +code generator. For a more complex example, see the [JavaScript code +generator][js-code-generator]. Note that you also need to write block-code +generators for any built-in blocks that you want to use. + +## Block-code generators + +Each block is responsible for generating its own code. When you create a block, +you need to write a separate block-code generator for each language you want to +support. + +A **block-code generator** is a function that returns the code for that block as +a string. For example, a block that compares two numbers returns a string of the +form `'a < b'` and a block that represents an if statement returns a string of +the form `'if (...) {\n...\n};\n'`. + +```js +import { javascriptGenerator } from 'blockly/javascript'; +import { pythonGenerator } from 'blockly/python'; + +// Write block-code generators for JavaScript and Python. +javascriptGenerator.forBlock['my_custom_block'] = function (block, generator) { + /* ... */ +}; +pythonGenerator.forBlock['my_custom_block'] = function (block, generator) { + /* ... */ +}; +``` + +Block-code generators are called by language code generators. + +For more information, see [Block-code +generators](/guides/create-custom-blocks/code-generation/block-code). + +## Generate and run code + +Your application can generate code at any time. For example, it might generate +code when the end-user clicks a button or every time the user makes a change. + +After you've generated the code, you need to figure out how to execute it. +Deciding how to execute it is very application-specific, and outside the scope +of Blockly. + +For more information, see [Generate and run +code](/guides/app-integration/run-code). + +[custom-code-generator]: /codelabs/custom-generator/codelab-overview/index.html +[js-code-generator]: https://github.com/RaspberryPiFoundation/blockly/blob/main/generators/javascript/javascript_generator.ts diff --git a/packages/docs/docs/guides/create-custom-blocks/define/block-anatomy.mdx b/packages/docs/docs/guides/create-custom-blocks/define/block-anatomy.mdx new file mode 100644 index 00000000000..689fd345bc5 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/block-anatomy.mdx @@ -0,0 +1,327 @@ +--- +title: Anatomy of a block +description: Explains the different parts of a block. +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Anatomy of a block + +This document explores the different parts of a block. + +## Connections + +**Connections** define where blocks can connect and what kind of blocks they can +connect to. + +:::info +The term **connection** normally refers to a relationship between two +things. In Blockly, it usually means _connector_, like a plug or socket. Thus, +when you connect two blocks, you fit their connections together. +::: + +There are four types of connections: + +| Connection type | Image | +| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| Output connection | an output connection | +| Input connection | an input connection | +| Previous connection | a previous connection | +| Next connection | a next connection | + +[output]: /images/connections/output-connection.png +[input]: /images/connections/input-connection.png +[previous]: /images/connections/previous-connection.png +[next]: /images/connections/next-connection.png + +Output connections and input connections can connect together, and next +connections and previous connections can connect together. You can further +restrict connections with [connection +checks](/guides/create-custom-blocks/inputs/connection-checks). + +You can [customize the shapes of +connections](/guides/create-custom-blocks/renderers/create-custom-renderers/connection-shapes) +using a custom renderer. + +### Top-level connections + +Blocks have three connections whose use is optional. + +A block may have a single output connection, represented as a male jigsaw +connector on the leading edge of a block. An output connection passes a block's +value (expression) to another block. A block with an output connection is called +a **value block**. + +A math_number block. + +A block may have a previous connection on its top (represented as a notch) and a +next connection on its bottom (represented as a tab). These allow blocks to be +stacked vertically, representing a sequence of statements. A block without an +output connection is called a **statement block** and usually has both previous +and next connections. + +A variables_set block. + +For more information, see [Top-level +connections](/guides/create-custom-blocks/define/top-level-connections). + +## Fields + +**Fields** define the majority of UI elements within a block. These include the +string labels, dropdowns, checkboxes, images, and inputs for +[literal]() data +such as strings and numbers. For example, this loop block uses label fields, a +dropdown field, and number fields. + +A block with multiple fields. + +Blockly provides a number of [built-in +fields](/guides/create-custom-blocks/fields/built-in-fields/overview), +including text inputs, color pickers, and images. You can also [create your own +fields](/guides/create-custom-blocks/fields/customizing-fields/overview). + +For more information, see +[Fields](/guides/create-custom-blocks/fields/overview). + +## Inputs + +**Inputs** are containers for fields and connections. A block is built by +rendering its inputs in one or more rows like bricks. + +:::info +The term **input** has a number of meanings in Blockly. Its most +common meaning is the one described here: a container for fields and +connections. Less commonly, it means to enter a value or refers to a value that +has been entered. +::: + +There are four different types of inputs, all of which can contain fields +(including labels) and two of which contain a single connection. You can also +[create custom +inputs](/guides/create-custom-blocks/inputs/creating-custom-inputs), +which support [custom +rendering](/guides/create-custom-blocks/renderers/overview). + +| Input type | Connection type | Image | +| ---------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | +| Dummy input | None | dummy input | +| End-of-row input | None | end-of-row input | +| Value input | Input connection | value input | +| Statement input | Next connection | statement input | + +We will introduce these inputs through a series of examples. For information +about defining the inputs, connections, and fields that make up a block, see +[Block structure in +JSON](/guides/create-custom-blocks/define/structure-json) and [Block +structure in +JavaScript](/guides/create-custom-blocks/define/structure-js). + +### Dummy inputs + +A **dummy input** is just a container for fields -- it does not have a +connection. For example, the following number block has a single dummy input +that contains a single number field. + +A number block with a dummy input and a number field. + +As a more complex example, consider a block that adds two numbers together. This +could be built from a single dummy input with three fields (number, label, +number): + +An addition block built from a dummy input with three fields. + +or three dummy inputs, each with a single field: + +An addition block built from three dummy inputs, each wieht a single field. + +### End-of-row inputs + +Blockly uses heuristics to decide whether to render all inputs in a single row +or render each input in its own row. If you want to be sure that an input starts +a new row, use an **end-of-row input** as the previous input. + +Like dummy inputs, end-of-row inputs can contain fields but do not have a +connection. For example, here is the addition block built from an end-of-row +input with two fields and a dummy input with one field. The end-of-row input +forces the dummy input to be rendered in a new row. + +An addition block split into two rows by an end-of-row input. + +### Value inputs + +Fields are limited in what they can accept. For example, number fields only +accept numbers. But what if you want to add two variables together? Or add the +result of a procedure call to the result of a different calculation? To solve +this problem, use input connections instead of fields. This allows users to use +value blocks as input values. + +A **value input** contains zero or more fields and ends in an input connection. +The following block replaces the number fields in the addition block with input +connections. It is built from two value inputs -- the first does not contain any +fields and the second contains a label field. Both end in input connections. + +An addition block with two value inputs. + +### Statement inputs + +The last type of input is a **statement input**, which contains zero or more +fields and ends with a next connection. The next connection lets you nest a +stack of statement blocks inside your block. For example, consider the following +repeat block. The second row of this block consists of a statement input with a +single label field and a next connection. + +A repeat block with a statement input to nest repeated statements. + +Statement inputs are always rendered in their own row. You can see this in the +following if-then-else block, which has a value input in its first row and +statement inputs in the next two rows. + +An if-then-else block with separate statement inputs for then and else statements. + +### Inline versus external inputs + +Inputs can be rendered **inline** or **externally**. This controls whether the +connectors for value inputs are rendered inside the block (inline) or on the +outside edge (external), as well as whether inputs are rendered in the same or +different rows. + +![The same block rendered once with inline inputs and once with external +inputs.](/images/set-inputs-inline.png) + +When you create a custom block, you can specify which to use or let Blockly +decide for you. For more information, see [Inline vs. external +inputs](/guides/create-custom-blocks/define/inline-vs-external). + +### Go play! + +The best way to learn about inputs, fields, and connections is to construct +blocks in the [Blockly Developer Tools](https://raspberrypifoundation.github.io/blockly-samples/examples/developer-tools/index.html) and choose different +settings for the `inputs` dropdown (`automatic`, `external`, `inline`). + +## Icons + +In addition to inputs, connections, and fields, blocks can have one or more +**icons**. These have a variety of uses, such as displaying warnings, entering +block-level comments, or displaying the mutator UI. For example, here is a block +with a comment icon and its associated editor. + +A block with a comment icon and an open comment editor. + +For more information, see +[Icons](/guides/create-custom-blocks/icons/overview). + +## Blocks and JavaScript objects + +Blocks, inputs, connections, fields, and icons are all JavaScript objects. + +| Blockly component | Base class | Subclasses | +| ----------------- | ------------ | -------------------- | +| Block | `Block` | `BlockSvg` | +| Input | `Input` | `DummyInput` | +| | | `EndRowInput` | +| | | `ValueInput` | +| | | `StatementInput` | +| | | custom input | +| Connection | `Connection` | `RenderedConnection` | +| Field | `Field` | `FieldTextInput` | +| | | `FieldNumber` | +| | | `FieldLabel` | +| | | custom field | +| | | etc. | +| Icon | `Icon` | `CommentIcon` | +| | | `MutatorIcon` | +| | | `WarningIcon` | +| | | custom icon | + +The objects in a block form a tree-shaped object. Understanding how the +graphical representation of a block corresponds to this tree is helpful when you +write code to manipulate blocks programmatically. For example, a `controls_for` +block: + +![A loop block with a variable field, value inputs for to, from, and by, and a +statement input for repeated +statements.](/images/block-anatomy/controls-for.png) + +corresponds to the following tree of JavaScript objects. + +```js +// means an instance of an Object. +{ // Block + nextConnection: , // ConnectionType NEXT_STATEMENT + outputConnection: null, + previousConnection: , // ConnectionType PREVIOUS_STATEMENT + inputList: [ // Array of Inputs in block + { // ValueInput + connection: , // ConnectionType INPUT_VALUE + fieldRow: [ // Array of fields in Input + , // 'count with' + , // i + , // 'from' + ], + }, + { // ValueInput + connection: , // ConnectionType INPUT_VALUE + fieldRow: [ + , // 'to' + ], + }, + { // ValueInput + connection: , // ConnectionType INPUT_VALUE + fieldRow: [ + , // 'by' + ], + }, + { // StatementInput + connection: , // ConnectionType NEXT_STATEMENT + fieldRow: [ + , // 'do' + ], + }, + ] +} +``` diff --git a/packages/docs/docs/guides/create-custom-blocks/define/block-definitions.mdx b/packages/docs/docs/guides/create-custom-blocks/define/block-definitions.mdx new file mode 100644 index 00000000000..71601748e10 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/block-definitions.mdx @@ -0,0 +1,102 @@ +--- +description: What are block definitions and how do they work? +title: What's a block definition? +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# What's a block definition? + +A **block definition** is an object that defines a custom block. For example, it +defines the block's look and feel, (text, fields, connections, colour, etc.), as +well as its behavior (block-level event handler, etc.). + +For example, this block: + +![A `string_length` block.](/images/text-length.png) + +can be defined in JSON or JavaScript as follows: + + + + ```js + Blockly.common.defineBlocksWithJsonArray([{ + "type": "string_length", + "message0": 'length of %1', + "args0": [ + { + "type": "input_value", + "name": "VALUE", + "check": "String" + } + ], + "output": "Number", + "colour": 160, + "tooltip": "Returns number of letters in the provided text.", + "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp" + }]); + ``` + + `defineBlocksWithJsonArray` creates a block definition from a JSON object. + + + ```js + Blockly.Blocks['string_length'] = { + init: function() { + this.appendValueInput('VALUE') + .setCheck('String') + .appendField('length of'); + this.setOutput(true, 'Number'); + this.setColour(160); + this.setTooltip('Returns number of letters in the provided text.'); + this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp'); + } + }; + ``` + + When you use JavaScript, you create the block definition directly. + + +## How block definitions work + +A block definition is a [mixin](https://en.wikipedia.org/wiki/Mixin) containing +function-valued properties. When a new block is instantiated, these properties +are copied to the newly created block object. Blockly calls these functions to +invoke custom behavior. + +Because the definition functions are mixed in to the block object: + +- The `this` keyword in definition functions refers to the block object. That + is, it can be used to access the public methods and properties in the + [`Block`](/reference/blockly.block_class) (or + [`BlockSvg`](/reference/blockly.blocksvg_class)) class. + +Blockly defines a small number of functions you can use to customize blocks. The +most common of these is `init`, which Blockly calls to initialize a block and +which is used to define the block's look and feel. For a complete list, see the +function-valued properties in the +[`Block`](/reference/blockly.block_class#properties) and +[`BlockSvg`](/reference/blockly.blocksvg_class#properties) classes. +These properties effectively form an interface for block definitions to +implement; all of them are optional. + +Block definitions can also have custom functions, although Blockly will not call +these directly. Instead, they can be used to implement other functions. For +example, a block-level event handler (the `Block.onchange` property) could +delegate different events to different custom functions. + +## How to create block definitions + +There are several different ways to create block definitions: + +- Use the Blockly Developer Tools to define the look and feel of your block. + Copy the generated JSON or JavaScript to your code and add custom code as + needed. For more information, see [Blockly Developer + Tools](/guides/create-custom-blocks/blockly-developer-tools). +- Find a similar block, copy its definition, and modify it as needed. For more + information, see [Modify existing + definitions](/guides/create-custom-blocks/define/modify-definitions). +- Write a block definition by hand. For more information, see [JSON and + JavaScript](/guides/create-custom-blocks/define/json-and-js). diff --git a/packages/docs/docs/guides/create-custom-blocks/define/block-help.mdx b/packages/docs/docs/guides/create-custom-blocks/define/block-help.mdx new file mode 100644 index 00000000000..664737f2450 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/block-help.mdx @@ -0,0 +1,118 @@ +--- +description: How to provide help for blocks. +title: Block help +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Block help + +You can provide block help in the form of tooltips and a help URL. + +## Tooltips + +Tooltips offer instant help when the user hovers their mouse over the block. +If the text is long, it will wrap automatically. + + + + ```js + { + // ..., + "tooltip": "Tooltip text." + } + ``` + + + ```js + init: function() { + this.setTooltip("Tooltip text."); + } + ``` + + +In the JavaScript API, tooltips can also be defined as a function instead of a +static string. This allows for dynamic help. See `math_arithmetic` for an +example of a tooltip that changes depending on which dropdown option has been +chosen. + + + + ```js + Blockly.Blocks['math_arithmetic'] = { + init: function() { + // ... + + // Assign 'this' to a variable for use in the tooltip closure below. + var thisBlock = this; + this.setTooltip(function() { + var mode = thisBlock.getFieldValue('OP'); + var TOOLTIPS = { + 'ADD': Blockly.Msg['MATH_ARITHMETIC_TOOLTIP_ADD'], + 'MINUS': Blockly.Msg['MATH_ARITHMETIC_TOOLTIP_MINUS'], + 'MULTIPLY': Blockly.Msg['MATH_ARITHMETIC_TOOLTIP_MULTIPLY'], + 'DIVIDE': Blockly.Msg['MATH_ARITHMETIC_TOOLTIP_DIVIDE'], + 'POWER': Blockly.Msg['MATH_ARITHMETIC_TOOLTIP_POWER'] + }; + return TOOLTIPS[mode]; + }); + } + }; + ``` + + +Using the JavaScript API, blocks can specify a function, instead of a static +string, which returns the tooltip string. This allows for dynamic tooltips. +See `math_arithmetic` for an example. + +### Customizing + +You can also customize the look of your tooltips by providing a custom rendering +function. Create a function that accepts two parameters: + +- first, a `
` element where you will render the content +- second, the actual element that is being moused over and that you will show + the tooltip for + +In the body of the function, you can render whatever content you like into the +div. To get the tooltip string defined on the block being moused over, you can +call `Blockly.Tooltip.getTooltipOfObject(element);` where `element` is the +second parameter above. + +Finally, register this function so Blockly can call it at the appropriate time: + +```js +Blockly.Tooltip.setCustomTooltip(yourFnHere); +``` + +For an example, see the +[Custom Tooltips demo](https://raspberrypifoundation.github.io/blockly-samples/examples/custom-tooltips-demo/). + +## Help URL + +Blocks can have a help page associated with them. This is available to users by +right-clicking the block and selecting "Help" from the context menu. If this +value is `null` then the "Help" item is not shown. + + + + ```js + { + // ..., + "helpUrl": "https://en.wikipedia.org/wiki/For_loop" + } + ``` + + + ```js + init: function() { + // ... + this.setHelpUrl('https://en.wikipedia.org/wiki/For_loop'); + } + ``` + + +Using the JavaScript API, blocks can specify a function, instead of a static +string, which returns a URL string, thus allowing for dynamic help. diff --git a/packages/docs/docs/guides/create-custom-blocks/define/block-state.mdx b/packages/docs/docs/guides/create-custom-blocks/define/block-state.mdx new file mode 100644 index 00000000000..94ee9321a9e --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/block-state.mdx @@ -0,0 +1,91 @@ +--- +description: How to set block state. +title: Block state +image: images/blockly_banner.png +--- + +# Block state + +Block instances have a number of properties that configure how they behave to +the user. While these can be set in the block definition, they are more commonly +used to constrain blocks in the workspace to reflect certain properties of the +domain (e.g., there is exactly one 'start' event), or focus the user's effort +(e.g., a tutorial). + +## Deletable state + +```js +block.setDeletable(false); +``` + +When set to `false`, the user will not be able to delete the block. Blocks +default to deletable on an editable workspace. + +Any block, (even undeletable ones) may be deleted programmatically: + +```js +block.dispose(); +``` + +## Editable state + +```js +block.setEditable(false); +``` + +When set to `false`, the user will not be able to change the block's fields +(e.g. dropdowns and text inputs). Blocks default to editable on an editable +workspace. + +## Movable state + +```js +block.setMovable(false); +``` + +When set to `false`, the user will not be able to move the block directly. An +immovable block that is a child of another block may not be disconnected from +that block, though it will move with its parent if the parent is moved. Blocks +default to movable on an editable workspace. + +Any block (even immovable ones) may be moved programmatically once it is on a +workspace. + +```js +block.moveBy(dx, dy); +``` + +The starting position for a block on a workspace defaults to `(0, 0)`. + +## Block data + +```js +block.data = '16dcb3a4-bd39-11e4-8dfc-aa07a5b093db'; +``` + +Data is an optional and arbitrary string that is attached to the block. When the +block is serialized the data string is serialized with it. This includes when +the block is duplicated or copy/pasted. + +Often this is used to associate a block with an external resource. + +When serialized to JSON, the data is stored as a top-level property in the +block: + +```json +{ + "type": "my_block", + "data": "16dcb3a4-bd39-11e4-8dfc-aa07a5b093db" + // etc.. +} +``` + +When serialized to XML (the old iceboxed serialization system) the data string +is stored in a `` tag within the block: + +```xml + + 16dcb3a4-bd39-11e4-8dfc-aa07a5b093db + + +``` diff --git a/packages/docs/docs/guides/create-custom-blocks/define/destroy.mdx b/packages/docs/docs/guides/create-custom-blocks/define/destroy.mdx new file mode 100644 index 00000000000..69cf10c1d77 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/destroy.mdx @@ -0,0 +1,45 @@ +--- +description: How to define a destroy hook. +title: Destroy hook +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Destroy hook + +Blocks have a `destroy` hook, which is called when they are deleted from the +workspace. This can be used to destroy any backing data models or external +resources associated with the block that are no longer needed. + + + + ```js + { + // ..., + "extensions":["destroy"], + } + + Blockly.Extensions.registerMixin('destroy', { + destroy: function() { + this.myResource.dispose(); + } + }); + ``` + + In JSON, define a `destroy` hook with a + [mixin](/guides/create-custom-blocks/define/extensions#mixins). + + + ```js + Blockly.Blocks['block_type'] = { + destroy: function() { + this.myResource.dispose(); + } + } + ``` + + +The `destroy` method is called after the block's parent has been disposed, but +before any of its children or fields have been disposed. diff --git a/packages/docs/docs/guides/create-custom-blocks/define/extensions.mdx b/packages/docs/docs/guides/create-custom-blocks/define/extensions.mdx new file mode 100644 index 00000000000..58b414524c1 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/extensions.mdx @@ -0,0 +1,91 @@ +--- +description: Adding extra functionality into the behavior of blocks. +title: Extensions and mixins +image: images/blockly_banner.png +--- + +# Extensions and mixins + +**Extensions** are functions that are run on a block during initialization. +These often add some **custom configuration or behavior** to a block. +**Mixins** allow you to to add properties or helper functions to a block, but +not run them immediately. + +You only need to use extensions or mixins when you define a block with JSON. If +you use JavaScript to define a block, you can call initialization functions +directly in `init` and add methods or properties directly to the definition. + +## Extensions + +Extensions are functions that run on each block of a given type as the block is +created. For example, they may add custom configuration (e.g. setting the +block's tooltip) or custom behavior (e.g. adding an event listener to the +block). + +```js +// This extension sets the block's tooltip to be a function which displays +// the parent block's tooltip (if it exists). +Blockly.Extensions.register('parent_tooltip_extension', function () { + // this refers to the block that the extension is being run on + var thisBlock = this; + this.setTooltip(function () { + var parent = thisBlock.getParent(); + return ( + (parent && parent.getInputsInline() && parent.tooltip) || + Blockly.Msg['MATH_NUMBER_TOOLTIP'] + ); + }); +}); +``` + +Extensions have to be "registered" so that they can be associated with a string +key. Then you can assign this string key to the `extensions` property of your +block type's [JSON +definition](/guides/create-custom-blocks/define/json-and-js) to apply +the extension to the block. + +```js +{ + //..., + "extensions": ["parent_tooltip_extension",] +} +``` + +You can also add multiple extensions at once. Note that the `extensions` +property must be an array, even if you are only applying one extension. + +```js +{ + //..., + "extensions": ["parent_tooltip_extension", "break_warning_extension"], +} +``` + +## Mixins + +Blockly also provides a convenience method for situations where you want to add +some properties/helper functions to a block, but not run them immediately. This +works by allowing you to register a [mixin](https://en.wikipedia.org/wiki/Mixin) +object that contains all of your additional properties/methods. The mixin object +is then wrapped in a function which applies the mixin every time an instance of +the given block type is created. + +```js +Blockly.Extensions.registerMixin('my_mixin', { + someProperty: 'a cool value', + + someMethod: function() { + // Do something cool! + } +))` +``` + +String keys associated with mixins can be referenced in JSON just like any other +extension. + +```js +{ + //..., + "extensions": ["my_mixin"], +} +``` diff --git a/packages/docs/docs/guides/create-custom-blocks/define/inline-vs-external.mdx b/packages/docs/docs/guides/create-custom-blocks/define/inline-vs-external.mdx new file mode 100644 index 00000000000..ff3eeea0ce1 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/inline-vs-external.mdx @@ -0,0 +1,77 @@ +--- +description: The difference between inline and external inputs. +title: Inline vs. external inputs +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Inline vs. external inputs + +Inputs can be rendered **inline** or **externally**. This controls whether the +connectors for value inputs are rendered inside the block (inline) or on the +outside edge (external), as well as whether inputs are rendered in the same or +different rows. + +![Inline and external variations of the "count with x from value to value do +statement" block. In the inline variation, the block has two rows: the top row +has "count with x from value to value" and the bottom row has "do statement". +The value inputs look like puzzle pieces cut out of the inside of the top row. +In the external variation, the block has four rows: "count with x", "from +value", "to value", and "do statement". The value inputs are at the ends of the +second and third rows and look like female puzzle +connectors.](/images/set-inputs-inline.png) + +The block definition can specify an optional boolean controlling whether inputs +are inline or not. + + + + ```js + { + // ..., + "inputsInline": true + } + ``` + + + ```js + init: function() { + // ... + this.setInputsInline(true); + } + ``` + + +When this boolean is set to `true` (inline inputs): + +- The connectors for value inputs are rendered inside the block. +- Statement inputs are rendered on their own row. +- Dummy, end-of-row, and value inputs are all rendered in the same row, except + that any input following a statement or end-of-row input is rendered on a + new row. + +When it is set to `false` (external inputs): + +- The connectors for value inputs are rendered on the outside edge of the + block. +- All inputs are rendered in their own row, except that an end-of-row input + that follows a dummy input is rendered in the same row as the dummy input. + +If you're having trouble visualizing this, construct blocks in the [Blockly +Developer +Tools](https://raspberrypifoundation.github.io/blockly-samples/examples/developer-tools/index.html) +and choose different settings for the `inputs` dropdown (`automatic`, +`external`, `inline`). + +If this boolean is not defined then Blockly will use some heuristics to guess +which mode is +best. Assuming Blockly makes the right choice, leaving this field undefined +is preferable since different language translations can automatically have +different modes. See the example of `"set %1 to %2"` (external inputs) and +`"put %2 in %1"` (inline inputs) in [Interpolation token +order](/guides/create-custom-blocks/define/structure-json#interpolation-token-order). + +Use inline inputs when a block is likely to have small inputs such as numbers. +The user can toggle this option through the context menu. diff --git a/packages/docs/docs/guides/create-custom-blocks/define/json-and-js.mdx b/packages/docs/docs/guides/create-custom-blocks/define/json-and-js.mdx new file mode 100644 index 00000000000..5c2e0323153 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/json-and-js.mdx @@ -0,0 +1,253 @@ +--- +title: JSON and JavaScript +description: How to use JSON or JavaScript to define custom blocks. +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# JSON and JavaScript + +Blockly has two ways of defining blocks: JSON objects, which use key-value +pairs, and JavaScript functions, which call Blockly's API. The JSON format is +preferred because it [simplifies +localization](/guides/configure/web/translations#json-message-interpolation) +and is easier to read and write. However, it cannot be used to directly define +advanced features such as mutators or validators. These must be written in +JavaScript, usually as +[extensions](/guides/create-custom-blocks/define/extensions). + +:::info +The "JSON" objects are, in fact, plain JavaScript objects. They are +called JSON objects because their values must be serializable as JSON. The term +is used because (a) it appears in the Blockly API and (b) it is a convenient way +to distinguish between the two different methods of defining blocks. +::: + +## Use JSON or JavaScript + +This block: + +![A `string_length` block.](/images/text-length.png) + +can be defined in JSON or JavaScript as follows. + + + + + +```json +{ + "blocks": [ + { + "type": "string_length", + "message0": "length of %1", + "args0": [ + { + "type": "input_value", + "name": "VALUE", + "check": "String" + } + ], + "output": "Number", + "colour": 160, + "tooltip": "Returns number of letters in the provided text.", + "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp" + } + ] +} +``` + +`defineBlocksWithJsonArray` converts each JSON object into a +[block definition object](/guides/create-custom-blocks/define/block-definitions) +with an `init` function. It stores these objects in `Blockly.Blocks`. + + + + + +```js +Blockly.Blocks['string_length'] = { + init: function () { + this.appendValueInput('VALUE').setCheck('String').appendField('length of'); + this.setOutput(true, 'Number'); + this.setColour(160); + this.setTooltip('Returns number of letters in the provided text.'); + this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp'); + }, +}; +``` + +Because +[block definition objects](/guides/create-custom-blocks/define/block-definitions) +are mixed in to block objects, the keyword `this` refers to the actual block +being created. + + + + + +Both methods result in a block definition object being stored in +`Blockly.Blocks` with a key of the block type name (`string_length`). The block +definition object has a single method (`init`), which defines the block's shape. + +## Mix JSON and JavaScript + +The JSON format primarily supports defining the look and feel of a block. It +cannot directly define some features, such as validators and mutators, which +require you to define a function. To solve this problem, define as much of your +block with JSON as possible, and use JavaScript for the rest. + +The following example creates a block definition with an `init` function, which +uses `jsonInit` to load a JSON object and the JavaScript API to define a dynamic +tooltip. + + + + + +```js +// Define the block structure in JSON. +var mathChangeJson = { + message0: 'change %1 by %2', + args0: [ + { + type: 'field_variable', + name: 'VAR', + variable: 'item', + variableTypes: [''], + }, + { + type: 'input_value', + name: 'DELTA', + check: 'Number', + }, + ], + previousStatement: null, + nextStatement: null, + colour: 230, +}; + +Blockly.Blocks['math_change'] = { + init: function () { + // Use jsonInit to load the JSON block structure. + this.jsonInit(mathChangeJson); + + // Use JavaScript to define a tooltip function. + var thisBlock = this; + this.setTooltip(function () { + return 'Add a number to variable "%1".'.replace( + '%1', + thisBlock.getFieldValue('VAR'), + ); + }); + }, +}; +``` + + + + + +## Block definition API + +This section summarizes the objects and functions used to define custom blocks. + +### Blockly.Blocks + +[`Blockly.Blocks`](/reference/blockly.blocks_variable) is an object +that stores block definitions. Its keys are block type names and its values are +block definition objects. Use `Blockly.Blocks` when defining blocks with +JavaScript: + +```js +Blockly.Blocks['my_block'] = { + init: function () { + /* ... */ + }, + onchange: function () { + /* ... */ + }, + // ... +}; +``` + +A common error is to assume `Blockly.Blocks` stores blocks and try something +like the following. This fails because `Blockly.Blocks` stores block +definitions, not blocks. + +```js +// Fails with "Blockly.Blocks.my_block.setColour is not a function". +Blockly.Blocks['my_block'].setColour(150); +``` + +### defineBlocksWithJsonArray + +[`defineBlocksWithJsonArray`](/reference/blockly.common_namespace.defineblockswithjsonarray_1_function) +accepts an array of JSON objects, creates block definitions from them, and adds +them to `Blockly.Blocks`. + +```js +Blockly.common.defineBlocksWithJsonArray([ + { + type: 'my_block1', + // ... + }, + { + type: 'my_block3', + // ... + }, + { + type: 'my_block2', + // ... + }, +]); +``` + +### createBlockDefinitionsFromJsonArray and defineBlocks + +[`createBlockDefinitionsFromJsonArray`](/reference/blockly.common_namespace.createblockdefinitionsfromjsonarray_1_function) +accepts an array of JSON objects and returns an object that maps block type +names to block definitions. This is generally used with `defineBlocks`, which +adds the block definitions to `Blockly.Blocks`. + +```js +const myBlockDefinitions = Blockly.common.createBlockDefinitionsFromJsonArray([ + { + type: 'my_block1', + // ... + }, + { + type: 'my_block3', + // ... + }, + { + type: 'my_block2', + // ... + }, +]); + +Blockly.common.defineBlocks(myBlockDefinitions); +``` + +### Block.jsonInit + +[`jsonInit`](/reference/blockly.block_class.jsoninit_1_method) +accepts a JSON object and calls the corresponding methods on `Block`. For +example, a JSON object with the key-value pair `colour: 150` results in a call +to `this.setColour(150)`. Use `jsonInit` in an `init` function to load a JSON +object. + +```js +var myJson = { + // ... +}; + +Blockly.Blocks['my_block'] = { + init: function () { + this.jsonInit(myJson); + // The rest of the init function. + }, +}; +``` diff --git a/packages/docs/docs/guides/create-custom-blocks/define/modify-definitions.mdx b/packages/docs/docs/guides/create-custom-blocks/define/modify-definitions.mdx new file mode 100644 index 00000000000..bfbff17dedb --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/modify-definitions.mdx @@ -0,0 +1,201 @@ +--- +description: How to modify existing block definitions. +title: Modify block definitions +image: images/blockly_banner.png +--- + +# Modify block definitions + +A common question is how to modify the definition of an existing block. For +example, you might want to add a connection check or change a field to a value +input. + +In general, it is not possible to modify a block definition in place. + +## How to modify an existing definition + +If you want to modify the definition of an existing block type: + +1. Make a copy of the existing definition, including block-code generators. +1. Modify the copy and give your type a new name. +1. Add your new definition to `Blockly.Blocks`. + +## Why can't I directly modify an existing definition? + +If you're curious as to why you can't modify an existing definition, read on. +We'll consider some possibilities. + +### Modify an existing definition directly + +There are two ways to directly modify the definition of an existing block: +monkeypatching and forking the code. Both are strongly discouraged, as you run +the risk of breaking code that depends on the monkeypatched or forked code. Both +techniques also make it difficult to integrate updates and bug fixes. For more +information, see [What about +monkeypatching?](/guides/programming/using_blockly_apis#what-about-monkeypatching) +and [Fork Blockly](/guides/programming/forking_blockly). + +### Subclass an existing definition + +It might occur to you to somehow subclass an existing definition. Unfortunately, +this isn't possible because block definitions aren't classes -- they're mixins. +There is, for example, no way to overwrite a colour property because the +definition does not have a colour property. Instead, it has an `init` function +that calls `setColour` to set the colour property on the block. Because the call +is inside `init`, there is no way to replace it without replacing the entire +`init` function. + +### Overwrite a function in an existing definition + +It is possible to overwrite a function in an existing definition: + +```js +Blockly.Blocks['existing_block'].init = function () { + /*new function*/ +}; +``` + +This works, but you have to copy and modify the existing function -- you can't +magically replace just one line. There are several problems with this: + +- It isn't much different from copying and modifying the entire definition. +- You can't use it to modify the `init` function of blocks that are defined in + JSON, such as Blockly's built-in blocks. This is because there is no `init` + function to copy -- it's generated at run time. +- It requires you to define your block using JavaScript, which may [cause + problems with + localization](/guides/configure/web/translations#json-message-interpolation). + +### Overwrite the results of init + +One way to "replace just one line" of an `init` function is to replace the +`init` function with a function that calls the original `init` function and then +overwrites the result of that call. For example, the following code changes the +color of the `logic_null` block: + +```js +const originalInit = Blockly.Blocks['logic_null'].init; +Blockly.Blocks['logic_null'].init = function () { + originalInit.call(this); + this.setColour(300); +}; +``` + +Unfortunately, this is less useful that it seems. For example: + +- Broadening [connection + checks](/guides/create-custom-blocks/inputs/connection-checks) or + applying a less-restrictive field validator may invalidate assumptions made + by block-code generators and event handlers. + +- Replacing a field with a value input will break block-code generators and + field validators and may break event handlers. It may also be extremely + difficult to do for localized blocks because different locales may result in + blocks with [different types and orders of inputs and + fields](/guides/configure/web/translations#json-message-interpolation). + +### Overwrite a key-value pair in a JSON definition + +If the JSON for a block is publicly available, it may be possible to overwrite +individual JSON values. For example: + +```js +// Block definition. +blockJson = {...}; +Blockly.Blocks['my_block'] = { + init: function() { + initJson(blockJson); // Called when the block is created. + } +} + +// Third-party code. +blockJson.colour = 100; +``` + +However, this only works if the JSON object is publicly available, the +definition explicitly defines the `init` function, and the `init` function calls +`initJson`. It doesn't work if the JSON is passed to `defineBlocksWithJsonArray` +or `createBlockDefinitionsFromJsonArray` because the JSON is processed before a +third party has a chance to modify it. (Note that Blockly's built-in blocks use +`createBlockDefinitionsFromJsonArray`.) + +But what if the JSON isn't defined this way? Shouldn't it still be possible to +overwrite JSON properties? Unfortunately, no. The definition contains an `init` +function (not JSON) and there is no function to convert an `init` function to +JSON. + +```js +// Doesn't work. There is no getJson() function. +const json = Blockly.Blocks['existing_block'].getJson(); +json['message0'] = 'my new message0'; +Blockly.Blocks['existing_block'].init = function () { + initJson(json); +}; +``` + +## Design for reuse + +As you design your own custom blocks, you may be able to design them in ways +that promote reuse. + +### Reuse JSON + +If you have two blocks that are substantially similar, you can create a parent +JSON definition and reuse this in child definitions. For example: + +```js +const parentJson = { + // shared properties +}; + +Blockly.Blocks['child_block_1'] = { + init: function () { + initJson({ ...parentJson, colour: 100 }); + }, +}; + +Blockly.Blocks['child_block_2'] = { + init: function () { + initJson({ ...parentJson, colour: 200 }); + }, +}; +``` + +Another alternative is to define your JSON in a publicly available object and +pass that object to `initJson` in your `init` function. This makes it possible +for others to overwrite individual properties. For more information, see +[Overwrite a key-value pair in a JSON +definition](#overwrite-a-key-value-pair-in-a-json-definition). + +### Reuse functions + +Blocks may define a number of [standard +functions](/guides/create-custom-blocks/define/block-definitions#how-block-definitions-work), +such as block-level event handlers, custom tooltips, field validators, and the +functions used by mutators, as well as functions that provide custom behavior, +such as a function that sets field values from external data, like the current +position of a robot's arm. + +It may be possible to reuse these functions across blocks. + +### Use a dropdown field + +If you have a set of blocks that are substantially the same except for an +operator, you may be able to design a single block that has a dropdown field for +the operator. For example: + +- The built-in `logic_operation` block uses a dropdown with the operators + `and` and `or`. +- The built-in `math_arithmetic` block uses a dropdown with the operators `+`, + `-`, `×`, `÷`, and `^`. + +Writing code generators for such blocks is usually a bit more complex, but still +easier than writing and maintaining multiple blocks. + +### Use a mutator + +If you have a set of blocks that represent different variations of the same +programming structure, you may be able to create a single block that uses a +[mutator](/guides/create-custom-blocks/mutators). For example, the +built-in `controls_if` block can represent multiple variations of `if-then-else` +statements. diff --git a/packages/docs/docs/guides/create-custom-blocks/define/structure-js.mdx b/packages/docs/docs/guides/create-custom-blocks/define/structure-js.mdx new file mode 100644 index 00000000000..537f2c199c9 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/structure-js.mdx @@ -0,0 +1,165 @@ +--- +description: How to define block structure in JavaScript. +title: Block structure in JavaScript +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Block structure in JavaScript + +In this document, we'll discuss how to use JavaScript to define the inputs and +fields (including labels) in your block. If you're not familiar with these +terms, see [Anatomy of a +block](/guides/create-custom-blocks/define/block-anatomy) before +proceeding. + +You can also define your inputs, fields, and connections [in +JSON](/guides/create-custom-blocks/define/structure-json). + +## Append inputs + +The JavaScript API includes an `append` method for each [input +type](/guides/create-custom-blocks/define/block-anatomy#inputs): + + + + ```js + init: function() { + // ... + this.appendEndRowInput() + .appendField('for each') + .appendField('item') + .appendField(new Blockly.FieldVariable(), 'VAR'); + this.appendValueInput('LIST') + .setCheck('Array') + .setAlign(Blockly.inputs.Align.RIGHT) + .appendField('in list'); + this.appendStatementInput('DO') + .appendField('do'); + this.appendDummyInput() + .appendField('end'); + } + ``` + + +A block with four rows. The first row has the labels "for each" and "item" and a variable dropdown with "x" chosen. The second row has the label "in list" and a value input. The third row has the label "do" and a statement input. And the last row has the label "end". + +Each `appendInput` method can take an identifier string, which is used by code +generators to retrieve code for the block connected to the input. Code +generators rarely reference dummy and end-of-row inputs, so there is generally +no reason to assign them an identifier. + +The JavaScript API also includes a generic `appendInput` method for appending +[custom inputs][custom-inputs]. Note that in this case, the identifier should +be passed directly to your custom input's constructor. + + + + ```js init: function(){' '} + { + // ... + this.appendInput(new MyCustomInput('INPUT_NAME')).appendField( + 'an example label', + ) + } + ``` + + +All of the `appendInput` methods (both generic and non-generic) return the input +object so that they can be further configured using method chaining. There are +three built-in methods used for configuring inputs. + +## Append fields + +Once an input has been created and appended to a block with `appendInput`, one +may optionally append any number of +[fields](/guides/create-custom-blocks/define/block-anatomy#fields) to +the input. These fields +are often used as labels to describe what each input is for. + + + + ```js + init: function() { + // ... + this.appendDummyInput() + .appendField('hello'); + } + ``` + + +![A block with the label "hello".](/images/append-field.png) + +The simplest field is a label. Blockly's convention is to use all +lowercase text, with the exception of proper names (e.g. Google, SQL). + +An input row can contain any number of fields. Multiple `appendField` +calls may be chained together to efficiently add several fields to the same +input row. + + + + ```js + init: function() { + // ... + this.appendDummyInput() + .appendField('hello') + .appendField(new Blockly.FieldLabel('Neil', 'person')); + } + ``` + + +![A block with the label "hello" in plain text and the label "Neil" in +italics.](/images/append-field-label.png) + +The `appendField('hello')` call is actually a shortcut for using an explicit +`FieldLabel` constructor: `appendField(new Blockly.FieldLabel('hello'))`. +The only time one would wish to use the constructor is when specifying a +class name so that the label may be styled using a CSS rule. + +## Connection checks + + + + ```js + init: function() { + // ... + this.appendValueInput('NUM') + .setCheck('Number'); + } + ``` + + +The `setCheck` method is used for type-checking connections. If given +an argument of null, the default, then this input may be connected to any block. +See [Connection +checks](/guides/create-custom-blocks/inputs/connection-checks) for +details. + +## Align fields + + + + ```js + init: function() { + // ... + this.appendValueInput('LIST') + .appendField('in list') + .setAlign(Blockly.inputs.Align.RIGHT); + } + ``` + + +The `setAlign` method is used to align fields within an input. There are three +self-descriptive values which may be passed as an argument to this function: +`Blockly.inputs.Align.LEFT`, `Blockly.inputs.Align.RIGHT`, and +`Blockly.inputs.Align.CENTER`. + +When a block is rendered in right-to-left mode (e.g. Arabic and Hebrew), left +and right are reversed. Thus `Blockly.inputs.Align.RIGHT` would align fields to +the left. + +[custom-inputs]: /guides/create-custom-blocks/inputs/creating-custom-inputs diff --git a/packages/docs/docs/guides/create-custom-blocks/define/structure-json.mdx b/packages/docs/docs/guides/create-custom-blocks/define/structure-json.mdx new file mode 100644 index 00000000000..a7127a26740 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/structure-json.mdx @@ -0,0 +1,398 @@ +--- +description: How to define block structure in JSON. +title: Block structure in JSON +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Image from '@site/src/components/Image'; + +# Block structure in JSON + +In this document, we'll discuss how to use JSON to define the inputs, fields +(including labels), and connections in your block. If you're not familiar with +these terms, see [Anatomy of a +block](/guides/create-custom-blocks/define/block-anatomy) before +proceeding. + +You can also define your inputs, fields, and connections [in +JavaScript](/guides/create-custom-blocks/define/structure-js). + +## Overview + +In JSON, you describe a block's structure with one or more message strings +(`message0`, `message1`, ...) and their corresponding argument arrays (`args0`, +`args1`, ...). Message strings consist of text, which is converted to labels, +and interpolation tokens (`%1`, `%2`, ...), which mark the locations of +connections and non-label fields. The argument arrays describe how to handle the +interpolation tokens. + +For example, this block: + +![A variable setter block. It has the label "set", a dropdown for choosing the +variable, the label "to", and a value input.](/images/variables-set.png) + +is defined by the following JSON: + + + + ```js + { + "message0": "set %1 to %2", + "args0": [ + { + "type": "field_variable", + "name": "VAR", + "variable": "item", + "variableTypes": [""] + }, + { + "type": "input_value", + "name": "VALUE" + } + ] + } + ``` + + +The first interpolation token (`%1`) represents a [variable +field](/guides/create-custom-blocks/fields/built-in-fields/variable) +(`type: "field_variable"`). It is described by the first object in the `args0` +array. The second token (`%2`) represents the input connection at the end of a +[value input](/guides/create-custom-blocks/define/block-anatomy#value-inputs) +(`type: "input_value"`). It is described by the second object in the `args0` +array. + +## Messages and inputs + +When an interpolation token marks a connection, it is really marking the end of +the input that contains the connection. This is because the connections in value +and statement inputs are rendered at the end of the input. The input contains +all of the fields (including labels) after the previous input and up to the +current token. The following sections show sample messages and the inputs that +are created from them. + +### Example 1 + + + + ```js + { + "message0": "set %1 to %2", + "args0": [ + {"type": "field_variable", ...} // token %1 + {"type": "input_value", ...} // token %2 + ], + } + ``` + + +This creates a single value input with three fields: a label (`"set"`), a +variable field, and another label (`"to"`). + +Map the message to a value input with three fields. + +### Example 2 + + + + ```js + { + "message0": "%1 + %2", + "args0": [ + {"type": "input_value", ...} // token %1 + {"type": "input_value", ...} // token %2 + ], + } + ``` + + +This creates two value inputs. The first has no fields and the second has one +field (`"+"`). + +Map the message to two value inputs. + +### Example 3 + + + + ```js + { + "message0": "%1 + %2 %3", + "args0": [ + {"type": "input_value", ...} // token %1 + {"type": "input_end_row", ...} // token %2 + {"type": "input_value", ...} // token %3 + ], + } + ``` + + +This creates: + +- A value input with no fields, +- An [end-of-row input](/guides/create-custom-blocks/define/block-anatomy#end-of-row-inputs) + with a label field (`"+"`), which causes the following value input to be + rendered on a new row, and +- A value input with no fields. + +Map the message to two value inputs and an end-of-row input. + +## Dummy input at end of message + +If your `message` string ends with text or fields, you don't need to add an +interpolation token for the dummy input that contains them -- Blockly adds it +for you. For example, instead of defining a `lists_isEmpty` block like this: + + + + ```js + { + "message0": "%1 is empty %2", + "args0": [ + {"type": "input_value", ...} // token %1 + {"type": "input_dummy", ...} // token %2 + ], + } + ``` + + + +Map the message to a value input and an automatically created dummy input. + +you can let Blockly add the dummy input and define it like this: + + + + ```js + { + "message0": "%1 is empty", + "args0": [ + {"type": "input_value", ...} // token %1 + ], + } + ``` + + + +Map the message to a value input and an automatically created dummy input. + +The automatic addition of a tailing dummy input allows translators to change +`message` without needing to modify the arguments that describe the +interpolation tokens. For more information, see [Interpolation token +order](#interpolation-token-order). + +### implicitAlign + +In rare cases the automatically created trailing dummy input needs to be aligned +to the `"RIGHT"` or `"CENTRE"`. The default if not specified is `"LEFT"`. + +In the example below `message0` is `"send email to %1 subject %2 secure %3"` +and Blockly automatically adds a dummy input for the third row. Setting +`implicitAlign0` to `"RIGHT"` forces this row to be right aligned. + +![A block for sending email. The first row has the label "send email to" and a +value input. The second row has the label "subject" and a value input. The +third line has the label "secure" and a checkbox; it is +right-aligned.](/images/send-email.png) + +`implicitAlign` +applies to all inputs that are not explicitly defined in the JSON +block definition, including end-of-row inputs that [replace newline characters +(`'\n'`)](#text-handling). There is also the deprecated property +`lastDummyAlign0` that has the same behavior as `implicitAlign0`. + +When designing blocks for RTL (Arabic and Hebrew), left and right are reversed. +Thus `"RIGHT"` would align fields to the left. + +## Multiple messages + +Some blocks are naturally divided into two or more separate parts. +Consider this repeat block which has two rows: + +![A repeat block with two rows. The first row has the label "repeat", a value +input, and the label "times". The second row has the label "do" and a statement +input.](/images/repeat.png) + +If this block were described with a single message, the `message0` property +would be `"repeat %1 times %2 do %3"`, where `%2` represents an end-of-row +input. This string is awkward for a translator because +it is difficult to explain what the `%2` substitution means. The `%2` end-of-row +input may also not even be desired in some languages. And there may be multiple +blocks that wish to share the text of the second row. A better approach +is to use more than one `message` and `args` properties: + + + + ```js + { + "message0": "repeat %1 times", + "args0": [ + {"type": "input_value", ...} // token %1 in message0 + ], + "message1": "do %1", + "args1": [ + {"type": "input_statement", ...} // token %1 in message1 + ], + } + ``` + + + +Map the message to a value input and an automatically created dummy input and the message to a statement
+input. + +Any number of `message`, `args`, and `implicitAlign` properties may be defined +in the JSON format, starting with 0 and incrementing sequentially. Note that the +Block Factory is not capable of splitting messages into multiple parts, but +doing so manually is straightforward. + +## Interpolation token order + +When localizing blocks, you might need to change the order of the interpolation +tokens in a message. This is particularly important in languages that have a +different word order than English. For example, we started with a block defined +by the message `"set %1 to %2"`: + +![A variable setter block with the label "set", a dropdown field for the +variable, the label "to", and an external value +input.](/images/variables-set.png) + +Now consider a hypothetical language where `"set %1 to %2"` needs to be reversed +to say `"put %2 in %1"`. Changing the message (including the order of the +interpolation tokens) and leaving the arguments array unchanged results in the +following block: + +![A variable setter block with the label "put", an inline value input, the label +"to", and a dropdown field for the variable.](/images/variables-put.png) + +Blockly automatically changed the order of the fields, [created a dummy +input](#dummy-input-at-end-of-message), and switched from external to internal +inputs. + +The ability to change the order of the interpolation tokens in a message makes +localization easier. For more information, see [JSON message +interpolation](/guides/configure/web/translations#json-message-interpolation). + +## Text handling + +Text on either side of an interpolation token is whitespace-trimmed. +Text using the character `%` (e.g. when referring to a percentage) should use +`%%` so that it is not interpreted as an interpolation token. + +Blockly also automatically replaces any newline character (`\n`) in the message +string with an end-of-row input. + + + + ```js + { + "message0": "set %1\nto %2", + "args0": [ + {"type": "field_variable", ...}, // token %1 + {"type": "input_value", ...}, // token %2 + ] + } + ``` + + + +Map the newline character to an end-of-row input. + +## Arguments arrays + +Each message string is paired with an `args` array of the same number. For +example, `message0` goes with `args0`. The interpolation tokens +(`%1`, `%2`, ...) refer to the items of the `args` array and must match the +`args0` array completely: no duplicates, no omissions. **Token numbers refer to +the order of the items in the arguments array; they are not required to occur +in order in a message string.** + +Every object in the arguments array has a +`type` string. The rest of the parameters vary depending on the type: + +- [**Fields**](/guides/create-custom-blocks/fields/overview): + - [`field_input`](/guides/create-custom-blocks/fields/built-in-fields/text-input) + - [`field_dropdown`](/guides/create-custom-blocks/fields/built-in-fields/dropdown) + - [`field_checkbox`](/guides/create-custom-blocks/fields/built-in-fields/checkbox) + - [`field_colour`](https://www.npmjs.com/package/@blockly/field-colour) + - [`field_number`](/guides/create-custom-blocks/fields/built-in-fields/number) + - [`field_angle`](https://www.npmjs.com/package/@blockly/field-angle) + - [`field_variable`](/guides/create-custom-blocks/fields/built-in-fields/variable) + - [`field_label`](/guides/create-custom-blocks/fields/built-in-fields/label) + - [`field_image`](/guides/create-custom-blocks/fields/built-in-fields/image). +- [**Inputs**](/guides/create-custom-blocks/define/block-anatomy#inputs): + - `input_value` + - `input_statement` + - `input_dummy` + - `input_end_row` + +You can also define your own [custom fields][custom-fields] and +[custom inputs][custom-inputs] and pass them as args. + +### alt fields + +Every object may also have an `alt` field. In the case that Blockly does not +recognize the object's `type`, then the `alt` object is used in its place. For +example, if a new field named `field_time` is added to Blockly, blocks using +this field could use `alt` to define a `field_input` fallback for older versions +of Blockly: + + + + ```js + { + "message0": "sound alarm at %1", + "args0": [ + { + "type": "field_time", + "name": "TEMPO", + "hour": 9, + "minutes": 0, + "alt": + { + "type": "field_input", + "name": "TEMPOTEXT", + "text": "9:00" + } + } + ] + } + ``` + + +An `alt` object may have its own `alt` object, thus allowing for chaining. +Ultimately, if Blockly cannot create an object in the `args0` array (after +attempting any `alt` objects) then that object is simply skipped. + +[custom-inputs]: /guides/create-custom-blocks/inputs/creating-custom-inputs +[custom-fields]: /guides/create-custom-blocks/fields/customizing-fields/creating diff --git a/packages/docs/docs/guides/create-custom-blocks/define/top-level-connections.mdx b/packages/docs/docs/guides/create-custom-blocks/define/top-level-connections.mdx new file mode 100644 index 00000000000..57a22c8ef79 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/define/top-level-connections.mdx @@ -0,0 +1,166 @@ +--- +description: How to define next, previous, and output connections. +title: Top-level connections +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Top-level connections + +Blocks have three connections whose use is optional. + +## Statement Connections + +Users can create sequences of blocks using the `nextStatement` and +`previousStatement` connectors. In Blockly's standard layout, these connections +are on the top and the bottom, with the blocks stacked vertically. + +A block with a previous connector cannot have an [output +connector](#output-connection). The term _statement block_ refers +to a block with no output connector. A statement block will usually have both +a previous connection and a next connection. + +`nextStatement` and `previousStatement` connections can be +[typed](/guides/create-custom-blocks/inputs/connection-checks), +but this feature is not utilized by standard blocks. + +### Next Connection + +Creates a point at the bottom of the block, so that other statements can be +stacked below it. A block with a next connection but no previous connection +usually represents an event, and can be configured to render with +[a hat](/guides/design/applications#event-driven-program). + +![A block with no fields and a tab on the +bottom.](/images/set-next-statement.png) + + + + Untyped: + + ```js + { + ..., + "nextStatement": null, + } + ``` + + Typed (*rare*): + + ```js + { + "nextStatement": "Action", + ... + } + ``` + + + Untyped: + + ```js + this.setNextStatement(true); // false implies no next connector, the default + ``` + + Typed (rare): + + ```js + this.setNextStatement(true, 'Action'); + ``` + + +### Previous Connection + +Creates a notch at the top of the block, so that it can be connected as a stack +of statements. + +Blocks with a previous connection cannot have an output connection. + +![A block with no fields and a notch on the +top.](/images/set-previous-statement.png) + + + + Untyped: + + ```js + { + ..., + "previousStatement": null, + } + ``` + + Typed (*rare*): + + ```js + { + "previousStatement": "Action", + ... + } + ``` + + + Untyped: + + ```js + this.setPreviousStatement(true); // false implies no previous connector, the default + ``` + + Typed (rare): + + ```js + this.setPreviousStatement(true, 'Action'); + ``` + + +## Output connection + +A block may have a single output connection, represented as a male jigsaw +connector on the leading edge. Outputs connect to value inputs. Blocks with an +output are usually called _value blocks_. + +![A block with no fields and a male puzzle connector on the left +edge.](/images/set-output.png) + + + + Untyped: + + ```js + { + // ..., + "output": null, + } + ``` + + Typed: + + ```js + { + // ..., + "output": "Number", + } + ``` + + + Untyped: + + ```js + init: function() { + // ... + this.setOutput(true); + } + ``` + + Typed: + + ```js + init: function() { + // ... + this.setOutput(true, 'Number'); + } + ``` + + +Blocks with an output connector cannot also have a previous statement notch. diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/anatomy-of-a-field.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/anatomy-of-a-field.mdx new file mode 100644 index 00000000000..16208756a65 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/anatomy-of-a-field.mdx @@ -0,0 +1,121 @@ +--- +description: The different parts of a field. +title: Anatomy of a field +image: images/blockly_banner.png +--- + +# Anatomy of a field + +## Value + +All fields are required to have a value, which is the source of truth for the +field's data. This can be of any type (string, number, array, date, etc). +Fields may use validators to restrict values or translate to a +machine-readable format (e.g. normalizing date formats). + +## Text + +All fields contain text, which is a simple human-readable string representing +the field's value. This does not necessarily mean they are the same. For +instance, the text on a boolean field may be ‘On' or ‘Off', while its value is +`true` or `false`. + +This text is what is displayed when the block is collapsed, for accessibility, +and may optionally be part of the [on-block display](#on-block-display). + +## Editable vs non-editable fields + +In general, editable fields allow the user to make changes to the code, while +non-editable fields display information to the user about the block. +Editable fields may show a rich editor when clicked. + +Editable fields include: + +- [Checkbox](/guides/create-custom-blocks/fields/built-in-fields/checkbox) +- [Colour](https://www.npmjs.com/package/@blockly/field-colour) +- [Dropdown](/guides/create-custom-blocks/fields/built-in-fields/dropdown) +- [Number](/guides/create-custom-blocks/fields/built-in-fields/number) +- [Text Input](/guides/create-custom-blocks/fields/built-in-fields/text-input) + +Non-editable fields include: + +- [Label](/guides/create-custom-blocks/fields/built-in-fields/label) +- [Label Serializable](/guides/create-custom-blocks/fields/built-in-fields/label-serializable) +- [Image](/guides/create-custom-blocks/fields/built-in-fields/image) + +## Serialization + +A serializable field's value gets encoded in the save format (JSON or XML). All +editable fields are serializable, because their values are dynamic. Non-editable +fields' values are usually not dynamic, so they are usually not serialized. + +Serialized fields include: + +- [Checkbox](/guides/create-custom-blocks/fields/built-in-fields/checkbox) +- [Colour](/guides/create-custom-blocks/fields/built-in-fields/colour) +- [Dropdown](/guides/create-custom-blocks/fields/built-in-fields/dropdown) +- [Number](/guides/create-custom-blocks/fields/built-in-fields/number) +- [Text Input](/guides/create-custom-blocks/fields/built-in-fields/text-input) +- [Label Serializable](/guides/create-custom-blocks/fields/built-in-fields/label-serializable) + +Non-serialized fields include: + +- [Label](/guides/create-custom-blocks/fields/built-in-fields/label) +- [Image](/guides/create-custom-blocks/fields/built-in-fields/image) + +Note how the Label Serializable field is not editable, but is serializable. This +means that it can only be edited programmatically, rather than through a +user-visible UI. Once edited, its value is encoded in the generated JSON/XML. + +## Code generation + +Besides connecting and disconnecting blocks, fields are the only way that the +user can control the code generated by Blockly. The editor provided by a field +lets the user modify the value stored by the field. The block's generator may +then access the field's value for use in the generated code. + +For more information about using a field's value in a generator see +[field code generation][field-generator]. + +## On-block display + +A field's on-block display is a collection of SVG elements representing the +field's value. They take up space on the block, and as they change size they +force the block to change size. A field's on-block display can be simple or +complex, depending on its needs. + +These are some examples of different on-block displays, in order of increasing +complexity. + +| Field type | Description | +| ---------- | ----------------------------------------------------------------------------------------------------- | +| Label | Contains only a text element. | +| Angle | Contains a background rect, text element, and a degree symbol. | +| Turtle | Contains a background rect, text element, and many SVG elements used to construct the turtle graphic. | + +## Editor display + +When a user clicks on an editable field, the field may display an +arbitrarily complex editor. + +These are some examples of different editors, in order of increasing +complexity. + +| Field type | Description | +| ------------ | -------------------------------------------------------------------------------------------------------------------- | +| Checkbox | No editor when clicked. The on-block display updates. | +| Number input | Text editor overlaid above the on-block display. Users can type; the editor may change color to indicate bad values. | +| Angle picker | The angle picker has both a text editor for typing numbers and a draggable editor for selecting angles visually. | + +## Other display modes + +Collapsed mode: the user collapses the block.The block displays a text representation +of its values, using the text returned by the individual +fields. + +![Turtle field block collapsing](/images/fields/yertle_collapsing.gif) + +Accessibility mode: users may be using a screenreader or similar technology to +interact with Blockly. The text of the field may be read out to the user. + +[field-generator]: /guides/create-custom-blocks/code-generation/block-code#get-field-values diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/checkbox.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/checkbox.mdx new file mode 100644 index 00000000000..49e5c749b15 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/checkbox.mdx @@ -0,0 +1,157 @@ +--- +description: A field for modeling true/false values. +title: Checkbox fields +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Checkbox fields + +A checkbox field stores a string as its value, and a string as its text. Its +value is either `'TRUE'` or `'FALSE'`, and its text is either `'true'` or +`'false'`. + +#### Checkbox field + +![A block with the label "checkbox:" and a checkbox field with a check +mark.](/images/fields/checkbox/on_block.png) + +#### Checkbox field on collapsed block + +![The same block after being collapsed. It has the label "variable: true" and a +jagged right edge to show it is +collapsed.](/images/fields/checkbox/collapsed.png) + +## Creation + + + + ```js + { + "type": "example_checkbox", + "message0": "checkbox: %1", + "args0": [ + { + "type": "field_checkbox", + "name": "FIELDNAME", + "checked": true + } + ] + } + ``` + + + ```js + Blockly.Blocks['example_checkbox'] = { + init: function() { + this.appendDummyInput() + .appendField('checkbox:') + .appendField(new Blockly.FieldCheckbox(true), 'FIELDNAME'); + } + }; + ``` + + +The checkbox constructor takes in an optional value and an optional +[validator](#creating-a-checkbox-validator). The optional value should be either +`'TRUE'`, `'FALSE'`, or a boolean, otherwise it will default to `false`. + +## Serialization + + + + The JSON for a checkbox field looks like so: + + ```js + { + "fields": { + "FIELDNAME": true + } + } + ``` + Where `FIELDNAME` is a string referencing a checkbox field, and + the value is the value to apply to the field. The value must be a boolean. + + + The XML for a checkbox field looks like so: + + ```xml + TRUE + ``` + + or + + ```xml + true + ``` + :::note + Quotes do not need to be applied to the inner text. + ::: + + Where the `name` attribute contains a string referencing an checkbox field, + and the inner text is the value to apply to the field. The inner text value + follows the same rules as the constructor value. + + Note that after being deserialized and reserialized all of the inner text + values will be in caps (`'TRUE'` or `'FALSE'`). This is sometimes important + when diffing workspaces. + + +## Customization + +### Checkmark character + +The `Blockly.FieldCheckbox.CHECK_CHAR` property can be used to change what the +checkmark looks like. The value should be a string containing a unicode +character. + +![Checkbox field with heart instead of check](/images/fields/checkbox/customized.png) + +The `CHECK_CHAR` property defaults to `\u2713` or ✓. + +This is a global property, so it will modify all checkbox fields when set. + +## Creating a checkbox validator + +:::note +For information on validators in general see [Validators](/guides/create-custom-blocks/fields/validators). +::: + +A checkbox field's value is either `'TRUE'` or `'FALSE'` so a validator should +accept those values (i.e. a string) and return `'TRUE'`, `'FALSE'`, `null`, or +`undefined`. + +:::warning +the `getValueBoolean` method should not be used inside of validators, +because it returns based on the current value, not the new value. +::: + +Here's an example of a validator that hides or shows a text input field based on +whether the checkbox is checked: + +``` + validate: function(newValue) { + var sourceBlock = this.getSourceBlock(); + sourceBlock.showTextField_ = newValue == 'TRUE'; + sourceBlock.updateTextField(); + + return newValue; + }, + + updateTextField: function() { + var input = this.getInput('DUMMY'); + if (this.showTextField_ && !this.getField('TEXT')) { + input.appendField(new Blockly.FieldTextInput(), 'TEXT'); + } else if (!this.showTextField_ && this.getField('TEXT')) { + input.removeField('TEXT'); + } + } +``` + +#### Checkbox field with a validator + +![An animated GIF that shows a checkbox being checked. When the checkbox is +checked, a text field is +displayed.](/images/fields/checkbox/validator.gif) diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/dropdown.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/dropdown.mdx new file mode 100644 index 00000000000..a28dbc1af27 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/dropdown.mdx @@ -0,0 +1,606 @@ +--- +title: Dropdown fields +description: A field for selecting values from a limited set. +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Dropdown fields + +The dropdown field stores a string as its value and a string as its text. The +value is a language-neutral key that will be used for accessing the text and +will not get translated when Blockly is switched between languages. The text is +a human-readable string that will be displayed to the user. + +#### Dropdown field + +![A block with the label "drop down:", a dropdown field with "first" selected, +and the label "item".](/images/fields/dropdown/on_block.png) + +#### Dropdown field with editor open + +![The same block with the dropdown open. The dropdown contains the items "first" +and "second".](/images/fields/dropdown/with_editor.png) + +#### Dropdown field on collapsed block + +![The same block after being collapsed. It has the label "drop down: first item" +and a jagged right edge to show it is +collapsed.](/images/fields/dropdown/collapsed.png) + +## Creation + +The dropdown constructor takes in a menu generator and an optional +[validator](#creating-a-dropdown-validator). The menu generator is either an +array of options (where each option contains a human-readable part and a +language-neutral string) or a function that generates an array of options. The +human-readable part of each option can be a string, an image, or an HTML element +and the array can contain a mixture of options of different types. + +### Simple text dropdowns + +![Open dropdown with two text options](/images/fields/dropdown/with_editor.png) + + + +```js +{ + "type": "example_dropdown", + "message0": "drop down: %1", + "args0": [ + { + "type": "field_dropdown", + "name": "FIELDNAME", + "options": [ + [ "first item", "ITEM1" ], + [ "second item", "ITEM2" ] + ] + } + ] +} +``` + + +```js +Blockly.Blocks['example_dropdown'] = { + init: function() { + this.appendDummyInput() + .appendField('drop down:') + .appendField(new Blockly.FieldDropdown([ + ['first item', 'ITEM1'], + ['second item', 'ITEM2'] + ]), 'FIELDNAME'); + } +}; +``` + + + +Keeping the human-readable information separate from the language-neutral key +allows the dropdown menu's setting to be preserved between languages. For +instance an English version of a block may define `[['left', 'LEFT'], ['right', +'RIGHT]]` while a German version of the same block would define `[['links', +'LEFT'], ['rechts', 'RIGHT]]`. + +### Image dropdowns + +Options in a dropdown menu may be images, which are represented as objects with +`src`, `width`, `height`, and `alt` properties. + +![Dropdown field containing images and text](/images/fields/dropdown/with_images.png) + + + +```js +{ + "type": "image_dropdown", + "message0": "flag %1", + "args0": [ + { + "type": "field_dropdown", + "name": "FLAG", + "options": [ + ["none", "NONE"], + [{"src": "canada.png", "width": 50, "height": 25, "alt": "Canada"}, "CANADA"], + [{"src": "usa.png", "width": 50, "height": 25, "alt": "USA"}, "USA"], + [{"src": "mexico.png", "width": 50, "height": 25, "alt": "Mexico"}, "MEXICO"] + ] + } + ] +} +``` + + +```js +Blockly.Blocks['image_dropdown'] = { + init: function() { + var input = this.appendDummyInput() + .appendField('flag'); + var options = [ + ['none', 'NONE'], + [{'src': 'canada.png', 'width': 50, 'height': 25, 'alt': 'Canada'}, 'CANADA'], + [{'src': 'usa.png', 'width': 50, 'height': 25, 'alt': 'USA'}, 'USA'], + [{'src': 'mexico.png', 'width': 50, 'height': 25, 'alt': 'Mexico'}, 'MEXICO'] + ]; + input.appendField(new Blockly.FieldDropdown(options), 'FLAG'); + } +}; +``` + + + +### HTML dropdowns + +An option may be any HTML element, as long as it is not too large and does not +attempt to handle mouse or keyboard events. (It is your responsibility +to follow these rules -- Blockly does not enforce them.) + +When the dropdown is open, the list displays the HTML element. When it is closed +and the element is the selected option, the list displays (in descending order +of preference) the element's `title` attribute, its `aria-label` attribute, or +its `innerText` property. + +![Dropdown field containing text and HTML +elements](/images/fields/dropdown/with_html.png) + + + +```js +{ + "type": "flags_with_text_dropdown", + "message0": "flag with text %1", + "args0": [ + { + "type": "field_dropdown", + "name": "FLAG_WITH_TEXT", + "options": [ + ["x", "X"], // Placeholder. An empty array throws an exception. + ] + } + ], + // Use an extension to add the HTML element options. + "extensions": ["flag_with_text_extension"] +} +``` + +```js +Blockly.Extensions.register('flag_with_text_extension', function () { + function createFlagWithTextDiv(text, src) { + const div = document.createElement('div'); + div.setAttribute('style', 'width: 75px;'); + div.setAttribute('title', text); + const img = document.createElement('img'); + img.setAttribute('src', src); + img.setAttribute('style', 'height: 25px; display: block; margin: auto;'); + div.appendChild(img); + const para = document.createElement('p'); + para.innerText = text; + para.setAttribute('style', 'text-align: center; margin: 5px;'); + div.appendChild(para); + return div; + } + + const canadaDiv = createFlagWithTextDiv('Canada', 'canada.png'); + const usaDiv = createFlagWithTextDiv('USA', 'usa.png'); + const mexicoDiv = createFlagWithTextDiv('Mexico', 'mexico.png'); + const options = [ + ['none', 'NONE'], + [canadaDiv, 'CANADA'], + [usaDiv, 'USA'], + [mexicoDiv, 'MEXICO'], + ]; + this.getField('FLAG_WITH_TEXT').setOptions(options); +}); +``` + +This is done using a JSON +[extension](/guides/create-custom-blocks/define/extensions). + + + +```js +function createFlagWithTextDiv(text, src) { + const div = document.createElement('div'); + div.setAttribute('style', 'width: 75px;'); + div.setAttribute('title', text); + const img = document.createElement('img'); + img.setAttribute('src', src); + img.setAttribute('style', 'height: 25px; display: block; margin: auto;'); + div.appendChild(img); + const para = document.createElement('p'); + para.innerText = text; + para.setAttribute('style', 'text-align: center; margin: 5px;'); + div.appendChild(para); + return div; +} + +const canadaDiv = createFlagWithTextDiv('Canada', 'canada.png'); +const usaDiv = createFlagWithTextDiv('USA', 'usa.png'); +const mexicoDiv = createFlagWithTextDiv('Mexico', 'mexico.png'); + +Blockly.Blocks['flags_with_text_dropdown'] = { +init: function() { +const input = this.appendDummyInput() +.appendField('flag with text'); +const options = [ +['none', 'NONE'], +[canadaDiv, 'CANADA'], +[usaDiv, 'USA'], +[mexicoDiv, 'MEXICO'] +]; +input.appendField(new Blockly.FieldDropdown(options), 'FLAG_WITH_TEXT'); +} +}; + +```` + + + + +### Dynamic dropdowns + +![Dropdown field with days of the week](/images/fields/dropdown/dynamic.png) + + + +```js +{ + "type": "dynamic_dropdown", + "message0": "day %1", + "args0": [ + { + "type": "field_dropdown", + "name": "DAY", + "options": [ + ["x", "X"], // Placeholder. An empty array throws an exception. + ] + } + ], + // Use an extension to set the menu function. + "extensions": ["dynamic_menu_extension"] +} +```` + +```js +Blockly.Extensions.register('dynamic_menu_extension', function () { + this.getField('DAY').setOptions(function () { + var options = []; + var now = Date.now(); + for (var i = 0; i < 7; i++) { + var dateString = String(new Date(now)).substring(0, 3); + options.push([dateString, dateString.toUpperCase()]); + now += 24 * 60 * 60 * 1000; + } + return options; + }); +}); +``` + +This is done using a JSON +[extension](/guides/create-custom-blocks/define/extensions). + + + +```js +Blockly.Blocks['dynamic_dropdown'] = { + init: function() { + var input = this.appendDummyInput() + .appendField('day') + .appendField(new Blockly.FieldDropdown( + this.generateOptions), 'DAY'); + }, + +generateOptions: function() { +var options = []; +var now = Date.now(); +for(var i = 0; i < 7; i++) { +var dateString = String(new Date(now)).substring(0, 3); +options.push([dateString, dateString.toUpperCase()]); +now += 24 _ 60 _ 60 \* 1000; +} +return options; +} +}; + +```` + + + +A dropdown can also be provided with a function instead of a list of static +options, which allows the options to be dynamic. The function should return an +array of options in the same `[human-readable-value, language-neutral-key]` +format as static options. Every time the dropdown is clicked the function is +run and the options are recalculated. + +:::note +[Prefix/suffix matching](#prefixsuffix-matching) does not occur for +dynamic dropdowns. +::: + +### Separators + +Use the string `'separator'` to add a line between options in a dropdown menu. + +![Dropdown field with a line between the second and third +options](/images/fields/dropdown/with_separator.png) + + + +```js +{ + "type": "separator_dropdown", + "message0": "food %1", + "args0": [ + { + "type": "field_dropdown", + "name": "FOOD", + "options": [ + ["water", "WATER"], + ["juice", "JUICE"], + "separator", + ["salad", "SALAD"], + ["soup", "SOUP"], + ] + } + ] +} +```` + + + +```js +Blockly.Blocks["separator_dropdown"] = { + init: function() { + var input = this.appendDummyInput() + .appendField("food1"); + var options = [ + ["water", "WATER"], + ["juice", "JUICE"], + "separator", + ["salad", "SALAD"], + ["soup", "SOUP"], + ]; + input.appendField(new Blockly.FieldDropdown(options), "FOOD"); + } +}; +``` + + + +## Serialization + + + +The JSON for a dropdown field looks like so: + +```js +{ + "fields": { + "FIELDNAME": "LANGUAGE-NEUTRAL-KEY" + } +} +``` + +Where `FIELDNAME` is a string referencing a dropdown field, and +the value is the value to apply to the field. The value should be a +language-neutral option key. + + + +The XML for a dropdown field looks like so: + +```xml +LANGUAGE-NEUTRAL-KEY +``` + +Where the field's `name` attribute contains a string referencing a dropdown +field, and the inner text is the value to apply to the field. The inner +text should be a valid language-neutral option key. + + + + +## Customization + +### Dropdown arrow + +The `Blockly.FieldDropdown.ARROW_CHAR` property can be used to change the +unicode character representing the dropdown arrow. + +![Dropdown field with custom arrow](/images/fields/dropdown/customized_arrow.png) + +The `ARROW_CHAR` property defaults to `\u25BC` (▼) on Android and `\u25BE` (▾) +otherwise. + +This is a global property, so it will modify all dropdown fields when set. + +### Menu height + +The `Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH` property can be used to change +the maximum height of the menu. It is defined as a percentage of the viewport +height, the viewport being the window. + +The `MAX_MENU_HEIGHT_VH` property defaults to 0.45. + +This is a global property, so it will modify all dropdown fields when set. + +## Prefix/suffix matching + +If all the dropdown menu options share common prefix and/or suffix +words, these words are automatically factored out and inserted as static text. +For example, here are two ways to create the same block (this first without +suffix matching, and the second with): + +Without suffix matching: + + + +```js +{ + "type": "dropdown_no_matching", + "message0": "hello %1", + "args0": [ + { + "type": "field_dropdown", + "name": "MODE", + "options": [ + ["world", "WORLD"], + ["computer", "CPU"] + ] + } + ] +} +``` + + +```js +Blockly.Blocks['dropdown_no_matching'] = { + init: function() { + var options = [ + ['world', 'WORLD'], + ['computer', 'CPU'] + ]; + + this.appendDummyInput() + .appendField('hello') + .appendField(new Blockly.FieldDropdown(options), 'MODE'); + +} +}; + +```` + + + + +With suffix matching: + + + +```js +{ + "type": "dropdown_with_matching", + "message0": "%1", + "args0": [ + { + "type": "field_dropdown", + "name": "MODE", + "options": [ + ["hello world", "WORLD"], + ["hello computer", "CPU"] + ] + } + ] +} +```` + + + +```js +Blockly.Blocks['dropdown_with_matching'] = { + init: function() { + var options = [ + ['hello world', 'WORLD'], + ['hello computer', 'CPU'] + ]; + + this.appendDummyInput() + .appendField(new Blockly.FieldDropdown(options), 'MODE'); + +} +}; + +```` + + + + +![Dropdown field with "hello" as a label and "world", "computer" as options](/images/fields/dropdown/prefix_matched.png) + +One advantage of this approach is that the block is easier to translate into +other languages. The earlier code has the strings `'hello'`, `'world'`, and +`'computer'`, whereas the revised code has the strings `'hello world'` and +`'hello computer'`. Translators have a much easier time translating phrases than +words in isolation. + +Another advantage of this approach is that word order often changes between +languages. Imagine a language that used `'world hello'` and `'computer hello'`. +The suffix matching algorithm will detect the common `'hello'` and display it +after the drop-down. + +However, sometimes the prefix/suffix matching fails. There are some cases where +two words should always go together and the prefix should not be factored out. +For example `'drive red car'` and `'drive red truck'` should arguably only +have `'drive'` factored out, not `'drive red'`. The Unicode non-breaking +space `'\u00A0'` may be used in place of a regular space to suppress the +prefix/suffix matcher. Thus the above example can be fixed with +`'drive red\u00A0car'` and `'drive red\u00A0truck'`. + +Another place where prefix/suffix matching fails is in languages that do not +separate individual words with spaces. Chinese is a good example. The string +`'訪問中國'` means `'visit China'`, note the lack of spaces between words. +Collectively, the last two characters (`'中國'`) are the word for `'China'`, +but if split they would mean `'centre'` and `'country'` respectively. To make +prefix/suffix matching work in languages such as Chinese, +just insert a space where the break should be. For example `'訪問 中國'` and +`'訪問 美國'` would result in `"visit [China/USA]"`, whereas `'訪問 中 國'` and +`'訪問 美 國'` would result in `"visit [centre/beautiful] country"`. + +## Creating a dropdown validator + +:::note +For information on validators in general see [Validators](/guides/create-custom-blocks/fields/validators). +::: + +A dropdown field's value is a language-neutral string, so any validators must +accept a string and return a string _that is an available option_, `null`, or +`undefined`. + +If your validator returns anything else, Blockly's behaviour is undefined and +your program may crash. + + +For example, you could define a dropdown field with three options and a +validator like this: + +```js +validate: function(newValue) { + this.getSourceBlock().updateConnections(newValue); + return newValue; +}, + +init: function() { + var options = [ + ['has neither', 'NEITHER'], + ['has statement', 'STATEMENT'], + ['has value', 'VALUE'], + ]; + + this.appendDummyInput() + // Pass the field constructor the options list, the validator, and the name. + .appendField(new Blockly.FieldDropdown(options, this.validate), 'MODE'); +} +```` + +`validate` always returns the value it was passed, but it calls the helper +function `updateConnection` which adds or removes inputs based on the dropdown +value: + +```js +updateConnections: function(newValue) { + this.removeInput('STATEMENT', /* no error */ true); + this.removeInput('VALUE', /* no error */ true); + if (newValue == 'STATEMENT') { + this.appendStatementInput('STATEMENT'); + } else if (newValue == 'VALUE') { + this.appendValueInput('VALUE'); + } +} +``` + +![An animated GIF showing a dropdown field with three items: "neither", +"statement", and "value". When "neither" is selected, it has no inputs. When +"statement" is selected, it has a statement input. When "value" is connected, it +has a "value" input.](/images/fields/dropdown/validator.gif) diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/image.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/image.mdx new file mode 100644 index 00000000000..deb4d659019 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/image.mdx @@ -0,0 +1,104 @@ +--- +description: A field for showing images to the user. +title: Image fields +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Image fields + +An image field stores a string as its value, and a string as its text. Its +value is the src of the image, while its text is an alt string +describing/representing the image. + +#### Image field + +![A block with the label "image:" and an image of a yellow +star.](/images/fields/image/on_block.png) + +#### Image field on collapsed block + +![The same block after being collapsed. It has the label "variable: *", where +"*" is the alt text for the image, and a jagged right edge to show it is +collapsed.](/images/fields/image/collapsed.png) + +## Creation + + + + ```js + { + "type": "example_image", + "message0": "image: %1", + "args0": [ + { + "type": "field_image", + "src": "https://www.gstatic.com/codesite/ph/images/star_on.gif", + "width": 15, + "height": 15, + "alt": "*" + } + ] + } + ``` + + + ```js + Blockly.Blocks['example_image'] = { + init: function() { + this.appendDummyInput() + .appendField("image:") + .appendField(new Blockly.FieldImage( + "https://www.gstatic.com/codesite/ph/images/star_on.gif", + 15, + 15, + "*")); + } + }; + ``` + + +The image constructor takes in: + +| Parameter | Description | +| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `src` | A string that points to a [raster image](https://developer.mozilla.org/en-US/docs/Glossary/raster_image) file. | +| `width` | Must cast to a non-zero number. | +| `height` | Must cast to a non-zero number. | +| `opt_alt` | (Optional) A string that accurately describes/represents the image. This is used instead of the image when the block is collapsed. If it is `null` or `undefined` an empty string will be used. | +| `opt_onClick` | (Optional) A function to call when the field is clicked. | +| `opt_flipRtl` | (Optional) A boolean. If `true`, the image is flipped across the vertical axis when in right-to-left mode. Defaults to `false`. Useful for "turn left" and "turn right" icons. | + +## Serialization + +Image fields are not serializable. + +## Click handler + +:::note +For information on validators in general see [Validators](/guides/create-custom-blocks/fields/validators). +::: + +The image field does not accept a validator; instead it explicitly accepts a +function that is called whenever the field is clicked. This means that images +can act like buttons that exist on blocks. + +The on click handler can be set in the [JavaScript Constructor](#creation) or +using the +[`setOnClickHandler`](/reference/blockly.fieldimage_class.setonclickhandler_1_method) +function. + +Here is an example of an on click handler that collapses the block when +called. + +``` +function() { + this.getSourceBlock().setCollapsed(true); +} +``` + +![An animated GIF showing the image being clicked, the block collapsing, a +right-click to display the context menu, Expand Block being chosen, and the +block being expanded.](/images/fields/image/click_handler.gif) diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/label-serializable.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/label-serializable.mdx new file mode 100644 index 00000000000..d29109f2770 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/label-serializable.mdx @@ -0,0 +1,92 @@ +--- +description: A non-editable text field whose value is serialized. +title: Serializable label fields +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Serializable label fields + +Serializable labels work exactly the same as [normal labels](/guides/create-custom-blocks/fields/built-in-fields/label) +except they also serialize to XML. They should only be used if you are editing +the content of a label programmatically, and wish it to serialize to XML. + +#### Serializable label field + +![A block with the serializable label "a serializable label". Visually, this is +no different from a block with a normal +label.](/images/fields/label-serializable/on_block.png) + +#### Serializable label field on a collapsed block + +![The same block after being collapsed. It has the label "a serializable label" +and a jagged right edge to show it is +collapsed.](/images/fields/label-serializable/collapsed.png) + +## Creation + + + + ```js + { + "type": "example_serializable_label", + "message0": "%1", + "args0": [ + { + "type": "field_label_serializable", + "name": "FIELDNAME", + "text": "a serializable label" + } + ] + } + ``` + + + ```js + Blockly.Blocks['example_serializable_label'] = { + init: function() { + this.appendDummyInput() + .appendField(new Blockly.FieldLabelSerializable("a serializable label"), "FIELDNAME"); + } + }; + ``` + + +The serializable label field takes in an optional value, and an optional css +class string. Both default to an empty string. + +## Serialization + + + + The JSON for a serializable label field looks like so: + + ```js + { + "fields": { + "FIELDNAME": text + } + } + ``` + + Where `FIELDNAME` is a string referencing a serializable label field, and + the value is the value to apply to the field. The value + follows the same rules as the constructor value. + + + The XML for a serializable label field looks like so: + + ```xml + text + ``` + + The `field` node's `name` attribute contains a string referencing a serializable + label field, and the node's inner text is the value to apply to the field. + + +## Validators + +Serializable label fields do not support validators, because they are not +editable by a user. diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/label.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/label.mdx new file mode 100644 index 00000000000..1193e3c45eb --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/label.mdx @@ -0,0 +1,94 @@ +--- +description: A non-editable text field. +title: Label fields +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Label fields + +A label field stores a string as its `value` and a string as its `text`. The +`value` and `text` of a label field are always the same. + +#### Label field + +![A block with two rows. The first has the label "a label" and the second has +the label "and another label".](/images/fields/label/on_block.png) + +#### Label field on collapsed block + +![The same block after being collapsed. It has a single row, the label "a label +and another label", and a jagged right edge to show it is +collapsed.](/images/fields/label/collapsed.png) + +## Creation + + + + ```js + { + "type": "example_label", + "message0": "a label %1 and another label", + "args0": [ + { + "type": "input_dummy" + } + ] + } + ``` + + Any message text between interpolation arguments becomes label strings. + Alternatively, labels may be interpolated explicitly, either as an object or + as text. This is generally discouraged as it makes translation more + difficult. + + ```js + { + "type": "example_label", + "message0": "%1 %2 %3", + "args0": [ + { + "type": "field_label", + "text": "a label" + }, + { + "type": "input_dummy" + }, + "and another label" + ] + } + ``` + + + ```js + Blockly.Blocks['example_label'] = { + init: function() { + this.appendDummyInput() + .appendField(new Blockly.FieldLabel('a label')); + this.appendDummyInput() + .appendField('and another label'); + } + }; + ``` + + +The [`appendField`](/reference/blockly.input_class.appendfield_1_method) +function accepts both `FieldLabel` objects and, more commonly, strings to create +labels. + +The label field takes in an optional value, and an optional css class string. +Both default to an empty string. + +## Serialization + +Label fields are not serializable. + +If you would like your label to be serialized, because it is being changed +programmatically, see the [Serializable Label](/guides/create-custom-blocks/fields/built-in-fields/label-serializable) +field. + +## Validators + +Label fields do not support validators, because they are not editable. diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/number.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/number.mdx new file mode 100644 index 00000000000..8cb4918da2c --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/number.mdx @@ -0,0 +1,158 @@ +--- +description: A field for selecting numeric values. +title: Number fields +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Number fields + +A number field stores a number as its `value`, and a string as its `text`. Its `value` +is always a valid number as defined by the [constraints](#constraints) given to +the field at creation; its text could be any string entered into its editor. + +#### Number field + +![A block with the label "number:" and a number field set to +100.](/images/fields/number/on_block.png) + +#### Number field with editor open + +![The same block with the field being +edited.](/images/fields/number/with_editor.png) + +#### Number field on collapsed block + +![The same block after being collapsed. It has the label "number: 100" and a +jagged right edge to show it is +collapsed.](/images/fields/number/collapsed.png) + +## Creation + + + + ```js + { + "type": "example_number", + "message0": "number: %1", + "args0": [ + { + "type": "field_number", + "name": "FIELDNAME", + "value": 100, + "min": 0, + "max": 100, + "precision": 10 + } + ] + } + ``` + + + ```js + Blockly.Blocks['example_number'] = { + init: function() { + this.appendDummyInput() + .appendField("number:") + .appendField(new Blockly.FieldNumber(100, 0, 100, 10), 'FIELDNAME'); + } + }; + ``` + + +The number constructor takes in the following: + +- an optional `value` +- an optional [`min`](#minimum-value) +- an optional [`max`](#maximum-value) +- an optional [`precision`](#rounding) +- an optional [`validator`](#creating-a-number-validator) + +The `value` should cast to a number. If it does not 0 will be used. + +## Serialization + + + + The JSON for a number field looks like so: + + ```js + { + "fields": { + "FIELDNAME": 0 + } + } + ``` + + Where `FIELDNAME` is a string referencing a number field, and + the value is the value to apply to the field. The value + follows the same rules as the constructor value. + + + The XML for a number field looks like so: + + ```xml + 0 + ``` + + The `field` node's `name` attribute contains a string referencing a number + field, and the node's inner `text` is the `value` to apply to the field. The + inner text value follows the same rules as the constructor value. + + +## Constraints + +Constraints can be set in the field definition, or by using the +[setConstraints](/reference/blockly.fieldnumber_class.setconstraints_1_method) +function. + +### Minimum value + +The `min` value sets the smallest/most-negative value the field is allowed to +contain. + +### Maximum value + +The `max` value sets the largest/most-positive value the field is allowed to +contain. + +### Rounding + +The `precision` rounds the value to the nearest multiple of precision. This can be +used to make the field only accept multiples of .01, 10, 42, etc. + +## Common constraints + +### Positive numbers + +To force your field to only accept positive numbers, set the `min` value to + +1. + +### Integers + +To force your field to only accept integers, set the `precision` to 1. + +## Creating a number validator + +:::note +For information on validators in general see [Validators](../validators). +::: + +A number field's value is a number, so any validators must accept a `number` and +return a `number`, `null`, or `undefined`. + +Here is an example of a validator that changes the value to be either 0 or 1 +depending on if the value was odd or even. + +``` +function(newValue) { + return newValue % 2; +} +``` + +![An animated GIF showing the validator at work. When the user types 10 and +clicks elsewhere, the field is set to 0. When the user types 11 and clicks +elsewhere, the field is set to 1.](/images/fields/number/validator.gif) diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/overview.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/overview.mdx new file mode 100644 index 00000000000..dd518f51d96 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/overview.mdx @@ -0,0 +1,37 @@ +--- +title: Built-in fields +image: images/blockly_banner.png +--- + +# Built-in fields + +Blockly provides a number of prebuilt fields that you can use when defining a +block. There are also a number of fields available as +[plugins](/guides/programming/plugin_overview). + +Built-in fields: + +- [Checkbox](/guides/create-custom-blocks/fields/built-in-fields/checkbox) +- [Dropdown](/guides/create-custom-blocks/fields/built-in-fields/dropdown) +- [Image](/guides/create-custom-blocks/fields/built-in-fields/image) +- [Label](/guides/create-custom-blocks/fields/built-in-fields/label) +- [Serializable label](/guides/create-custom-blocks/fields/built-in-fields/label-serializable) +- [Number](/guides/create-custom-blocks/fields/built-in-fields/number) +- [Text input](/guides/create-custom-blocks/fields/built-in-fields/text-input) +- [Variables](/guides/create-custom-blocks/fields/built-in-fields/variable) + +Plugin fields: + +- [Angle picker](https://www.npmjs.com/package/@blockly/field-angle) +- [Bitmap](https://www.npmjs.com/package/@blockly/field-bitmap) +- [Colour picker](https://www.npmjs.com/package/@blockly/field-colour) +- [Colour picker with HSV sliders](https://www.npmjs.com/package/@blockly/field-colour-hsv-sliders) +- [Date](https://www.npmjs.com/package/@blockly/field-date) +- [Dropdown grid](https://www.npmjs.com/package/@blockly/field-grid-dropdown) +- [Dependent dropdown](https://www.npmjs.com/package/@blockly/field-dependent-dropdown) +- [Multiline text input](https://www.npmjs.com/package/@blockly/field-multilineinput) +- [Number slider](https://www.npmjs.com/package/@blockly/field-slider) + +For a full list of plugin fields, see [Blockly Plugins & Demos][blockly-demos]. + +[blockly-demos]: https://raspberrypifoundation.github.io/blockly-samples/#fields diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/text-input.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/text-input.mdx new file mode 100644 index 00000000000..6a40aec4932 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/text-input.mdx @@ -0,0 +1,139 @@ +--- +description: An editable text field for inputting single-line values. +title: Text input fields +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Text input fields + +A text input field stores a string as its value and a string as its text. Its +value is always a valid string, while its text could be any string entered into +its editor. + +#### Text input field + +![A block with the label "text input:" and a text input field set to "default +text".](/images/fields/text-input/on_block.png) + +#### Text input field with editor open + +![The same block with the field being +edited.](/images/fields/text-input/with_editor.png) + +#### Text input field on collapsed block + +![The same block after being collapsed. It has the label "text input: default +text" and a jagged right edge to show it is +collapsed.](/images/fields/text-input/collapsed.png) + +## Creation + + + + ```js + { + "type": "example_textinput", + "message0": "text input: %1", + "args0": [ + { + "type": "field_input", + "name": "FIELDNAME", + "text": "default text", + "spellcheck": false + } + ] + } + ``` + + + ```js + Blockly.Blocks['example_textinput'] = { + init: function() { + this.appendDummyInput() + .appendField("text input:") + .appendField(new Blockly.FieldTextInput('default text'), + 'FIELDNAME'); + } + }; + ``` + + +The text input constructor takes in an optional value and an optional +[validator](#creating-a-text-input-validator). The value should cast to a +string. If it is `null` or `undefined`, an empty string will be used. + +The JSON definition also allows you to set the [spellcheck](#spellcheck) option. + +## Serialization and XML + + + + The JSON for a text input field looks like so: + + ```js + { + "fields": { + "FIELDNAME": "text" + } + } + ``` + + Where `FIELDNAME` is a string referencing a text input field, and + the value is the value to apply to the field. The value + follows the same rules as the constructor value. + + + The XML for a text input field looks like so: + + ```xml + text + ``` + + Where the field's `name` attribute contains a string referencing a text input + field, and the inner text is the value to apply to the field. The inner + text value follows the same rules as the constructor value. + + +## Customization + +### Spellcheck + +The +`setSpellcheck` function can be used to set whether the field spellchecks its input text or not. + +### Text input fields with and without spellcheck + +![An animated GIF showing two blocks with text input fields. The first block has +spellcheck on and misspelled words are underlined with a wavy red line. The +second block has spellcheck off and misspelled words are not +underlined.](/images/fields/text-input/spellcheck.gif) + +Spellchecking is on by default. + +This applies to individual fields. If you want to modify all fields change the +`Blockly.FieldTextInput.prototype.spellcheck_` property. + +## Creating a text input validator + +:::note +For information on validators in general see [Validators](/guides/create-custom-blocks/fields/validators). +::: + +A text input field's value is a string, so any validators must accept a string +and return a string, `null`, or `undefined`. + +Here is an example of a validator that removes all `a` characters from the +string: + +``` +function(newValue) { + return newValue.replace(/a/g, ''); +} +``` + +![An animated GIF showing a text input field being validated. When the user +types "bbbaaa" and clicks elsewhere, the field is changed to +"bbb".](/images/fields/text-input/validator.gif) diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/variable.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/variable.mdx new file mode 100644 index 00000000000..67368708f9c --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/built-in-fields/variable.mdx @@ -0,0 +1,199 @@ +--- +description: A field that models identifiers, correctly handling renaming and coalescing. +title: Variable fields +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Variable fields + +A variable field stores a string as its value, and a string as its text. The +value is an ID of a variable, while the text is the name of a variable. + +#### Variable field + +![A block with the label "variable:" and a dropdown field with "x" +selected.](/images/fields/variable/on_block.png) + +#### Variable field with editor open + +![The same block with the dropdown open. The menu has the items "x", "Rename +variable..." and "Delete the "x" +variable"](/images/fields/variable/with_editor.png) + +#### Variable field on collapsed block + +![The same block after being collapsed. It has the label "variable: x" and a +jagged right edge to show it is +collapsed.](/images/fields/variable/collapsed.png) + +## Creation + +### Untyped + + + + ```js + { + "type": "example_variable_untyped", + "message0": "variable: %1", + "args0": [ + { + "type": "field_variable", + "name": "FIELDNAME", + "variable": "x" + } + ] + } + ``` + + + ```js + Blockly.Blocks['example_variable_untyped'] = { + init: function() { + this.appendDummyInput() + .appendField('variable:') + .appendField(new Blockly.FieldVariable('x'), 'FIELDNAME'); + } + }; + ``` + + +### Typed + + + + ```js + { + "type": "example_variable_typed", + "message0": "variable: %1", + "args0": [ + { + "type": "field_variable", + "name": "FIELDNAME", + "variable": "x", + "variableTypes": ["Number", "String"], + "defaultType": "Number" + } + ] + } + ``` + + + ```js + Blockly.Blocks['example_variable_typed'] = { + init: function() { + this.appendDummyInput() + .appendField('variable:') + .appendField(new Blockly.FieldVariable( + 'X', + null, + ['Number', 'String'], + 'Number' + ), 'FIELDNAME'); + } + }; + ``` + + +The variable constructor takes in an optional variable name, an optional +[validator](#creating-a-variable-validator), an optional array of variable +types, and an optional default type. + +- The **variable name** should be a string. This will be the name of the + initial variable the field holds. If it is null or undefined a unique name + will be generated. +- The **variable types** should be an array of strings. This tells the field + what types of variables the field can hold (i.e. what types of variables to + add to the dropdown). If it is null or undefined, all variable types will + be accepted (and added to the dropdown). +- The **default type** should be a string. This will be used when creating the + field's initial variable model. If this is defined, its should be included + in the variable types array. If it is null or undefined this value defaults + to an empty string, meaning the initial variable will be flexibly typed. + +→ For more information on strict typing, see +[Type Checks](/guides/create-custom-blocks/inputs/connection-checks). + +## Serialization + + + + The JSON for a variable field looks like so: + + ```json + { + "fields": { + "FIELDNAME": { + "id": "QJD^+@[RVIwbLSZoDb:V" + } + } + } + ``` + + Where `FIELDNAME` is a string referencing a variable field, and + the value is the ID of the variable the field references. + + If you are using this field in the toolbox, you can also specify the name + and (optional) type directly, since there will be no variable available to + reference. + + ```json + { + "fields": { + "FIELDNAME": { + "name": "my_variable", + "type": "string" + } + } + } + ``` + + + The XML for a variable field looks like so: + + ```xml + name + ``` + + + The node's `name` attribute contains a string referencing a variable + field. + + The node's `id` attribute contains the ID of the variable the field + references. + + The node's `variabletype` attribute contains the type of the variable. + The `variabletype` follows the same rules as the constructor's default + type parameter. + + The node's inner text is the name of the variable. The inner text value + follows the same rules as the constructor's variable name parameter. + + +## Creating a variable validator + +:::note +For information on validators in general see [Validators](/guides/create-custom-blocks/fields/validators). +::: + +A variable field's value is a string, so any validators must accept a string and +return a string, `null`, or `undefined`. + +Here's an example of a validator that only accepts some predefined variables as +options. These variables would need to be defined with the +[`Workspace.getVariableMap().createVariable`](/reference/blockly.ivariablemap_interface.createvariable_1_methodsignature) +function when the workspace is loaded. + +```js +function(newValue) { + var validIds = ['Worf', 'Riker', 'Picard']; + if (validIds.indexOf(newValue) == -1) { + return null; + } + return newValue; +} +``` + +![An animated GIF showing the validation function at work. When "Picard" or +"Riker" is chosen from the dropdown, the dropdown is set to that choice. When +"x" is chosen, the dropdown is set to the previous choice, which is +"Riker".](/images/fields/variable/validator.gif) diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/creating.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/creating.mdx new file mode 100644 index 00000000000..65a35c89720 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/creating.mdx @@ -0,0 +1,901 @@ +--- +title: Create a custom field +description: How to create your own custom fields. +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Create a custom field + +Before creating a new field type, consider if one of the [other +methods](/guides/create-custom-blocks/fields/customizing-fields/overview) +for customizing fields suits your needs. If your application needs to store a +new value type, or you wish to create a new UI for an existing value type, you +probably need to create a new field type. + +To create a new field, do the following: + +1. [Implement a constructor](#implementing-a-constructor). +1. [Register a JSON key and implement `fromJson`](#json-and-registration). +1. [Handle initialization of the on-block UI and event + listeners](#initializing). +1. [Handle disposal of event listeners](#disposing) (UI disposal is handled for + you). +1. [Implement value handling](#value-handling). +1. [Add a text-representation of your field's value, for accessibility](#text). +1. Add additional functionality such as: + - [An editor](#creating-an-editor). + - [On-block display updates](#updating-the-on-block-display). + - [Serialization](#serialization). +1. Configure additional aspects of your field, such as: + - [Editable and serializable + properties](#editable-and-serializable-properties) + - [CSS](#css) + - [Cursor](#customizing-the-cursor) + +This section assumes that you have read and are familiar with the contents in +[Anatomy of a +Field](/guides/create-custom-blocks/fields/anatomy-of-a-field). + +For an example of a custom field see the [Custom Fields +demo](https://raspberrypifoundation.github.io/blockly-samples/examples/pitch-field-demo/) +. + +## Implementing a constructor + +The field's constructor is responsible for setting up the field's initial value +and optionally setting up a [local +validator](/guides/create-custom-blocks/fields/validators). The custom +field's constructor is called during the source block initialization regardless +of whether the source block is defined in JSON or JavaScript. So, the custom +field doesn't have access to the source block during construction. + +The following code sample creates a custom field named `GenericField`: + +```js +class GenericField extends Blockly.Field { + constructor(value, validator) { + super(value, validator); + + this.SERIALIZABLE = true; + } +} +``` + +### Method signature + +Field constructors usually take in a value and a local validator. The value is +optional, and if you don't pass a value (or you pass a value that fails class +validation) then the default value of the superclass will be used. For the +default `Field` class, that value is `null`. If you don't want that default +value, then be sure to pass a suitable value. The validator parameter is only +present for editable fields and is typically marked as optional. Learn more +about validators in the [Validators +docs](/guides/create-custom-blocks/fields/validators). + +### Structure + +The logic inside of your constructor should follow this flow: + +1. Call the inherited super constructor (all custom fields should inherit from + `Blockly.Field` or one of its subclasses) to properly initialize the value + and set the local validator for your field. +1. If your field is serializable, set the corresponding property in the + constructor. Editable fields must be serializable, and fields are editable + by default, so you should probably set this property to true unless you know + it shouldn't be serializable. +1. Optional: Apply additional customization (for example, [Label fields](/guides/create-custom-blocks/fields/built-in-fields/label) + allow a css class to be passed, which is then applied to the text). + +## JSON and registration + +In [JSON block +definitions](/guides/create-custom-blocks/define/json-and-js), fields +are described by a string (e.g. `field_number`, `field_textinput`). Blockly +maintains a map from these strings to field objects, and calls `fromJson` on the +appropriate object during construction. + +Call `Blockly.fieldRegistry.register` to add your field type to this map, +passing in the field class as the second argument: + +```js +Blockly.fieldRegistry.register('field_generic', GenericField); +``` + +You also need to define your `fromJson` function. Your implementation should +first dereference any [references to localization +tokens](/guides/configure/web/translations#use-localization-tokens-in-json) +using +[`replaceMessageReferences`](/reference/blockly.utils_namespace.parsing_namespace.replacemessagereferences_1_function), +and then pass the values to the constructor. + +```js +GenericField.fromJson = function (options) { + const value = Blockly.utils.parsing.replaceMessageReferences( + options['value'], + ); + return new CustomFields.GenericField(value); +}; +``` + +:::note +Local validators are not currently supported when using a JSON definition. +But they can be applied via an +[extension](/guides/create-custom-blocks/define/extensions). +::: + +## Initializing + +When your field is constructed, it basically only contains a value. +Initialization is where the DOM is built, the model is built (if the field +possesses a model), and events are bound. + +### On-Block display + +During initialization you are responsible for creating anything you will need +for the field's on-block display. + +#### Defaults, background, and text + +The default `initView` function creates a light coloured `rect` element and a +`text` element. If you want your field to have both of these, plus some extra +goodies, call the superclass `initView` function before adding the rest of your +DOM elements. If you want your field to have one, but not both, of these +elements you can use the `createBorderRect_` or `createTextElement_` functions. + +#### Customizing DOM construction + +If your field is a generic text field (e.g. [Text +Input](/guides/create-custom-blocks/fields/built-in-fields/text-input)), +DOM construction will be handled for you. Otherwise you will need to override +the `initView` function to create the DOM elements that you will need during +future rendering of your field. + +For example, a dropdown field may contain both images and text. In `initView` it +creates a single image element and a single text element. Then during `render_` +it shows the active element and hides the other, based on the type of the +selected option. + +Creating DOM elements can either be done using the +`Blockly.utils.dom.createSvgElement` method, or using traditional DOM creation +methods. + +The requirements of a field's on-block display are: + +- All DOM elements must be children of the field's `fieldGroup_`. The field + group is created automatically. +- All DOM elements must stay inside the reported dimensions of the field. + +See the +[Rendering](/guides/create-custom-blocks/fields/customizing-fields/creating#updating-the-on-block-display) +section for more details on customizing and updating your on-block display. + +#### Adding Text Symbols + +If you want to add symbols to a field's text (such as the +[Angle](https://www.npmjs.com/package/@blockly/field-angle) +field's degree symbol) you can append the symbol element (usually contained in a +``) directly to the field's `textElement_`. + +### Input events + +By default fields register tooltip events, and mousedown events (to be used for +showing +[editors](/guides/create-custom-blocks/fields/customizing-fields/creating#creating-an-editor)). +If you want to listen for other kinds of events (e.g. if you want to handle +dragging on a field) you should override the field's `bindEvents_` function. + +```js +bindEvents_() { + // Call the superclass function to preserve the default behavior as well. + super.bindEvents_(); + + // Then register your own additional event listeners. + this.mouseDownWrapper_ = + Blockly.browserEvents.conditionalBind(this.getClickTarget_(), 'mousedown', this, + function(event) { + this.originalMouseX_ = event.clientX; + this.isMouseDown_ = true; + this.originalValue_ = this.getValue(); + event.stopPropagation(); + } + ); + this.mouseMoveWrapper_ = + Blockly.browserEvents.conditionalBind(document, 'mousemove', this, + function(event) { + if (!this.isMouseDown_) { + return; + } + var delta = event.clientX - this.originalMouseX_; + this.setValue(this.originalValue_ + delta); + } + ); + this.mouseUpWrapper_ = + Blockly.browserEvents.conditionalBind(document, 'mouseup', this, + function(_event) { + this.isMouseDown_ = false; + } + ); +} +``` + +:::note +When overriding `bindEvents_` you should always call the base function. +::: + +To bind to an event you should generally use the +[`Blockly.utils.browserEvents.conditionalBind`](/reference/blockly.utils_namespace.browserevents_namespace.conditionalbind_1_function) +function. This method of binding events filters out secondary touches during +drags. If you want your handler to run even in the middle of an in-progress drag +you can use the +[`Blockly.browserEvents.bind`](/reference/blockly.utils_namespace.browserevents_namespace.bind_1_function) +function. + +## Disposing + +If you registered any custom event listeners inside the field's `bindEvents_` +function they will need to be unregistered inside the `dispose` function. + +:::note +When overriding dispose you should always call the base function. +::: + +If you correctly [initialized the +view](/guides/create-custom-blocks/fields/customizing-fields/creating#initializing) +of your field (by appending all DOM elements to the `fieldGroup_`), then the +field's DOM will be disposed of automatically. + +## Value Handling + +→ For information about a field's value vs its text see [Anatomy of a +field](/guides/create-custom-blocks/fields/anatomy-of-a-field). + +### Validation order + +Flowchart describing the order in which validators are run + +### Implementing a class validator + +Fields should only accept certain values. For example, number fields should only +accept numbers, colour fields should only accept colours etc. This is ensured +through class and local +[validators](/guides/create-custom-blocks/fields/validators). The class +validator follows the same rules as local validators except that it is also run +in the +[constructor](/guides/create-custom-blocks/fields/customizing-fields/creating#implementing-a-constructor) +and, as such, it should not reference the source block. + +To implement your field's class validator, override the `doClassValidation_` +function. + +```js +doClassValidation_(newValue) { + if (typeof newValue != 'string') { + return null; + } + return newValue; +}; +``` + +:::note +The `newValue` passed to `doClassValidation_` could be of any type +(depending on how responsible your fellow developers are), so be prepared to +handle edge cases. +::: + +### Handling valid values + +If the value passed to a field with `setValue` is valid you will receive a +`doValueUpdate_` callback. By default the `doValueUpdate_` function: + +- Sets the `value_` property to `newValue`. +- Sets the [`isDirty_`](/guides/create-custom-blocks/fields/customizing-fields/creating#isdirty_) + property to `true`. + +If you simply need to store the value, and don't want to do any custom handling, +you do not need to override `doValueUpdate_`. + +Otherwise, if you wish to do things like: + +- Custom storage of `newValue`. +- Change other properties based on `newValue`. +- Save whether the current value is valid or not. + +You will need to override `doValueUpdate_`: + +```js +doValueUpdate_(newValue) { + super.doValueUpdate_(newValue); + this.displayValue_ = newValue; + this.isValueValid_ = true; +} +``` + +:::warning +If your field needs to access properties of the block or workspace when +setting the value, you should make `doValueUpdate_` fail cleanly if those are +not available. +::: + +### Handling invalid values + +If the value passed to the field with `setValue` is invalid you will receive a +`doValueInvalid_` callback. By default the `doValueInvalid_` function does +nothing. This means that by default invalid values will not be shown. It also +means the field will not be rerendered, because the +[`isDirty_`](/guides/create-custom-blocks/fields/customizing-fields/creating#isdirty_) +property will not be set. + +If you wish to display invalid values you should override `doValueInvalid_`. +Under most circumstances you should set a `displayValue_` property to the +invalid value, set +[`isDirty_`](/guides/create-custom-blocks/fields/customizing-fields/creating#isdirty_) +to `true`, and [override +render\_](/guides/create-custom-blocks/fields/customizing-fields/creating#updating-the-on-block-display) +for the on-block display to update based on the `displayValue_` instead of the +`value_`. + +```js +doValueInvalid_(newValue) { + this.displayValue_ = newValue; + this.isDirty_ = true; + this.isValueValid_ = false; +} +``` + +:::warning +Never set the `value_` property to an invalid value. Field values +should always be valid for use in +[code generation][field-generator]. +::: + +### Multi-part values + +When your field contains a multipart value (e.g. lists, vectors, objects) you +may wish the parts to be handled like individual values. + +```js +doClassValidation_(newValue) { + if (FieldTurtle.PATTERNS.indexOf(newValue.pattern) == -1) { + newValue.pattern = null; + } + + if (FieldTurtle.HATS.indexOf(newValue.hat) == -1) { + newValue.hat = null; + } + + if (FieldTurtle.NAMES.indexOf(newValue.turtleName) == -1) { + newValue.turtleName = null; + } + + if (!newValue.pattern || !newValue.hat || !newValue.turtleName) { + this.cachedValidatedValue_ = newValue; + return null; + } + return newValue; +} +``` + +In the above example each property of `newValue` is validated individually. Then +at the end of the `doClassValidation_` function, if any individual property is +invalid, the value is cached to the `cacheValidatedValue_` property before +returning `null` (invalid). Caching the object with individually validated +properties allows the +[`doValueInvalid_`](/guides/create-custom-blocks/fields/customizing-fields/creating#handling-invalid-values) +function to handle them separately, simply by doing a +`!this.cacheValidatedValue_.property` check, instead of re-validating each +property individually. + +This pattern for validating multi-part values can also be used in [local +validators](/guides/create-custom-blocks/fields/validators) but +currently there is no way to enforce this pattern. + +### isDirty\_ + +`isDirty_` is a flag used in the +[`setValue`](/reference/blockly.field_class.setvalue_1_method) +function, as well as other parts of the field, to tell if the field needs to be +re-rendered. If the field's display value has changed, `isDirty_` should usually +be set to `true`. + +## Text + +→ For information about where a field's text is used and how it is different +from the field's value, see [Anatomy of a +field](/guides/create-custom-blocks/fields/anatomy-of-a-field). + +If the text of your field is different than the value of your field, you should +override the +[`getText`](/reference/blockly.field_class.gettext_1_method)function +to provide the correct text. + +```js +getText() { + let text = this.value_.turtleName + ' wearing a ' + this.value_.hat; + if (this.value_.hat == 'Stovepipe' || this.value_.hat == 'Propeller') { + text += ' hat'; + } + return text; +} +``` + +## Creating an editor + +If you define the `showEditor_` function, Blockly will automatically listen for +clicks and call `showEditor_` at the appropriate time. You can display any HTML +in your editor by wrapping it one of two special `div`s, called the +`DropDownDiv` and `WidgetDiv`, which float above the rest of Blockly's UI. + +:::info +Updates to an editor's display should be handled during +[rendering](/guides/create-custom-blocks/fields/customizing-fields/creating#updating-the-on-block-display), +instead of being handled immediately. This allows validators to intercept the +value before it is applied. +::: + +### DropDownDiv vs WidgetDiv + +The `DropDownDiv` is used to provide editors that live inside of a box connected +to a field. It automatically positions itself to be near the field while staying +within visible bounds. The angle picker and color picker are good examples of +the `DropDownDiv`. + +![Image of angle picker](/images/angle-picker.png) + +The [`WidgetDiv`](/reference/blockly.widgetdiv_namespace) is used to +provide editors that do not live inside of a box. Number fields use the +`WidgetDiv` to cover the field with an HTML text input box. While the +`DropDownDiv` handles positioning for you, the `WidgetDiv` does not. Elements +will need to be manually positioned. The coordinate system is in pixel +coordinates relative to the top left of the window. The text input editor is a +good example of the `WidgetDiv`. + +Image of text input editor + +### DropDownDiv sample code + +```js +showEditor_() { + // Create the widget HTML + this.editor_ = this.dropdownCreate_(); + Blockly.DropDownDiv.getContentDiv().appendChild(this.editor_); + + // Set the dropdown's background colour. + // This can be used to make it match the colour of the field. + Blockly.DropDownDiv.setColour('white', 'silver'); + + // Show it next to the field. Always pass a dispose function. + Blockly.DropDownDiv.showPositionedByField( + this, this.disposeWidget_.bind(this)); +} +``` + +:::note +Creating HTML programmatically can be quite long-winded so it is not +provided here. For an example of this see the [Custom Fields +Demo](https://raspberrypifoundation.github.io/blockly-samples/examples/pitch-field-demo/) +. +::: + +### WidgetDiv sample code + +```js +showEditor_() { + // Show the div. This automatically closes the dropdown if it is open. + // Always pass a dispose function. + Blockly.WidgetDiv.show( + this, this.sourceBlock_.RTL, this.widgetDispose_.bind(this)); + + // Create the widget HTML. + var widget = this.createWidget_(); + Blockly.WidgetDiv.getDiv().appendChild(widget); +} +``` + +:::note +Creating widget HTML programmatically can be quite long-winded so it is +not provided here. For an example of this see the implementation of [Text Input +Field](https://github.com/RaspberryPiFoundation/blockly/blob/main/core/field_textinput.ts) +. +::: + +:::note +If you are creating a widget that is meant to act like an input but uses a +custom element you can add `data-is-text-input='true'` to your element to notify +Blockly to treat the element as an input. +::: + +### Cleaning up + +Both the `DropDownDiv` and the `WidgetDiv` handle destroying the widget HTML +elements, but you need to manually dispose of any event listeners you have +applied to those elements. + +```js +widgetDispose_() { + for (let i = this.editorListeners_.length, listener; + listener = this.editorListeners_[i]; i--) { + Blockly.browserEvents.unbind(listener); + this.editorListeners_.pop(); + } +} +``` + +The `dispose` function is called in a `null` context on the `DropDownDiv`. On +the `WidgetDiv` it is called in the context of the `WidgetDiv`. In either case +it is best to use the +[bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) +function when passing a dispose function, as shown in the above `DropDownDiv` +and `WidgetDiv` examples. + +→ For information about disposing not specific to disposing of editors see +[Disposing](/guides/create-custom-blocks/fields/customizing-fields/creating#disposing). + +## Updating the on-block display + +The `render_` function is used to update the field's on-block display to match +its internal value. + +Common examples include: + +- Change the text (dropdown) +- Change the color (color) + +:::info +The field should never call `render_` directly. Instead rerenders +should be triggered by setting the +[`isDirty_`](/guides/create-custom-blocks/fields/customizing-fields/creating#isdirty_) +property to `true`. +::: + +### Defaults + +The default `render_` function sets the display text to the result of the +[`getDisplayText_`](/reference/blockly.field_class.getdisplaytext__1_method) +function. The `getDisplayText_` function returns the field's `value_` property +cast to a string, after it has been truncated to respect the maximum text +length. + +If you are using the default on-block display, and the default text behavior +works for your field, you do not need to override `render_`. + +If the default text behavior works for your field, but your field's on-block +display has additional static elements, you can call the default `render_` +function, but you will still need to override it to [update the field's +size](/guides/create-custom-blocks/fields/customizing-fields/creating#updating-size). + +If the default text behavior does not work for your field, or your field's +on-block display has additional dynamic elements, you will need to [customize +the `render_` +function](/guides/create-custom-blocks/fields/customizing-fields/creating#customizing-rendering). + +Flowchart describing how to make decision of whether to override render_ + +### Customizing rendering + +If the default rendering behavior does not work for your field, you will need to +define custom rendering behavior. This can involve anything from setting custom +display text, to changing image elements, to updating background colours. + +All DOM attribute changes are legal, the only two things to remember are: + +1. DOM _creation_ should be handled during + [initialization](/guides/create-custom-blocks/fields/customizing-fields/creating#initializing), + as it is more efficient. +1. You should always [update the `size_`](/guides/create-custom-blocks/fields/customizing-fields/creating#updating-size) + property to match the on-block display's size. + +```js +render_() { + switch(this.value_.hat) { + case 'Stovepipe': + this.stovepipe_.style.display = ''; + break; + case 'Crown': + this.crown_.style.display = ''; + break; + case 'Mask': + this.mask_.style.display = ''; + break; + case 'Propeller': + this.propeller_.style.display = ''; + break; + case 'Fedora': + this.fedora_.style.display = ''; + break; + } + + switch(this.value_.pattern) { + case 'Dots': + this.shellPattern_.setAttribute('fill', 'url(#polkadots)'); + break; + case 'Stripes': + this.shellPattern_.setAttribute('fill', 'url(#stripes)'); + break; + case 'Hexagons': + this.shellPattern_.setAttribute('fill', 'url(#hexagons)'); + break; + } + + this.textContent_.nodeValue = this.value_.turtleName; + + this.updateSize_(); +} +``` + +:::info +Always use `this.textContent_.nodeValue` to update the display text +of your field. This helps support [text +symbols](/guides/create-custom-blocks/fields/customizing-fields/creating#adding-text-symbols). +::: + +### Updating size + +Updating the `size_` property of a field is very important, as it informs the +block rendering code how to position the field. The best way to figure out +exactly what that `size_` should be is by experimenting. + +```js +updateSize_() { + const bbox = this.movableGroup_.getBBox(); + let width = bbox.width; + let height = bbox.height; + if (this.borderRect_) { + width += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2; + height += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2; + this.borderRect_.setAttribute('width', width); + this.borderRect_.setAttribute('height', height); + } + // Note how both the width and the height can be dynamic. + this.size_.width = width; + this.size_.height = height; +} +``` + +:::warning +Calling `getBBox` during rendering can cause layout thrashing, so you +may want to investigate other ways of getting the size. +::: + +:::note +The width and height of a field can be dynamic and updating the size does +not have to be contained in its own function; it can be handled inside +`render_`. However, it is usually separated to keep code more organized. +::: + +### Matching block colours + +If you want elements of your field to match the colours of the block they are +attached to, you should override the `applyColour` method. You will want to +access the colour through the block's style property. + +```js +applyColour() { + const sourceBlock = this.sourceBlock_; + if (sourceBlock.isShadow()) { + this.arrow_.style.fill = sourceBlock.style.colourSecondary; + } else { + this.arrow_.style.fill = sourceBlock.style.colourPrimary; + } +} +``` + +:::note +You may want to cache the colours in the `applyColour` method, so you can +apply them to your +[editor](/guides/create-custom-blocks/fields/customizing-fields/creating#creating-an-editor) +when it is activated. +::: + +### Updating editability + +The `updateEditable` function can be used to change how your field appears +depending on if it is editable or not. The default function makes it so the +background does/doesn't have a hover response (border) if it is/isn't editable. +The on-block display should not change size depending on its editability, but +all other changes are allowed. + +```js +updateEditable() { + if (!this.fieldGroup_) { + // Not initialized yet. + return; + } + super.updateEditable(); + + const group = this.getClickTarget_(); + if (!this.isCurrentlyEditable()) { + group.style.cursor = 'not-allowed'; + } else { + group.style.cursor = this.CURSOR; + } +} +``` + +:::warning +Messing with a field's cursor is fragile. +::: + +## Serialization + +[Serialization](/guides/configure/web/serialization) is about saving the +state of your field so that it can be reloaded into the workspace later. + +The state of your workspace always includes the field's value, but it could also +include other state, such as the state of your field's UI. For example, if your +field was a zoomable map that allowed the user to select countries, you could +also serialize the zoom level. + +If your field is serializable, you must set the `SERIALIZABLE` property to +`true`. + +Blockly provides two sets of serialization hooks for fields. One pair of hooks +works with the new JSON serialization system, and the other pair works with the +old XML serialization system. + +### `saveState` and `loadState` + +`saveState` and `loadState` are serialization hooks that work with the new JSON +serialization system. + +In some cases you do not need to provide these, because the default +implementations will work. If (1) your field is a direct subclass of the base +`Blockly.Field` class, (2) your value is a [JSON serializable +type](https://en.wikipedia.org/wiki/JSON#Data_types), and (3) you only need to +serialize the value, then the default implementation will work just fine! + +Otherwise, your `saveState` function should return a JSON serializable +object/value which represents the state of the field. And your `loadState` +function should accept the same JSON serializable object/value, and apply it to +the field. + +```js +saveState() { + return { + 'country': this.getValue(), // Value state + 'zoom': this.getZoomLevel(), // UI state + }; +} + +loadState(state) { + this.setValue(state['country']); + this.setZoomLevel(state['zoom']); +} +``` + +#### Full serialization and backing data + +`saveState` also receives an optional parameter `doFullSerialization`. This is +used by fields that normally reference state serialized by a different +[serializer][serializer] (like backing data models). The parameter signals that +the referenced state won't be available when the block is deserialized, so the +field should do all of the serialization itself. For example, this is true when +an individual block is serialized, or when a block is copy-pasted. + +Two common use cases for this are: + +- When an individual block is loaded into a workspace where the backing data + model doesn't exist, the field has enough information in its own state to + create a new data model. +- When a block is copy-pasted, the field always creates a new backing + data model instead of referencing an existing one. + +One field that uses this is the built-in variable field. Normally it serializes +the ID of the variable it is referencing, but if `doFullSerialization` is true +it serializes all of its state. + +```js +saveState(doFullSerialization) { + const state = {'id': this.variable_.getId()}; + if (doFullSerialization) { + state['name'] = this.variable_.name; + state['type'] = this.variable_.type; + } + return state; +} + +loadState(state) { + const variable = Blockly.Variables.getOrCreateVariablePackage( + this.getSourceBlock().workspace, + state['id'], + state['name'], // May not exist. + state['type']); // May not exist. + this.setValue(variable.getId()); +} +``` + +The variable field does this to make sure that if it is loaded into a workspace +where its variable doesn't exist, it can create a new variable to reference. + +### `toXml` and `fromXml` + +`toXml` and `fromXml` are serialization hooks that work with the old XML +serialization system. Only use these hooks if you have to (e.g. you're working +on an old codebase that hasn't migrated yet), otherwise use `saveState` and +`loadState`. + +Your `toXml` function should return an XML node which represents the state of +the field. And your `fromXml` function should accept the same XML node and apply +it to the field. + +```js +toXml(fieldElement) { + fieldElement.textContent = this.getValue(); + fieldElement.setAttribute('zoom', this.getZoomLevel()); + return fieldElement; +} + +fromXml(fieldElement) { + this.setValue(fieldElement.textContent); + this.setZoomLevel(fieldElement.getAttribute('zoom')); +} +``` + +## Editable and serializable properties + +The `EDITABLE` property determines if the field should have UI to indicate that +it can be interacted with. It defaults to `true`. + +The `SERIALIZABLE` property determines if the field should be serialized. It +defaults to `false`. If this property is `true`, you may need to provide +serialization and deserialization functions (see +[Serialization](/guides/create-custom-blocks/fields/customizing-fields/creating#serialization)). + +:::info +If `EDITABLE` is `true` for your field `SERIALIZABLE` should also be +set to `true`. This is not the case by default for backwards compatibility +reasons. +::: + +## Customizing with CSS \{#css\} + +You can customize your field with CSS. In the [`initView` +method](#on-block-display), add a custom class to your field's `fieldGroup_`, +then reference this class in your CSS. + +For example, to use a different cursor: + +```js +initView() { + ... + + // Add a custom CSS class. + if (this.fieldGroup_) { + Blockly.utils.dom.addClass(this.fieldGroup_, 'myCustomField'); + } +} +``` + +```css +.myCustomField { + cursor: cell; +} +``` + +## Customizing the cursor + +By default, classes that extend `FieldInput` use a `text` cursor when a user +hovers over the field, fields being dragged use a `grabbing` cursor, and all +other fields use a `default` cursor. If you want to use a different cursor, set +it [using CSS](#css). + +:::note +Before version 12.0.0, the `CURSOR` property determined the cursor. Its +value was a valid CSS cursor string. +::: + +[serializer]: /guides/configure/web/serialization#serializer-hooks +[field-generator]: /guides/create-custom-blocks/code-generation/overview#block-code-generators diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/extending.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/extending.mdx new file mode 100644 index 00000000000..f7557c30d2a --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/extending.mdx @@ -0,0 +1,74 @@ +--- +description: How to add functionality to an existing field. +title: Extend an existing field +image: images/blockly_banner.png +--- + +# Extend an existing field + +In order to extend an existing field you must subclass a built in field (e.g +`FieldTextInput`, `FieldColour`) and then modify part of it to fit your needs. +Some parts of a field you can modify are: + +- Its + [editor](/guides/create-custom-blocks/fields/anatomy-of-a-field#editor-display). +- Its + [on-block display](/guides/create-custom-blocks/fields/anatomy-of-a-field#on-block-display). +- The + [text](/guides/create-custom-blocks/fields/anatomy-of-a-field#text) + it displays. + +If you want to [create a +custom field](/guides/create-custom-blocks/fields/customizing-fields/creating) +that does not need behaviour from any built-in field you should subclass `Field`. + +## Common extensions + +Most custom fields extend one of these three types: + +- [Text Input](/guides/create-custom-blocks/fields/built-in-fields/text-input): If you want your users to type into your field, you should extend + `FieldTextInput`. +- [Number](/guides/create-custom-blocks/fields/built-in-fields/number): If you want to store a number, you should extend `FieldNumber`. +- [Dropdown](/guides/create-custom-blocks/fields/built-in-fields/dropdown): If you want to create a dropdown, but you want it to store a different model + than the default string or image model, you should extend `FieldDropdown`. - Caution: Before extending `FieldDropdown`, check that the dropdown field's + [customization options](/guides/create-custom-blocks/fields/built-in-fields/dropdown#customization) cannot fulfill your needs. + +Under certain circumstances you may wish to extend a different field type. For +example `FieldLabelSerializable` extends `FieldLabel`. + +## Subclassing + +```js +import * as Blockly from 'blockly'; + +export class MyCustomTextField extends Blockly.FieldTextInput { + constructor(value, validator, config) { + super(value, validator, config); + } +} +``` + +The constructor for a field's subclass looks very similar to the [constructor for +a custom field](/guides/create-custom-blocks/fields/customizing-fields/creating#implementing-a-constructor). The signature of the sub-constructor should +generally match the signature of the super-constructor. + +## JSON and registration + +You should also register the field once: + +```js +Blockly.fieldRegistry.register('my_custom_text_field', MyCustomTextField); +``` + +and provide an implementation of `fromJson` in the class so that it works with +the JSON format: + +```js +static fromJson(options) { + const value = Blockly.utils.parsing.replaceMessageReferences(options.value); + return new MyCustomTextField(value); +} +``` + +For more information about registering a field see the [JSON and registration](/guides/create-custom-blocks/fields/customizing-fields/creating#json-and-registration) +section in Creating a Custom Field. diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/overview.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/overview.mdx new file mode 100644 index 00000000000..5c239cd49c7 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/overview.mdx @@ -0,0 +1,31 @@ +--- +description: Methods for customizing fields. +title: Custom fields +image: images/blockly_banner.png +--- + +# Custom fields + +While Blockly provides many useful fields, your application may have a +specialized case. Here are a few steps to take when customizing fields: + +1. Read the documentation of any fields similar to what you require; they may + provide a useful interface for customization. For example, + [dropdowns](/guides/create-custom-blocks/fields/built-in-fields/dropdown) have a lot of hidden functionality. + +2. Consider using a [validator](/guides/create-custom-blocks/fields/validators) to solve your problem. + Validators allow you to only accept certain values, modify input, or trigger + functionality when a field's value changes. + +3. Consider [extending a field](/guides/create-custom-blocks/fields/customizing-fields/extending). + If there is a field that represents the value type you require, but you want to + modify its [editor](/guides/create-custom-blocks/fields/anatomy-of-a-field#editor-display), its + [appearance](/guides/create-custom-blocks/fields/anatomy-of-a-field#on-block-display), or the + [text](/guides/create-custom-blocks/fields/customizing-fields/creating#text) it + displays, you can [create a subclass](/guides/create-custom-blocks/fields/customizing-fields/extending#subclassing) + that inherits the bulk of the functionality, while overriding the specific parts + you want to change. + +4. [Create a new field type](/guides/create-custom-blocks/fields/customizing-fields/creating). + While this is the most powerful option, it is also the most time consuming, and + should generally only be used if you need to store a new value type. diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/upgrading.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/upgrading.mdx new file mode 100644 index 00000000000..5b26cdae415 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/customizing-fields/upgrading.mdx @@ -0,0 +1,360 @@ +--- +description: Upgrading custom fields that were implemented before version 2. +title: Upgrade a custom field +image: images/blockly_banner.png +--- + +# Upgrade a custom field + +In July 2019 ([release 2.20190722](https://github.com/RaspberryPiFoundation/blockly/releases/tag/2.20190722.0)) +a more codified fields API was added. It is intended to +be as backwards compatible as possible. This means that if you had created a +custom field before July 2019 it will most likely continue to work. +Before deciding whether your custom field needs to be upgraded you should read +through the [Danger areas](#danger-areas) section, and give your field a thorough testing. + +Because there was a lack of standardization between fields before July 2019 +it is tricky to cover all changes a developer might need to make. +This document tries to cover all likely changes, but if this document does not +cover something you are interested in, please read the section on +[getting upgrade assistance](#getting-upgrade-assistance). + +:::note +If you have a small number of custom fields it may be easier to simply +rewrite them using the [custom field creation instructions](/guides/create-custom-blocks/fields/customizing-fields/creating), +rather than trying to upgrade them piecemeal. +::: + +## Danger areas + +Danger areas are known places where the API has changed, and your field could be +broken. + +### Blockly.Field.register + +Fields are not longer registered through `Blockly.Field.register();`. There is +now a `fieldRegistry` namespace that handles registration. + +```js +Blockly.Field.register('my_field_name', myFieldClass); +``` + +Becomes: + +```js +Blockly.fieldRegistry.register('my_field_name', myFieldClass); +``` + +### setText + +The `setText` function is no longer called by the Blockly core, so if your `setText` +function contains logic it will need to be moved to the +[value handling](/guides/create-custom-blocks/fields/customizing-fields/creating#value-handling) +suite of functions, the [`getText`](/guides/create-custom-blocks/fields/customizing-fields/creating#text) +function, and the [rendering functions](/guides/create-custom-blocks/fields/customizing-fields/creating#updating-the-on-block-display) +(depending on what exactly your `setText` function is doing). + +```js +CustomFields.UpgradeField.prototype.setText = function (newText) { + // Do validation. + if (typeof newText != 'string' || newText === this.text_) { + return; + } + + // Fire event. + if (this.sourceBlock_ && Blockly.Events.isEnabled()) { + Blockly.events.fire( + new Blockly.Events.BlockChange( + this.sourceBlock_, + 'field', + this.name, + this.text_, + newText, + ), + ); + } + + // Update text value. + this.text_ = 'prefix' + newText; + + // Rerender. + this.size_.width = 0; +}; +``` + +Becomes: + +```js +CustomFields.UpgradeField.prototype.doClassValidation_ = function (newValue) { + if (typeof newValue != 'string') { + return null; + } + return newValue; +}; + +CustomFields.UpgradeField.prototype.getText = function () { + return 'prefix' + this.value_; +}; +``` + +Blockly automatically handles: + +- Checking if the new value is different than the old value. +- Updating the value. +- Firing change events. +- Rerendering the field. + +You will need to handle: + +- [Value validation](/guides/create-custom-blocks/fields/customizing-fields/creating#value-handling) (`doClassValidation_`). +- [Field text](/guides/create-custom-blocks/fields/customizing-fields/creating#text) (`getText`). +- [Field UI](/guides/create-custom-blocks/fields/customizing-fields/creating#updating-the-on-block-display) + +:::note +We recommend that you change any `setText` calls to +`setValue` calls, as `setValue` supports validation and `setText` does not. +::: + +## Recommended upgrades + +Recommended upgrades are places where the field API has been changed, but if you +choose not to make changes your field will most likely still work. + +### SERIALIZABLE + +For more information about the `EDITABLE` and `SERIALIZABLE` properties see +[Editable and serializable properties](/guides/create-custom-blocks/fields/customizing-fields/creating#editable-and-serializable-properties). + +```js +CustomFields.UpgradeField.prototype.SERIALIZABLE = true; +``` + +The warning below is ignorable, but you can resolve it by defining the `SERIALIZABLE` +property: + +``` +Detected an editable field that was not serializable. Please define +SERIALIZABLE property as true on all editable custom fields. Proceeding +with serialization. +``` + +The warning above means that Blockly believes you want the +field to be serialized (because the `EDITABLE` property is true), but +cannot be sure until you define the `SERIALIZABLE` property. If you choose to +leave this alone everything will function properly, and your field will be +serialized, but you will receive console warnings. + +### size\_.width + +```js +this.size_.width = 0; +``` + +Becomes: + +```js +this.isDirty_ = true; +``` + +The warning below is ignorable, but you can resolve it by setting the `isDirty_` +property instead of the `size_.width` property: + +``` +Deprecated use of setting size_.width to 0 to rerender a field. Set +field.isDirty_ to true instead. +``` + +The warning above means that Blockly has detected you are using an old method for rerendering a +field, and would like you to use the new method. + +For more information about the `isDirty_` property see +[isDirty\_](/guides/create-custom-blocks/fields/customizing-fields/creating#isdirty-). + +### init + +The `init` function has been made into a [template +function](https://en.wikipedia.org/wiki/Template_method_pattern) to reduce +duplicate code in subclasses. + +```js +CustomFields.UpgradeField.prototype.init = function () { + if (this.fieldGroup_) { + // Already initialized once. + return; + } + + // Call superclass. + CustomFields.UpgradeField.superClass_.init.call(this); + + // Create DOM elements. + this.extraDom_ = Blockly.utils.dom.createSvgElement('image', { + height: '10px', + width: '10px', + }); + this.extraDom_.setAttributeNS( + 'http://www.w3.org/1999/xlink', + 'xlink:href', + 'image.svg', + ); + this.extraDom_.style.cursor = 'pointer'; + this.fieldGroup_.appendChild(this.extraDom_); + + // Bind events. + this.mouseOverWrapper_ = Blockly.browserEvents.bind( + this.getClickTarget_(), + 'mouseover', + this, + this.onMouseOver_, + ); + this.mouseOutWrapper_ = Blockly.browserEvents.bind( + this.getClickTarget_(), + 'mouseout', + this, + this.onMouseOut_, + ); + + // Render. + this.setValue(this.getValue()); +}; +``` + +Becomes: + +```js +CustomFields.UpgradeField.prototype.initView = function () { + CustomFields.UpgradeField.superClass_.initView.call(this); + + this.extraDom_ = Blockly.utils.dom.createSvgElement('image', { + height: '10px', + width: '10px', + }); + this.extraDom_.setAttributeNS( + 'http://www.w3.org/1999/xlink', + 'xlink:href', + 'image.svg', + ); + this.extraDom_.style.cursor = 'pointer'; + this.fieldGroup_.appendChild(this.extraDom_); +}; + +CustomFields.UpgradeField.prototype.bindEvents_ = function () { + CustomFields.UpgradeField.superClass_.bindEvents_.call(this); + + this.mouseOverWrapper_ = Blockly.bindEvent_( + this.getClickTarget_(), + 'mouseover', + this, + this.onMouseOver_, + ); + this.mouseOutWrapper_ = Blockly.bindEvent_( + this.getClickTarget_(), + 'mouseout', + this, + this.onMouseOut_, + ); +}; +``` + +This means that blockly now automatically handles: + +- Checking if the field is already initialized. +- Creating the `fieldGroup_`. +- Rendering the field. +- Binding tooltip and show editor events. + +You will need to handle: + +- Adding additional + [DOM elements](/guides/create-custom-blocks/fields/customizing-fields/creating#on-block-display) (`initView`). +- Adding additional + [event bindings](/guides/create-custom-blocks/fields/customizing-fields/creating#input-events) (`bindEvents_`). +- [Disposing](/guides/create-custom-blocks/fields/customizing-fields/creating#disposing) of event bindings (`dispose`). + +:::info +All DOM creation should be done inside `initView` as that is most +efficient. Consider refactoring if you have DOM creation happening inside the +constructor, `setText`, `setValue`, or `render_`. +::: + +### onMouseDown\_ + +```js +CustomFields.UpgradeField.prototype.onMouseDown_ = function (e) { + // ... +}; +``` + +Becomes: + +```js +CustomFields.UpgradeField.prototype.showEditor_ = function () { + // ... +}; +``` + +We recommend that you override the `showEditor_` function to handle mouse +clicks rather than the `onMouseDown_` function as that allows input to pass +through the gesture system. + +For more information on editors see [Editors](/guides/create-custom-blocks/fields/customizing-fields/creating#creating-an-editor). + +### setValue + +The `setValue` function is now a [template +function](https://en.wikipedia.org/wiki/Template_method_pattern) to reduce +duplicate code in subclasses. If your `setValue` function contains logic, +consider refactoring it to fit the value handling paths described in [Value +handling](/guides/create-custom-blocks/fields/customizing-fields/creating#value-handling). + +### text\_ + +We recommend that you never access or update the `text_` property of your +field directly. Instead, use the +[`getText`](/reference/blockly.field_class.gettext_1_method) function +to access the user readable text of your field and the +[`setValue`](/reference/blockly.field_class.setvalue_1_method) function +to update the stored value of your field. + +For more information about a field's value vs its text see +[Anatomy of a field](/guides/create-custom-blocks/fields/anatomy-of-a-field). + +## Getting upgrade assistance + +:::note +Before asking for upgrade assistance please do your best to upgrade your +field independently using the information provided. +::: + +### What to provide + +When asking for assistance it is best to ask specific questions: + +Not recommended: "What's wrong with this field?" + +Also not recommended: "Help me upgrade this field." + +Recommended: "Field text is not updating properly." + +It is also necessary to provide resources to the people assisting you. These +files should be easy for others to use. + +Not recommended: + +- Images of code. +- Incomplete code. + +Recommended: + +- Complete field code in a text format. +- Images of gifs of bad field behavior. +- Steps to reproduce bad field behavior. +- The version of blockly you are upgrading from. + +### Where to post + +Post upgrade questions on the [blockly developer +forum](https://groups.google.com/g/blockly). + +If you are sure that the issue is a problem with the blockly core you can also +[post an issue](https://github.com/RaspberryPiFoundation/blockly/issues) on the blockly GitHub. +If you decide to post an issue, please fill out all requested information. diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/fields-vs-icons.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/fields-vs-icons.mdx new file mode 100644 index 00000000000..6a6b421bd6e --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/fields-vs-icons.mdx @@ -0,0 +1,30 @@ +--- +description: The differences and similarities between fields and icons. +title: Fields vs icons +image: images/blockly_banner.png +--- + +# Fields vs icons + +Fields and icons are both visual elements that appear on a block, but they have +different purposes. + +Fields show or define data about a block that affects how a program functions. +For example, the text block has two quotation marks, which indicate that you are +defining a string, and a text input that lets you define that string. The +quotation marks tell you about the function of the block, and the input lets +you modify the function. + +Icons show or define "meta" information about the block itself. For example, +you can append a comment icon to any block, which lets you write notes to +yourself, but does not affect how the block functions within the program. + +## Comparison of functionality + +| Attribute | Fields | Icons | +| ------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| Rendering | Fields can be made of whatever elements they want. | Icons can be made of whatever elements they want. | +| Number | Fields can each appear any number of times in a block. | Icons can each appear once in a block. | +| Placement | Fields can be positioned in any location on any input of a block. | Icons are always positioned at the top-start of a block. | +| Serialization | Fields can be serialized, and often are. | Icons can be serialized, but are often not, because they often don't have state. | +| Collapsing | Fields are hidden when a block is collapsed and their text is shown instead. | Icons can control whether they are shown or hidden when the block is collapsed. | diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/lifecycle.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/lifecycle.mdx new file mode 100644 index 00000000000..c6a6ba76c55 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/lifecycle.mdx @@ -0,0 +1,34 @@ +--- +description: The order in which parts of a field are initialized. +title: Lifecycle +image: images/blockly_banner.png +--- + +# Lifecycle + +:::note +When loading from XML the value of a field is set later than you might expect +which can cause problems if your field constructor needs information from the workspace. +::: + +:::note +A field object is created before being attached to a block. This can cause +problems if your field constructor needs information from the workspace. +::: + +Field creation happens in the order below. + +1. The field's constructor is called. + 1. The constructor sets the value to the provided or default value. + 1. The constructor sets the local validator but does not call it. + +1. Field is appended to the block. + 1. `setSourceBlock` is called + 1. If the field is on a rendered workspace, init is called. + 1. The `fieldGroup_` is created and appended. + 1. `initView` is called. + 1. `bindEvents_` is called. + +1. Field XML value is set. + +![Flowchart describing construction and initialization of a field](/images/fields/field_construction_flowchart.jpg) diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/overview.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/overview.mdx new file mode 100644 index 00000000000..03a575feb73 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/overview.mdx @@ -0,0 +1,38 @@ +--- +description: What field are, which kinds are provided by default, and how to customize them. +title: Fields +image: images/blockly_banner.png +--- + +# Fields + +Fields are used to define most UI elements on a block. Examples of fields +include string labels, images, inputs for literal data such as strings and +numbers, and rich editors like date pickers and angle pickers. The simplest +example of a field is the `math_number` block, which uses a `field_number` to +let the user type a number. + +![A block with a number field.](/images/math-number.png) + +:::note +If you need to show meta-information about a block, you probably want an +icon instead. Read more about [Fields vs Icons][fields-vs-icons]. +::: + +Blockly provides several fields by default to handle a variety of user input. +These can be customized through field-specific configuration or with validators, +which tell a field how to handle specific content in a standard editor. + +→ More info on [Built-in fields](/guides/create-custom-blocks/fields/built-in-fields/overview). + +→ More info on [Validators](/guides/create-custom-blocks/fields/validators). + +If you need a fully custom field it takes a bit more work and you'll want to +read most of the fields documentation. Start by learning about the parts +that make up a field or the overview of creating custom fields. + +→ More info on the [anatomy of a field](/guides/create-custom-blocks/fields/anatomy-of-a-field). + +→ More info on [creating custom fields](/guides/create-custom-blocks/fields/customizing-fields/overview). + +[fields-vs-icons]: /guides/create-custom-blocks/fields/fields-vs-icons diff --git a/packages/docs/docs/guides/create-custom-blocks/fields/validators.mdx b/packages/docs/docs/guides/create-custom-blocks/fields/validators.mdx new file mode 100644 index 00000000000..fb15883bd91 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/fields/validators.mdx @@ -0,0 +1,219 @@ +--- +description: How to limit the range of valid values that can be held by a field. +title: Validators +image: images/blockly_banner.png +--- + +# Validators + +A validator is a function that takes in the fields new value, and then acts on +it. They are a simple way to customize a field. They allow you to trigger +functionality when a field's value changes, modify input, or limit which values +are acceptable. + +Some common examples: + +- Restricting a text field to only accept letters. +- Requiring that a text field be non-empty. +- Requiring that a date be in the future. +- Modifying a block's shape based on a dropdown. + +:::note +Validators modify a field's +[_value_ not its _text_](/guides/create-custom-blocks/fields/anatomy-of-a-field#value). +::: + +## Types of validators + +Validators execute at different times depending on what kind of validator they +are. + +**Class validators** are part of a field type's class definition, and are +usually used to restrict the _type_ of value allowed by the field (e.g. number +fields only accept numeric characters). Class validators are run on all values +passed to the field (including the value passed to the constructor). + +For more information about class validators see the +[Implementing a class validator](/guides/create-custom-blocks/fields/customizing-fields/creating#implementing-a-class-validator) +section in Creating a Custom Field. + +**Local validators** are defined at the time of a field's construction. Local +validators run on all values passed to the field _except the value passed to the +constructor_. This means they run on: + +- Values contained in XML. +- Values passed to `setValue`. +- Values passed to `setFieldValue`. +- Values changed by the user. + +Class validators are run before local validators because they act like +gatekeepers. They make sure that the value is of the correct type before passing +it on. + +For more information about the sequence of value validation, and values in +general see Values. + +## Registering a local validator + +Local validators can be registered in two ways: + +- Directly added in a field's constructor. + +:::note +The signature of the field +constructor may be different depending on the field type. +::: + +```js +Blockly.Blocks['validator_example'] = { + init: function () { + // Remove all 'a' characters from the text input's value. + var validator = function (newValue) { + return newValue.replace(/\a/g, ''); + }; + + this.appendDummyInput().appendField( + new Blockly.FieldTextInput('default', validator), + ); + }, +}; +``` + +- With + [`setValidator`](/reference/blockly.field_class.setvalidator_1_method). + +```js +Blockly.Blocks['validator_example'] = { + init: function () { + // Remove all 'a' characters from the text input's value. + var validator = function (newValue) { + return newValue.replace(/\a/g, ''); + }; + + var field = new Blockly.FieldTextInput('default'); + field.setValidator(validator); + + this.appendDummyInput().appendField(field); + }, +}; +``` + +Either of the above methods can be wrapped in an +[extension](/guides/create-custom-blocks/define/extensions), to support +the JSON format. + +The field's value may be very different depending on the type of field being +validated (e.g. a number field will store a number, while a text input field +will store a string) so it is best to read the documentation for your specific +field before creating a validator. + +:::note +Only editable fields accept validators, so be sure to check the specific +field's documentation. +::: + +## Return values + +The return value of the validator determines what the field does next. There +are three possibilities: + +**Modified Return Value** + +A modified or different value, which then becomes the field's new value. +This is often used to clean up a value, such as by removing trailing +whitespace. + +Example of a Modifying Validator: + +```js +// Remove all 'a' characters from the text input's value. +var validator = function (newValue) { + return newValue.replace(/\a/g, ''); +}; +``` + +![Text input field with a modifying validator](/images/fields/modifying_validator.gif) + +**Null Return Value** + +Null, which means the given value is invalid. In most cases the field will +ignore the input value. The exact behaviour is specified by the field's +`doValueInvalid_` +[function](/guides/create-custom-blocks/fields/customizing-fields/creating#handling-invalid-values). + +Example of a Nulling Validator: + +```js +// Any value containing a 'b' character is invalid. Other values are valid. +var validator = function (newValue) { + if (newValue.indexOf('b') != -1) { + return null; + } + return newValue; +}; +``` + +![Text input field with a nulling validator](/images/fields/nulling_validator.gif) + +**Undefined Return Value** + +Undefined (or no return statement) or the input value, which means that the +input value should become the field's new value. These types of validators +generally act as change listeners. + +Example of a Listener Validator: + +```js +// Log the new value to console. +var validator = function (newValue) { + console.log(newValue); +}; +``` + +Note once again how the display _text_ does not necessarily reflect the field's +_value_. + +## Value of this + +Inside of a validator `this` refers to the field, not the block. If you need to +access the block inside of a validator use the `getSourceBlock` function. You +can also use the +[`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) +function to set the context within which the validator is called. + +Sample code using `getSourceBlock`: + +```js +Blockly.Blocks['colour_match'] = { + init: function () { + this.appendDummyInput().appendField( + new Blockly.FieldColour(null, this.validate), + 'COLOUR', + ); + this.setColour(this.getFieldValue('COLOUR')); + }, + + validate: function (colourHex) { + this.getSourceBlock().setColour(colourHex); + }, +}; +``` + +Sample code using +[`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind): + +```js +Blockly.Blocks['colour_match'] = { + init: function () { + this.appendDummyInput().appendField( + new Blockly.FieldColour(null, this.validate.bind(this)), + 'COLOUR', + ); + this.validate(this.getFieldValue('COLOUR')); + }, + + validate: function (colourHex) { + this.setColour(colourHex); + }, +}; +``` diff --git a/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/basic-implementation.mdx b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/basic-implementation.mdx new file mode 100644 index 00000000000..6ba87d1319c --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/basic-implementation.mdx @@ -0,0 +1,209 @@ +--- +description: How to create your own custom icons. +title: Create custom icons +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Create custom icons + +To create a custom icon you need to implement the [`IIcon`][IIcon] interface. +This tells Blockly how you want your icon to be rendered, what you want it to +do if it's clicked, etc. + +We recommend subclassing the [`Icon`][Icon] abstract class, because it already +provides default implementations of many methods in the [`IIcon`][IIcon] +interface. + +```js +class MyIcon extends Blockly.icons.Icon { + // The constructor should always take in the source block so that svg elements + // can be properly created. + constructor(sourceBlock) { + super(sourceBlock); + } +} +``` + +## Specify the icon's type + +The [`getType`][getType] method returns a value representing the type of the +icon. It is used for [registering the icon][registering] for serialization, and +retrieving the icon from [`getIcon`][getIcon]. + + + + ```js + getType() { + return new Blockly.icons.IconType('my_icon'); + } + ``` + + + ```ts + getType(): Blockly.icons.IconType { + return new Blockly.icons.IconType('my_icon'); + } + ``` + + +## Create the icon's view + +The icon's view refers to the SVG elements that live on the block. + +### Initialize the view + +The [`initView`][initView] method is where you create the SVG elements of your +icon that live on the block. New elements should be children of the +`this.svgRoot` element so that they get automatically cleaned up when the icon +is destroyed. + +The [`Blockly.utils.dom`][blockly-utils-dom] module provides a clean interface +for instantiating SVGs. + +```js +initView(pointerdownListener) { + if (this.svgRoot) return; // Already initialized. + + // This adds the pointerdownListener to the svgRoot element. + // If you do not call `super` you must do this yourself. + super.initView(pointerdownListener); + + Blockly.utils.dom.createSvgElement( + Blockly.utils.Svg.CIRCLE, + { + 'class': 'my-css-class', + 'r': '8', + 'cx': '8', + 'cy': '8', + }, + this.svgRoot // Append to the svgRoot. + ); +} +``` + +### Return the size + +The [`getSize`][getSize] method returns the size of the icon, so that the +[renderer][renderer] can make the block wide enough for it. + +The size is in arbitrary "workspace units" (which don't change as the workspace +changes scale). + +```js +getSize() { + return new Blockly.utils.Size(16, 16); +} +``` + +### Set the order + +Icons have a static order within the block. For example, the built-in mutator +icons are always shown in front of comment icons, which are shown in front of +warning icons. + +The order is controlled by the value returned by the [`getWeight`][getWeight] +method. Icons with more positive weights are rendered after icons with less +positive weights. + +```js +getWeight() { + return 10; +} +``` + +:::note +the weight is only checked when the icon is appended to the block, so +dynamic weights are not supported. +::: + +## Implement onclick behavior + +Many icons are interactive and do something when they are clicked. For example, +the built-in icons all show a [bubble][bubble] when they are clicked. You can +use the [`onClick`][onClick] method to implement this. + +```js +onClick() { + // Do something when clicked. +} +``` + +## Respond to block changes + +Some icons also want to respond to changes in the block, in particular changes +to editability and collapsed-ness. + +### Editability + +If your icon should behave differently depending on whether the block is +editable or not (for example, not being clickable when the block is not +editable), implement the [`updateEditable`][updateEditable] method. This method +gets called automatically when the block's editable status changes. + +```js +updateEditable() { + if (this.sourceBlock.isEditable()) { + // Do editable things. + } else { + // Do non-editable things. + } +} +``` + +### Collapsed-ness + +Some icons are shown when the block is collapsed, but by default they are +not. If you want your icon to be shown, override the +[`isShownWhenCollapsed`][isShownWhenCollapsed] method to return `true`. + +```js +isShownWhenCollapsed() { + return true; +} +``` + +And then override the [`updateCollapsed`][updateCollapsed] method. + +```js +updateCollapsed() { + // By default icons are hidden when the block is collapsed. We want it to + // be shown, so do nothing. +} +``` + +## Dispose of the icon + +Icons should clean up any dom elements or external references when they are +disposed. By default, anything that is appended to `this.svgRoot` gets +destroyed, but other references need to be manually cleaned up. This should be +done within the [`dispose`][dispose] method. + +```js +dispose() { + // Always call super! + super.dispose(); + + this.myBubble?.dispose(); + this.myOtherReference?.dispose(); +} +``` + +[bubble]: /guides/create-custom-blocks/icons/creating-custom-icons/use-bubbles +[IIcon]: /reference/blockly.iicon_interface +[Icon]: /reference/blockly.icons_namespace.icon_class +[getType]: /reference/blockly.iicon_interface.gettype_1_methodsignature +[registering]: /guides/create-custom-blocks/icons/creating-custom-icons/save-and-load#register-icon-classes +[getIcon]: /reference/blockly.block_class.geticon_1_method +[initView]: /reference/blockly.iicon_interface.initview_1_methodsignature +[blockly-utils-dom]: /reference/blockly.utils_namespace.dom_namespace +[getSize]: /reference/blockly.iicon_interface.getsize_1_methodsignature +[renderer]: /guides/create-custom-blocks/renderers/overview +[getWeight]: /reference/blockly.iicon_interface.getweight_1_methodsignature +[onClick]: /reference/blockly.iicon_interface.onclick_1_methodsignature +[updateEditable]: /reference/blockly.iicon_interface.updateeditable_1_methodsignature +[isShownWhenCollapsed]: /reference/blockly.iicon_interface.isshownwhencollapsed_1_methodsignature +[updateCollapsed]: /reference/blockly.iicon_interface.updatecollapsed_1_methodsignature +[dispose]: /reference/blockly.iicon_interface.dispose_1_methodsignature diff --git a/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/creating-custom-bubbles.mdx b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/creating-custom-bubbles.mdx new file mode 100644 index 00000000000..1d0b3709d92 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/creating-custom-bubbles.mdx @@ -0,0 +1,87 @@ +--- +description: How to create a custom bubble. +title: Create custom bubbles +image: images/blockly_banner.png +--- + +# Create custom bubbles + +A bubble is a pop up UI that looks like a speech bubble you would see in a +comic. They have a "tail" that points at a block, and a "head" that contains +arbitrary svg elements. + +![A bubble with the head and the tail labeled](/images/bubbles/bubble_head_tail.png) + +If the [built-in bubbles][built-in-bubbles] don't work for your use case, you +can create a custom bubble by subclassing the [`Bubble`][bubble] class. + +## Create the view + +A bubble's view is all of the svg elements that live inside the "head" of the +bubble. These elements are created inside of the bubble's constructor, and they +should be children of the `this.contentContainer` element so that they get +automatically cleaned up when the icon is destroyed. + +The [`Blockly.utils.dom`][blockly-utils-dom] module provides a clean interface +for instantiating svgs. + +```js +class MyBubble extends Blockly.bubbles.Bubble { + // See the Blockly.bubbles.Bubble class for information about what these + // parameters are. + constructor(workspace, anchor, ownerRect) { + super(workspace, anchor, ownerRect); + + this.text = Blockly.utils.dom.createSvgElement( + Blockly.utils.Svg.TEXT, + { class: 'my-bubble-class' }, + this.contentContainer, + ); + const node = Blockly.utils.dom.createTextNode('some text'); + this.text.appendChild(node); + } +} +``` + +## Set the size + +The bubble's size needs to be set using [`setSize`][setSize] so that the outer +border can properly surround the contents of the bubble. It should be set +during construction, and whenever the size of the UI elements change. + +```js +constructor(workspace, anchor, ownerRect) { + // Create the view elements... (see above) + + const bbox = this.text.getBBox(); + this.setSize( + new Blockly.utils.Size( + bbox.width + Blockly.bubbles.Bubble.BORDER_WIDTH * 2, + bbox.height + Blockly.bubbles.Bubble.BORDER_WIDTH * 2, + ), + true + ); +} +``` + +## Dispose of the bubble + +Bubbles should clean up any dom elements or external references when they are +disposed. By default, anything that is appended to `this.contentContainer` gets +destroyed, but other references need to be manually cleaned up. This should be +done within the [`dispose`][dispose] method. + +```js +dispose() { + super.dispose(); + + // Dispose of other references. + this.myArbitraryReference.dispose(); +} +``` + +[built-in-bubbles]: /reference/blockly.bubbles_namespace +[blockly-utils-dom]: /reference/blockly.utils_namespace.dom_namespace +[bubble]: /reference/blockly.bubbles_namespace.bubble_class +[setSize]: /reference/blockly.bubbles_namespace.bubble_class.setsize_1_method +[dispose]: /reference/blockly.bubbles_namespace.bubble_class.dispose_1_method diff --git a/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/override-built-in.mdx b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/override-built-in.mdx new file mode 100644 index 00000000000..acb81b58961 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/override-built-in.mdx @@ -0,0 +1,165 @@ +--- +description: How to override built-in comment icons. +title: Override comment icon +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Override comment icon + +You can override the built-in comment icon. For example, you may want the +comment's [pop-up bubble][use-bubbles] to look different. + +A block with the comment icon highlighted + +To override the comment icon, extend `CommentIcon`, override selected methods in +`ICommentIcon`, and register your new icon. + +:::note +Blockly has three kinds of built-in icons: comments, warnings, and +mutators. Only the comment icon is overridable. +::: + +## Extend CommentIcon + +Start by extending `CommentIcon`. + +```js +class MyCommentIcon extends Blockly.icons.CommentIcon { + constructor(sourceBlock) { + super(sourceBlock); + } +} +``` + +## Override methods in ICommentIcon and Icon + +To customize your icon, you can override methods in `ICommentIcon` (described in +the following sections) and +[`Blockly.icons.Icon`](/reference/blockly.icons_namespace.icon_class) +(described in [Create custom +icons](/guides/create-custom-blocks/icons/creating-custom-icons/basic-implementation)). +Do not override `getType`, which must return `Blockly.icons.IconType.COMMENT`. + +### Text + +The `ICommentIcon` interface requires that the comment has text. +The `getText` method must return the text of the comment. The `setText` method +must set the text of the comment and update any visuals. + +```js +getText() { + return this.text; +} + +setText(text) { + this.text = text; + this.myRenderMethod(); +} +``` + +### Bubble + +Your custom comment icon must implement the [`IHasBubble`][IHasBubble] interface +to support serialization. Even if your icon doesn't technically have a bubble, +you should store the visibility information on your class so that the saved +state is maintained. Otherwise you'll lose information from the user if you load +a save that includes whether the comment was open or not. + +```js +bubbleIsVisible() { + return this.bubbleVisible; +} + +setBubbleVisible(visible: boolean) { + this.bubbleVisible = visible; +} +``` + +For more information about bubbles, see [Use pop-up bubbles][use-bubbles]. + +The `ICommentIcon` interface requires a `getBubbleSize` method that returns a +size, and a `setBubbleSize` that sets it. The same reasoning from earlier of +saving state even if your icon doesn't technically have a bubble applies here as +well. + +```js +getBubbleSize() { + return this.bubbleSize; +} + +setBubbleSize(size) { + this.bubbleSize = size; + this.myRenderMethod(); +} +``` + +`ICommentIcon` also requires `getBubbleLocation` and `setBubbleLocation` +methods, which get and set the location of the bubble in the workspace. + +```js +setBubbleLocation(location) { + this.bubbleLocation = location; +} + +getBubbleLocation() { + return this.bubbleLocation; +} +``` + +### Save and load + +Your custom comment icon must implement the [`ISerializable`][ISerializable] +interface. The state should conform to the [`CommentState`][CommentState] +interface. + +```js +saveState() { + return { + text: this.text, + pinned: this.bubbleVisible, + height: this.bubbleSize.height, + width: this.bubbleSize.width, + x: this.bubbleLocation.x, + y: this.bubbleLocation.y, + } +} + +loadState(state) { + this.setText(state.text); + this.setBubbleVisible(state.pinned); + this.setBubbleSize(new Blockly.utils.Size(state.width, state.height)); + this.setBubbleLocation(new Blockly.utils.Coordinate(state.x, state.y)); +} +``` + +For more information about icon serialization see +[Save and load icons][icon-serialization]. + +## Register your icon + +Finally, unregister the existing comment icon and register your comment icon so +Blockly can instantiate it. Use the string `'comment'` for unregistration and +`IconTypes.COMMENT` for registration. + +```js +Blockly.icons.registry.unregister('comment'); +Blockly.icons.registry.register(Blockly.icons.IconType.COMMENT, myCommentIcon); +``` + +After you register your icon, Blockly will use it in place of the built-in +comment icon, such as when the user clicks "Add Comment" on the context menu or +you call `myBlock.setCommentText()`. + +[ICommentIcon]: /reference/blockly.icommenticon_interface +[IHasBubble]: /reference/blockly.ihasbubble_interface +[use-bubbles]: /guides/create-custom-blocks/icons/creating-custom-icons/use-bubbles +[ISerializable]: /reference/blockly.iserializable_interface +[CommentState]: /reference/blockly.icons_namespace.commentstate_interface +[icon-serialization]: /guides/create-custom-blocks/icons/creating-custom-icons/save-and-load +[comment-icon-image]: /images/block-icons/comment-icon-outline.png diff --git a/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/save-and-load.mdx b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/save-and-load.mdx new file mode 100644 index 00000000000..cb80e31075e --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/save-and-load.mdx @@ -0,0 +1,108 @@ +--- +description: How to save and load custom icons. +title: Save and load icons +image: images/blockly_banner.png +--- + +# Save and load icons + +Some icons have state that needs to be saved, while others are instantiated +based on existing state. For example, comment icons need to save their text, +while warning icons don't because they are instantiated based on how blocks are +connected. + +If your icon needs to save its state, you need to implement the +[`ISerializable`][ISerializable] interface and [register][registering] your +icon. + +The state returned by your icon gets included in the `icons` property of your +block's state: + +```js +{ + 'blocks': { + 'languageVersion': 0, + 'blocks': [ + { + 'type': 'my_block', + 'icons': { + // Your state goes here! + 'my_icon': 'some state', + } + } + ] + } +} +``` + +:::info +saving and loading custom icons does not work with the old XML +serialization system, only the new JSON system. +::: + +## Save state + +To save the state of your icon, you need to implement the +[`saveState`][saveState] method of the [`ISerializable`][ISerializable] +interface. This method can return arbitrary json, which gets passed to your +`loadState` method. + +```js +saveState() { + return this.state; // Some arbirtary JSON-compatible data. +} +``` + +### Full serialization and backing data + +`saveState` also receives an optional `doFullSerialization` parameter. This is +used by icons that reference state serialized by a different +[serializer][serializer] (like backing data models). The parameter signals that +the referenced state won't be available when the block is deserialized, so the +icon should serialize all of the backing state itself. For example, this is true +when an individual block is serialized, or when a block is copy-pasted. + +Two common use cases for this are: + +- When an individual block is loaded into a workspace where the backing data + model doesn't exist, the icon has enough information in its own state to + create a new data model. +- When a block is copy-pasted, the icon always creates a new backing + data model instead of referencing an existing one. + +## Load state + +To save the state of your icon, you need to implement the +[`loadState`][loadState] method of the [`ISerializable`][ISerializable] +interface. This method takes in the JSON returned by your `saveState` method. + +```js +loadState(state) { + this.state = state; +} +``` + +## Register icon classes + +Finally you need to register your icon so that the serialization system can +instantiate it. Remember that the [`IconType`][IconType] used to register your +icon needs to have the same string as the one returned by its +[`getType`][getType] method. + +```js +class myIcon extends Blockly.icons.Icon { + getType() { + return new Blockly.icons.IconType('my_icon'); + } +} + +Blockly.icons.registry.register(new Blockly.icons.IconType('my_icon'), myIcon); +``` + +[ISerializable]: /reference/blockly.iserializable_interface +[registering]: /guides/create-custom-blocks/icons/creating-custom-icons/save-and-load#register-icon-classes +[saveState]: /reference/blockly.iserializable_interface.savestate_1_methodsignature +[loadState]: /reference/blockly.iserializable_interface.loadstate_1_methodsignature +[IconType]: /reference/blockly.icons_namespace.icontype_class +[getType]: /reference/blockly.iicon_interface.gettype_1_methodsignature +[serializer]: /guides/configure/web/serialization#serializer-hooks diff --git a/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/use-bubbles.mdx b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/use-bubbles.mdx new file mode 100644 index 00000000000..ab711306c25 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/use-bubbles.mdx @@ -0,0 +1,86 @@ +--- +description: How to use pop-up bubbles within your custom icon. +title: Use pop-up bubbles +image: images/blockly_banner.png +--- + +# Use pop-up bubbles + +The built-in icons use a pop-up-bubble-style UI to display extra information or +editors. Custom icons can also replicate this behavior, to maintain a +consistent look-and-feel. + +If your icon should show a bubble, you need to implement the +[`IHasBubble`][IHasBubble] interface. + +## Show or hide the bubble + +Icons that use bubbles should implement the +[`setBubbleVisible`][setBubbleVisible] method to show or hide the bubble. + +```js +// Implement the setBubbleVisible method of the IHasBubble interface. +async setBubbleVisible(visible) { + // State is already correct. + if (!!this.myBubble === visible) return; + + // Wait for queued renders to finish so that the icon will be correctly + // positioned before displaying the bubble. + await Blockly.renderManagement.finishQueuedRenders(); + + if (visible) { + this.myBubble = new MyBubble(this.getAnchorLocation(), this.getOwnerRect()); + } else { + this.myBubble?.dispose(); + } +} + +// Implement helper methods for getting the anchor location and bounds. + +// Returns the location of the middle of this icon in workspace coordinates. +getAnchorLocation() { + const size = this.getSize(); + const midIcon = new Blockly.utils.Coordinate(size.width / 2, size.height / 2); + return Blockly.utils.Coordinate.sum(this.workspaceLocation, midIcon); +} + +// Returns the rect the bubble should avoid overlapping, i.e. the block this +// icon is appended to. +getOwnerRect() { + const bbox = this.sourceBlock.getSvgRoot().getBBox(); + return new Blockly.utils.Rect( + bbox.y, bbox.y + bbox.height, bbox.x, bbox.x + bbox.width); +} +``` + +## Deal with dragging the block + +When the icon changes location, the bubble does not automatically move with it. +You either need to update the location of the bubble, or hide it. This can be +done inside the [`onLocationChange`][onLocationChange] method of the +[`IIcon`][IIcon] interface. + +```js +onLocationChange(blockOrigin) { + super.onLocationChange(blockOrigin); + this.myBubble?.setAnchorLocation(this.getAnchorLocation()); +} +``` + +## Return the visibility of the bubble + +The [`IHasBubble`][IHasBubble] interface also requires that you implement an +[`bubbleIsVisible`][bubbleIsVisible] method that returns whether the bubble is +visible or not. + +```js +isBubbleVisible() { + return !!this.myBubble; +} +``` + +[IIcon]: /reference/blockly.iicon_interface +[IHasBubble]: /reference/blockly.ihasbubble_interface +[setBubbleVisible]: /reference/blockly.ihasbubble_interface.setbubblevisible_1_methodsignature +[bubbleIsVisible]: /reference/blockly.ihasbubble_interface.bubbleisvisible_1_methodsignature +[onLocationChange]: /reference/blockly.iicon_interface.onlocationchange_1_methodsignature diff --git a/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/use-custom-icons.mdx b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/use-custom-icons.mdx new file mode 100644 index 00000000000..07b3462f9d4 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/icons/creating-custom-icons/use-custom-icons.mdx @@ -0,0 +1,56 @@ +--- +description: How to use custom icons. +title: Use custom icons +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Use custom icons + +To use a custom icon, call `addIcon` or `getIcon` on a block. + +## Add an icon + +To add a custom icon to a block, pass the block to the icon's constructor and +call `addIcon` on the block. For example, you might want to do this when +initializing the block or in response to an event. + + + + ```js + // Use an extension to add a custom icon during initialization. + Blockly.Extensions.register("addMyIcon", function () { + this.addIcon(new MyIcon(this)); + }) + + Blockly.common.defineBlocksWithJsonArray([ + { + type: "my_block", + // ... + extensions: ["addMyIcon"], + }, + ]) + ``` + + + ```js + // Add a custom icon during initialization. + Blockly.Blocks['my_block'] = { + init: function() { + //... + this.addIcon(new MyIcon(this)); + }, + } + ``` + + +## Get an icon + +To get a custom icon from a block, call `getIcon` and pass the [icon's type +string](/guides/create-custom-blocks/icons/creating-custom-icons/basic-implementation#specify-the-icons-type). + +```js +const myIcon = myBlock.getIcon('my_icon'); +``` diff --git a/packages/docs/docs/guides/create-custom-blocks/icons/overview.mdx b/packages/docs/docs/guides/create-custom-blocks/icons/overview.mdx new file mode 100644 index 00000000000..bd8e5e460ca --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/icons/overview.mdx @@ -0,0 +1,27 @@ +--- +description: What icons are, and how to customize them. +title: Icons +image: images/blockly_banner.png +--- + +# Icons + +Icons are used to define certain UI elements that show or define "meta" +information about a block. Usually this means they act as a clickable button +that opens a pop up with more information or an editor. + +→ More info on [Fields vs Icons][fields-vs-icons]. + +Blockly provides some built-in icons that fulfill common use cases, like adding +comments or warnings to blocks. You can check out the [reference +documentation][icons-reference] for more information about those. + +Blockly also lets you define your own custom icons if the built-in ones don't +serve your use case. For example, you might want an icon that displays version +or copyright information in a pop-up bubble. + +→ More info on [Creating custom icons][custom-icons]. + +[fields-vs-icons]: /guides/create-custom-blocks/fields/fields-vs-icons +[custom-icons]: /guides/create-custom-blocks/icons/creating-custom-icons/basic-implementation +[icons-reference]: /reference/blockly.icons_namespace diff --git a/packages/docs/docs/guides/create-custom-blocks/inputs/connection-check-playbook.mdx b/packages/docs/docs/guides/create-custom-blocks/inputs/connection-check-playbook.mdx new file mode 100644 index 00000000000..7a85a6b8c68 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/inputs/connection-check-playbook.mdx @@ -0,0 +1,172 @@ +--- +description: Examples of using connection checks. +title: Connection check playbook +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Connection check playbook + +This document shows ways to use [connection +checks](/guides/create-custom-blocks/inputs/connection-checks). + +## Value examples + +When you are defining connection checks for inputs and outputs, usually you +should think of the checks as representing types. + +Inputs' checks should include every "type" they accept, and outputs' checks +should include _exactly_ what they "return". + +### Accept a single type + +In the most basic case where you want create a block that "accepts" or "returns" +one type, you need to include that type in the connection's connection check. + +a value block that accepts a single type + +### Accept multiple types + +To create a block that "accepts" multiple types, you need to include every +accepted type in the input's connection check. + +a value block that accepts multiple types + +By convention, if an output can _sometimes_ be accepted in multiple situations +(e.g. if you allow numbers to sometimes be used as strings) the output should be +more restrictive, and the input(s) should be more permissive. This convention +makes sure that outputs don't connect where they're not supported. + +### Accept any type + +To create a block that "accepts" any type, you need to set the input's +connection check to `null`. + +a value block that accepts any type + +### Return subtypes + +To create a block that "returns" a subtype, you need to include both the type +and the supertype in the output's connection check. + +a value block that returns its type and its supertype + +In the case of subtypes, it is okay to have multiple checks in an output check, +because the block _always_ "returns" both types. + +### Return parameterized types + +To create a block that "returns" a parameterized type, you need to include both +the parameterized version and the unparameterized version in the output's +connection check. + +Depending on how strict you want your block language to be, you may also want to +include the type's [variance(s)][variance]. + +a value block that returns its parameterized type and its unparameterized type + +Just like with subtypes, it is okay to have multiple checks in an output check +in this case, because the block _always_ "returns" both types. + +## Stack or statement examples + +There are a few common ways developers define checks for previous and next +connections. Usually you think of these as restricting the ordering of blocks. + +Next connections should include which blocks should follow the current one, and +previous connections include what the current block "is". + +:::info +Block types, such as `'controls_if'`, and connection checks are +different. When this says "which blocks should follow the current one", it means +the connection check should include relevant check strings, not block types. +::: + +### Keep blocks in order + +To create a set of blocks that connect in a defined order, you need to include +which blocks should follow the current one in the next connection check, and +what the current block "is" in the previous connection check. + +statement blocks that have a forced order + +### Allow lots of middle blocks + +To create a set of ordered blocks that allow lots of middle blocks, you need to +include at least one entry from the middle block's previous connection check in +the middle block's next connection check. This allows the block to be followed +by more of itself. + +statement blocks that allow lots of middle blocks + +### Allow no middle blocks + +To create a set of ordered blocks where the middle blocks are optional, you need +to include at least one entry from both the middle block's previous connection +check, and the last block's previous connection check in the first block's next +connection check. This allows the first block to be followed by either a middle +block, or a last block. + +statement blocks that allow no middle blocks + +### Either-or stacks + +To create a block that can only be followed by blocks from one group, or blocks +from another (and not both), you need to do two things: + +1. You need to include at least one entry from both of the groups previous + connection checks in the first block's next connection check. + +2. You need to define the groups' next connection checks to only include values + which are in their previous connection checks (so they can only be followed + by blocks of the same group). + +statement blocks that can be followed by multiple of one type of block, or multiple of another, but not both + +[values-single-image]: /images/connection-checks/values-single.jpg +[values-multiple-image]: /images/connection-checks/values-multiple.jpg +[values-subtype-image]: /images/connection-checks/values-subtype.png +[values-parameterized-type-image]: /images/connection-checks/values-parameterized-type.png +[values-any-type-image]: /images/connection-checks/values-any-type.jpg +[statements-ordered-image]: /images/connection-checks/statements-ordered.png +[statements-multiple-middle-blocks-image]: /images/connection-checks/statements-multiple-middle-blocks.png +[statements-no-middle-blocks-image]: /images/connection-checks/statements-no-middle-blocks.png +[statements-either-or-image]: /images/connection-checks/statements-either-or.png +[variance]: https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) diff --git a/packages/docs/docs/guides/create-custom-blocks/inputs/connection-checks.mdx b/packages/docs/docs/guides/create-custom-blocks/inputs/connection-checks.mdx new file mode 100644 index 00000000000..e78e96e9a86 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/inputs/connection-checks.mdx @@ -0,0 +1,242 @@ +--- +description: How to further restrict which blocks can connect to each other. +title: Connection checks +image: images/blockly_banner.png +--- + +# Connection checks + +Connection checks restrict which connections (and therefore blocks) can connect +to each other. + +Connection checks are useful for modeling types. For example, the following +three blocks have no business being connected, because they represent code that +returns different types: + +![An empty list block, connected to a square root block, connected to an +uppercase block](/images/type-bad.png) + +Connection checks can be used to prevent these blocks from connecting. This +gives users instantaneous feedback and prevents many simple mistakes. + +## How they work + +Every connection can be associated with a "connection check" which is a nullable +array of strings. + +Two connections can connect if: + +1. They are compatible [types][connection-type] (e.g. an output connecting to + an input). +2. They have at least one string in their connection check in common. + +For example, connections with the following two checks could connect, because +they share the `'apple'` string: + +```none +['apple', 'ball', 'cat'] +['apple', 'bear', 'caterpillar'] +``` + +But connections with these two checks couldn't connect, because they don't share +any strings: + +```none +['apple', 'ball', 'cat'] +['ape', 'bear', 'caterpillar'] +``` + +There is one other special case. If either array is `null`, then the two +connections can also connect. This lets you define connections that can connect +to anything. + +```none +null +['ape', 'bear', 'caterpillar] +``` + +:::info +The strings used in connection checks have no inherent meaning. For +example, using the string `'Number'` does not guarantee that a connection +represents a number. Instead, they are only used to match other strings. +::: + +:::info +Block types, such as `'math_number'`, and connection checks are +entirely separate sets of strings. Including a block type in a connection check +does _not_ make it so blocks of that type can connect. +::: + +## Examples + +For a list of examples of how to use connection checks, see the [Connection +check +playbook](/guides/create-custom-blocks/inputs/connection-check-playbook). + +## Set checks + +By default, all connections have a `null` connection-check, meaning they can +connect to anything. Connection checks need to be assigned manually. + +How you assign connection checks to connections is different depending on +whether you're using JSON block definitions, or JavaScript block definitions. + +### JSON + +For top-level connections, you assign the check directly to the property that +defines the connection. The value you assign can be `null`, a string (which +becomes the only entry in the connection check), or an array of strings. + +```js +{ + 'type': 'custom_value_block', + + 'output': 'a connection check entry', +}, +{ + 'type': 'custom_statement_block', + + 'nextStatement': null, // null check + 'previousStatement': ['four', 'connection', 'check', 'entries'] +} +``` + +For inputs, you can assign the check to a `check` property of the input +definition. If the `check` property doesn't exist, the check is considered +`null`. The value you assign can be a string, or an array of strings. + +```js +{ + 'type': 'custom_block', + 'message0': '%1 %2', + + 'args0': [ + { + 'type': 'input_value', + 'check': 'a connection check entry' // Accepts custom_value_block + }, + { + 'type': 'input_statement', + 'check': ['two', 'entries'] // Accepts custom_statement_block + } + ] +} +``` + +### JavaScript + +For top-level connections, you can pass the check directly to the method that +defines the connection. If you don't pass a value, the check is considered +`null`. The value you pass can be a string (which becomes the only entry in the +connection check), or an array of strings. + +```js +Blockly.Blocks['custom_value_block'] = { + init: function () { + this.setOutput(true, 'a connection check entry'); + }, +}; +Blockly.Blocks['custom_statement_block'] = { + init: function () { + this.setNextStatement(true); // null check + this.setPreviousStatement(true, ['four', 'connection', 'check', 'entries']); + }, +}; +``` + +For inputs, you can pass the check to the `setCheck` method, after you have +defined the input. If the `setCheck` method isn't called, the check is +considered `null`. The value you pass can be a string, or an array of strings. + +```js +Blockly.Blocks['custom_block'] = { + init: function () { + this.appendValueInput('NAME').setCheck('a connection check entry'); // Accepts custom_value_block + this.appendStatementInput('NAME').setCheck(['two', 'entries']); // Accepts custom_statement_block + }, +}; +``` + +### Built-in check strings + +The built-in blocks have connection checks with the values `'Array'`, +`'Boolean'`, `'Colour'`, `'Number'`, and `'String'`. If you want your blocks to +interoperate with the built-in blocks, you can use these values to make them +compatible. + +## Limitations + +This system is quite robust and can solve many use-cases, but it does have a few +limitations. + +### Restrict the greater context + +This system does not, by itself, support restricting the "greater context" in +which a connection is allowed to connect. For example, you cannot say that a +`break` block is only allowed to exist inside of a `loop` block. The connection +checking system only considers the immediate two connections being connected. + +You _can_ support this by using the [event system][event-system] to listen to +[block move][BlockMove] events and check if the block is incorrectly positioned. + +```js +Blockly.Blocks['custom_block'] = { + init: function() { } + + onchange: function(e) { + if (this.workspace.isDragging()) return; + if (e.type !== Blockly.Events.BlockMove) return; + if (!this.getSurroundLoop()) this.outputConnection.disconnect(); + } + + loopTypes: new Set(); // Your valid *block types* (not connection checks). + + getSurroundLoop: function () { + let block = this.getSurroundParent(); + do { + if (loopTypes.has(block.type)) return block; + block = block.getSurroundParent(); + } while (block); + return null; + }, +} +``` + +### Generic types + +This system does not, by itself, support defining generic types. For example, +you cannot create an "Identity" block, that "returns" whatever its input is. + +You can _somewhat_ support this by actively changing the connection check on the +block's output to match its input. Which you can do using the event system to +listen to block move events. + +```js +Blockly.Blocks['custom_block'] = { + init: function() { } + + onchange: function(e) { + if (e.type !== Blockly.Events.BlockMove) return; + this.setOutput( + true, this.getInputTargetBlock()?.outputConnection.getCheck()); + } +} +``` + +But if the connected block is _also_ generic, then this doesn't work correctly. +There is no good work around for this case. + +## Connection checkers + +If this system doesn't work for your use case, you can also change how the +connection checks are compared by creating a +[custom connection checker][custom-connection-checker]. + +For example, if you wanted to create a more advanced system that handles some of +the [limitations](#limitations) of this one, you can create a custom +connection checker. + +[connection-type]: /guides/create-custom-blocks/define/block-anatomy#connections +[event-system]: /guides/configure/web/events +[BlockMove]: /reference/blockly.events_namespace.blockmove_class +[custom-connection-checker]: /guides/create-custom-blocks/inputs/connection_checker diff --git a/packages/docs/docs/guides/create-custom-blocks/inputs/connection-previews.mdx b/packages/docs/docs/guides/create-custom-blocks/inputs/connection-previews.mdx new file mode 100644 index 00000000000..25e834dd66d --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/inputs/connection-previews.mdx @@ -0,0 +1,214 @@ +--- +description: How to create custom previews for pending connections. +title: Connection previewers +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Connection previewers + +A connection previewer creates a visual preview of a pending connection. It +gives you an indication of where the dragging block will be connected when it is +dropped. + +The default connection previewer puts [insertion markers][insertion-marker] +where blocks will connect. It also highlights connections, and puts a fade +effect on blocks that will be replaced and disconnected. + +![A demonstration of the built-in previewer][built-in-previewer-image] + +## Kinds of pending connections + +There are two kinds of pending connections. In one case case, the dropped block +replaces an existing block, and the existing block is disconnected. In the other +case, the dropped block is inserted without disconnecting other blocks. + +### Replacement + +Replacement happens when a connection on the dragged block is going to connect +to a connection that already has a block, and there is nowhere for the existing +block to be reattached. When the dragged block is dropped, the replaced block +will be disconnected, and the dragged block will be connected in its place. + +By default, we indicate this by putting a fade effect on the block that is being +replaced. + +The built-in replacement preview + +### Insertion + +Insertion happens in two cases. It happens when a connection on the dragged +block is going to connect to a connection that is empty. And it happens when a +connection on the dragged block is going to a connection that already has a +block, but it can be inserted between the two existing blocks, so the existing +block doesn't get disconnected. + +By default, we indicate this by creating insertion markers, and highlighting the +connections that will connect. + +The built-in insertion preview + +## Create a custom previewer + +If you want to use a different visual to preview pending connections, you can +create a custom [`IConnectionPreviewer`][IConnectionPreviewer] implementation. + +### Construction and disposal + +You need to implement a constructor and a disposal method for your +`IConnectionPreviewer`. + +The constructor is called whenever a block drag begins, and it is passed the +block that is being dragged. If you need to initialize any state based on the +block, you can do that in the constructor. + +```js +class MyConnectionPreviewer implements IConnectionPreviewer { + constructor(draggedBlock: Blockly.BlockSvg) { + // Initialize state here. + } +} +``` + +The `dispose` method is called whenever a block drag ends. If you need to +dereference any state when your `IConnectionPreviewer` instance is disposed, you +should do that here. + +```js +dispose() { + // Dispose of and dereference any state. +} +``` + +### Create the preview + +Your `IConnectionPreviewer` needs to implement logic for visually previewing +connections. + +#### Replacement + +To preview [replacements](#replacement), implement the `previewReplacement` +method. + +```js +previewReplacement(draggedConn, staticConn, replacedBlock) { + // Visually indicate that the replacedBlock will be disconnected, and the + // draggedConn will be connected to the staticConn. +} +``` + +#### Insertion + +To preview [insertions](#insertion), implement the `previewConnection` method. + +```js +previewConnection(draggedConn, staticConn) { + // Visually indicate the draggedConn will be connected to the staticConn. +} +``` + +If you want to have a different preview depending on if the dragged block is +being connected to an empty input, or if it is being inserted between blocks, +you can check if the `staticConn` is currently connected to another connection. +If the `staticConn` is currently connected, then the `draggedConn` is being +inserted between blocks. + +```js +previewConnection(draggedConn, staticConn) { + if (staticConn.targetConnection) { + // The dragged block is being inserted between blocks. + } else { + // The dragged block is connecting to an empty input. + } +} +``` + +#### CSS previews + +You can preview connections by applying css to the block. For example, the +default replacement fade is toggled by adding the `blocklyReplaceable` CSS class +to the block. + +```js +previewReplacement(draggedConn, staticConn, replacedBlock) { + Blockly.utils.dom.addClass(replacedblock.getSvgRoot(), 'my-custom-class'); +} +``` + +#### Renderer previews + +You can preview connections by implementing a [custom renderer][custom-renderer] +that has special previewing hooks. + +```js +previewReplacement(draggedConn, staticConn, replacedBlock) { + const renderer = replacedBlock.workspace.getRenderer() + if (renderer.addReplacementIndicator) { + renderer.addReplacementIndicator(replacedBlock); + } +} +``` + +### Hide the preview + +Your `IConnectionPreviewer` needs to be able to hide previews. This gets called +when the dragged block moves out of range of all connections, so no preview +should be shown. It also gets called right before the previewer is disposed. + +```js +hidePreview() { + // Remove CSS classes, toggle renderer methods, etc. +} +``` + +### Registration and use + +Finally, once you've completed the creation of your `IConnectionPreviewer`, you +need to register it. This associates the renderer with a string so that you can +pass it to your configuration options. You can also pass the +`IConnectionPreviewer` class (i.e. constructor) directly to your configuration +options. + +```js +Blockly.registry.register( + Blockly.registry.Type.CONNECTION_PREVIEWER, + 'MyConnectionPreviewer', + MyConnectionPreviewer, +); + +// You can use the string. +const myWorkspace = Blockly.inject({ + // options... + plugins: { + connectionPreviewer: 'myConnectionPreviewer', + }, +}; + +// Or you can pass the class / constructor directly. +const myWorkspace = Blockly.inject({ + // options... + plugins: { + connectionPreviewer: MyConnectionPreviewer, + }, +}; +``` + +For more information about registration, see +[Injecting subclasses][inject-subclasses]. + +[built-in-replacement-preview-image]: /images/connections/built-in-replacement-preview.png +[built-in-insertion-preview-image]: /images/connections/built-in-insertion-preview.png +[built-in-previewer-image]: /images/connections/built-in-previewer.gif +[IConnectionPreviewer]: /reference/blockly.iconnectionpreviewer_interface +[insertion-marker]: /guides/get-started/workspace-anatomy#insertion-marker +[custom-renderer]: /guides/create-custom-blocks/renderers/create-custom-renderers/basic-implementation +[inject-subclasses]: /guides/configure/web/customization#injecting-subclasses diff --git a/packages/docs/docs/guides/create-custom-blocks/inputs/connection_checker.mdx b/packages/docs/docs/guides/create-custom-blocks/inputs/connection_checker.mdx new file mode 100644 index 00000000000..30e1f31ea4a --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/inputs/connection_checker.mdx @@ -0,0 +1,68 @@ +--- +description: An interface for controlling how Blockly determines which blocks can connect and how. +title: Custom connection checkers +image: images/blockly_banner.png +--- + +# Custom connection checkers + +A major benefit of using Blockly is that it ensures the generated code is +syntactically correct. + +The Connection Checker is the object that enforces Blockly's rules about which +connections are compatible. By default the checker applies a simple type system, +as described in the [Connection +checks](/guides/create-custom-blocks/inputs/connection-checks) page. + +## The Checks + +Blockly applies three levels of checks: safety, type, and drag checks. + +### Safety checks + +Safety checks ensure that the blocks are on the same workspace, that the +connections are on different blocks, and so on. These ensure that Blockly does +not get into a bad state. + +Safety checks also block nonsensical combinations, such as connecting two next +connections. + +### Type checks + +Developers can label connections with type information. Type checks use this +information to enforce a type system--e.g. by blocking the connection of a +string where a number is expected. + +### Drag checks + +Drag checks are applied only when connecting blocks by dragging, rather than +programmatically. For example, only connections within a certain radius should +be considered during a drag. + +## Overriding the Connection Checker + +Developers who wish to provide their own logic for type checks or drag checks +can register a substitute connection checker object that implements the +`IConnectionChecker` interface. + +To implement your own safety checks: override +[`doSafetyChecks`](https://github.com/RaspberryPiFoundation/blockly/blob/7e03c6e31c084606d5c3f8c5ecd26b0c4459ac6d/core/interfaces/i_connection_checker.ts#L75) +on your connection checker. + +:::warning +In general, developers should not override Blockly's safety checks. +::: + +To implement your own type checks: override +[`doTypeChecks`](https://github.com/RaspberryPiFoundation/blockly/blob/7e03c6e31c084606d5c3f8c5ecd26b0c4459ac6d/core/interfaces/i_connection_checker.ts#L86) +on your connection checker. + +To implement your own drag checks: override +[`doDragChecks`](https://github.com/RaspberryPiFoundation/blockly/blob/7e03c6e31c084606d5c3f8c5ecd26b0c4459ac6d/core/interfaces/i_connection_checker.ts#L96) +on your connection checker. + +## Example code + +The [strict connection checker +plugin](https://github.com/RaspberryPiFoundation/blockly-samples/tree/main/plugins/strict-connection-checker) +is a simple example of a custom checker. diff --git a/packages/docs/docs/guides/create-custom-blocks/inputs/creating-custom-inputs.mdx b/packages/docs/docs/guides/create-custom-blocks/inputs/creating-custom-inputs.mdx new file mode 100644 index 00000000000..6efbde1306b --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/inputs/creating-custom-inputs.mdx @@ -0,0 +1,55 @@ +--- +description: How to create your own custom inputs. +title: Create custom inputs +image: images/blockly_banner.png +--- + +# Create custom inputs + +To create a custom input, you need to subclass [`Input`][Input], or one of +its subclasses. + +```js +class MyInput extends Blockly.inputs.Input { + // The constructor should always take in a name and a block to be compatible + // with JSON block definitions. + constructor(name, block) { + super(name, block); + // etc... + } +} +``` + +## Optionally create a connection + +If you want your input to have a connection, that should be created in the +constructor, by calling the [`makeConnection`][makeConnection] method. + +```js +constructor(name, block) { + super(name, block); + + this.connection = this.makeConnection(ConnectionType.INPUT_VALUE); +} +``` + +## Register the input + +To be able to use your custom input in a [JSON block definition][json-block-def] +you need to register it and associate it with a string. + +```js +class MyInput extends Blockly.inputs.Input {} + +Blockly.registry.register(Blockly.registry.Type.INPUT, 'my_input', MyInput); +``` + +:::note +unlike [custom fields][custom-fields], you can't override +built-in inputs, and you can't add custom JSON configuration to them. +::: + +[Input]: /reference/blockly.inputs_namespace.input_class +[makeConnection]: /reference/blockly.inputs_namespace.input_class.makeconnection_1_method +[json-block-def]: /guides/create-custom-blocks/define/json-and-js +[custom-fields]: /guides/create-custom-blocks/fields/customizing-fields/creating diff --git a/packages/docs/docs/guides/create-custom-blocks/legacy-blockly-developer-tools.md b/packages/docs/docs/guides/create-custom-blocks/legacy-blockly-developer-tools.md new file mode 100644 index 00000000000..5939668d59b --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/legacy-blockly-developer-tools.md @@ -0,0 +1,248 @@ +--- +description: How to use Blockly's tools for defining blocks, toolboxes, and workspaces. +title: Legacy Blockly Developer Tools +image: images/blockly_banner.png +--- + +# Legacy Blockly Developer Tools + +:::warning +The tools in this document have been deprecated, but this +documentation is preserved for your reference. The legacy tools are only +compatible with Blockly v10 and earlier. If you want to migrate your block +definitions to Blockly v11+, follow [these instructions][block-factory-import] +to load your block definitions into the new tool. +::: + +[Legacy Blockly Developer Tools][legacy-tool] is a web-based developer tool that +automates parts of the Blockly configuration process, including creating custom +blocks, building your toolbox, and configuring your Blockly workspace. + +The Blockly developer process using the tool consists of three parts: + +- Create custom blocks using Block Factory and Block Exporter. +- Build a toolbox and default workspace using Workspace Factory. +- Configure your workspace using Workspace Factory (currently a web-only + feature). + +## Block Factory Tab + +The Block Factory tab helps you create [block +definitions](/guides/create-custom-blocks/define/block-definitions) and +[block-code generators][block-code-generator] for custom blocks. On this tab you +can easily create, modify, and save custom blocks. + +### Defining a block + +This video walks through the steps of defining a block in detail. The UI is out +date, but the block features it highlights are still accurate. + + + +### Managing the library + +Blocks are referenced by their name, so each block you want to create must have +a unique name. The UI enforces this and makes it clear when you are 'saving' +a new block or 'updating' an existing block. + +![The Block Factory tab with Save and Delete buttons that include the block +name.](/images/block_save_as.png) ![The Block Factory tab with Update +and Delete buttons that include the block +name.](/images/update_button.png) + +You can switch between blocks you've previously saved or create a new empty +block by clicking the Library button. Changing the name of an existing block is +another way to quickly create multiple blocks with similar definitions. + +![Block Library dropdown with four entries: "Create New Block" and the names of +three previously created blocks.](/images/blocklib_button.png) + +### Exporting and importing a library + +Blocks are saved to the browser's local storage. Clearing the browser's local +storage will delete your blocks. To save your blocks indefinitely, you must +download your library. Your Block Library is downloaded as an XML +file that can be imported to set your Block Library to the state it was when +you downloaded the file. Note that importing a Block Library replaces your +current one, so you might want to export first. + +The import and export features are also the recommended way to maintain and +share different sets of custom blocks. + +![The Clear Library, Import Block Library, and Download Block Library +buttons.](/images/block_manage_buttons.png) + +## Block Exporter tab + +Once you have designed your blocks you will need to export the block definitions +and generator stubs to use them in an app. This is done on the +Block Exporter tab. + +Every block stored in your Block Library will be shown in the Block Selector. +Click on the block to to select or deselect it for export. If you want to select +all the blocks in your library, use the "Select" → "All Stored In Block +Library" option. If you built your toolbox or configured your workspace using +the Workspace Factory tab, you can also select all the blocks you used by +clicking "Select" → "All Used In Workspace Factory". + +![The Block Selector area of the Block Exporter tab. This has a Select button to +select all blocks in the block library or select all blocks used in the +Workspace Factory, a Clear Selected button, and a list of blocks that can be +selected individually.](/images/block_exporter_select.png) + +The export settings let you choose which generated language you want to target +and whether you want the definitions, the generator stubs, or both for the +selected blocks. Once you've selected these, click 'Export' to download your +files. + +![The entire Block Exporter tab. This has a Block Selector area, an Export +Settings area, and an Export Preview +area.](/images/block_exporter_tab.png) + +:::note +If using a save dialog on Mac you can only download +[one file at a time](https://github.com/RaspberryPiFoundation/blockly/issues/647) +::: + +## Workspace Factory tab + +The Workspace Factory makes it easy to configure a toolbox and the default +set of blocks in a workspace. You can switch between editing the toolbox and the +starting workspace with the "Toolbox" and "Workspace" buttons. + +![The Toolbox and Workspace buttons.](/images/ws_fac_tb_ws_buttons.png) + +### Building a toolbox + +This tab helps build the XML for a Toolbox. The material assumes +familiarity with features of a [Toolbox](/guides/configure/web/toolboxes/toolbox). +If you already have XML for a toolbox that you want to edit here, you can +load it by clicking "Load to Edit". + +### Toolbox without categories + +If you have a few blocks and want to display them without any categories, simply +drag them into the workspace, and you will see your blocks appear in the toolbox +in the preview. + +![The Workspace Factory tab with the Toolbox button chosen. There is a Blockly +editor on the left for choosing the blocks in the toolbox, a categories area in +the center for adding categories to the toolbox, and a preview area on the right +to show the toolbox you have constructed. Three blocks have been dragged onto +the workspace on the left. This constructs a flyout toolbox, which is shown on +the right.](/images/workspace_fac_no_cat.png) + +### Toolbox with categories + +If you want display blocks in categories, click the "+" button and select the +dropdown item for new category. This will add a category to your category list +that you can select and edit. Select "Standard Category" to add an individual +standard Blockly category (Logic, Loops, etc.), or "Standard Toolbox" to add all +standard Blockly categories. Use the arrow buttons to reorder categories. + +![The categories area of the Workspace Factory tab. This shows the current list +of categories and buttons to add and delete categories and move them up and down +in the list. The + button has been selected to add a +category.](/images/category_menu.png) + +:::note +The standard categories and toolbox include all the blocks in the +[Playground](https://blockly-demo.appspot.com/static/tests/playground.html). +This set of blocks is not appropriate for most apps and should be pruned as +needed. Also, some blocks are not supported on mobile yet. +::: + +To change the selected category’s name or color use the "Edit Category" +dropdown. Dragging a block into the workspace will add it to the selected +category. + +![The Edit Category dropdown, with fields to change a category's name and +color.](/images/edit_category.png) + +### Advanced blocks + +By default, you can add any of the standard blocks or any blocks in your library +to the toolbox. If you have blocks defined in JSON that aren't in your library, +you can import them using the "Import Custom Blocks" button. + +Some blocks should be used together or include defaults. This is done with +[groups and shadows](/guides/configure/web/toolboxes/preset). Any +blocks that are connected in the editor will be added to the toolbox as a group. +Blocks that are attached to another block can also be changed to shadow blocks +by selecting the child block and clicking the "Make Shadow" button. +:::note +Only child blocks that don't contain a variable may be changed to shadow +blocks. +::: + +If you include a variable or function block in their toolbox, include a +"Variables" or "Functions" category in your toolbox to allow users to fully +utilize the block. Learn more about ["Variables" or "Functions" +categories](/guides/configure/web/toolboxes/dynamic#built-in-dynamic-categories). + +### Configuring a workspace + +To configure different parts of your workspace, go to the "Workspace Factory" +tab and select "Workspace". + +#### Choose Workspace Options + +Set different values for [configuration +options](/guides/configure/web/configuration_struct#the-options-dictionary) +and see the result in the preview area. Enabling +[grid](/guides/configure/web/grid) or +[zoom](/guides/configure/web/zoom) reveals more options to configure. +Also, switching to using categories usually requires a more complex +workspace; a trashcan and scrollbars are added automatically when you add your +first category. + +![The Workspace Factory tab with the Workspace button selected. The categories +area has been replaced with a list of workspace options to choose +from.](/images/configure_workspace.png) + +#### Add Pre-loaded Blocks to the Workspace + +This is optional but may be necessary if you want to display a set of blocks in +the workspace: + +- When the application loads. +- When an event (advancing a level, clicking a help button, etc.) is triggered. + +Drag blocks into the editing space to see them in your workspace in the preview. +You can create block groups, disable blocks, and make certain blocks shadow +blocks when you select them. + +![The Workspace Factory tab with the Workspace button selected. Blocks have been +dragged onto the workspace of the Blockly editor on the left. These are shown as +pre-loaded blocks in the workspace of the Blockly editor on the +right.](/images/load_workspace_blocks.png) + +You can export these blocks as XML (see below). Add them to your workspace with +`Blockly.Xml.domToWorkspace`, immediately after you create your workspace: + +```js +var xmlText = + '' + + ''; +Blockly.Xml.domToWorkspace(Blockly.utils.xml.textToDom(xmlText), workspace); +``` + +This sample code adds a single `math_number` block to the workspace. + +### Exporting + +Workspace Factory gives you the following export options: + +![The Export dropdown at the top of the Workspace Factory tab, with options to +export starter code, the toolbox, the pre-loaded workspace blocks, or all of +these.](/images/workspace_export_opt.png) + +- Starter Code: Produces starter html and javascript to inject your customized + Blockly workspace. +- Toolbox: Produces XML to specify your toolbox. +- Workspace Blocks: Produces XML which can be loaded into a workspace. + +[block-code-generator]: /guides/create-custom-blocks/code-generation/overview#block-code-generators +[block-factory-import]: /guides/create-custom-blocks/blockly-developer-tools#import-from-legacy-block-factory +[legacy-tool]: https://blockly-demo.appspot.com/static/demos/blockfactory/index.html diff --git a/packages/docs/docs/guides/create-custom-blocks/mutators.mdx b/packages/docs/docs/guides/create-custom-blocks/mutators.mdx new file mode 100644 index 00000000000..9683692a211 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/mutators.mdx @@ -0,0 +1,324 @@ +--- +description: How to define a mutator. +title: Mutators +image: images/blockly_banner.png +--- + +# Mutators + +A mutator is a mixin that adds extra serialization (extra state that gets saved +and loaded) to a block. For example, the built-in `controls_if` and +`list_create_with` blocks need extra serialization so that they can save how +many inputs they have. It may also add a UI so the user can change the block's +shape. + +![Three mutations of a create list block: no inputs, three inputs, and five +inputs.](/images/lists-mutated.png) + +![Two mutations of an if/do block: if-do and if-do-else-if-do-else.](/images/if-mutated.png) + +Note that changing the shape of your block _does not necessarily_ mean you need +extra serialization. For example, the `math_number_property` block changes +shape, but it does that based on a dropdown field, whose value already gets +serialized. As such, it can just use a [field +validator](/guides/create-custom-blocks/fields/validators), and doesn't +need a mutator. + +![The `math_number_property` block with its dropdown set to `even`. It has a +single value input.](/images/is-even.png) ![The `math_number_property` +block with its dropdown set to `divisible by`. It has two value +inputs.](/images/is-divisible-by.png) + +See the [serialization +page](/guides/configure/web/serialization#when-to-save-extra-state) for +more information about when you need a mutator and when you don't. + +Mutators also provide a built-in UI for users to change the shapes of blocks if +you provide some optional methods. + +## Serialization hooks + +Mutators have two pairs of serialization hooks they work with. One pair of hooks +works with the new JSON serialization system, and the other pair works with the +old XML serialization system. You have to provide at least one of these pairs. + +### saveExtraState and loadExtraState + +`saveExtraState` and `loadExtraState` are serialization hooks that work with the +new JSON serialization system. `saveExtraState` returns a JSON serializable +value which represents the extra state of the block, and `loadExtraState` +accepts that same JSON serializable value, and applies it to the block. + +```js +// These are the serialization hooks for the lists_create_with block. +saveExtraState: function() { + return { + 'itemCount': this.itemCount_, + }; +}, + +loadExtraState: function(state) { + this.itemCount_ = state['itemCount']; + // This is a helper function which adds or removes inputs from the block. + this.updateShape_(); +}, +``` + +The resulting JSON will look like: + +```json +{ + "type": "lists_create_with", + "extraState": { + "itemCount": 3 // or whatever the count is + } +} +``` + +#### No state + +If your block is in its default state when it is serialized, then your +`saveExtraState` method can return `null` to indicate this. If your +`saveExtraState` method returns `null` then no `extraState` property is added to +the JSON. This keeps your save file size small. + +#### Full serialization and backing data + +`saveExtraState` also receives an optional `doFullSerialization` parameter. This +is used by blocks that reference state serialized by a different +[serializer][serializer] (like backing data models). The parameter signals that +the referenced state won't be available when the block is deserialized, so the +block should serialize all of the backing state itself. For example, this is +true when an individual block is serialized, or when a block is copy-pasted. + +Two common use cases for this are: + +- When an individual block is loaded into a workspace where the backing data + model doesn't exist, it has enough information in its own state to + create a new data model. +- When a block is copy-pasted, it always creates a new backing + data model instead of referencing an existing one. + +Some blocks that use this are the +[@blockly/block-shareable-procedures][shareable-procedures] blocks. Normally +they serialize a reference to a backing data model, which stores their state. +But if the `doFullSerialization` parameter is true, then they serialize all of +their state. The shareable procedure blocks use this to make sure that when they +are copy-pasted they create a new backing data model, instead of referencing an +existing model. + +### mutationToDom and domToMutation + +`mutationToDom` and `domToMutation` are serialization hooks that work with the +old XML serialization system. Only use these hooks if you have to (e.g. you're +working on an old code-base that hasn't migrated yet), otherwise use +`saveExtraState` and `loadExtraState`. + +`mutationToDom` returns an XML node which represents the extra state of the +block, and `domToMutation` accepts that same XML node and applies the state to +the block. + +```js +// These are the old XML serialization hooks for the lists_create_with block. +mutationToDom: function() { + // You *must* create a element. + // This element can have children. + var container = Blockly.utils.xml.createElement('mutation'); + container.setAttribute('items', this.itemCount_); + return container; +}, + +domToMutation: function(xmlElement) { + this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10); + // This is a helper function which adds or removes inputs from the block. + this.updateShape_(); +}, +``` + +The resulting XML will look like: + +```xml + + + +``` + +If your `mutationToDom` function returns null, then no extra element will be +added to the XML. + +## UI Hooks + +If you provide certain functions as part of your mutator, Blockly will add a +default "mutator" UI to your block. + +![An if-do block with its mutator bubble open. This lets users add else-if and +else clauses to the if-do block.](/images/mutator-annot.png) + +You don't have to use this UI if you want to add extra serialization. You could +use a custom UI, like the [blocks-plus-minus +plugin](https://github.com/RaspberryPiFoundation/blockly-samples/tree/main/plugins/block-plus-minus) +provides, or you could use no UI at all! + +### compose and decompose + +The default UI relies on the `compose` and `decompose` functions. + +`decompose` "explodes" the block into smaller sub-blocks which can be moved +around, added and deleted. This function should return a "top block" which is +the main block in the mutator workspace that sub-blocks connect to. + +`compose` then interprets the configuration of the sub-blocks and uses them to +modify the main block. This function should accept the "top block" which was +returned by `decompose` as a parameter. + +Note that these functions get "mixed in" to the block being "mutated" so `this` +can be used to refer to that block. + +```js +// These are the decompose and compose functions for the lists_create_with block. +decompose: function(workspace) { + // This is a special sub-block that only gets created in the mutator UI. + // It acts as our "top block" + var topBlock = workspace.newBlock('lists_create_with_container'); + topBlock.initSvg(); + + // Then we add one sub-block for each item in the list. + var connection = topBlock.getInput('STACK').connection; + for (var i = 0; i < this.itemCount_; i++) { + var itemBlock = workspace.newBlock('lists_create_with_item'); + itemBlock.initSvg(); + connection.connect(itemBlock.previousConnection); + connection = itemBlock.nextConnection; + } + + // And finally we have to return the top-block. + return topBlock; +}, + +// The container block is the top-block returned by decompose. +compose: function(topBlock) { + // First we get the first sub-block (which represents an input on our main block). + var itemBlock = topBlock.getInputTargetBlock('STACK'); + + // Then we collect up all of the connections of on our main block that are + // referenced by our sub-blocks. + // This relates to the saveConnections hook (explained below). + var connections = []; + while (itemBlock && !itemBlock.isInsertionMarker()) { // Ignore insertion markers! + connections.push(itemBlock.valueConnection_); + itemBlock = itemBlock.nextConnection && + itemBlock.nextConnection.targetBlock(); + } + + // Then we disconnect any children where the sub-block associated with that + // child has been deleted/removed from the stack. + for (var i = 0; i < this.itemCount_; i++) { + var connection = this.getInput('ADD' + i).connection.targetConnection; + if (connection && connections.indexOf(connection) == -1) { + connection.disconnect(); + } + } + + // Then we update the shape of our block (removing or adding iputs as necessary). + // `this` refers to the main block. + this.itemCount_ = connections.length; + this.updateShape_(); + + // And finally we reconnect any child blocks. + for (var i = 0; i < this.itemCount_; i++) { + connections[i].reconnect(this, 'ADD' + i); + } +}, +``` + +### saveConnections + +Optionally, you can also define a `saveConnections` function which works with +the default UI. This function gives you a chance to associate children of your +main block (which exists on the main workspace) with sub-blocks that exist in +your mutator workspace. You can then use this data to make sure your `compose` +function properly re-connects the children of your main block when your +sub-blocks are reorganized. + +`saveConnections` should accept the "top block" returned by your `decompose` +function as a parameter. If the `saveConnections` function is defined, Blockly +will call it before calling `compose`. + +```js +saveConnections: function(topBlock) { + // First we get the first sub-block (which represents an input on our main block). + var itemBlock = topBlock.getInputTargetBlock('STACK'); + + // Then we go through and assign references to connections on our main block + // (input.connection.targetConnection) to properties on our sub blocks + // (itemBlock.valueConnection_). + var i = 0; + while (itemBlock) { + // `this` refers to the main block (which is being "mutated"). + var input = this.getInput('ADD' + i); + // This is the important line of this function! + itemBlock.valueConnection_ = input && input.connection.targetConnection; + i++; + itemBlock = itemBlock.nextConnection && + itemBlock.nextConnection.targetBlock(); + } +}, +``` + +## Registering + +Mutators are just a special kind of mixin, so they also have to be +registered before you can use them in your block type's [JSON +definition](/guides/create-custom-blocks/define/json-and-js). + +```js +// Function signature. +Blockly.Extensions.registerMutator(name, mixinObj, opt_helperFn, opt_blockList); + +// Example call. +Blockly.Extensions.registerMutator( + 'controls_if_mutator', + { + /* mutator methods */ + }, + undefined, + ['controls_if_elseif', 'controls_if_else'], +); +``` + +- `name`: A string to associate with the mutator so you can use it in JSON. +- `mixinObj`: An object containing the various mutation methods. E.g. + `saveExtraState` and `loadExtraState`. +- `opt_helperFn`: An optional [helper function](#helper-function) that will + run on the block after the mixin is mixed in. +- `opt_blockList`: An optional array of block types (as strings) that will be + added to the flyout in the default mutator UI, if the UI methods are also + defined. + +Note that unlike extensions, each block type may only have one mutator. + +```js +{ + //... + "mutator": "controls_if_mutator" +} +``` + +### Helper function + +Along with the mixin, a mutator may register a helper function. This function is +run on each block of the given type after it is created and the `mixinObj` is +added. It can be used to add additional triggers or effects to a mutation. + +For example, you could add a helper to your list-like block that sets the +initial number of items: + +```js +var helper = function () { + this.itemCount_ = 5; + this.updateShape(); +}; +``` + +[shareable-procedures]: https://www.npmjs.com/package/@blockly/block-shareable-procedures +[serializer]: /guides/configure/web/serialization#serializer-hooks diff --git a/packages/docs/docs/guides/create-custom-blocks/overview.mdx b/packages/docs/docs/guides/create-custom-blocks/overview.mdx new file mode 100644 index 00000000000..4805f613c7d --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/overview.mdx @@ -0,0 +1,134 @@ +--- +description: Introduction to creating custom blocks. +title: Custom blocks overview +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Custom blocks overview + +Blockly comes with a large number of predefined blocks, from mathematical +functions to looping structures. However, most applications need to define and +implement custom blocks for their domain. For example, a drawing application +might need blocks to draw lines and circles and a robotics application might +need blocks to move an arm and manipulate a claw. + +To define and use a new type of block, you need three things: + +- **Block definition**: Defines the look and feel of a block type as well as + certain behaviors. +- **Block-code generator**: Generates the code string for blocks of this type. + It is always written in JavaScript, even if the target language is not + JavaScript. +- **Toolbox reference**: A reference to the block type in the toolbox, so + users can add it to the workspace. + +## Block definition + +A **block definition** defines the look and feel of a block, such as its text, +fields, connections, and colour. It can also define block-specific behavior, +such as a block-specific event handler. For example, this block: + +![A `string_length` block.](/images/text-length.png) + +can be defined in JSON or JavaScript as follows: + + + + ```js + Blockly.common.defineBlocksWithJsonArray([{ + "type": "string_length", + "message0": 'length of %1', + "args0": [ + { + "type": "input_value", + "name": "VALUE", + "check": "String" + } + ], + "output": "Number", + "colour": 160, + "tooltip": "Returns number of letters in the provided text.", + "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp" + }]); + ``` + + + ```js + Blockly.Blocks['string_length'] = { + init: function() { + this.appendValueInput('VALUE') + .setCheck('String') + .appendField('length of'); + this.setOutput(true, 'Number'); + this.setColour(160); + this.setTooltip('Returns number of letters in the provided text.'); + this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp'); + } + }; + ``` + + +For more information about block definitions and how they work, see [What's a +block +definition?](/guides/create-custom-blocks/define/block-definitions). + +## Block-code generators + +To transform a block into code, you need separate generator functions for each +language you want to generate. For example, here is a generator that generates +JavaScript: + +```js +javascriptGenerator.forBlock['string_length'] = function (block, generator) { + // String or array length. + var argument0 = + generator.valueToCode(block, 'VALUE', Order.FUNCTION_CALL) || "''"; + return [argument0 + '.length', Order.MEMBER]; +}; +``` + +The generator function accepts the block being processed and a language +generator. It generates code for any blocks attached to inputs (such as the +`VALUE` input in the example) and any fields, and then concatenates the +resulting strings into a larger expression. + +For more information, see [Block-code +generators](/guides/create-custom-blocks/code-generation/block-code). + +## Toolbox reference + +After you have defined your block type, use the type name to reference it in a +toolbox: + + + + ```js + var toolbox = { + "kind": "categoryToolbox", + "name": "Text" + "contents": [ + { + "kind": "block", + "type": "string_length" + }, + ] + }; + ``` + + + ```html + + ``` + + +For more information, see [Define a flyout +toolbox](/guides/configure/web/toolboxes/flyout) or [Define a category +toolbox](/guides/configure/web/toolboxes/category). diff --git a/packages/docs/docs/guides/create-custom-blocks/procedures/creating-custom-procedure-blocks.mdx b/packages/docs/docs/guides/create-custom-blocks/procedures/creating-custom-procedure-blocks.mdx new file mode 100644 index 00000000000..2c98983b143 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/procedures/creating-custom-procedure-blocks.mdx @@ -0,0 +1,271 @@ +--- +description: How to create custom procedure blocks. +title: Create custom procedure blocks +image: images/blockly_banner.png +--- + +# Create custom procedure blocks + +Creating custom procedure blocks requires that you: + +1. Install the [@blockly/block-shareable-procedures][shareable-procedures] + plugin, as described on the [using procedures + page](/guides/create-custom-blocks/procedures/using-procedures). +2. Use the JSON serialization system, as explained on the [overview + page](/guides/create-custom-blocks/procedures/overview). + +:::note +If you defined custom procedure blocks to work with the legacy procedure +system (before [@blockly/block-shareable-procedures][shareable-procedures] was +available) you can upgrade them to work with the new +[@blockly/block-shareable-procedures][shareable-procedures] blocks by following +the steps that follow. +::: + +## Add data models to the workspace + +Both procedure definition and procedure caller blocks reference a backing data +model which defines the signature of the procedure (name, parameters, and +return). This enables more flexibility in how you design your application (e.g. +you could allow procedures to be defined in one workspace, and referenced in +another). + +This means that you will need to add the procedure data models to the workspace +for your blocks to work. There are many ways you could do this (e.g. custom +UIs). + +The [@blockly/block-shareable-procedures][shareable-procedures] does this by +having procedure-definition blocks dynamically create their backing data models +when they are instantiated into the workspace. To implement this yourself, you +create the model in `init` and delete it in `destroy`. + +```js +import {ObservableProcedureModel} from '@blockly/block-shareable-procedures'; + +Blockly.Blocks['my_procedure_def'] = { + init: function() { + this.model = new ObservableProcedureModel('default name'); + this.workspace.getProcedureMap().add(model); + // etc... + } + + destroy: function() { + // (Optionally) Destroy the model when the definition block is deleted. + + // Insertion markers reference the model of the original block. + if (this.isInsertionMarker()) return; + this.workpace.getProcedureMap().delete(model.getId()); + } +} +``` + +## Return information about the blocks + +Your procedure definition and procedure call blocks need to implement the +`getProcedureModel`, `isProcedureDef`, and `getVarModels` methods. These are the +hooks Blockly code uses to get information about your procedure blocks. + +```js +Blockly.Blocks['my_procedure_def'] = { + getProcedureModel() { + return this.model; + }, + + isProcedureDef() { + return true; + }, + + getVarModels() { + // If your procedure references variables + // then you should return those models here. + return []; + }, +}; + +Blockly.Blocks['my_procedure_call'] = { + getProcedureModel() { + return this.model; + }, + + isProcedureDef() { + return false; + }, + + getVarModels() { + // If your procedure references variables + // then you should return those models here. + return []; + }, +}; +``` + +## Trigger rerendering on updates + +Your procedure definition and procedure call blocks need to implement the +`doProcedureUpdate` method. This is the hook the data models call to tell your +procedure blocks to re-render themselves. + +```js +Blockly.Blocks['my_procedure_def'] = { + doProcedureUpdate() { + this.setFieldValue(this.model.getName(), 'NAME'); + this.setFieldValue( + this.model.getParameters() + .map((p) => p.getName()) + .join(',') + 'PARAMS'); + this.setFieldValue( + this.model.getReturnTypes().join(','), 'RETURN'); + } +}; + +Blockly.Blocks['my_procedure_call'] = { + doProcedureUpdate() { + // Similar to the def block above... + } +}; +``` + +## Add custom serialization + +Serialization for procedure blocks must do two separate things. + +1. When loading from JSON your blocks will need to grab a _reference_ to their + backing data model, because the blocks and models are serialized separately. +2. When copying and pasting a procedure block, the block will need to serialize + the entire state of its procedure model, so that it can be replicated. + +Both of these things are handled through `saveExtraState` and `loadExtraState`. +Note again that custom procedure blocks are only supported when using the JSON +serialization system, so we only need to define JSON serialization hooks. + +```js +import { + ObservableProcedureModel, + ObservableParameterModel, + isProcedureBlock +} from '@blockly/block-shareable-procedures'; + +Blockly.Blocks['my_procedure_def'] = { + // When doFullSerialization is true, we should serialize the full state of + // the model. + saveExtraState(doFullSerialization) { + const state = Object.create(null); + state['procedureId']: this.model.getId(); + + if (doFullSerialization) { + state['name'] = this.model.getName(); + state['parameters'] = this.model.getParameters().map((p) => { + return {name: p.getName(), p.getId()}; + }); + state['returnTypes'] = this.model.getReturnTypes(); + + // Flag for deserialization. + state['createNewModel'] = true; + } + + return state; + }, + + loadExtraState(state) { + const id = state['procedureId'] + const map = this.workspace.getProcedureMap(); + + if (map.has(id) && !state['createNewModel']) { + // Delete the existing model (created in init). + map.delete(this.model.getId()); + // Grab a reference to the model we're supposed to reference. + this.model = map.get(id); + this.doProcedureUpdate(); + return; + } + + // There is no existing procedure model (we are likely pasting), so + // generate it from JSON. + this.model + .setName(state['name']) + .setReturnTypes(state['returnTypes']); + for (const [i, param] of state['parameters'].entries()) { + this.model.insertParameter( + i, + new ObservableParameterModel( + this.workspace, param['name'], param['id'])); + } + this.doProcedureUpdate(); + }, +}; + +Blockly.Blocks['my_procedure_call'] = { + saveExtraState() { + return { + 'procedureId': this.model.getId(), + }; + }, + + loadExtraState(state) { + // Delete our existing model (created in init). + this.workspace.getProcedureMap().delete(model.getId()); + // Grab a reference to the new model. + this.model = this.workspace.getProcedureMap() + .get(state['procedureId']); + if (this.model) this.doProcedureUpdate(); + }, + + // Handle pasting after the procedure definition has been deleted. + onchange(event) { + if (event.type === Blockly.Events.BLOCK_CREATE && + event.blockId === this.id) { + if(!this.model) { // Our procedure definition doesn't exist =( + this.dispose(); + } + } + } +}; +``` + +## Optionally modify the procedure model + +You can also add the ability for users to modify the procedure model. Calling +the `insertParameter`, `deleteParameter`, or `setReturnTypes` +[methods](/reference/blockly.procedures_namespace.iproceduremodel_interface) +will automatically trigger your blocks to rerender (via `doProcedureUpdate`). + +Options for creating UIs to modify the procedure model include using +[mutators](/guides/create-custom-blocks/mutators#ui-hooks) (which the +built-in procedure blocks use), image fields with click handlers, something +completely external to Blockly, etc. + +## Add blocks to the toolbox + +Blockly’s built-in dynamic procedure category is specific to Blockly’s built-in +procedure blocks. So to be able to access your blocks, you will need to define +your own [custom dynamic +category](/guides/configure/web/toolboxes/dynamic), and [add it +to your toolbox](/guides/configure/web/toolboxes/dynamic). + +```js +const proceduresFlyoutCallback = function (workspace) { + const blockList = []; + blockList.push({ + kind: 'block', + type: 'my_procedure_def', + }); + for (const model of workspace.getProcedureMap().getProcedures()) { + blockList.push({ + kind: 'block', + type: 'my_procedure_call', + extraState: { + procedureId: model.getId(), + }, + }); + } + return blockList; +}; + +myWorkspace.registerToolboxCategoryCallback( + 'MY_PROCEDURES', + proceduresFlyoutCallback, +); +``` + +[shareable-procedures]: https://www.npmjs.com/package/@blockly/block-shareable-procedures diff --git a/packages/docs/docs/guides/create-custom-blocks/procedures/creating-custom-procedure-data-models.mdx b/packages/docs/docs/guides/create-custom-blocks/procedures/creating-custom-procedure-data-models.mdx new file mode 100644 index 00000000000..2d209925de9 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/procedures/creating-custom-procedure-data-models.mdx @@ -0,0 +1,130 @@ +--- +description: How to create custom procedure data models. +title: Create custom procedure data models +image: images/blockly_banner.png +--- + +# Create custom procedure data models + +Procedure blocks all reference backing data models which define the signature of +the procedure (name, parameters, and return). The data models provided by the +[@blockly/block-shareable-procedures][shareable-procedures] plugin are built to +replicate the behavior of Blockly's legacy built-in procedure blocks. + +This includes some behavior that you may not want for your custom procedure +blocks, including: + +- Return types are not supported +- All parameters are associated with a global variable + +If you want different behavior, you can create your own custom procedure data +models. + +## Procedure model implementation + +Your procedure data model needs to implement the +[`IProcedureModel`][IProcedureModel] interface. + +```js +class MyProcedureModel { + constructor(workspace, name, id) { + this.workspace = workspace; + this.name = name; + this.id = id; + + // Note: construction should not add the model to the procedure map. + }, + + // Other methods are omitted for brevity... +} +``` + +## Parameter model implementation + +Your parameter data model needs to implement the +[`IParameterModel`][IParameterModel] interface. + +```js +class MyParameterModel { + constructor(workspace, name, id) { + this.workspace = workspace; + this.name = name; + this.id = id; + }, + + setProcedureModel(model) { + this.model = model; + return this; + } + + // Other methods are omitted for brevity... +} +``` + +## Trigger changes + +Any of the methods that trigger changes to the procedure model should also call +`triggerProceduresUpdate` from the +[@blockly/block-shareable-procedures][shareable-procedures] plugin. This will +call `doProcedureUpdate` on any procedure blocks, causing them to rerender. + +```js +import { triggerProceduresUpdate } from '@blockly/block-shareable-procedures'; + +class MyProcedureModel { + setName(name) { + this.name = name; + triggerProcedureUpdate(); + return this; + } + + // Other methods are omitted for brevity... +} + +class MyParameterModel { + setName(name) { + this.name = name; + triggerProcedureUpdate(); + return this; + } + + // Other methods are omitted for brevity... +} +``` + +## Events + +The procedure models in the +[@blockly/block-shareable-procedures][shareable-procedures] plugin also fire +events when the procedures are modified. This allows multiple workspaces to be +kept in sync, and procedure models to be shared across them. You can also choose +to fire events if you want. + +## Deserialization + +Your classes also each need a `static loadState` method to support +deserialization. + +```js +class MyProcedureModel { + static loadState(state, workspace) { + // Note that the procedure model should not deserialize parameters. + // The deserializer will handle that. + return new MyProcedureModel(workspace, state.name, state.id); + } + + // Other methods are omitted for brevity... +} + +class MyParameterModel { + static loadState(state, workspace) { + return new MyParameterModel(workspace, state.name, state.id); + } + + // Other methods are omitted for brevity... +} +``` + +[shareable-procedures]: https://www.npmjs.com/package/@blockly/block-shareable-procedures +[IProcedureModel]: /reference/blockly.procedures_namespace.iproceduremodel_interface +[IParameterModel]: /reference/blockly.procedures_namespace.iparametermodel_interface diff --git a/packages/docs/docs/guides/create-custom-blocks/procedures/overview.mdx b/packages/docs/docs/guides/create-custom-blocks/procedures/overview.mdx new file mode 100644 index 00000000000..821dfb1bf48 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/procedures/overview.mdx @@ -0,0 +1,56 @@ +--- +description: Overview of how Blockly conceptualizes procedures. +title: Procedures +image: images/blockly_banner.png +--- + +# Procedures + +In computer science terms, a procedure is a reusable bit of code that performs a +specific task. + +Blockly implements procedures as a set of blocks that generate code for defining +a procedure, and calling it. + +![Procedure caller and definition blocks](/images/procedures.png) + +→ More info on [using the blocks](/guides/create-custom-blocks/procedures/using-procedures). + +→ More info on [creating custom procedure blocks](/guides/create-custom-blocks/procedures/creating-custom-procedure-blocks). + +→ More info on [creating custom procedure models](/guides/create-custom-blocks/procedures/creating-custom-procedure-data-models), which allow you to add new functionality like typed parameters. + +## Built-in vs plugin + +Blockly provides two implementations of procedure blocks. + +One exists in the plugin [@blockly/block-shareable-procedures][shareable-procedures], +which implements procedure blocks that rely on a backing data model. This allows +you to do things with your procedure blocks such as having the definition +block exist in one workspace, and the call block exist in another. The plugin is +the recommended implementation of procedure blocks. + +The other is the legacy implementation, provided in Blockly core. These blocks +don't have a backing data model, and all information about procedures comes +from the blocks themselves. The only way a workspace knows which procedures +are available is by inspecting the procedure definition blocks contained in +that workspace. These blocks continue to be supported for backwards +compatibility, but most developers should be able to use the new blocks +provided by the plugin. + +- If you are using XML serialization, you can use the new blocks, but they + won't be shareable across workspaces. That feature requires extra serialization + that is only provided by the JSON serializer. When using XML, the new blocks + will behave identically to the legacy blocks. + [Learn more about upgrading to JSON](https://docs.google.com/document/d/1wv5ORrO4icVHeU15FLSn37mdNLyJpQbMTo7mmTqsGl0/edit?usp=sharing). + +- If you have defined custom procedure blocks, they need to be + [updated](/guides/create-custom-blocks/procedures/creating-custom-procedure-blocks) + to work with the new data models. + +- If you have defined custom procedure definition blocks, _but are using the + built-in procedure call block_, you need to continue using the legacy caller + block until you [update](/guides/create-custom-blocks/procedures/creating-custom-procedure-blocks) + your definition block. + +[shareable-procedures]: https://www.npmjs.com/package/@blockly/block-shareable-procedures diff --git a/packages/docs/docs/guides/create-custom-blocks/procedures/using-procedures.mdx b/packages/docs/docs/guides/create-custom-blocks/procedures/using-procedures.mdx new file mode 100644 index 00000000000..42716d41981 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/procedures/using-procedures.mdx @@ -0,0 +1,79 @@ +--- +description: How to use built-in procedure blocks in your application. +title: Use built-in procedure blocks +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Use built-in procedure blocks + +## Using the plugin + +To use procedure blocks, we recommend using the +[@blockly/block-shareable-procedures][shareable-procedures] plugin. +For the difference between the plugin blocks and the built-in blocks see the +[overview](/guides/create-custom-blocks/procedures/overview). + +### Installation + +Yarn: + +```shell +yarn add @blockly/block-shareable-procedures +``` + +NPM: + +```shell +npm install @blockly/block-shareable-procedures +``` + +### Usage + +```js +import Blockly from 'blockly'; +import {blocks, unregisterProcedureBlocks} '@blockly/block-shareable-procedures'; + +unregisterProcedureBlocks(); +Blockly.common.defineBlocks(blocks); +``` + +This will define procedure blocks that have the same names as the legacy +built-in procedure blocks. So if you are loading JSON or XML that was saved +with the old procedure blocks, they will continue to load properly. + +#### Adding them to the toolbox + +After you have defined your blocks (either the plugin ones, or the legacy +built-in ones), you need to make them available to your users. This requires +you to use a category style toolbox, because the procedure category is populated +dynamically, which is not supported by the flyout toolbox. + +You can add the dynamic category to your toolbox like so: + + + + ```js + { + "kind": "categoryToolbox", + "contents": [ + { + "kind": "category", + "name": "Functions", + "custom": "PROCEDURE" + } + ] + }; + ``` + + + ```xml + + ``` + + +[shareable-procedures]: https://www.npmjs.com/package/@blockly/block-shareable-procedures diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/constants.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/constants.mdx new file mode 100644 index 00000000000..4dd761fd1e1 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/constants.mdx @@ -0,0 +1,44 @@ +--- +description: What the renderer constant provider class is and what it does. +title: Constant provider +image: images/blockly_banner.png +--- + +# Constant provider + +The [`ConstantProvider`][ConstantProvider] is a collection of magic numbers, +shapes and strings used by all of the other renderer components, as well as +other parts of Blockly like the built-in fields. + +All constant values are assumed to be _constant_! Changing values at +runtime causes rendering bugs. + +## Connection shapes + +The constant provider contains definitions for the standard shapes of different +connections. [`Notch`][Notch]es define the shapes of next and previous +connections. And the [`PuzzleTab`][PuzzleTab]s define the shapes of input +and output connections. (These names are based on the shapes provided by +the default renderer.) + +### Connection shapes based on checks + +The constant provider can also define the shapes of connections dynamically +based on their [connection check][connection-check]. This is done using the +[`shapeFor`][shapeFor] method. + +## Other various paths + +The constant provider also defines paths for other various parts of the +block, like jagged edges for collapsed blocks. + +## Other various values + +And finally, the constant provider also defines various values for things like +the padding between different elements, or the minimum heights of rows. + +[ConstantProvider]: /reference/blockly.blockrendering_namespace.constantprovider_class +[Notch]: /reference/blockly.blockrendering_namespace.constantprovider_class.notch_property +[PuzzleTab]: /reference/blockly.blockrendering_namespace.constantprovider_class.puzzle_tab_property +[connection-check]: /guides/create-custom-blocks/inputs/connection-checks +[shapeFor]: /reference/blockly.blockrendering_namespace.constantprovider_class.shapefor_1_method diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/drawer.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/drawer.mdx new file mode 100644 index 00000000000..51b325378dc --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/drawer.mdx @@ -0,0 +1,24 @@ +--- +description: What the drawer class is and what it does. +title: Drawer +image: images/blockly_banner.png +--- + +# Drawer + +The [`Drawer`][Drawer] builds SVG [paths][paths] based on the +[renderer info][render-info] and passes them to the [path object][path-object]. + +It connects all of the different path representations of the different +measurables (which are defined in the [constant provider][constants]) +together. The drawer uses the [SVG path utils][svg-path-utils] provided by +Blockly to do this. + +The drawer also updates the offsets of connections within the block. + +[Drawer]: /reference/blockly.blockrendering_namespace.drawer_class +[paths]: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths +[render-info]: /guides/create-custom-blocks/renderers/concepts/info +[path-object]: /guides/create-custom-blocks/renderers/concepts/path-object +[constants]: /guides/create-custom-blocks/renderers/concepts/constants +[svg-path-utils]: /reference/blockly.utils_namespace.svgpaths_namespace diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/elements.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/elements.mdx new file mode 100644 index 00000000000..cf7d222673c --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/elements.mdx @@ -0,0 +1,59 @@ +--- +description: What the element measurable is and what it does. +title: Elements +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Elements + +During [measurement][render-info] the block gets broken up into [rows][row] +containing non-overlapping elements and element spacers. + +## Elements + +Elements represent visual things on a block. Examples include elements +representing: + +- Fields +- Icons +- Connections +- Corners + +A repeat-for block with the elements outlined + +Each element is a rectangle defining the bounds of the visual thing, plus some +extra data specific to each kind of element. + +The bounds of the element are usually determined by some external class +(that is, the thing they represent). For example, +[field elements][field-element] represent fields, and their size is determined +by the field's [`getSize`][getSize] method. + +## Element spacer + +An element spacer is an empty space that goes between elements in a row. + +A repeat-for block with the element spacers highlighted in pink + +The bounds of spacers are determined by the [render info][render-info] during +measurement. After measuring all of the elements of the block, the +[render info][render-info] inserts spaces of its chosen size between +the elements. The sizes don't have to be consistent; they are often different +depending on the elements to either side of the spacer. + +[render-info]: /guides/create-custom-blocks/renderers/concepts/info +[row]: /guides/create-custom-blocks/renderers/concepts/rows +[field-element]: /reference/blockly.blockrendering_namespace.field_class +[getSize]: /reference/blockly.field_class.getsize_1_method +[element-image]: /images/rendering/debug-renderer/element.png +[element-spacer-image]: /images/rendering/debug-renderer/element-spacer.png diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/info.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/info.mdx new file mode 100644 index 00000000000..ab27e25ab7a --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/info.mdx @@ -0,0 +1,36 @@ +--- +description: What the renderer info class is and what it does. +title: Render info +image: images/blockly_banner.png +--- + +# Render info + +The [`RenderInfo`][RenderInfo] determines how a block's visual elements get +laid out. + +A block is always built out of inputs, connections, and fields, but those +can be laid out in many different ways. For example, the same block definition +can be rendered with [inline inputs or external inputs][external-vs-inline]. + +![External vs inline inputs](/images/set-inputs-inline.png) + +The render info determines which layout is chosen. + +As the first step of rendering, the render info looks at the block's definition, +and the measurements of its visual pieces. Then it decides how the block should +be laid out, and organizes the information accordingly. The information gets +turned into non-overlapping [elements][element] and [spacers][element-spacer], +which are organized into non-overlapping [rows][row], and +[row spacers][row-spacer]. + +Then the [drawer][drawer] uses that organized layout information to create the +SVG paths representing the block. + +[RenderInfo]: /reference/blockly.blockrendering_namespace.renderinfo_class +[drawer]: /guides/create-custom-blocks/renderers/concepts/drawer +[row]: /guides/create-custom-blocks/renderers/concepts/rows +[element]: /guides/create-custom-blocks/renderers/concepts/elements +[row-spacer]: /guides/create-custom-blocks/renderers/concepts/rows#row-spacer +[element-spacer]: /guides/create-custom-blocks/renderers/concepts/elements#element-spacer +[external-vs-inline]: /guides/create-custom-blocks/define/inline-vs-external diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/overview.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/overview.mdx new file mode 100644 index 00000000000..2dcf7c79455 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/overview.mdx @@ -0,0 +1,119 @@ +--- +description: An overview of important renderer concepts. +title: Renderer concepts +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Renderer concepts + +Before you start building a custom renderer, it is helpful to understand the +different components that make up a renderer, as well as how a block gets +broken up into rows and elements. + +## Renderer components + +A renderer is built up of several different components. Each component has a +unique job to maximize code reuse and extensibility. + +### Renderer + +The [renderer][renderer] is a factory class that bundles all of the other +components together. + +### Constant provider + +The [constant provider][constants] is a collection of numbers, and shapes used +by all of the other components, as well as built-in fields. + +### Render info + +The [render info][render-info] decides how it a block should be laid out based +on its definition, and then creates a collection of +[measurables](#block-measurables) and data about the block which the +[drawer][drawer] uses to create SVG paths. + +### Path Object + +The [path object][path-object] contains the SVG elements that live in the dom +and make up the block. + +### Drawer + +The [drawer][drawer] (as in "one-who-draws") builds SVG [paths][paths] based on +the [render info][render-info] and applies them to the +[path object][path-object]. + +## Block measurables + +A measurable is a rectangle representing a region of a block. Measurables are +what the [render info][render-info] uses to define the layout of the block. + +Some measurables also include extra data (such as the visual thing they are +representing), or helper methods that the render info can use to figure out how +to lay out the block. + +Different renderers may create custom measurables to change these data or +helper methods. + +### Rows + +A [row][row] is a horizontal collection of [elements][element] and +[element spacers][element-spacer]. + +A repeat-for block with the rows outlined. + +### Row spacers + +A [row spacer][row-spacer] is an empty vertical space that goes between two +rows. + +A repeat-for block with the row spacers highlighted in blue + +### Elements + +An [element][element] represents a visual thing on a block. These include +[fields][field], [icons][icon], connections, etc. + +A repeat-for block with the elements outlined + +### Element spacers + +An [element spacer][element-spacer] is an empty space that goes between elements +in a row. + +A repeat-for block with the element spacers highlighted in pink + +[renderer]: /guides/create-custom-blocks/renderers/concepts/renderer +[constants]: /guides/create-custom-blocks/renderers/concepts/constants +[render-info]: /guides/create-custom-blocks/renderers/concepts/info +[path-object]: /guides/create-custom-blocks/renderers/concepts/path-object +[drawer]: /guides/create-custom-blocks/renderers/concepts/drawer +[paths]: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths +[row]: /guides/create-custom-blocks/renderers/concepts/rows +[element]: /guides/create-custom-blocks/renderers/concepts/elements +[row-spacer]: /guides/create-custom-blocks/renderers/concepts/rows#row-spacer +[element-spacer]: /guides/create-custom-blocks/renderers/concepts/elements#element-spacer +[field]: /guides/create-custom-blocks/fields/overview +[icon]: /guides/create-custom-blocks/icons/overview +[row-image]: /images/rendering/debug-renderer/row.png +[row-spacer-image]: /images/rendering/debug-renderer/row-spacer.png +[element-image]: /images/rendering/debug-renderer/element.png +[element-spacer-image]: /images/rendering/debug-renderer/element-spacer.png diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/path-object.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/path-object.mdx new file mode 100644 index 00000000000..64b32e999ea --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/path-object.mdx @@ -0,0 +1,34 @@ +--- +description: What the path object class is and what it does. +title: Path object +image: images/blockly_banner.png +--- + +# Path object + +The [`PathObject`][PathObject] contains the SVG elements in the DOM +that make up the block. + +For example, in the [Geras][built-in-renderers] renderer, blocks have a "main" +path, a "dark" path and a "light" path, to give them a 3d effect. The +path object creates the SVG elements for each of these paths. + +![geras paths][geras-paths-image] + +This is opposed to the [Thrasos][built-in-renderers] renderer, whose blocks +have a single path element with a stroke: + +![thrasos paths][thrasos-paths-image] + +It also handles: + +- Applying the shape generated by the [drawer][drawer] to the SVG elements. +- Applying [theme colors][theme] to the SVG elements. +- Applying other styling to the SVG elements. + +[PathObject]: /reference/blockly.blockrendering_namespace.pathobject_class +[theme]: /guides/configure/web/appearance/themes#block-style +[built-in-renderers]: /guides/create-custom-blocks/renderers/overview#built-in-renderers +[drawer]: /guides/create-custom-blocks/renderers/concepts/drawer +[geras-paths-image]: /images/rendering/renderers/geras-paths.png +[thrasos-paths-image]: /images/rendering/renderers/thrasos-paths.png diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/renderer.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/renderer.mdx new file mode 100644 index 00000000000..0581365aece --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/renderer.mdx @@ -0,0 +1,23 @@ +--- +description: What the renderer class is and what it does. +title: Renderer +image: images/blockly_banner.png +--- + +# Renderer + +The [`Renderer`][Renderer] is a factory class that bundles all of the other +components of a renderer together. + +It contains methods for creating the [constant provider][constants], +[render info][render-info], [path object][path-object], and [drawer][drawer]. +And it contains code for wiring them all together when it renders a block. + +If you want to change just one part of an existing renderer (e.g. the constants) +you can subclass the relevant factory method. + +[Renderer]: /reference/blockly.blockrendering_namespace.renderer_class +[constants]: /guides/create-custom-blocks/renderers/concepts/constants +[render-info]: /guides/create-custom-blocks/renderers/concepts/info +[path-object]: /guides/create-custom-blocks/renderers/concepts/path-object +[drawer]: /guides/create-custom-blocks/renderers/concepts/drawer diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/rows.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/rows.mdx new file mode 100644 index 00000000000..bf4332b9b24 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/concepts/rows.mdx @@ -0,0 +1,58 @@ +--- +description: What the row measurable is and what it does. +title: Rows +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Rows + +Blocks are defined as a collection of inputs, but the [render info][render-info] +determines how these inputs get broken up into rows and spacer rows. + +For example, when a block is set to [inline inputs][external-vs-inline], +the block is made of fewer rows than when it is set to +[external inputs][external-vs-inline]. It has the same number of inputs but +a different number of rows! + +![blocks set to inline and external inputs](/images/set-inputs-inline.png) + +## Row + +A [`Row`][Row] is a horizontal collection of non-overlapping [elements][element] +and [element spacers][element-spacer]. + +A repeat-for block with the rows outlined. + +The bounds of a row are determined by the bounds of the [elements][element] and +[spacers][element-spacer] that belong to that row, so that all of the elements +are contained. + +## Row spacer + +A [`RowSpacer`][RowSpacer] is an empty vertical space that goes between two +rows. + +A repeat-for block with the row spacers highlighted in blue + +The bounds of the row spacers are determined by the +[render info][render-info] itself. After measuring all of the rows of the block, +the [render info][render-info] inserts spaces of its chosen size between rows. + +[Row]: /reference/blockly.blockrendering_namespace.row_class +[RowSpacer]: /reference/blockly.blockrendering_namespace.spacerrow_class +[render-info]: /guides/create-custom-blocks/renderers/concepts/info +[external-vs-inline]: /guides/create-custom-blocks/define/inline-vs-external +[element]: /guides/create-custom-blocks/renderers/concepts/elements +[element-spacer]: /guides/create-custom-blocks/renderers/concepts/elements#element-spacer +[row-image]: /images/rendering/debug-renderer/row.png +[row-spacer-image]: /images/rendering/debug-renderer/row-spacer.png diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/create-custom-renderers/basic-implementation.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/create-custom-renderers/basic-implementation.mdx new file mode 100644 index 00000000000..a1b01e76b91 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/create-custom-renderers/basic-implementation.mdx @@ -0,0 +1,104 @@ +--- +description: How to create your own custom renderer. +title: Create custom renderers +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Create custom renderers + +:::note +If you haven't read through the [renderer concept docs][renderer-concept] +or completed the [custom renderers codelab][custom-renderer-codelab] we +recommend doing those first! +::: + +To create a custom renderer, you need to subclass the [`Renderer`][Renderer] +class. Refer to the [renderer concept docs][renderer-concept] for more +information about what a renderer is and what it does. + +```js +class CustomRenderer extends Blockly.blockRendering.Renderer { + constructor() { + super(); + } +} +``` + +Without any customization, the default renderer looks like this: + +base renderer + +You can also subclass one of the other [built-in renderers][built-in-renderers] +and then override parts of it. + +```js +class CustomRenderer extends Blockly.thrasos.Renderer { + constructor() { + super(); + } +} +``` + +## Subclass other renderer components + +The actual shape of the block is determined by the +[subcomponents][renderer-component] of the renderer. + +By default, the [`Renderer`][Renderer] class provides working versions of +all the [renderer components][renderer-component]. This lets you modify a +single component, without having to worry about the others. + +For example, if you want to +[change the shapes of connections][connection-shape], you can override the +[constants][constants] without having to touch the other components. + +Check out the [renderer component docs][renderer-component] for more +information about what each individual component does. + +## Override factory methods + +After subclassing the [renderer components][renderer-component], you need to +override the [`Renderer`][Renderer]'s factory methods for the components you +subclassed. This lets the renderer properly wire the different components +together. + +There is a method for each kind of component: + +- [`makeConstants_`][makeConstants] +- [`makeRenderInfo_`][makeRenderInfo] +- [`makePathObject`][makePathObject] (note there is no underscore) +- [`makeDrawer_`][makeDrawer] + +## Register the renderer + +Finally, once you've completed the creation of your custom renderer, you need to +register it. This associates the renderer with a string so that you can pass it +to your [configuration options][inject-config]. + +```js +Blockly.blockRendering.register('custom_renderer', CustomRenderer); + +const workspace = Blockly.inject(blocklyDiv, { + renderer: 'custom_renderer', +}); +``` + +[Renderer]: /reference/blockly.blockrendering_namespace.renderer_class +[renderer-concept]: /guides/create-custom-blocks/renderers/concepts/renderer +[base-renderer-image]: /images/rendering/renderers/base-renderer.png +[built-in-renderers]: /guides/create-custom-blocks/renderers/overview#built-in-renderers +[renderer-component]: /guides/create-custom-blocks/renderers/concepts/overview +[connection-shape]: /guides/create-custom-blocks/renderers/create-custom-renderers/connection-shapes +[constants]: /guides/create-custom-blocks/renderers/concepts/constants +[makeConstants]: /reference/blockly.blockrendering_namespace.renderer_class.makeconstants__1_method +[makeRenderInfo]: /reference/blockly.blockrendering_namespace.renderer_class.makerenderinfo__1_method +[makePathObject]: /reference/blockly.blockrendering_namespace.renderer_class.makepathobject_1_method +[makeDrawer]: /reference/blockly.blockrendering_namespace.renderer_class.makedrawer__1_method +[inject-config]: /guides/configure/web/configuration_struct +[custom-renderer-codelab]: /codelabs/custom-renderer/codelab-overview/index.html diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/create-custom-renderers/connection-shapes.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/create-custom-renderers/connection-shapes.mdx new file mode 100644 index 00000000000..2e606d291c3 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/create-custom-renderers/connection-shapes.mdx @@ -0,0 +1,333 @@ +--- +description: How to modify the shapes of connections. +title: Connection shapes +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Connection shapes + +There are several ways you can customize the ways connections look, each with +increasing difficulty. All of them require creating a +[custom renderer][basic-implementation]. + +## Basic dimensions + +connections with different dimensions + +You can customize connections by changing their width or height, while +maintaining the same basic shape. To do this, you need to create a +custom [constant provider][constants] component, and override some constants. + +Different renderers define and use different constants, so check out the +reference documentation for your super class: + +- [base constants][BaseConstants] +- [Geras constants][GerasConstants] +- [Zelos constants][ZelosConstants] + +:::note +Thrasos does not define its own constants. If you are using Thrasos, +check out the base constants. +::: + +For the base renderer, you can override [`NOTCH_WIDTH`][NOTCH_WIDTH] and +[`NOTCH_HEIGHT`][NOTCH_HEIGHT] for next and previous connections, and +[`TAB_WIDTH`][TAB_WIDTH] and [`TAB_HEIGHT`][TAB_HEIGHT] for input and output +connections. + +```js +class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider { + constructor() { + super(); + this.NOTCH_WIDTH = 20; + this.NOTCH_HEIGHT = 10; + this.TAB_HEIGHT = 8; + } +} +``` + +## Basic shapes + +connections with different shapes + +You can customize connections by overriding their basic shape. Basic shapes +have a height, a width, and _two_ paths. + +Each path draws the same shape, but from opposite ends! + +![a notch drawn from both directions][shape-direction-image] + +This is necessary because as the drawer draws the outline of the +block, it draws each kind of connection in both directions. For example, +previous connections are drawn from left to right, but next connections are +drawn from right to left. So you need to provide paths for both of +those cases. + +the direction a block gets drawn in + +:::note +the [path object][path-object] handles flipping paths in RTL mode, so +you just need to think about things in LTR! +::: + +You can override the [`makeNotch`][makeNotch] method for next and previous +connections, and the [`makePuzzleTab`][makePuzzleTab] method for input and +output connections. + +```js +class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider { + makePuzzleTab() { + const width = this.TAB_WIDTH; + const height = this.TAB_HEIGHT; + return { + type: this.SHAPES.PUZZLE, + width, + height, + pathUp: Blockly.utils.svgPaths.line([ + Blockly.utils.svgPaths.point(-width, -height / 2), + Blockly.utils.svgPaths.point(width, -height / 2), + ]), + pathDown: Blockly.utils.svgPaths.line([ + Blockly.utils.svgPaths.point(-width, height / 2), + Blockly.utils.svgPaths.point(width, height / 2), + ]), + }; + } +} +``` + +Check out the [MDN SVG path documentation][svg-path] for information about how +to define path strings. The `Blockly.utils.svgPaths` namespace is provided +as a thin wrapper around these strings to make them more readable. + +## Shapes for connection checks + +different connections with different shapes + +You can customize connections by changing the shape based on the connection's +[connection check][connection-check]. + +This lets you create different shapes to represent different data types. +For example, strings could be represented by triangular connections, while +booleans are represented by round connections. + +To supply different shapes for different connection checks, you need to override +the [`shapeFor`][shapeFor] method. The shapes returned should be initialized +in `init`. + +See [basic shapes][basic-shapes] for information about what kinds of +shapes are supported. + +```js +export class ConstantProvider + extends Blockly.blockRendering.BaseConstantProvider +{ + shapeFor(connection) { + let check = connection.getCheck(); + // For connections with no check, match any child block. + if (!check && connection.targetConnection) { + check = connection.targetConnection.getCheck(); + } + + if (check && check.includes('String')) return this.TRIANGULAR_TAB; + if (check && check.includes('Boolean')) return this.ROUND_TAB; + + return super.shapeFor(connection); + } +} +``` + +## Custom inputs + +You can customize connection shapes by creating an entirely custom input. This +is only done if you want some connections to look different from others, but +you don't want it to be based on the [connection check][connection-check]. + +For example, if you want some value inputs to be indented like statement inputs, +you can create a custom input to support this. + +### Create a custom input class + +Follow the steps for [creating a custom input][custom-input]. + +### Create a measurable + +You need to create a [measurable][measurable] to represent your custom input. + +Your custom input measurable should inherit from +[`Blockly.blockRendering.InputConnection`][InputConnection]. It can also include +whatever extra measurement data you need to draw the input's shape. + +```js +export class CustomInputMeasurable + extends Blockly.blockRendering.InputConnection +{ + constructor(constants, input) { + super(constants, input); + + // Any extra measurement data... + } +} +``` + +### Instantiate your measurable + +Your [render info][render-info] needs to instantiate your custom +measurable. To do this, you need to override the [`addInput_`][addInput] method. + +```js +export class RenderInfo extends Blockly.blockRendering.RenderInfo { + addInput_(input, activeRow) { + if (input instanceof CustomInput) { + activeRow.elements.push( + new CustomInputMeasurable(this.constants_, input), + ); + } + super.addInput_(input, activeRow); + } +} +``` + +### Optionally create a row + +By default, inputs don't create new [rows][row]. If you want your input +to trigger the end of a row, you need to override the +[`shouldStartNewRow_`][shouldStartNewRow] method of your +[render info][render-info]. + +```js +export class RenderInfo extends Blockly.blockRendering.RenderInfo { + shouldStartNewRow_(currInput, prevInput) { + if (prevInput instanceof CustomInput) return true; + return super.shouldStartNewRow_(currInput, prevInput); + } +} +``` + +### Optionally create a shape for your input + +It is a good idea to store the shape of your input in a constant, just like +we do for notches and puzzle tabs. This keeps your code organized, and makes +it easier to modify later. + +### Draw the input + +Lastly, you need to modify your [drawer][drawer] to draw the shape. + +Custom inputs can either: + +- Affect the outline of your block, like statement inputs + + image of outline inputs + +- Or affect the internals of your block, like inline value inputs + + image of internal inputs + +If the input affects the outline of your block, override +[`drawOutline_`][drawOutline], otherwise, override +[`drawInternals_`][drawInternals]. + +```js +export class Drawer extends Blockly.blockRendering.Drawer { + drawOutline_() { + this.drawTop_(); + for (let r = 1; r < this.info_.rows.length - 1; r++) { + const row = this.info_.rows[r]; + + // Insert checks for your input here! + if (row.getLastInput() instanceof CustomInputMeasurable) { + this.drawCustomInput(row); + } else if (row.hasJaggedEdge) { + this.drawJaggedEdge_(row); + } else if (row.hasStatement) { + this.drawStatementInput_(row); + } else if (row.hasExternalInput) { + this.drawValueInput_(row); + } else { + this.drawRightSideRow_(row); + } + } + this.drawBottom_(); + this.drawLeft_(); + } + + protected drawInternals_() { + for (const row of rows) { + for (const elem of row) { + + // Insert checks for your input here! + if (elem instanceof CustomInputMeasurable) { + this.drawCustomInput(elem); + } + + if (Types.isInlineInput(elem)) { + this.drawInlineInput_(elem as InlineInput); + } else if (Types.isIcon(elem) || Types.isField(elem)) { + this.layoutField_(elem as Field | Icon); + } + } + } + } +} +``` + +[overridden-connection-constants-image]: /images/rendering/connection-shapes/overridden-connection-constants.png +[connection-check-specific-shapes-image]: /images/rendering/connection-shapes/connection-check-specific-shapes.png +[overridden-connection-shapes-image]: /images/rendering/connection-shapes/overridden-connection-shapes.png +[shape-direction-image]: /images/rendering/connection-shapes/shape-direction.png +[drawing-direction-image]: /images/rendering/connection-shapes/drawing-direction.png +[outline-inputs-image]: /images/rendering/connection-shapes/outline-inputs.png +[internal-inputs-image]: /images/rendering/connection-shapes/internal-inputs.png +[basic-implementation]: /guides/create-custom-blocks/renderers/create-custom-renderers/basic-implementation +[constants]: /guides/create-custom-blocks/renderers/concepts/constants +[BaseConstants]: /reference/blockly.blockrendering_namespace.constantprovider_class +[GerasConstants]: /reference/blockly.geras_namespace.constantprovider_class +[ZelosConstants]: /reference/blockly.zelos_namespace.constantprovider_class +[NOTCH_WIDTH]: /reference/blockly.blockrendering_namespace.constantprovider_class.notch_width_property +[NOTCH_HEIGHT]: /reference/blockly.blockrendering_namespace.constantprovider_class.notch_height_property +[TAB_WIDTH]: /reference/blockly.blockrendering_namespace.constantprovider_class.tab_width_property +[TAB_HEIGHT]: /reference/blockly.blockrendering_namespace.constantprovider_class.tab_height_property +[path-object]: /guides/create-custom-blocks/renderers/concepts/path-object +[makeNotch]: /reference/blockly.blockrendering_namespace.constantprovider_class.makenotch_1_method +[makePuzzleTab]: /reference/blockly.blockrendering_namespace.constantprovider_class.makepuzzletab_1_method +[connection-check]: /guides/create-custom-blocks/inputs/connection-checks +[shapeFor]: /reference/blockly.blockrendering_namespace.constantprovider_class.shapefor_1_method +[basic-shapes]: #basic-shapes +[custom-input]: /guides/create-custom-blocks/inputs/creating-custom-inputs +[measurable]: /guides/create-custom-blocks/renderers/concepts/overview#block-measurables +[InputConnection]: /reference/blockly.blockrendering_namespace.inputconnection_class +[render-info]: /guides/create-custom-blocks/renderers/concepts/info +[addInput]: /reference/blockly.blockrendering_namespace.renderinfo_class.addinput__1_method +[row]: /guides/create-custom-blocks/renderers/concepts/rows +[shouldStartNewRow]: /reference/blockly.blockrendering_namespace.renderinfo_class.shouldstartnewrow__1_method +[drawer]: /guides/create-custom-blocks/renderers/concepts/drawer +[drawOutline]: /reference/blockly.blockrendering_namespace.drawer_class.drawoutline__1_method +[drawInternals]: /reference/blockly.blockrendering_namespace.drawer_class.drawinternals__1_method +[svg-path]: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths diff --git a/packages/docs/docs/guides/create-custom-blocks/renderers/overview.mdx b/packages/docs/docs/guides/create-custom-blocks/renderers/overview.mdx new file mode 100644 index 00000000000..40cce5d4717 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/renderers/overview.mdx @@ -0,0 +1,50 @@ +--- +description: What a renderer is, built-in renderers, and how to create a custom one. +title: Renderers +image: images/blockly_banner.png +--- + +# Renderers + +The shape of a block is determined by a renderer, based on the +[block's definition][block-definition] (that is, its fields and connections). + +## Built-in renderers + +Blockly provides three built-in renderers, each of which give a slightly +different feel to the program. + +| Renderer | Description | Image | +| -------- | ------------------------------------------------------------------------------------------------------------------- | ------------------- | +| Thrasos | The recommended renderer. It is a more modern take on the geras renderer, with more even spacing and solid borders. | ![thrasos][thrasos] | +| Geras | The default renderer. It is the original renderer that Blockly was built with. | ![geras][geras] | +| Zelos | A renderer based on Scratch-3.0 block design. | ![zelos][zelos] | + +To use one of these renderers, pass the name into the configuration options: + +```js +Blockly.inject('blocklyDiv', { + renderer: 'thrasos', +}); +``` + +## Custom renderers + +If you want to give your program a different look and feel than any of the +built-in renderers, you can also create a custom renderer. To get started the +Blockly team recommends you: + +1. Read through the [renderer concept docs][concept] to learn + how all of the components of a renderer fit together. +2. Complete the [custom renderer codelab][custom-renderer-codelab] to + get hands-on practice with custom rendering. +3. Add the [debug renderer][debug-renderer] to your project. +4. Customize your renderer. + +[block-definition]: /guides/create-custom-blocks/define/block-definitions +[concept]: /guides/create-custom-blocks/renderers/concepts/overview +[custom-renderer-codelab]: /codelabs/custom-renderer/codelab-overview/index.html +[debug-renderer]: https://www.npmjs.com/package/@blockly/dev-tools#debug-renderer +[thrasos]: /images/rendering/renderers/thrasos.png +[geras]: /images/rendering/renderers/geras.png +[zelos]: /images/rendering/renderers/zelos.png diff --git a/packages/docs/docs/guides/create-custom-blocks/variables.mdx b/packages/docs/docs/guides/create-custom-blocks/variables.mdx new file mode 100644 index 00000000000..8b669cf7cc0 --- /dev/null +++ b/packages/docs/docs/guides/create-custom-blocks/variables.mdx @@ -0,0 +1,267 @@ +--- +description: Functionality Blockly provides for modeling variables. +title: Variables +image: images/blockly_banner.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Variables + +Variables are an important programming concept. Blockly supports dynamically +typed languages such as Python and JavaScript and with a little extra work, you +can add information to support strongly typed languages (or static typed +languages) such as Java or C. + +For more information on dynamic versus static typed languages, see [Introduction +to Data Types: Static, Dynamic, Strong & +Weak](https://www.sitepoint.com/typing-versus-dynamic-typing/). + +Blockly supplies variable fields which are dynamic dropdown boxes that show +the names of variables the user has provided. Below is an example of one. + +![A variable field with a dropdown to pick a variable, change the current +variable's name, or delete the current +variable.](/images/variable-dropdown.png) + +By default, Blockly allows any type to be assigned to a variable and all of +Blockly's provided generators are for dynamically typed languages. If you are +using a typed language instead, you can configure Blockly to support it by doing +the following: + +- [Specify a variable type and its blocks](#typed-variable-blocks), including + getters and setters. +- [Configure the toolbox](#add-variables-to-toolbox) to use your variable type + and blocks. +- [Define generators](#define-generators) for variables and their blocks. + +## Untyped Variable Blocks + +The most basic blocks for accessing and manipulating a variable are the getter +and setter blocks. Let's walk through the getter and setter blocks that Blockly +provides. + + + + ```js + // Block for variable getter. + { + "type": "variables_get", + "message0": "%1", + "args0": [ + { // Beginning of the field variable dropdown + "type": "field_variable", + "name": "VAR", // Static name of the field + "variable": "%{BKY_VARIABLES_DEFAULT_NAME}" // Given at runtime + } // End of the field variable dropdown + ], + "output": null, // Null means the return value can be of any type + ... + }, + + // Block for variable setter. + { + "type": "variables_set", + "message0": "%{BKY_VARIABLES_SET}", + "args0": [ + { + "type": "field_variable", + "name": "VAR", + "variable": "%{BKY_VARIABLES_DEFAULT_NAME}" + }, + { + "type": "input_value", // This expects an input of any type + "name": "VALUE" + } + ], + ... + } + ``` + + + ```js + // Block for variable getter. + Blockly.Blocks['variables_get'] = { + init: function() { + this.appendDummyInput() + .appendField(new Blockly.FieldVariable("VAR_NAME"), "FIELD_NAME"); + this.setOutput(true, null); + ... + } + }; + + + // Block for variable setter. + Blockly.Blocks['variables_set'] = { + init: function() { + this.appendValueInput("NAME") + .setCheck(null) + .appendField("set") + .appendField(new Blockly.FieldVariable("VAR_NAME"), "FIELD_NAME") + .appendField("to"); + this.setOutput(true, null); + ... + } + }; + ``` + + +This creates the following two blocks: + +![Getter and setter blocks for the variable +`foo`.](/images/getter-and-setter.png) + +An important detail to notice is that by setting the variable getter's "output" +to null, the return value can be of any type. Also, notice that variable +setter's input does not specify any checks. As a result, the variable can be set +to any type of value. + +## Typed Variable Blocks + +You can add getters and setters that enforce type checking. For example, if you +have created a variable of type `"Panda"`, the following definitions create a +getter and setter with the appropriate types. + + + + ```js + // Block for Panda variable getter. + { + "type": "variables_get_panda", + "message0": "%1", + "args0": [ + { + "type": "field_variable", + "name": "VAR", + "variable": "%{BKY_VARIABLES_DEFAULT_NAME}", + "variableTypes": ["Panda"], // Specifies what types to put in the dropdown + "defaultType": "Panda" + } + ], + "output": "Panda", // Returns a value of "Panda" + ... + }, + + // Block for Panda variable setter. + { + "type": "variables_set_panda", + "message0": "%{BKY_VARIABLES_SET}", + "args0": [ + { + "type": "field_variable", + "name": "VAR", + "variable": "%{BKY_VARIABLES_DEFAULT_NAME}", + "variableTypes": ["Panda"], + "defaultType": "Panda" + }, + { + "type": "input_value", + "name": "VALUE", + "check": "Panda" // Checks that the input value is of type "Panda" + } + ], + "previousStatement": null, + "nextStatement": null, + ... + } + ``` + + + ```js + // Block for Panda variable getter. + Blockly.Blocks['variables_get_panda'] = { + init: function() { + this.appendDummyInput() + .appendField(new Blockly.FieldVariable( + "VAR_NAME", ['Panda'], 'Panda'), "FIELD_NAME"); + this.setOutput(true, 'Panda'); + ... + } + }; + + // Block for Panda variable setter. + Blockly.Blocks['variables_set_panda'] = { + init: function() { + this.appendValueInput("NAME") + .setCheck('Panda') + .appendField("set") + .appendField(new Blockly.FieldVariable( + "VAR_NAME", null, ['Panda'], 'Panda'), "FIELD_NAME") + .appendField("to"); + this.setPreviousStatement(true, null); + this.setNextStatement(true, null); + ... + } + }; + ``` + + +This creates two types of blocks, a getter and a setter. Their dropdowns only +display variables of type `"Panda"`. Their inputs and outputs only accept +connections with type `"Panda"`. The `defaultType` of the field must be set to +one of the values in the `variableTypes` array. Not setting the `defaultType` +while providing a `variableTypes` array will cause an error to be thrown. + +By default there is no visual indicator to tell the user which type is being +used. One easy way to differentiate variable types is by +[colour](/guides/configure/web/appearance/block-colour). + +:::note +The `variableTypes` key is optional on a field_variable. If it is +undefined only variables of the empty string type `""` will be shown. To show +all variables of any type use `"variableTypes": null`. +::: + +## Add Variables to Toolbox + +To make this new type of variable useful to your users, you need to add a way to +create and use the new variables. + +Create a new [dynamic category](/guides/configure/web/toolboxes/dynamic) +for variables if you do not already have one. + +![An open category named "Variables" containing a "Create variable" +button.](/images/variables-category.png) + +Add your new getters and setters to the category. + +![The same category after `foo` and `bar` variables have been created. It +contains a "Create variable" button, set-variable-to and change-variable-by +blocks, and getter blocks.](/images/variables-category-filled.png) + +### Create Variable Button + +Next, your user needs a way to create variables. The simplest way is with a +"Create Variable" [button](/guides/configure/web/toolboxes/buttons). + +When creating the button, make the callback call + +```js +Blockly.Variables.createVariableButtonHandler( + button.getTargetWorkspace(), + null, + 'panda', +); +``` + +and a `"Panda"` typed variable will be created! + +The easiest way to allow users to create variables of multiple types is to have +one "create" button per type (e.g. Create String Variable, Create Number +Variable, Create Panda Variable). + +If you have more than two or three variable types, you can quickly end up with +too many buttons. In that case, consider using +[@blockly/plugin-typed-variable-modal](https://www.npmjs.com/package/@blockly/plugin-typed-variable-modal) +to display a popup from which users can select their desired variable type. + +## Define Generators + +Finally, you will need to [define block-code generators][block-code-generator] +for your new variable blocks. You can also access the list of variables directly +with `Workspace.getVariableMap().getAllVariables()` to get all variables of all +types or `Workspace.getVariableMap().getVariablesOfType()` to get all variables +of a specific type. + +[block-code-generator]: /guides/create-custom-blocks/code-generation/overview#block-code-generators diff --git a/packages/docs/docs/guides/design/app-overview.mdx b/packages/docs/docs/guides/design/app-overview.mdx new file mode 100644 index 00000000000..17077a84ec9 --- /dev/null +++ b/packages/docs/docs/guides/design/app-overview.mdx @@ -0,0 +1,185 @@ +--- +description: Discusses how Blockly is used in applications. +title: Introduction to Blockly applications +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Introduction to Blockly applications + +A Blockly application is a web application that contains a Blockly editor +(workspace). This document gives examples of what Blockly applications are used +for and looks at typical UI features. + +If you haven't already done so, be sure to read the [visual +glossary](/guides/get-started/workspace-anatomy) and [basic application +steps](/guides/get-started/workspace-creation) before continuing with +this document. + +## What do Blockly applications do? + +Blockly applications help users write programs in a variety of fields, from +video games to robotics to data analysis. Users **write their programs using +blocks**, which the application uses to **generate text-based code**, such as +JavaScript or Python. The application then **runs the generated code directly** +or the user **downloads and runs it on another platform**, such as a robot or +hand-held video game controller. + +Here are some examples of the kinds of programs users write with Blockly +applications: + +- **Puzzle solutions, animation, or music:** The generated code solves a + puzzle (like a maze), displays an animation, or plays music. For an example, + see [Code.org's Music Lab](https://studio.code.org/projects/music/new). + +- **Video games:** The generated code runs a video game. For example, create + the first two levels of "Whack the Mole" in [MakeCode + Arcade](https://arcade.makecode.com/) and download the game to a controller + or play it in the simulator. + +- **Robotics:** The generated code directs a robot. For example, program a + robot with [Ozoblockly](https://games.ozoblockly.com/shapetracer-freeform) + and download it to a real robot or run it in the simulator. + +- **Drawing:** The generated code draws a 2D or 3D drawing. For an example, + see [BlocksCAD](https://www.blockscad3d.com/editor/). + +- **Data analysis:** The generated code analyzes data and creates a graph. For + an example, see [this demonstration of the Dialogic + Platform](https://dialogiconderzoek.nl/diadashboard/platform/demo1.gif). + +- **Application-specific code:** The generated code performs a task specific + to a particular application. For example, [Blockly Developer Tools](https://raspberrypifoundation.github.io/blockly-samples/examples/developer-tools/index.html) + is a tool for designing new Blockly blocks. It generates block definition + code, which users copy and paste into their own Blockly application. + +## User interfaces + +A good way to understand the typical components of Blockly applications is to +look at their user interfaces. + +### Basic UI components + +Almost all Blockly applications share a few basic components: a Blockly editor +(workspace), an output panel, and a "Run" button. For example, here is the UI of +the [Maze](https://blockly.games/maze?level=4) in Blockly Games. + +The UI of a maze application with an editor, an output panel, and a Run button. + +A few Blockly applications omit the "Run" button and instead update the output +panel every time the user makes a change. For example, the +[Graph](https://raspberrypifoundation.github.io/blockly-samples/examples/graph-demo/index.html) +application in Blockly's samples has two output panels (one for the graph and +one for the equation) that it updates on every change. + +The UI of a graph application with an editor, an output panel for an equation constructed by the user, and an output panel for a graph of that equation. + +Some applications don't have an output panel. This is most common in hardware +applications, such as those for programming robots. While some of these +applications include a hardware simulator, many of them just let users download +and run the generated code directly on the target device. + +### Additional UI components + +Most applications have additional UI components. Some of these meet general +needs, such as saving the user's work, while others fulfill application-specific +needs, such as designing a GUI. Here are some examples: + +- [Scratch](https://scratch.mit.edu/), an application for creating animations + and video games, has graphics and sound editors; panels to create new + sprites and backdrops; and file, edit, and settings menus: + + The Scratch user interface. + +- [MakeCode Arcade](https://www.microsoft.com/en-us/makecode), an application + for creating video games, has output controls, code and graphics editors, a + settings menu, and download and save buttons. Its output panel simulates a + handheld game controller. + + The MakeCode Arcade user interface. + +- [MIT App Inventor](https://appinventor.mit.edu/), an application for + creating phone apps, has separate screens for its GUI designer and Blockly + editor, as well as file, connection, build, and settings menus. Instead of + an output panel, users test generated code on their phone. + + The GUI designer in the App Inventor user interface + The Blockly editor in the App Inventor user interface + +Which additional components you should include depends on your application's +goals and the abilities of your users. Some common components are: + +- Administration: + - File management (new, open, save, save as, delete) + - Account management (create, login, logout) + - Settings (language, UI configuration) + +- Programming: + - Edit commands (undo, redo, copy, cut, paste, duplicate) + - GUI designer + - Graphics and sound editors + - Code editor or read-only code display + +- Testing + - Output configuration (start/stop, playback speed, volume, screenshot, + etc.) + - Debugger (breakpoints, run, step, block highlighting) + - Set test parameters + +- Hardware + - Connection (USB, Bluetooth, QR code) + - Configuration (choose model, choose accessories, assign component names) + - Control (manually control robot, record robot position) + - Download code + +- Help + - Documentation + - Interactive tutorials + - Context-sensitive help + +## Where do I go from here? + +If you're still thinking about your application, continue reading about [design +considerations](/guides/design/applications). + +If you want to see what it's like to build a simple application, try the +[Getting started with Blockly +codelab](/codelabs/getting-started/codelab-overview/index.html). + +And if you're ready to write your application: + +- [Build your editor](/guides/configure/web/configuration_struct) +- [Build your blocks](/guides/create-custom-blocks/overview) +- [Build your application](/guides/app-integration/run-code) diff --git a/packages/docs/docs/guides/design/appearance.mdx b/packages/docs/docs/guides/design/appearance.mdx new file mode 100644 index 00000000000..b0bb75cd290 --- /dev/null +++ b/packages/docs/docs/guides/design/appearance.mdx @@ -0,0 +1,103 @@ +--- +description: Design considerations for block appearance. +title: Block appearance +image: images/blockly_banner.png +--- + +# Block appearance + +The appearance of blocks provides important clues on how they are to be used. +Here are some things to consider when styling your own blocks. + +## Use visible borders + +In the 2000s the 'Aqua' look was in style and every onscreen object was +decorated with highlighting and shadows. In the 2010s the 'Material Design' look +came into style and every onscreen object was simplified to a clean, flat, +borderless shape. Most block programming environments have highlighting and +shadows around each block, so when today's graphic designers see this they +invariably strip off these outdated decorations. + +![Blocks without visible borders. It is difficult to see where the block +boundaries are.](/images/mistakes02.png) + +As can be seen in the above example of five blocks (from scriptr.io), these +'outdated decorations' are vital for distinguishing connected blocks that are +the same colour. + +_Recommendation: If reskinning Blockly, don't let today's fashions break your +app._ + +## Add directional arrows + +![A block with a circular arrow that shows a right turn is +clockwise.](/images/language05.png) + +Feedback from children in the US (though interestingly not from other nations) +revealed rampant confusion between left and right. This was resolved with the +addition of arrows. If direction is relative (to an avatar, for example) the +style of arrow is important. A → straight arrow or a ↱ turn arrow is confusing +when the avatar is facing the opposite direction. Most helpful is a ⟳ circular +arrow, even in cases where the angle turned is smaller than the arrow indicates. + +_Recommendation: Supplement text with Unicode icons where possible._ + +## Use different horizontal and vertical connectors + +Blockly has two different connection types: the horizontal puzzle shapes and the +vertical stacking notches. A good user interface should strive to minimize the +number of design elements. Accordingly, many designers try to make both +connection types look the same (as shown below). + +![Counterexample showing the same style used for both horizontal and vertical +connectors.](/images/rotate.png) + +The result creates confusion among new users as they search for ways to _rotate_ +blocks so that they can fit into incompatible connections. Blockly makes +programming elements visual and tangible, so one has to be mindful of +inadvertently suggesting user interactions which are not supported. + +Accordingly, Blockly uses a tightly-fitting puzzle shape for value connections, +and a visually distinct alignment notch for statement stacking. + +_Recommendation: If reskinning Blockly, ensure horizontal and vertical +connections look different._ + +## Show that nesting statements can be stacked + +'C'-shaped blocks invariably have a connector on the inside-top, but some +environments also have a connector on the inside bottom (e.g. Wonder Workshop) +whereas others do not (e.g. Blockly and Scratch). Since most statement blocks +have both a top and bottom connector, some users do not immediately see that +statements will fit inside a 'C' that does not have a bottom connector. + +![Blocks with statement inputs, one which has a bottom connector and two which +do not. A green check mark shows that it is easy to see that a statement block +fits in the block with the bottom connector.](/images/mistakes03a.png) + +Once users figure out that one statement block fits inside a 'C', they then need +to figure out that more than one statement will also fit. Some environments nest +the first statement's lower connection into the bottom of the 'C' (e.g. Wonder +Workshop and Scratch) whereas others leave a small gap (e.g. Blockly). Snug +nesting leaves no hint that more blocks can be stacked. + +![Blocks with nested statements. The block without a bottom connector has a gap +between the nested statement and the bottom of the statement input, which shows +that more statement blocks can be added.](/images/mistakes03b.png) + +These two issues interact badly with each other. If an inside bottom connector +exists (Wonder Workshop) then the initial statement's connection is made more +obvious, but at the expense of the ability to discover stacking. If no inside +bottom connector exists (Blockly) then the initial statement's connection is not +obvious, but stacking is discoverable. Having no inside bottom connector and +nesting the statement's bottom connector (Scratch) fared the worst for +discoverability when tested with Blockly. + +Our experience was that the initial statement's connection is a lesser challenge +for users than discovering stacking. And once discovered, the former is never +forgotten, whereas the latter needs prompting. Blockly tried both the Wonder +Workshop and the Scratch approaches until one day a rendering bug occurred which +added the small gap. We saw a marked improvement in user studies with Blockly +due to this bug (now a 'feature' we are proud of). + +_Recommendation: If reskinning Blockly, leave the existing stacking UI._ diff --git a/packages/docs/docs/guides/design/applications.mdx b/packages/docs/docs/guides/design/applications.mdx new file mode 100644 index 00000000000..fc3a8f375e2 --- /dev/null +++ b/packages/docs/docs/guides/design/applications.mdx @@ -0,0 +1,178 @@ +--- +description: Design considerations for Blockly applications +title: Application design +image: images/blockly_banner.png +--- + +# Application design + +There are several paradigms to choose from when designing an application +which uses Blockly. Consideration of these choices should be made +early, since they affect the blocks the user will need. + +## Configuration + +Many Blockly applications are used to describe configurations, rather than +executable programs. Configuration applications typically start by initializing +one root level block on the workspace. A good example is the [Blockly Developer +Tools](https://raspberrypifoundation.github.io/blockly-samples/examples/developer-tools/index.html): + +![A block used to design other blocks. Users can specify the block name, block +inputs, whether inputs are internal or external, and so +on.](/images/configuration.png) + +```js +Blockly.Blocks['factory_base'] = { + init: function () { + this.setDeletable(false); + this.setMovable(false); + this.setEditable(false); + // etc... + }, +}; + +Blockly.serialization.blocks.append({ type: 'factory_base' }, workspace); +``` + +This creates an undeletable, unmovable block that that holds all the +user's configuration. The workspace may be serialized at any time +to determine the current configuration. + +Such applications may wish to automatically disable any block not +connected to the root block. This can be accomplished on the with one line: + +```js +workspace.addChangeListener(Blockly.Events.disableOrphans); +``` + +## Serial program + +The majority of Blockly applications are designed to create serial +programs. Users stack together blocks which are executed in order. + +![A stack of blocks with commands to move, turn left, and move +again.](/images/stack.png) + +Every (non-disabled) block on the workspace will form part of the +program. If there are multiple stacks of blocks, higher ones are +executed first. (If two stacks are approximately the same height, +stacks to the left (right in RTL mode) are given priority.) + +The workspace may be exported to executable code at any time. This code +may be executed client side in JavaScript (using `eval` or the JS +Interpreter), or server side in any language. + +```js +import { javascriptGenerator } from 'blockly/javascript'; + +var code = javascriptGenerator.workspaceToCode(workspace); +``` + +## Parallel program + +Some Blockly applications choose to execute all stacks of blocks in +parallel, rather than serially. An example would be a music application +where a drum loop runs concurrently with a melody. + +One way of implementing parallel execution is to generate the code for each +block individually: + +```js +import { javascriptGenerator } from 'blockly/javascript'; + +var json = Blockly.serialization.workspaces.save(workspace); + +// Store top blocks separately, and remove them from the JSON. +var blocks = json['blocks']['blocks']; +var topBlocks = blocks.slice(); // Create shallow copy. +blocks.length = 0; + +// Load each block into the workspace individually and generate code. +var allCode = []; +var headless = new Blockly.Workspace(); +for (var i = 0; block < topBlocks.length; i++) { + var block = topBlocks[i]; + blocks.push(block); + Blockly.serialization.workspaces.load(json, headless); + allCode.push(javascriptGenerator.workspaceToCode(headless)); + blocks.length = 0; +} +``` + +If the target language is JavaScript, the `allCode` array may then be +used to create multiple JS Interpreters for simultaneous execution. If +the target language is something like Python, then the `allCode` array +may be assembled into a single program that uses a threading module. + +As with any parallel program, careful decisions must be made regarding +any shared resources such as variables and functions. + +## Event driven program + +Event handlers are just functions that get called by the system, rather +than by the program. These blocks can either enclose the stack of +blocks to be executed, or they may be headers that sit on top of a stack +of blocks. + +![Two "on mouse click" blocks, one with a statement input and one with a next +connection.](/images/event1.png) + +Some developers like to add a 'hat' to the top of event blocks so that they look +distinct from other blocks. This is not the default look for Blockly, but it may +be added by either overriding the renderer constant `ADD_START_HATS` to `true` +([Custom renderers codelab - Override +constants](/codelabs/custom-renderer/override-constants/index.html)). +or by adding a theme and setting the hat option on the block style. For more +information for setting hats on blocks as part of themes, see [Block +style](/guides/configure/web/appearance/themes/#block-style) in the themes +documentation. + +![The same "on mouse click" blocks with hats, which form a hump on top of the +block.](/images/event2.png) + +Within an event-driven model, it might make sense to also make a handler +for the program start. Under this model, any block on the workspace not +connected to an event handler would be ignored and would not execute. + +When designing a system that uses events, consider whether it is +possible or desirable to support multiple instances of the same event +handler. + +## Workspace layout + +There are two reasonable ways to layout a screen from left to right. One way +starts with the toolbar on the left, the workspace in the middle, and the output +visualization on the right. This layout is used by version 1 of Scratch, as well +as Made with Code. + +![An application with the toolbar on the left, the workspace in the middle, and +a maze (the output visualization) on the +right.](/images/mistakes08a.png) + +The other way starts with the output visualization on the left, the toolbar in +the middle, and the workspace on the right. This layout is used by version 2 of +Scratch, as well as most Blockly applications. + +![An application with a maze (the output visualization) on the left, the toolbar +in the middle, and the workspace on the right.](/images/mistakes08b.png) + +In either case the workspace should stretch to take up available screen size -- +users need as much room to program as they can get. As can be seen in the +screenshots above, the first layout performs poorly on wide screens since the +user's code and the output visualization are separated. Whereas the second +layout allows for extra space for larger programs while still keeping all three +sections close together. + +It also makes logical sense for users to first consider the problem they are +attempting to solve, then look at the tools that are provided, and only then +start programming. + +Of course the entire order needs to be flipped for Arabic and Hebrew +translations. + +In some cases, such as when using a small number of simple blocks, it may make +sense for the toolbox to be above or below the workspace. Blockly supports +horizontal scrolling in the Toolbox for these cases, but it should be used with +care. + +_Recommendation: Place the program visualization next to the toolbar._ diff --git a/packages/docs/docs/guides/design/blocks.mdx b/packages/docs/docs/guides/design/blocks.mdx new file mode 100644 index 00000000000..b6b33d43b47 --- /dev/null +++ b/packages/docs/docs/guides/design/blocks.mdx @@ -0,0 +1,123 @@ +--- +description: Recommendations for how to design your blocks. +title: Block design +image: images/blockly_banner.png +--- + +# Block design + +Over the years, the Blockly team has designed many of their own blocks and +helped others to design theirs. The following are some of the lessons they have +learned. + +## Prefer high-level blocks + +Wherever possible a higher-level approach should be taken, even if it reduces +execution performance or flexibility. Consider this Apps Script expression: + +```none +SpreadsheetApp.getActiveSheet().getDataRange().getValues() +``` + +Under a 1:1 mapping which preserves all potential capabilities, the above +expression would be built using four blocks. But Blockly aims for a higher-level +and would provide one block that encapsulates the entire expression. The goal is +to optimize for the 95% case, even if it makes the remaining 5% more difficult. +Blockly is not intended to be a replacement for text-based languages, it is +intended to help users get over the initial learning curve so that they can use +text-based languages. + +_Recommendation: Don't blindly convert your entire API into blocks._ + +## Consider user input choices + +![Three repeat blocks showing different ways to input a number: drop-down, +numeric field, and value input.](/images/language03.png) + +There are three ways to obtain a parameter from the user. A dropdown is the most +restrictive and is good for simple tutorials and exercises. An input field +allows for more freedom and is good for more creative activities. A value block +input (usually with a shadow block) offers the opportunity to compute a value +(e.g. a random generator) instead of just being a static value. + +_Recommendation: Choose an input method appropriate to your users._ + +## Use separate conditional and loop blocks + +![Counterexample showing if/then and while blocks in the same +category.](/images/language01.png) + +The most difficult blocks for new users are conditionals and loops. Many +block-based environments group both of these blocks into the same 'Controls' +category, with both blocks having the same shape and the same colour. This often +leads to frustration as new users confuse the two blocks. Blockly recommends +moving conditionals and loops into separate 'Logic' and 'Loops' categories, each +with a different colour. This makes it clear that these are distinct ideas that +behave differently, despite having similar shapes. + +_Recommendation: Keep conditionals and loops separate._ + +## Handle a variable number of inputs + +Certain blocks may require a variable number of inputs. Examples are an +addition block that sums an arbitrary set of numbers, or an if/elseif/else +block with an arbitrary set of elseif clauses, or a list constructor with +an arbitrary number of initialized elements. There are several strategies, +each with its advantages and disadvantages. + +a) The simplest approach is to make the user compose the block out of smaller +blocks. An example would be adding three numbers, by nesting two two-number +addition blocks. Another example would be only providing if/else blocks, +and making the user nest them to create elseif conditions. + +![Nested addition blocks: 1 + (2 + 3).](/images/mutate-compound.png) + +The advantage of this approach is its initial simplicity (both for the user and +the developer). The disadvantage is that in cases where there are a large +number of nestings, code becomes very cumbersome and difficult for the user to +read and maintain. + +b) An alternative is to dynamically expand the block so that there is always one +free input at the end. Likewise, the block deletes the last input if there are +two free inputs at the end. This is the approach that the first version of +App Inventor used. + +![Block that adds four value inputs, the last one of which is +empty.](/images/mutate-extra.png) + +Blocks that grew automatically were disliked by App Inventor's users for a couple +of reasons. First, there was always a free input and the program was never +'complete'. Second, inserting an element in the middle of the stack was +frustrating since it involved disconnecting all elements below the edit and +reconnecting them. That said, if order is not important, and users can be +made comfortable with holes in their program, this is a very convenient option. + +c) To solve the hole problem, some developers add +/- buttons to blocks that +manually add or remove inputs. Open Roberta uses two such buttons to add +or remove inputs from the bottom. Other developers add two buttons at each +row so that insertion and deletion from the middle of the stack may be +accommodated. Others add two up/down buttons at each row so that reordering of +the stack may be accommodated. + +![Block that adds three external value inputs and has plus and minus buttons to +add or remove inputs.](/images/mutate-add-minus.png) + +This strategy is a spectrum of options ranging from just two buttons per block, +through to four buttons per row. At one end is the danger that users aren't able +to perform the actions they need, at the other end the UI is so filled with +buttons that it looks like the bridge of the starship Enterprise. + +d) The most flexible approach is to add a mutator bubble to the block. This +is represented as a single button that opens a configuration dialog for that +block. Elements may be added, deleted, or rearranged at will. + +![Block that adds three value inputs and has a mutator for adding or removing +value inputs.](/images/mutate-bubble.png) + +The disadvantage of this approach is that it mutators are not intuitive for +novice users. Introducing mutators requires some form of instruction. +Blockly-based applications targeting younger children should not use mutators. +Though once learned, they are invaluable for power users. + +_Recommendation: Each strategy has pros and cons, choose what's right for +your users._ diff --git a/packages/docs/docs/guides/design/education.mdx b/packages/docs/docs/guides/design/education.mdx new file mode 100644 index 00000000000..8280ddf3ce9 --- /dev/null +++ b/packages/docs/docs/guides/design/education.mdx @@ -0,0 +1,98 @@ +--- +description: Recommendations for writing education applications. +title: Educational applications +image: images/blockly_banner.png +--- + +# Educational applications + +The Blockly team has many years of experience designing educational +applications. The following are some of the things they have learned that might +help you in designing your own educational application. + +## Prefer free-form to fill-in-the-blank exercises + +Exercises designed to teach a specific concept often provide partial solutions +which the student needs to modify to reach the desired effect. A class of +non-editable, non-movable, non-deletable blocks was created in Blockly to +support this. However, students hated these fill-in-the-blank exercises. +They have no sense of ownership over the solution. + +![As an example of a fill-in-the-blank exercise, a repeat block where the +student must choose the number of repeats from a +drop-down.](/images/mistakes07.png) + +Designing free-form exercises that teach the same concepts is more challenging. +One technique that has proven successful is to use the student's own solution +for one exercise as the starting point for the next exercise. + +_Recommendation: Don't write code for the user._ + +## Use persistent instructions + +[Blockly Games](https://blockly.games/) is specifically designed to be +self-teaching, no teacher or lesson plan needed. To accomplish this, the first +version of Blockly Games had instructions on each level. Most students would not +read them. We reduced them to a single sentence, increased the font size, and +highlighted them in a yellow bubble. Most students would not read them. We +created modal popups with the instructions. Most students instinctively closed +the popups without reading them, then were lost. + +![An unclosable popup instruction with an arrow pointing to the block that +needs to be changed.](/images/mistakes06.png) + +Finally we created popups that cannot be closed. They are programmed to monitor +the student's actions and only close themselves when the student has performed +the required action. These contextually-aware popups are challenging to program, +but quite effective. It was also important for them to be in the field of view +without interfering with the workspace. + +_Recommendation: Instructions should be short and persistent, but not +obnoxious._ + +## Use live block images in help + +![A ternary block with text in Hebrew.](/images/language04.png) + +Documentation for blocks should include images of the blocks it is referring to. +Taking screenshots is easy. But if there are 50 such images, and the application +is translated into 50 languages, suddenly one is maintaining 2,500 static +images. Then the colour scheme changes, and 2,500 images need updating +-- again. + +To extract ourselves from this maintenance nightmare, Blockly Games replaced all +screenshots with instances of Blockly running in readonly mode. The result looks +identical to a picture, but is guaranteed to be up to date. Readonly mode has +made internationalization possible. + +_Recommendation: If you support more than one language, use readonly mode._ + +## Have an exit strategy for students + +Block-based programming is often a starting point for programming. In the +context of teaching computer programming, it is a gateway drug that gets +students addicted, before moving them on to harder things. How long this +block-based programming period should last for students is hotly debated, +but if your goal is to teach programming it should be temporary. + +Given this, block-based programming environments used for teaching programming +must have an off-ramp appropriate to their students. Blockly Games has four +strategies: + +1. All text on the blocks (e.g. "if", "while") is lowercase to match text-based + programming languages. + + ![A while block with parentheses and braces to show JavaScript syntax.](/images/mistakes99.png) + +1. The JavaScript version of the student's code is always displayed after each + level to increase familiarity. +1. In the penultimate game the block text is replaced with actual JavaScript + (as shown to the right). At this point the student is programming in JavaScript. +1. In the ultimate game the blocks editor is replaced with a text editor. + +Block-based programming environments used for teaching programming need to have +a concrete plan for graduating their students. A solid exit strategy also goes +a long way towards placating those who argue that block-based programming isn't +"real programming". + +_Recommendation: Consider the user's end goals and design appropriately._ diff --git a/packages/docs/docs/guides/design/languages.mdx b/packages/docs/docs/guides/design/languages.mdx new file mode 100644 index 00000000000..e5c3f02acdb --- /dev/null +++ b/packages/docs/docs/guides/design/languages.mdx @@ -0,0 +1,128 @@ +--- +description: The differences between block- and text-based languages. +title: Block- vs. text-based languages +image: images/blockly_banner.png +--- + +# Block- vs. text-based languages + +Block-based languages differ from text-based languages in a number of ways, +primarily because they are designed for novice users. Here is a list of things +to consider when designing your own block-based language. + +## Use one-based lists + +![Block that selects the letter at a certain index in a string and which uses 1 +to mean the first letter.](/images/language02.png) + +Novice programmers react badly when they encounter zero-based lists for the +first time. As a result, Blockly follows the lead of Lua and Lambda Moo by +making list and string indexing one-based. + +For more advanced uses of Blockly, zero-based lists are supported to make +transitioning to text easier. For younger or more novice audiences one-based +indexing is still recommended. + +_Recommendation: One is the first number._ + +## Support liberal naming rules + +![Blocks with the case-insensitive variable names location_x (lower case x) and +location_X (upper case X).](/images/mistakes09.png) + +Novice programmers do not expect that `location_X` and `location_x` are +different variables. As a result, Blockly follows the lead of BASIC and HTML by +making variables and functions case-insensitive. Scratch uses a more subtle +approach (as seen to the right) and is case-sensitive for variable names but not +for equality checks. + +Also, Blockly does not require that variables and functions conform to the +typical `[_A-Za-z][_A-Za-z0-9]*` scheme. If one wants to name a variable `List +of zip codes` or `רשימת מיקודים` that is perfectly alright. + +_Recommendation: Ignore case, allow any names._ + +## Make all variables global + +Novice programmers also have difficulties understanding scope. As a result, +Blockly follows the lead of Scratch by making all variables global. The only +down-side of global variables is that recursion is trickier (one has to push and +pop variables onto a list), but that's a programming technique that's beyond the +scope of Blockly's target users. + +_Recommendation: Scope is out of scope, leave it for later._ + +## Consider how to handle optional return values + +Many functions in text-based programming perform an action, then return a value. +This return value may or may not be used. An example is a stack's `pop()` +function. Pop might be called to get and remove the last element, or it might be +called to just remove the last element with the return value being ignored. + +```js +var last = stack.pop(); // Get and remove last element. +stack.pop(); // Just remove last element. +``` + +Block-based languages are generally not good at ignoring a return value. A value +block has to plug into something that accepts the value. There are several +strategies to deal with this problem. + +a) Steer around the problem. Most block-based languages design the language to +avoid these cases. For example, Scratch does not have any blocks that have both +side effects and a return value. + +b) Provide two blocks. If space in the toolbox is not an issue, a simple +solution is to provide two of each of this type of block, one with and one +without a return value. The downside is that this can lead to a confusing +toolbox with lot of nearly identical blocks. + +![A value block that removes and returns the last item in a list and a statement +block that just removes the last item in a last.](/images/return1.png) + +c) Mutate one block. Use a dropdown, checkbox, or other control allowing the +user to choose whether there is a return value or not. The block then changes +shape depending on its options. An example of this can be seen in Blockly's list +access block. + +![Block that changes shape from a value block to a statement block when removing +the last item in a list, depending on whether it also returns that +item.](/images/return3.png) + +d) Eat the value. The first version of App Inventor created a special pipe block +that ate any connected value. Users didn't understand the concept, and the +second version of App Inventor removed the pipe block and instead recommended +that users simply assign the value to a throwaway variable. + +![Blocks showing two different ways to ignore the output of a block. The first +uses a pipe block to "eat" the value and the second sets the value of a variable +named "junk".](/images/return2.png) + +_Recommendation: Each strategy has pros and cons, choose what's right for your +users._ + +## Generate readable code + +Advanced Blockly users should be able to look at the generated code (JavaScript, +Python, PHP, Lua, Dart, etc) and immediately recognize the program they wrote. +This means extra effort needs to be made to keep this machine-generated code +readable. Superfluous parentheses, numeric variables, crushed whitespace and +verbose code templates all get in the way of producing elegant code. Generated +code should include comments and should conform to [Google's style +guides](https://github.com/google/styleguide/blob/gh-pages/README.md). + +_Recommendation: Be proud of your generated code. Show it to the user._ + +## Accept differences between languages + +A side effect of the desire for clean code is that Blockly's behaviour is +largely defined in terms of how the cross-compiled language behaves. The most +common output language is JavaScript, but if Blockly were to cross-compile to a +different language, no unreasonable attempts should be made to preserve the +exact behaviour across both languages. For example, in JavaScript an empty +string is false, whereas in Lua it is true. Defining a single pattern of +behaviour for Blockly's code to execute regardless of the target language would +result in unmaintainable code that looks like it came out of the GWT compiler. + +_Recommendation: Blockly is not a language, allow the existing language to +affect behaviour._ diff --git a/packages/docs/docs/guides/get-started/blocks.mdx b/packages/docs/docs/guides/get-started/blocks.mdx new file mode 100644 index 00000000000..8c9b58e29d8 --- /dev/null +++ b/packages/docs/docs/guides/get-started/blocks.mdx @@ -0,0 +1,72 @@ +--- +description: Basic information about creating a block. +title: Define custom blocks +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +# Define custom blocks + +Blocks are what you use to program. They represent expressions and statements in +text-based programming languages. + +For more information about blocks and their parts, see the +[visual glossary][visual-glossary-blocks]. + +## Block definition + +A block definition specifies the puzzle piece connections and fields on your +block. Most of the look and style of your blocks is specified in other ways. The +string (usually code) your block gets converted to is defined as a [block-code +generator][block-code-generator]. + +The easiest way to define simple blocks is using JSON. + +This code snippet defines a "move forward" block with next and previous +connections, and one field for the distance. + +```js +// Create the definition. +const definitions = Blockly.common.createBlockDefinitionsFromJsonArray([ + { + // The type is like the "class name" for your block. It is used to construct + // new instances. E.g. in the toolbox. + type: 'my_custom_block', + // The message defines the basic text of your block, and where inputs or + // fields will be inserted. + message0: 'move forward %1', + args0: [ + // Each arg is associated with a %# in the message. + // This one gets substituted for %1. + { + // The type specifies the kind of input or field to be inserted. + type: 'field_number', + // The name allows you to reference the field and get its value. + name: 'FIELD_NAME', + }, + ], + // Adds an untyped previous connection to the top of the block. + previousStatement: null, + // Adds an untyped next connection to the bottom of the block. + nextStatement: null, + }, +]); + +// Register the definition. +Blockly.common.defineBlocks(definitions); +``` + +A block for moving forward + +For more information about how to define your blocks and add them to your +toolbox, see [Custom blocks overview][define-blocks]. + +[visual-glossary-blocks]: /guides/get-started/workspace-anatomy#blocks +[block-code-generator]: /guides/get-started/code-generation +[define-blocks]: /guides/create-custom-blocks/overview +[move-forward]: /images/example-blocks/move-forward.png diff --git a/packages/docs/docs/guides/get-started/code-generation.mdx b/packages/docs/docs/guides/get-started/code-generation.mdx new file mode 100644 index 00000000000..20a29e16a4f --- /dev/null +++ b/packages/docs/docs/guides/get-started/code-generation.mdx @@ -0,0 +1,68 @@ +--- +description: Basic information about generating code for blocks. +title: Generate code +image: images/blockly_banner.png +--- + +# Generate code + +Code generation is the process of turning the blocks on a workspace into a +string of code that can be executed. + +Code generation is extremely important, because it is what allows your blocks to +actually _do_ things, like evaluate arithmetic expressions, move a character +through a maze, or configure an online shop! + +Blockly doesn't "run" blocks directly. Instead you generate code strings, and +then execute those. + +## Code generators + +To generate code, you use a code generator instance. + +This code snippet shows how to generate JavaScript code for the blocks in a +workspace: + +```js +// javascriptGenerator is a code generator that makes JavaScript strings. +import { javascriptGenerator } from 'blockly/javascript'; + +const code = javascriptGenerator.workspaceToCode(myWorkspace); +``` + +For more information about the different code generators that Blockly provides +and how to access them, see [Language code generators][code-generator-overview]. + +## Block-code generators + +Each block has an associated block-code generator that defines what code it +generates. A block-code generator has to be defined for each individual language +you want to generate. + +This code snippets defines a JavaScript block-code generator for a "move +forward" block: + +```js +javascriptGenerator.forBlock['my_custom_block'] = function (block, generator) { + const steps = block.getFieldValue('FIELD_NAME'); + // moveForward is a function you would have to define yourself and provide + // within your execution context. + return `moveForward(${steps});\n`; +}; +``` + +For more information about how to define your block-code generators, see +[Block-code generators][block-code-generators]. + +## Execution + +After you've generated the code, you need to figure out how to execute it. +Deciding how to execute it is very application-specific, and outside the scope +of Blockly. + +For more information about ways to execute code, see +[Generate and run code][code-execution]. + +[code-generator-overview]: /guides/create-custom-blocks/code-generation/overview#language-code-generators +[block-code-generators]: /guides/create-custom-blocks/code-generation/overview#block-code-generators +[code-execution]: /guides/create-custom-blocks/code-generation/overview#generate-and-run-code diff --git a/packages/docs/docs/guides/get-started/get-the-code.mdx b/packages/docs/docs/guides/get-started/get-the-code.mdx new file mode 100644 index 00000000000..1f09001d1f6 --- /dev/null +++ b/packages/docs/docs/guides/get-started/get-the-code.mdx @@ -0,0 +1,194 @@ +--- +description: How to get the code to integrate Blockly into your application. +title: Get the code +image: images/blockly_banner.png +--- + +{/* Whenever you update this page update the following as well! */} +{/* https://github.com/RaspberryPiFoundation/blockly/blob/main/scripts/package/README.md */} + +# Get the code + +There are several ways to get the Blockly code, and several ways to load it +once you've gotten it. + +## Create-package script + +Blockly provides a script that bootstraps a starter application, which you can +then modify. It uses common web development tools like [webpack][webpack] and +[eslint][eslint], but doesn't include a framework, like React or Angular. + +This requires you to [install node.js and npm][install-node-npm] before running +the following commands. + +To create an application written in JavaScript in a new `hello-world` directory: + +```shell +npx @blockly/create-package app hello-world +``` + +To create an application written in TypeScript in a new `hello-world` directory: + +```shell +npx @blockly/create-package app hello-world --typescript +``` + +These create a package that [imports package targets][import]. It also uses a +package.json file to manage dependencies, which makes it easy to stay up-to-date +with the latest version of Blockly. + +It also comes with some handy starter scripts, such as one to test the project +locally in a browser: + +```shell +cd hello-world +npm run start +``` + +You can refer to the generated package.json file for other commands. + +## Unpkg + +If you are just playing around with ideas and don't want to bootstrap a full +application, you can load Blockly from unpkg using script tags. + +If you add the following to any HTML page, you can open the HTML directly in a +browser to experiment with Blockly: + +```html + + + + + + + + +``` + +This is not a good long-term solution for acquiring Blockly, because it doesn't +work with bundlers like webpack, but it is good for prototyping and +experimentation. + +## Get the code + +There are several ways which you can get the code to run Blockly. + +The Blockly team recommends requiring Blockly through a package manager (like +[NPM][npm-registry] or [Yarn][yarn-registry]) because: + +- It is easier to stay up to date with changes in Blockly +- It encourages [using plugins][plugins] instead of monkeypatching Blockly + +### NPM + +```shell +npm install blockly --save +``` + +### Yarn + +```shell +yarn add blockly +``` + +### GitHub + +You can also download the compressed code from our +[GitHub releases][github-releases]. However, this requires you to manually +download the code at regular intervals in order to receive the latest updates +and fixes to Blockly. + +:::warning +Github downloads are only provided for convenience for developers who +were previously forking Blockly. If you are a new developer, you should use a +package manager. +::: + +## Load the code + +Once you've gotten the code, there are several ways you can access it from your +code. + +#### Script tags + +```html + + + + + + + + +``` + +When using script tags, you can access imports from the global namespace: + +```js +// Access Blockly. +Blockly.thing; + +// Access the default blocks. +Blockly.libraryBlocks['block_type']; + +// Access the generator. +javascript.javascriptGenerator; +``` + +:::note +When using script tags you cannot have multiple message files because the +messages get applied directly to the `Blockly.Msg` array. +::: + +#### Imports + +:::note +Using imports of our package targets requires you to be using a bundler +(like webpack), since Blockly is packaged as a UMD, rather than an ESM. +::: + +```js +// Import Blockly core. +import * as Blockly from 'blockly/core'; +// Import the default blocks. +import * as libraryBlocks from 'blockly/blocks'; +// Import a generator. +import { javascriptGenerator } from 'blockly/javascript'; +// Import a message file. +import * as En from 'blockly/msg/en'; +``` + +When you import the message files, you also need to apply them. + +```js +Blockly.setLocale(En); +``` + +#### Requires + +```js +// Require Blockly core. +const Blockly = require('blockly/core'); +// Require the default blocks. +const libraryBlocks = require('blockly/blocks'); +// Require a generator. +const { javascriptGenerator } = require('blockly/javascript'); +// Require a message file. +const En = require('blockly/msg/en'); +``` + +When you require the message files, you also need to apply them. + +```js +Blockly.setLocale(En); +``` + +[npm-registry]: https://www.npmjs.com/package/blockly +[yarn-registry]: https://yarnpkg.com/package/blockly +[plugins]: /guides/programming/plugin_overview +[github-releases]: https://github.com/RaspberryPiFoundation/blockly/releases +[install-node-npm]: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm +[webpack]: https://webpack.js.org/guides/ +[eslint]: https://eslint.org/ +[import]: #imports diff --git a/packages/docs/docs/guides/get-started/save-and-load.mdx b/packages/docs/docs/guides/get-started/save-and-load.mdx new file mode 100644 index 00000000000..6d917ad3efb --- /dev/null +++ b/packages/docs/docs/guides/get-started/save-and-load.mdx @@ -0,0 +1,45 @@ +--- +description: Basic information about saving and loading the state of workspaces. +title: Save and load +image: images/blockly_banner.png +--- + +# Save and load + +Serialization is saving the state of your workspace so that it can be loaded +back into the workspace later. You convert all of the data you need to save into +a text-based format for easy storage. + +We recommend serializing your workspace to JSON. + +For more information, see [Serialization][serialization]. + +## Save + +The following code snippet shows how to convert the state of your workspace to +JSON for saving: + +```js +// Serialize the state. +const state = Blockly.serialization.workspaces.save(myWorkspace); + +// Then you save the state, e.g. to local storage. +localStorage.setItem('workspace-state', state); +``` + +## Load + +The following code snippet shows how to load some saved state into a workspace: + +```js +// Get your saved state from somewhere, e.g. local storage. +const state = localStorage.getItem('workspace-state'); + +// Deserialize the state. +Blockly.serialization.workspaces.load(state, myWorkspace); +``` + +This creates all of your saved blocks, variables, and other elements in the +workspace. + +[serialization]: /guides/configure/web/serialization diff --git a/packages/docs/docs/guides/get-started/toolbox.mdx b/packages/docs/docs/guides/get-started/toolbox.mdx new file mode 100644 index 00000000000..0b1873a96d0 --- /dev/null +++ b/packages/docs/docs/guides/get-started/toolbox.mdx @@ -0,0 +1,58 @@ +--- +description: Basic information about creating a toolbox, which allows users to access your blocks. +title: Add a toolbox +image: images/blockly_banner.png +--- + +# Add a toolbox + +The toolbox contains the blocks that you use to program. The blocks can be +dragged onto the workspace. + +For more information about what a toolbox looks like, see the [visual +glossary][visual-glossary-toolbox]. + +## Basic definition + +A toolbox definition specifies what blocks get included in the toolbox, and in +what order. Most of the look and style of your toolbox is specified in other +ways. + +We recommend defining your toolbox using JSON. + +This code snippet defines a flyout toolbox with two blocks: + +```js +const toolbox = { + // There are two kinds of toolboxes. The simpler one is a flyout toolbox. + kind: 'flyoutToolbox', + // The contents is the blocks and other items that exist in your toolbox. + contents: [ + { + kind: 'block', + type: 'controls_if', + }, + { + kind: 'block', + type: 'controls_whileUntil', + }, + // You can add more blocks to this array. + ], +}; + +// The toolbox gets passed to the configuration options during injection. +const workspace = Blockly.inject('blocklyDiv', { toolbox: toolbox }); +``` + +![Toolbox with if-do and repeat-while +blocks.](/images/toolbox-minimal.png) + +For more information about how to define and configure your toolbox, see +[Toolbox overview][toolbox-overview]. + +For more information about injection, see +[Workspace creation][workspace-creation]. + +[visual-glossary-toolbox]: /guides/get-started/workspace-anatomy#toolbox +[toolbox-overview]: /guides/configure/web/toolboxes/toolbox +[workspace-creation]: /guides/get-started/workspace-creation diff --git a/packages/docs/docs/guides/get-started/what-is-blockly.mdx b/packages/docs/docs/guides/get-started/what-is-blockly.mdx new file mode 100644 index 00000000000..df1a1ba34ef --- /dev/null +++ b/packages/docs/docs/guides/get-started/what-is-blockly.mdx @@ -0,0 +1,40 @@ +--- +title: What is Blockly? +description: What the Blockly library is and is not. +image: images/blockly_banner.png +--- + +# What is Blockly? + +Blockly is a web library that lets you add a customizable blocks-based code +editor to your app. The editor uses puzzle-piece like blocks to represent code +concepts like variables, logical expressions, loops, and more. It lets users +program without having to worry about syntax or the intimidation of the command +line. + +:::note +Blockly is for developers, Blockly apps are for learners. If you're here +to use apps rather than build them, try some of the products from [companies +that create Blockly apps][blockly-apps]. +::: + +Breaking it down further, you can think of Blockly in two ways: + +1. Like a fun puzzle-piece UI. +2. Like a fancy string builder. + +You define the puzzle connections and input fields, and then Blockly handles the +complicated rendering, dragging, and connecting of them. + +You define the string (usually code) that gets generated for each block, and +then Blockly handles concatenating whole strings of blocks. What you do with +that result is up to you. You can do anything from solving a maze, to animating +a character, to analyzing some data. For more examples, see the [Introduction to +Blockly applications](/guides/design/app-overview). + +Blockly lets you focus on applying blocks to your domain without worrying about +the details of how blocks work. For more information see +[Why Blockly?][why-blockly] + +[blockly-apps]: https://blockly.com/#learn-with-blockly +[why-blockly]: /guides/get-started/why-blockly diff --git a/packages/docs/docs/guides/get-started/why-blockly.mdx b/packages/docs/docs/guides/get-started/why-blockly.mdx new file mode 100644 index 00000000000..d893e0a3818 --- /dev/null +++ b/packages/docs/docs/guides/get-started/why-blockly.mdx @@ -0,0 +1,64 @@ +--- +description: Why to use Blockly, and alternative solutions. +title: Why Blockly? +image: images/blockly_banner.png +--- + +# Why Blockly? + +Blockly lets you focus on applying blocks to your domain without worrying about +the complexities of how those blocks should be rendered, dragged, or connected. + +It is applicable to a wide range of educational use-cases, such as: + +- Working students toward text-based programming. +- Encouraging computational thinking. +- Exploring other concepts (e.g. physics) computationally. + +As well as many many industry use-cases, such as: + +- Data analysis and cleaning. +- Automation (e.g. in robotics, process workflows, etc). +- Configuration (e.g. in online shops, IoT, etc). + +## Strengths + +Blockly has a number of strengths that make it the most popular option for +building a block-based programming environment. + +- **Availability.** Blockly is published on NPM, so you can require it in + the same way you require any other web dependency. +- **Fully featured.** Blockly comes bundled with common blocks that generate + code in 5 popular programming languages (JavaScript, Python, Lua, Dart, and + PHP). Plus it has a thriving [plugin ecosystem][plugins] that gives you even + more capabilities. +- **Customizability.** Blockly lets you easily define your own blocks, fields, + and inputs. Plus many of its core functionalities can be swapped out for + your own custom ones. +- **Internationalization.** Blockly's core library of blocks comes with + translations in 90+ languages, including right-to-left versions for Arabic + and Hebrew. +- **Open Source.** Raspberry Pi Foundation shares Blockly's technology with everyone so, together, we can educate the next generation of developers. + +## Alternatives + +There are some use cases where it makes sense to use a library other than +Blockly. Here are some other options: + +- [**PXT**][pxt]: This is an editor built on Blockly that powers + [MakeCode][make-code]. It outputs JavaScript exclusively, which enables it + to convert from code to blocks. It also comes bundled with a compiler and a + simulator. +- [**Droplet**][droplet]: This is the editor that powers + [Pencil Code][pencil-code]. It lets you type to create blocks without + dragging, and also supports going from code to blocks. +- [**Node-red**][node-red]: This is a node-based rather than block-based + programming editor, but it fulfills a similar function. It is popular for + wiring together hardware devices, often in industry contexts. + +[plugins]: https://raspberrypifoundation.github.io/blockly-samples/#plugins +[pxt]: https://github.com/Microsoft/pxt +[make-code]: https://makecode.com +[droplet]: https://github.com/PencilCode/droplet +[pencil-code]: https://pencilcode.net/ +[node-red]: https://nodered.org/ diff --git a/packages/docs/docs/guides/get-started/workspace-anatomy.mdx b/packages/docs/docs/guides/get-started/workspace-anatomy.mdx new file mode 100644 index 00000000000..c0e693e1c10 --- /dev/null +++ b/packages/docs/docs/guides/get-started/workspace-anatomy.mdx @@ -0,0 +1,183 @@ +--- +title: Visual glossary +description: The different parts of Blockly and what they look like. +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; + +[workspace]: /guides/configure/web/configuration_struct +[category-toolbox]: /guides/configure/web/toolboxes/category +[flyout-toolbox]: /guides/configure/web/toolboxes/flyout +[shadow-block]: /guides/configure/web/toolboxes/preset#shadow-blocks +[toolbox]: /guides/configure/web/toolboxes/toolbox +[zoom-controls]: /guides/configure/web/zoom +[context-menu]: /guides/configure/web/context-menus +[block]: /guides/create-custom-blocks/overview +[input]: /guides/create-custom-blocks/define/block-anatomy#inputs +[connection]: /guides/create-custom-blocks/define/block-anatomy#connections +[field]: /guides/create-custom-blocks/define/block-anatomy#fields +[icon]: /guides/create-custom-blocks/define/block-anatomy#icons + +# Visual glossary + +Blockly has a lot of vocabulary for its different visual components. This +document breaks down some of the most important ones you need to know to get +started with Blockly. + +## Workspace + +The [workspace][workspace] is the highest level component in Blockly. It +contains all of the other components. This is where you do the work of +programming! + +A workspace with a category toolbox, scroll bars, trashcan, and zoom controls. + +### Toolbox + +The [toolbox][toolbox] contains the blocks that you use to program. The blocks +can be dragged onto the workspace. + +There are two main types of toolboxes, flyout toolboxes and category toolboxes. +These can both be displayed vertically and horizontally. + +#### Flyout toolbox + +[Flyout toolboxes][flyout-toolbox] (aka simple toolboxes) have one set of blocks +which is displayed at all times. + +A workspace with a flyout toolbox containing four blocks. + +#### Category toolbox + +[Category toolboxes][category-toolbox] have multiple sets of blocks. + +A workspace with a category toolbox with eight categories (Logic, Loops, Math, etc.). No blocks are visible because no categories have been opened. + +If you click a category item it opens a flyout that displays the blocks in the +category. + +![The same workspace and category toolbox as in the previous image, except that the Logic category is open, showing seven logic blocks (if-do, comparison, and-or, etc.).](/images/glossary/category-with-flyout-toolbox.png) + +### Trashcan + +The trashcan lets you delete blocks by dragging and dropping them. You can also +click the trashcan to open a flyout containing the blocks you've deleted so you +can get them back. + +![A workspace with a trashcan in the lower right corner.](/images/glossary/trashcan.png) + +### Zoom controls + +The [zoom controls][zoom-controls] zoom the workspace in and out when you click +them. + +![A workspace with zoom controls above the trashcan.](/images/glossary/zoom-controls.png) + +### Context menu + +The [context menu][context-menu] appears when you right-click or long-press on +certain elements of the workspace (for example, the workspace background, or +blocks). It displays a list of actions you can perform on that element. + +![A context menu is open over an if-do block. The menu has the items, "Duplicate", "Add Comments", "Inline Inputs", "Collapse Block", "Disable Block", "Delete Block", and "Help".](/images/glossary/context-menu.png) + +## Blocks + +[Blocks][block] are what you use to program. They represent expressions and +statements in text-based programming languages. + +![An if-do block, a number block, and a block for creating a list.](/images/glossary/blocks.png) + +### Block stack + +A block stack is any collection of connected blocks. They could be connected +horizontally or vertically. + +![An if-do block with two blocks connected to it. A numeric comparison block is connected to the if input and a repeat block is connected to the do input.](/images/glossary/block-stack.png) + +### Shadow block + +A [shadow block][shadow-block] is an editable but non-movable block connected to +another block. You can drag non-shadow blocks on top of shadow blocks to +overwrite them. + +A block for rounding numbers connected to a shadow number block, and a print block connected to a shadow text block. The shadow blocks are greyed out to show that they are default blocks and that you can drag other blocks on top of them. + +### Insertion marker + +An insertion marker is a preview of where a stack of blocks will be connected if +it is dropped. It looks like a grey version of a block. + +![An if-do block with a marker showing where another block will be inserted.](/images/glossary/insertion-marker.png) + +## Block parts + +Blocks have several different parts that you can edit and interact with to +program. + +### Fields + +A [field][field] is a visual element that lives on a block. It could be editable +(like a text input), or only informational (like a label). A field is always +contained by an [input](#inputs). + +![A block with three fields: the label "repeat", a dropdown with the "while" option chosen, and the label "do".](/images/glossary/fields.png) + +### Connections + +A [connection][connection] is a place on a block other blocks can connect to. + +| Connection | Image | +| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| Output | an output connection | +| Input | an input connection | +| Previous | a previous connection | +| Next | a next connection | + +### Inputs + +An [input][input] is a container for fields and connections. A block +is built by rendering its inputs in one or more rows like bricks. + +Block built from a value input, an end-of-row input, and a statement input. + +All inputs can contain fields. Only value and statement inputs can contain a +connection. + +| Input type | Connection type | Notes | +| ---------- | --------------- | ------------------------------------- | +| Dummy | None | | +| End-of-row | None | Forces next input to start a new row. | +| Value | Input | | +| Statement | Next | | + +### Icons + +An [icon][icon] is a visual element that lives on a block. They always live +in the top-start corner of the block, and they often create bubbles. + +![An if-do block with a mutator icon and a comment icons.](/images/glossary/icons.png) + +![The same block with the mutator and comment bubbles open. The mutator bubble lets you add else clauses to the block and the comment bubble lets you enter a comment about the block.](/images/bubbles/bubbles.png) diff --git a/packages/docs/docs/guides/get-started/workspace-creation.mdx b/packages/docs/docs/guides/get-started/workspace-creation.mdx new file mode 100644 index 00000000000..b33acb1e566 --- /dev/null +++ b/packages/docs/docs/guides/get-started/workspace-creation.mdx @@ -0,0 +1,63 @@ +--- +description: How to create a Blockly workspace. +title: Create a workspace +image: images/blockly_banner.png +--- + +# Create a workspace + +A Blockly workspace is the highest level component of Blockly. It is the UI that +you use to program with blocks. + +For more information about the workspace and its subcomponents, see the [visual +glossary][visual-glossary]. + +## Injection div + +A Blockly workspace must be _injected_ into a `
`, called the "injection +div". + +The injection `div` can be sized [statically][fixed-demo] or +[dynamically][resizable-demo]. Blockly elements within the `div` update their +size when the window resizes. + +The following code snippet shows the HTML for a statically sized injection +`div`: + +```html +
+``` + +## Injection + +Injection creates all of the HTML sub-elements that make up the UI of a +workspace. It also does all of the initialization needed to get the workspace +ready for use. + +The injection function can take in the ID of the injection `div`, or the +injection `div` itself: + +```js +// Passes the ID. +const workspace = Blockly.inject('blocklyDiv', { + /* config */ +}); + +// Passes the injection div. +const workspace = Blockly.inject(document.getElementById('blocklyDiv'), { + /* config */ +}); +``` + +## Configuration + +The workspace can be configured with numerous options (such as layout and style) +during injection. + +For more information about configuration options, see +[Configuration options][config-options]. + +[visual-glossary]: /guides/get-started/workspace-anatomy +[config-options]: /guides/configure/web/configuration_struct#the-options-dictionary +[fixed-demo]: https://raspberrypifoundation.github.io/blockly-samples/examples/fixed-demo/index.html +[resizable-demo]: https://raspberrypifoundation.github.io/blockly-samples/examples/resizable-demo/index.html diff --git a/packages/docs/docs/guides/programming/forking_blockly.mdx b/packages/docs/docs/guides/programming/forking_blockly.mdx new file mode 100644 index 00000000000..5a1ba6af593 --- /dev/null +++ b/packages/docs/docs/guides/programming/forking_blockly.mdx @@ -0,0 +1,59 @@ +--- +title: Fork Blockly +description: Why not to fork Blockly, and alternatives to it.. +image: images/blockly_banner.png +--- + +# Fork Blockly + +Forking is a common way to modify an open source project to make it your own. +There are many successful forks of Blockly, including pxt-blockly, +scratch-blocks, and App Inventor. + +However, forking Blockly can make it difficult for you to pull in updates and +bugfixes in core Blockly. We strongly recommend that you customize Blockly using +plugins and custom classes instead of by forking. + +For more information, see +[Plugins](/guides/programming/plugin_overview) and [Advanced +customization](/guides/configure/web/customization). + +## Alternatives + +### Ask on the forum + +Someone else may have implemented the behaviour you want. Search the forum for +previous discussions, or post and ask if anyone else has already written that +code. + +### Use an existing plugin + +If your change is a commonly requested feature, we may already have published it +as a plugin on blockly-samples. + +### Write a plugin + +Write code that uses Blockly's publicly available APIs to make the change you +need. For instance, changes to block rendering, toolbox appearance, and +connection checking behaviour can all be implemented as plugins. + +### File a feature request + +If you need an API that isn't public, you can [file a +bug](https://github.com/RaspberryPiFoundation/blockly/issues) against core Blockly +to make that API public. + +### Make a pull request + +Blockly welcomes contributions! If your change is general-purpose, your best bet +may be to make a pull request. Blockly improves, you don't have to maintain a +fork, and everyone wins. + +Check out the [contributing](/guides/contribute/index) page to learn +more. + +## Updating a fork + +We recommend that you merge in the latest version of Blockly on a regular basis. +We publish Blockly quarterly, and each release includes release notes and a +discussion of any breaking changes. diff --git a/packages/docs/docs/guides/programming/plugin_overview.mdx b/packages/docs/docs/guides/programming/plugin_overview.mdx new file mode 100644 index 00000000000..6885af3cfbd --- /dev/null +++ b/packages/docs/docs/guides/programming/plugin_overview.mdx @@ -0,0 +1,177 @@ +--- +description: Plugins, their types, and how to use them. +title: Plugins +image: images/blockly_banner.png +--- + +import Image from '@site/src/components/Image'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Plugins + +A plugin is a self-contained piece of code that adds functionality to Blockly. +For example, it might add a custom field, define a new theme, or provide a +custom renderer. Plugins are generally packaged and distributed through npm. + +:::note +The [`BlocklyOptions` +object](/guides/configure/web/configuration_struct#the-options-dictionary) +has a `plugins` property for injecting classes that [customize Blockly +behavior](/guides/configure/web/customization). While these classes may +be implemented as plugins, this is not required and they are otherwise +unrelated. +::: + +For a quick introduction to plugins, see our [Plugins Overview talk +(2021)](https://www.youtube.com/watch?v=rg-V0w7UZFc&list=PLSIUOFhnxEiCjoIwJ0jAdwpTZET73CK7d&index=3). + +If you want to create your own plugin, see [Add a +plugin](/guides/contribute/samples/add_a_plugin). + +## First- and third-party plugins + +_First-party plugins_ are supported by the Blockly team and published under the +`@blockly` scope on npm. They are designed to be usable in a wide range of +Blockly applications. + +_Third-party plugins_ are maintained and published independently. They may be +more complex, more experimental, or targeted to a narrower range of Blockly +applications. + +## Find a plugin + +* Visit [Blockly Plugins & + Demos](https://raspberrypifoundation.github.io/blockly-samples/#plugins), which has live + demos of first-party plugins. + +* Search npm for + [`keyword:blockly-plugin`](https://www.npmjs.com/search?q=keyword%3Ablockly-plugin). + Plugins with the scope `@blockly` are published by the Blockly team. For + broader results, search for + [`keyword:blockly`](https://www.npmjs.com/search?q=keyword%3Ablockly) or + [`blockly`](https://www.npmjs.com/search?q=blockly). + +* See the [`blockly-samples/plugins` + directory](https://github.com/RaspberryPiFoundation/blockly-samples/tree/main/plugins) on + GitHub, which is the repository for first-party plugins. Each plugin has a + README that describes its behaviour and intended use. + +## Install a plugin + +We recommend installing plugins with a package manager like npm or yarn. This +makes it easy to receive updates. + +* **Install a plugin with a package manager** + + + ```shell + npm install @blockly/field-angle + ``` + + + ```shell + yarn add @blockly/field-angle + ``` + + +* **Install a plugin without a package manager** + + + ```html + + ``` + + You can also clone the GitHub repository that contains the plugin. For + first-party plugins, this is + [`blockly-samples`](https://github.com/RaspberryPiFoundation/blockly-samples/tree/main). + + + +Check the plugin's README to see if there are any additional installation +instructions. + +## Use a plugin + +Each plugin is different, so see the plugin's README for information on how to +use that plugin. The following example shows how to use the +[`@blockly/field-angle` +plugin](https://www.npmjs.com/package/@blockly/field-angle): + +1. Import code from the plugin. How you do this depends on how you installed + the plugin. + + + ```js + import Blockly from 'blockly'; + import {registerFieldAngle} from '@blockly/field-angle'; + ``` + + + You do not need to use an `import` statement. + + + ```js + import {registerFieldAngle} from 'path/to/plugin'; + ``` + + +1. Initialize the plugin as needed. Plugins that provide custom fields often + require you to register the field: + + ```js + registerFieldAngle(); + ``` + +1. Use the plugin. + + ```js + Blockly.common.defineBlocksWithJsonArray([ + { + type: "my_angle_block", + message0: "%1 degrees", + args0: [ + { + // Use @blockly/field-angle. + type: "field_angle", + name: "FIELDNAME", + value: 45, + }, + ], + output: null, + style: 'math_blocks' + }, + ]); + ``` + + A field for picking an angle from a 360-degree dial. + +## Plugin versions + +Plugins in `blockly-samples` use [semantic versioning](https://semver.org), +which requires breaking changes to use a new major version. Any new plugin that +monkey patches core will have a major version of 0 to [signify initial +development](https://semver.org/#spec-item-4). + +Most plugins include the `blockly` package as a +[`peerDependency`](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#peerdependencies) +rather than a `dependency`. This is because we assume that you have already +installed Blockly. (It doesn't make sense to use a plugin without using +Blockly.) This lets you manage the Blockly version yourself, but also requires +you to check the plugin's `package.json` to determine the minimum version of +Blockly it requires. If a plugin is updated to need a newer version of Blockly, +this is considered a breaking change and its major version will be increased. + +When you add a plugin to your application's `package.json`, the default is to +include a caret before the version: + +```json +"dependencies": { + "@blockly/field-angle": "^5.0.12" +} +``` + +This will let npm install any minor version at or above the listed version, so +version `5.0.20` or `5.1.0` works, but a new major version such as `6.0.1` does +not. When you update to a new version of Blockly, it's a good idea to check if +any of your plugins can be updated to a new major version as well. diff --git a/packages/docs/docs/guides/programming/unforking_blockly.mdx b/packages/docs/docs/guides/programming/unforking_blockly.mdx new file mode 100644 index 00000000000..b757b2d2c46 --- /dev/null +++ b/packages/docs/docs/guides/programming/unforking_blockly.mdx @@ -0,0 +1,92 @@ +--- +description: How to unfork Blockly +title: Unfork Blockly +image: images/blockly_banner.png +--- + +# Unfork Blockly + +This document is aimed at developers that have previously forked Blockly and are +looking to update to a recent release of Blockly, without patching the library. +Although this seems like a daunting task, there are a few steps that you can +take to make the process more manageable. + +## Understand Unforking + +Using mainline Blockly means you are using a recently released version of +Blockly, and all of your customizations use public Blockly APIs without +monkeypatching. Unforking is the work you need to do to implement your fork's +custom functionality with mainline APIs. + +## Simple Unforking Cases + +Below are two common reasons you might have forked, and solutions for how to +return to mainline: + +- **You created your own blocks and generators without changing any Blockly + code**: To unfork in this situation, you can simply move your custom blocks + and generators out of the Blockly repository and into your own application's + code. You should then be able to then update your Blockly version. +- **You added custom functionality on the Blockly namespace without changing + any Blockly code**: For example, you added custom fields or helper methods + only used by your own application. To unfork in this situation, move this + custom code to your own application outside of the Blockly repository. You + should then be able to then update your Blockly version. + +## Extensive Unforking Case + +### Determine forked functionality + +The final reason we see users fork is to patch Blockly to create custom +functionality that they perceive isn't included upstream at the time. If your +fork is significantly out of date, we may have already added the functionality +you need, either as [plugins](/guides/programming/plugin_overview) or in +core. Knowing what features you added in your fork can provide a roadmap for +what features you will need to update. + +### Understand the architecture + +Once you understand the features that use fork-specific APIs, consider: + +- For each feature using the fork, is there a way to replicate it using + Blockly APIs? +- If it seems as though you can't replicate the feature using Blockly APIs, + please reach out to us through the forum or file an issue on + [GitHub](https://github.com/RaspberryPiFoundation/blockly/issues). Our team will + then investigate adding APIs to enable your customization. + +### Determine your unforking path + +The next step is to actually begin the process of implementing the new Blockly +based architecture for features using the fork. There are two main approaches +you can take: + +- **Upgrade Blockly and see what breaks**: You will immediately see the areas + in your code that need to be updated. You can use this combined with what + you already know is custom behavior to guide your development. +- **Refactor your code to separate your features from Blockly**: This requires + you to gain a deep understanding of which features are custom to your fork + and which came from Blockly. Once your code is fully separated, replace your + old version of Blockly with the most recent version, then fix any remaining + integration issues. + +## Moving Forward + +Here are a few rules that you should follow as a Blockly developer in the +future: + +- In general, you shouldn't add new classes to the Blockly namespace. You can + register [custom + fields](/guides/create-custom-blocks/fields/customizing-fields/creating) + or other registrable classes without declaring them inside of the Blockly + repository or on the Blockly namespace. +- You shouldn't rely on Blockly's build tools in order to compile your own + application. We don't consider our build tools to be part of the public API, + so we may make changes to them which break your application. You are + responsible for compiling your application should you wish to do so. + +## Reach Out + +The Blockly team is available through the [Blockly +Forum](https://groups.google.com/g/blockly)! If you run into any issues during +the unforking process feel free to post them there and we can help. diff --git a/packages/docs/docs/guides/programming/using_blockly_apis.mdx b/packages/docs/docs/guides/programming/using_blockly_apis.mdx new file mode 100644 index 00000000000..5c588f51edb --- /dev/null +++ b/packages/docs/docs/guides/programming/using_blockly_apis.mdx @@ -0,0 +1,171 @@ +--- +description: Understanding the visibility of Blockly's APIs. +title: API visibility +image: images/blockly_banner.png +--- + +# API visibility + +This page describes best practices for calling functions and accessing +properties in core Blockly. These principles apply to creating +[plugins](/guides/programming/plugin_overview) for Blockly and to +integrating Blockly into a standalone application. + +## Visibility \{#visibility\} + +We use [TypeScript access +modifiers](https://www.typescriptlang.org/docs/handbook/2/classes.html#member-visibility) +to mark visibility in the core library as `public`, `private`, or `protected`. +Some properties may be annotated with `@internal` in their +[TsDoc](https://api-extractor.com/pages/tsdoc/tag_internal/) comments. + +All `public` and `protected` properties are documented in the +[References](/reference/blockly) section of the Blockly website. You +can also check visibility by reading the code. + +:::warning +While JavaScript does not enforce these visibility annotations, you +should avoid accessing anything that is not `public`. The Blockly team does not +guarantee stability of non-public properties and functions between releases. +::: + +### public \{#annotations-public\} + +Anything marked `public` is part of our public API. Any property in a module +that does not have a visibility modifier is considered public. + +We try to not change our public API frequently or without good reason and +warning. The exception: we may make a new API public in one release and modify +it in the next release in response to early feedback. After that you may +consider a public function or property stable. + +Public functions may be called from anywhere, and overridden in subclasses as +long as the signature does not change. + +### protected \{#annotations-protected\} + +Protected functions and properties may only be accessed by the defining class or +a subclass. + +Subclasses are allowed to override protected functions and properties, without +changing type signatures. + +For instance, a custom renderer that extends the base renderer class may access +its protected properties. + +In each case you should make sure you understand how the function or property is +used in the rest of the code. + +### private \{#annotations-private\} + +These can only be accessed by code in the same file as the definition. Directly +accessing these properties may result in undefined behaviour. + +Subclasses are not allowed to override private functions and properties. + +Private properties are subject to change without warning, as they are not +considered part of Blockly's public API. + +Some functions in Blockly do not have visibility annotations because they are +not exported from their module. These functions are essentially local variables +and cannot be used outside of their defining module. They should be considered +equivalent to private properties. + +:::note +Previously, Blockly used an underscore to denote private properties: +`example_`. In keeping with the current Google style guide, we no longer do this +in new code, and may change old code. Before calling a method in Blockly, ensure +that it appears in the reference documentation or is not marked private in the +code. In rare cases private functions were used so widely that they became +public, so you may see public functions that end in an underscore. +::: + +### internal \{#annotations-internal\} + +Internal functions and properties are intended to be used within the core +library, but not externally. They are designated with the TsDoc `@internal` +annotation. + +Internal properties are subject to change without warning, as they are not +considered part of Blockly's public API. + +Internal properties may be accessed from anywhere within core, and overridden in +subclasses in core as long as the signature does not change. They must not be +accessed from outside of the core library. + +### deprecated \{#annotations-deprecated\} + +Anything marked `@deprecated` should not be used. Most deprecations include +directions on the preferred code, either in a console warning or TSDoc. + +Where possible, deprecated functions will log a warning that includes the +intended deletion date and a recommendation for a replacement function to call. + +## FAQs + +The following are some common questions the Blockly team has encountered. + +### What if the function I want to use isn't public? + +File a [feature +request](https://github.com/RaspberryPiFoundation/blockly/issues/new?assignees=&labels=issue%3A+feature+request%2C+issue%3A+triage&template=feature_request.yaml) +on core Blockly. Include a description of your use case and a statement of what +you would like us to make public. + +We will use the feature to request to discuss whether to make it public, or +whether there are other ways for you to get the same information. + +If we decide to make it public, either you or the Blockly team will make the +appropriate change, and it will go live in the next Blockly release. + +If you choose to use a non-public member in a plugin, consider marking your +plugin as a beta and include the information in your `README`. + +### What about monkeypatching? + +_Read up on +[monkeypatching](https://en.wikipedia.org/wiki/Monkey_patch#Applications)._ + +Monkeypatching is unsafe, because patches could stop working without notice due +to using non-public pieces of the Blockly API. Patching in a plugin is +especially dangerous, because your code may interact poorly with any other +plugin that monkeypatches the same code. For this reason we **strongly** +recommend against monkeypatching in applications and third party plugins, and +will not accept it in first party plugins. + +### Can I override public functions? + +When subclassing: yes. Otherwise: no, that's monkeypatching. + +### Can I override protected functions? + +When subclassing: yes. Otherwise: no, that's monkeypatching. + +### Can I override internal or private functions? + +No, that's monkeypatching. + +### When can I access properties directly? When should I use a getter or a setter? + +If we publish a getter or a setter, please use that instead of directly +accessing the property. If the property is not public, definitely use getters +and setters. + +:::note +Consistent usage of getters and setters in plugins gives us flexibility to +make changes in core Blockly without breaking published code. +::: + +### What if a property doesn't have an annotation? + +By default it's public, but please drop us a line in case we want to put a +getter/setter pair in place for you. + +### What if a function doesn't have an annotation? + +It's public by default. + +### What if I'm still not sure? + +Ask a question on the [forum](https://groups.google.com/g/blockly) and we'll get +back to you within a few days. diff --git a/packages/docs/docs/publications/publications/publications.mdx b/packages/docs/docs/publications/publications/publications.mdx new file mode 100644 index 00000000000..e48e95cc2bc --- /dev/null +++ b/packages/docs/docs/publications/publications/publications.mdx @@ -0,0 +1,26 @@ +--- +title: Publications +description: Publications related to Blockly +--- + +# Publications by the Blockly team + +## Tips for Creating a Block Language with Blockly + +E. Pasternak, R. Fenichel and A. N. Marshall, "Tips for creating a block language with blockly," 2017 IEEE Blocks and Beyond Workshop (B&B), Raleigh, NC, USA, 2017, pp. 21-24. + +**Abstract**: Blockly is an open source library that makes it easy to add block based visual programming to an app. It is designed to be flexible and supports a large set of features for different applications. It has been used for programming animated characters on a screen; creating story scripts; controlling robots; and even generating legal documents. But Blockly is not itself a language; developers who use Blockly create their own block languages. When developers create an app using Blockly, they should carefully consider the style, which blocks to use, and what APIs and language features are right for their audience. + +**Publication link**: [http://ieeexplore.ieee.org/document/8120404/](http://ieeexplore.ieee.org/document/8120404/) + +[**Full PDF**](/publications/papers/TipsForCreatingABlockLanguage.pdf) + +## Ten things we've learned from Blockly + +N. Fraser, "Ten things we've learned from Blockly," 2015 IEEE Blocks and Beyond Workshop (Blocks and Beyond), Atlanta, GA, 2015, pp. 49-50. + +**Abstract**: Over the last four years the Blockly team has learned many lessons which are applicable to block-based programming in general. The following are a collection of ten mistakes we have made, or mistakes commonly made by others. Each issue is presented as noncontroversial folk knowledge without supporting data. + +**Publication link**: http://ieeexplore.ieee.org/document/7369000/ + +[**Full PDF**](/publications/papers/TenThingsWeveLearnedFromBlockly.pdf) diff --git a/packages/docs/docusaurus.config.js b/packages/docs/docusaurus.config.js new file mode 100644 index 00000000000..d49f1ace88c --- /dev/null +++ b/packages/docs/docusaurus.config.js @@ -0,0 +1,250 @@ +// @ts-check +// `@type` JSDoc annotations allow editor autocompletion and type checking +// (when paired with `@ts-check`). + +import { themes as prismThemes } from 'prism-react-renderer'; + +/** @type {import('@docusaurus/types').Config} */ +const config = { + title: 'Blockly Docs', + favicon: 'images/favicon.svg', + + future: { + v4: true, + }, + + url: 'https://raspberrypifoundation.github.io', + baseUrl: process.env.BASE_URL || '/docs/', + + // GitHub pages deployment config + organizationName: 'RaspberryPiFoundation', + projectName: 'blockly', + + onBrokenLinks: 'warn', + //onBrokenMarkdownLinks: 'warn', + + markdown: { + format: 'detect', + hooks: { + onBrokenMarkdownLinks: 'warn', + }, + }, + + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, + + plugins: [ + [ + '@docusaurus/plugin-client-redirects', + { + fromExtensions: ['md', 'mdx'], + createRedirects(existingPath) { + if (existingPath.startsWith('/reference/')) { + return [existingPath.replace('/reference/', '/reference/js/')]; + } + return undefined; + }, + }, + ], + ], + + presets: [ + [ + 'classic', + /** @type {import('@docusaurus/preset-classic').Options} */ + ({ + docs: { + routeBasePath: '/', + sidebarPath: './sidebars.js', + showLastUpdateTime: true, + editUrl: + 'https://github.com/RaspberryPiFoundation/blockly/tree/main/packages/docs', + }, + blog: false, + theme: { + customCss: './src/css/custom.css', + }, + // Passed to @docusaurus/plugin-google-tag-manager + googleTagManager: { + containerId: 'GTM-NSSCB6XT', + }, + }), + ], + ], + + themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + image: 'images/blockly_banner.png', + navbar: { + title: 'Blockly', + logo: { + alt: 'Blockly Logo', + src: 'images/logo.svg', + srcDark: 'images/blockly-dark-theme-logo.png', + }, + items: [ + { + type: 'dropdown', + label: 'Guides', + position: 'left', + items: [ + { + label: 'Get started', + to: 'guides/get-started/what-is-blockly', + }, + { + label: 'Design considerations', + to: 'guides/design/app-overview', + }, + { + label: 'Programming considerations', + to: 'guides/programming/using_blockly_apis', + }, + { + label: 'Build your editor', + to: 'guides/configure/web/configuration_struct', + }, + { + label: 'Build your blocks', + to: 'guides/create-custom-blocks/overview', + }, + { + label: 'Build your application', + to: 'guides/app-integration/run-code', + }, + { + label: 'Contribute to Blockly', + to: 'guides/contribute/index', + }, + ], + }, + { + type: 'docSidebar', + label: 'Reference', + sidebarId: 'referenceSidebar', + position: 'left', + }, + { + type: 'docSidebar', + label: 'Codelabs', + sidebarId: 'codelabsSidebar', + position: 'left', + }, + { + label: 'Samples', + href: 'https://raspberrypifoundation.github.io/blockly-samples/', + position: 'right', + }, + { + label: 'GitHub', + href: 'https://github.com/raspberrypifoundation/blockly', + position: 'right', + }, + ], + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + additionalLanguages: ['bash', 'typescript'], + }, + algolia: { + appId: 'JOPASJ603L', + apiKey: '9a6e9f24a807a1571990048ef66c9438', // safe to expose + indexName: 'Docusaurus_Website', + contextualSearch: true, + searchParameters: {}, + searchPagePath: 'search', + askAi: { + indexName: 'markdown-index', + apiKey: '9a6e9f24a807a1571990048ef66c9438', + appId: 'JOPASJ603L', + assistantId: '0JvuvoDNFavC', + }, + }, + docs: { + sidebar: { + hideable: true, + autoCollapseCategories: true, + }, + }, + footer: { + copyright: + 'Blockly is an open source project of the Raspberry Pi Foundation, a UK registered charity (1129409), supported by Google.', + links: [ + { + title: 'Docs', + items: [ + { + label: 'Guides', + to: '/guides/get-started/what-is-blockly', + }, + { + label: 'Reference', + to: '/reference', + }, + ], + }, + { + title: 'Learn', + items: [ + { + label: 'Codelabs', + to: '/codelabs/index', + }, + { + label: 'Samples and Demos', + to: 'https://raspberrypifoundation.github.io/blockly-samples/', + }, + ], + }, + { + title: 'Community', + items: [ + { + label: 'Community Forum', + to: 'https://groups.google.com/g/blockly', + }, + { + label: 'Blockly Summit', + to: 'http://www.blocklysummit.com', + }, + { + label: 'YouTube', + to: 'https://www.youtube.com/@blocklydev', + }, + { + label: 'Report Issue', + to: 'https://github.com/RaspberryPiFoundation/blockly/issues', + }, + ], + }, + { + title: 'About', + items: [ + { + label: 'Team', + to: 'http://blockly.com/team', + }, + { + label: 'Contact', + to: 'mailto:support@blockly.com', + }, + { + label: 'Privacy', + to: 'https://www.raspberrypi.org/privacy/', + }, + { + label: 'Cookies', + to: 'https://www.raspberrypi.org/cookies/', + }, + ], + }, + ], + }, + }), +}; + +export default config; diff --git a/packages/docs/eslint.config.mjs b/packages/docs/eslint.config.mjs new file mode 100644 index 00000000000..33fee652aac --- /dev/null +++ b/packages/docs/eslint.config.mjs @@ -0,0 +1,30 @@ +import * as mdx from 'eslint-plugin-mdx'; + +export default [ + { + ...mdx.flat, + files: ['**/*.mdx'], + rules: { + ...mdx.flat.rules, + 'mdx/remark': 'off', + }, + }, + { + ...mdx.flat, + files: ['**/*.md'], + ...mdx.flatCodeBlocks, + rules: { + ...mdx.flat.rules, + ...mdx.flatCodeBlocks.rules, + 'mdx/remark': 'off', + }, + }, + { + ignores: [ + 'docs/reference/**', + 'build/**', + '.docusaurus/**', + 'node_modules/**', + ], + }, +]; diff --git a/packages/docs/package.json b/packages/docs/package.json new file mode 100644 index 00000000000..10aa7b6be0b --- /dev/null +++ b/packages/docs/package.json @@ -0,0 +1,67 @@ +{ + "name": "blockly-docs", + "version": "0.0.0", + "private": true, + "description": "Blockly documentation site", + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "format": "prettier --write .", + "format:check": "prettier --check .", + "lint": "eslint 'docs/**/*.mdx'", + "lint:fix": "eslint 'docs/**/*.mdx' --fix" + }, + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/plugin-client-redirects": "^3.9.2", + "@docusaurus/preset-classic": "3.9.2", + "@mdx-js/react": "^3.0.1", + "clsx": "^2.1.1", + "js-yaml": "^4.1.0", + "prism-react-renderer": "^2.3.1", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "remark-directive": "^4.0.0" + }, + "devDependencies": { + "@docsearch/core": "^4.5.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/types": "3.9.2", + "eslint": "^10.1.0", + "eslint-plugin-mdx": "^3.7.0", + "gh-pages": "^6.3.0", + "prettier": "^3.8.1" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=20.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/RaspberryPiFoundation/blockly.git" + }, + "author": "Raspberry Pi Foundation", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/RaspberryPiFoundation/blockly/issues" + }, + "homepage": "https://github.com/RaspberryPiFoundation/blockly#readme" +} diff --git a/packages/docs/sidebars.js b/packages/docs/sidebars.js new file mode 100644 index 00000000000..7d0c7ea5644 --- /dev/null +++ b/packages/docs/sidebars.js @@ -0,0 +1,1453 @@ +// @ts-nocheck + +let referenceSidebar = []; +try { + referenceSidebar = require('./docs/reference/_reference.js').referenceSidebar; +} catch { + console.warn('Reference sidebar not found — run "npm run docs" in packages/blockly to generate it.'); +} + + +// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) + +/** + * Creating a sidebar enables you to: + - create an ordered group of docs +- render a sidebar for each doc of that group +- provide next/previous navigation + +The sidebars can be generated from the filesystem, or explicitly defined here. + +Create as many sidebars as you want. + +@type {import('@docusaurus/plugin-content-docs').SidebarsConfig} +*/ +const sidebars = { + codelabsSidebar: [ + { + type: 'doc', + label: 'Codelabs', + id: 'codelabs/index', + }, + { + type: 'category', + label: 'Getting started with Blockly', + items: [ + { + type: 'doc', + label: '1. Codelab-overview', + id: 'codelabs/getting-started/codelab-overview', + }, + { + type: 'doc', + label: '2. Setup', + id: 'codelabs/getting-started/setup', + }, + { + type: 'doc', + label: '3. Explore the app', + id: 'codelabs/getting-started/explore-the-app', + }, + { + type: 'doc', + label: '4. Add Blockly libraries', + id: 'codelabs/getting-started/add-blockly-libraries', + }, + { + type: 'doc', + label: '5. Create a Blockly workspace', + id: 'codelabs/getting-started/create-a-blockly-workspace', + }, + { + type: 'doc', + label: '6. Create a custom block', + id: 'codelabs/getting-started/create-a-custom-block', + }, + { + type: 'doc', + label: '7. Save/load workspace', + id: 'codelabs/getting-started/save-load-workspace', + }, + { + type: 'doc', + label: '8. Generate JavaScript code', + id: 'codelabs/getting-started/generate-javaScript-code', + }, + { + type: 'doc', + label: '9. Run generated code', + id: 'codelabs/getting-started/run-generated-code', + }, + { + type: 'doc', + label: '10. The End', + id: 'codelabs/getting-started/the-end', + }, + ], + }, + { + type: 'category', + label: 'Customizing a Blockly toolbox', + items: [ + { + type: 'doc', + label: '1. Codelab-overview', + id: 'codelabs/custom-toolbox/codelab-overview', + }, + { + type: 'doc', + label: '2. Setup', + id: 'codelabs/custom-toolbox/setup', + }, + { + type: 'doc', + label: '3. Change the look of a category', + id: 'codelabs/custom-toolbox/change-the-look-of-a-category', + }, + { + type: 'doc', + label: '4. Change the look of a selected category', + id: 'codelabs/custom-toolbox/change-the-look-of-a-selected-category', + }, + { + type: 'doc', + label: '5. Add an icon to your category', + id: 'codelabs/custom-toolbox/add-an-icon-to-your-category', + }, + { + type: 'doc', + label: '6. Change the category HTML', + id: 'codelabs/custom-toolbox/change-the-category-HTML', + }, + { + type: 'doc', + label: '7. Adding a custom toolbox item', + id: 'codelabs/custom-toolbox/adding-a-custom-toolbox-item', + }, + { + type: 'doc', + label: '8. Summary', + id: 'codelabs/custom-toolbox/summary', + }, + ], + }, + { + type: 'category', + label: 'Customizing your themes', + items: [ + { + type: 'doc', + label: '1. Codelab-overview', + id: 'codelabs/theme-extension-identifier/codelab-overview', + }, + { + type: 'doc', + label: '2. Setup', + id: 'codelabs/theme-extension-identifier/setup', + }, + { + type: 'doc', + label: '3. Workspace Theme', + id: 'codelabs/theme-extension-identifier/workspace-theme', + }, + { + type: 'doc', + label: '4. Customize Components', + id: 'codelabs/theme-extension-identifier/customize-components', + }, + { + type: 'doc', + label: '5. Customize Category Styles', + id: 'codelabs/theme-extension-identifier/customize-category-styles', + }, + { + type: 'doc', + label: '6. Customize Block Styles', + id: 'codelabs/theme-extension-identifier/customize-block-styles', + }, + { + type: 'doc', + label: '7. Summary', + id: 'codelabs/theme-extension-identifier/summary', + }, + ], + }, + { + type: 'category', + label: 'Customizing context menus', + items: [ + { + type: 'doc', + label: '1. Codelab-overview', + id: 'codelabs/context-menu-option/codelab-overview', + }, + { + type: 'doc', + label: '2. Setup', + id: 'codelabs/context-menu-option/setup', + }, + { + type: 'doc', + label: '3. Add a context menu item', + id: 'codelabs/context-menu-option/add-a-context-menu-item', + }, + { + type: 'doc', + label: '4. Precondition: Node type', + id: 'codelabs/context-menu-option/precondition-node-type', + }, + { + type: 'doc', + label: '5. Precondition: External state', + id: 'codelabs/context-menu-option/precondition-external-state', + }, + { + type: 'doc', + label: '6. Precondition: Blockly state', + id: 'codelabs/context-menu-option/precondition-blockly-state', + }, + { + type: 'doc', + label: '7. Callback', + id: 'codelabs/context-menu-option/callback', + }, + { + type: 'doc', + label: '8. Display text', + id: 'codelabs/context-menu-option/display-text', + }, + { + type: 'doc', + label: '9. Weight and id', + id: 'codelabs/context-menu-option/weight-and-id', + }, + { + type: 'doc', + label: '10. Separators', + id: 'codelabs/context-menu-option/separators', + }, + { + type: 'doc', + label: '11. Summary', + id: 'codelabs/context-menu-option/summary', + }, + ], + }, + { + type: 'category', + label: 'Block validation and warnings', + items: [ + { + type: 'doc', + label: '1. Codelab-overview', + id: 'codelabs/validation-and-warnings/codelab-overview', + }, + { + type: 'doc', + label: '2. Setup', + id: 'codelabs/validation-and-warnings/setup', + }, + { + type: 'doc', + label: '3. Validating blocks', + id: 'codelabs/validation-and-warnings/validating-blocks', + }, + { + type: 'doc', + label: '4. Displaying warnings', + id: 'codelabs/validation-and-warnings/displaying-warnings', + }, + { + type: 'doc', + label: '5. Summary', + id: 'codelabs/validation-and-warnings/summary', + }, + ], + }, + { + type: 'category', + label: 'Use CSS in Blockly', + items: [ + { + type: 'doc', + label: '1. Codelab-overview', + id: 'codelabs/css/codelab-overview', + }, + { + type: 'doc', + label: '2. Setup', + id: 'codelabs/css/setup', + }, + { + type: 'doc', + label: "3. A tour of Blockly's elements", + id: 'codelabs/css/tour', + }, + { + type: 'doc', + label: '4. Components', + id: 'codelabs/css/components', + }, + { + type: 'doc', + label: '5. Toolbox categories', + id: 'codelabs/css/categories', + }, + { + type: 'doc', + label: '6. Blocks', + id: 'codelabs/css/blocks', + }, + { + type: 'doc', + label: '7. Summary', + id: 'codelabs/css/summary', + }, + ], + }, + { + type: 'category', + label: 'Build a custom generator', + items: [ + { + type: 'doc', + label: '1. Codelab-overview', + id: 'codelabs/custom-generator/codelab-overview', + }, + { + type: 'doc', + label: '2. Setup', + id: 'codelabs/custom-generator/setup', + }, + { + type: 'doc', + label: '3. The basics', + id: 'codelabs/custom-generator/the-basics', + }, + { + type: 'doc', + label: '4. Block generator overview', + id: 'codelabs/custom-generator/block-generator-overview', + }, + { + type: 'doc', + label: '5. Value block generators', + id: 'codelabs/custom-generator/value-block-generators', + }, + { + type: 'doc', + label: '6. Member block generator', + id: 'codelabs/custom-generator/member-block-generator', + }, + { + type: 'doc', + label: '7. Array block generator', + id: 'codelabs/custom-generator/array-block-generator', + }, + { + type: 'doc', + label: '8. Object block generator', + id: 'codelabs/custom-generator/object-block-generator', + }, + { + type: 'doc', + label: '9. Generating a stack', + id: 'codelabs/custom-generator/generating-a-stack', + }, + { + type: 'doc', + label: '10. Summary', + id: 'codelabs/custom-generator/summary', + }, + ], + }, + { + type: 'category', + label: 'Build custom renderers', + items: [ + { + type: 'doc', + label: '1. Codelab-overview', + id: 'codelabs/custom-renderer/codelab-overview', + }, + { + type: 'doc', + label: '2. Setup', + id: 'codelabs/custom-renderer/setup', + }, + { + type: 'doc', + label: '3. Observe the built-in renderers', + id: 'codelabs/custom-renderer/observe-the-built-in-renderers', + }, + { + type: 'doc', + label: '4. Define and register a custom renderer', + id: 'codelabs/custom-renderer/define-and-register-a-custom-renderer', + }, + { + type: 'doc', + label: '5. Override constants', + id: 'codelabs/custom-renderer/override-constants', + }, + { + type: 'doc', + label: '6. Understand connection shapes', + id: 'codelabs/custom-renderer/understand-connection-shapes', + }, + { + type: 'doc', + label: '7. Change connection shapes', + id: 'codelabs/custom-renderer/change-connection-shapes', + }, + { + type: 'doc', + label: '8. Typed connection shapes', + id: 'codelabs/custom-renderer/typed-connection-shapes', + }, + { + type: 'doc', + label: '9. Summary', + id: 'codelabs/custom-renderer/summary', + }, + ], + }, + ], + guidesSidebar: [ + { + type: 'category', + label: 'Get started', + items: [ + { + type: 'doc', + label: 'What Is Blockly', + id: 'guides/get-started/what-is-blockly', + }, + { + type: 'doc', + label: 'Why Blockly', + id: 'guides/get-started/why-blockly', + }, + { + type: 'doc', + label: 'Get The Code', + id: 'guides/get-started/get-the-code', + }, + { + type: 'doc', + label: 'Visual glossary', + id: 'guides/get-started/workspace-anatomy', + }, + { + type: 'category', + label: 'Basic steps', + items: [ + { + type: 'doc', + label: 'Create a workspace', + id: 'guides/get-started/workspace-creation', + }, + { + type: 'doc', + label: 'Add a toolbox', + id: 'guides/get-started/toolbox', + }, + { + type: 'doc', + label: 'Define custom blocks', + id: 'guides/get-started/blocks', + }, + { + type: 'doc', + label: 'Generate code', + id: 'guides/get-started/code-generation', + }, + { + type: 'doc', + label: 'Save and load', + id: 'guides/get-started/save-and-load', + }, + ], + }, + { + type: 'category', + label: 'Try Blockly', + items: [ + { + type: 'link', + label: 'Get started codelab', + href: '/codelabs/getting-started/codelab-overview', + }, + { + type: 'link', + label: 'Blockly Playground', + href: 'https://blockly-demo.appspot.com/static/tests/playground.html', + }, + { + type: 'link', + label: 'Block Factory', + href: 'https://raspberrypifoundation.github.io/blockly-samples/examples/developer-tools/index.html', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Design considerations', + items: [ + { + type: 'doc', + label: 'Introduction to Blockly applications', + id: 'guides/design/app-overview', + }, + { + type: 'doc', + label: 'Application design', + id: 'guides/design/applications', + }, + { + type: 'doc', + label: 'Educational applications', + id: 'guides/design/education', + }, + { + type: 'doc', + label: 'Block design', + id: 'guides/design/blocks', + }, + { + type: 'doc', + label: 'Block- vs text-based languages', + id: 'guides/design/languages', + }, + { + type: 'doc', + label: 'Block appearance', + id: 'guides/design/appearance', + }, + ], + }, + { + type: 'category', + label: 'Programming considerations', + items: [ + { + type: 'doc', + label: 'API visibility', + id: 'guides/programming/using_blockly_apis', + }, + { + type: 'doc', + label: 'Plugins', + id: 'guides/programming/plugin_overview', + }, + { + type: 'doc', + label: 'Fork Blockly', + id: 'guides/programming/forking_blockly', + }, + { + type: 'doc', + label: 'Unfork Blockly', + id: 'guides/programming/unforking_blockly', + }, + ], + }, + { + type: 'category', + label: 'Build your editor', + items: [ + { + type: 'category', + label: 'Workspaces', + items: [ + { + type: 'category', + label: 'Create a workspace', + items: [ + { + type: 'doc', + label: 'Create a workspace', + id: 'guides/configure/web/configuration_struct', + }, + { + type: 'doc', + label: 'Grid option', + id: 'guides/configure/web/grid', + }, + { + type: 'doc', + label: 'Media folder option', + id: 'guides/configure/web/media', + }, + { + type: 'doc', + label: 'Move option', + id: 'guides/configure/web/move', + }, + { + type: 'doc', + label: 'Zoom option', + id: 'guides/configure/web/zoom', + }, + ], + }, + { + type: 'category', + label: 'Workspace size', + items: [ + { + type: 'doc', + label: 'Fixed-size workspace', + id: 'guides/configure/web/fixed-size', + }, + { + type: 'doc', + label: 'Resizable workspace', + id: 'guides/configure/web/resizable', + }, + { + type: 'doc', + label: 'Metrics Manager', + id: 'guides/configure/web/metrics_manager', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Toolboxes', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/configure/web/toolboxes/toolbox', + }, + { + type: 'category', + label: 'Flyout toolboxes', + items: [ + { + type: 'doc', + label: 'Define a flyout toolbox', + id: 'guides/configure/web/toolboxes/flyout', + }, + ], + }, + { + type: 'category', + label: 'Category toolboxes', + items: [ + { + type: 'doc', + label: 'Define a category toolbox', + id: 'guides/configure/web/toolboxes/category', + }, + { + type: 'doc', + label: 'Nested categories', + id: 'guides/configure/web/toolboxes/nested', + }, + { + type: 'doc', + label: 'Dynamic categories', + id: 'guides/configure/web/toolboxes/dynamic', + }, + { + type: 'doc', + label: 'Disable, hide, or expand categories', + id: 'guides/configure/web/toolboxes/disable-categories', + }, + { + type: 'doc', + label: 'Category appearance', + id: 'guides/configure/web/toolboxes/appearance', + }, + { + type: 'doc', + label: 'Programmatic access', + id: 'guides/configure/web/toolboxes/programmatic', + }, + ], + }, + { + type: 'doc', + label: 'Preset blocks', + id: 'guides/configure/web/toolboxes/preset', + }, + { + type: 'doc', + label: 'Separators', + id: 'guides/configure/web/toolboxes/separators', + }, + { + type: 'doc', + label: 'Buttons and labels', + id: 'guides/configure/web/toolboxes/buttons', + }, + { + type: 'doc', + label: 'Modify toolboxes', + id: 'guides/configure/web/toolboxes/modify', + }, + ], + }, + { + type: 'category', + label: 'Appearance', + items: [ + { + type: 'doc', + label: 'Themes', + id: 'guides/configure/web/appearance/themes', + }, + { + type: 'doc', + label: 'Colour formats', + id: 'guides/configure/web/appearance/colour-formats', + }, + { + type: 'doc', + label: 'Block colours', + id: 'guides/configure/web/appearance/block-colour', + }, + { + type: 'doc', + label: 'Style with CSS', + id: 'guides/configure/web/appearance/css', + }, + ], + }, + { + type: 'doc', + label: 'Save and load', + id: 'guides/configure/web/serialization', + }, + { + type: 'doc', + label: 'Events', + id: 'guides/configure/web/events', + }, + { + type: 'category', + label: 'Shortcuts and context menus', + items: [ + { + type: 'doc', + label: 'Keyboard shortcuts', + id: 'guides/configure/web/keyboard-shortcuts', + }, + { + type: 'doc', + label: 'Copy and paste', + id: 'guides/configure/web/copy-paste', + }, + { + type: 'doc', + label: 'Context menus', + id: 'guides/configure/web/context-menus', + }, + ], + }, + { + type: 'category', + label: 'Drag and drop', + items: [ + { + type: 'doc', + label: 'Custom draggables', + id: 'guides/configure/web/dragging/draggable', + }, + { + type: 'doc', + label: 'Custom block drag strategies', + id: 'guides/configure/web/dragging/block-drag-strategies', + }, + { + type: 'doc', + label: 'Custom draggers', + id: 'guides/configure/web/dragging/dragger', + }, + ], + }, + { + type: 'category', + label: 'Comments', + items: [ + { + type: 'doc', + label: 'Workspace comments', + id: 'guides/configure/web/workspace_comment', + }, + { + type: 'doc', + label: 'Block comments', + id: 'guides/configure/web/block_comment', + }, + ], + }, + { + type: 'doc', + label: 'Localization', + id: 'guides/configure/web/translations', + }, + { + type: 'doc', + label: 'Focus system', + id: 'guides/configure/web/focus', + }, + { + type: 'doc', + label: 'Advanced customization', + id: 'guides/configure/web/customization', + }, + { + type: 'category', + label: 'Accessibility', + items: [ + { + type: 'doc', + label: 'Keyboard navigation', + id: 'guides/configure/web/keyboard-nav', + }, + { + type: 'doc', + label: 'Colour and accessibility', + id: 'guides/configure/web/colour-a11y', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Build your blocks', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/overview', + }, + { + type: 'category', + label: 'Block definitions', + items: [ + { + type: 'doc', + label: "What's a block definition?", + id: 'guides/create-custom-blocks/define/block-definitions', + }, + { + type: 'category', + label: 'Ways to define blocks', + items: [ + { + type: 'doc', + label: 'Blockly Developer Tools', + id: 'guides/create-custom-blocks/blockly-developer-tools', + }, + { + type: 'doc', + label: 'JSON and JavaScript', + id: 'guides/create-custom-blocks/define/json-and-js', + }, + { + type: 'doc', + label: 'Extensions and mixins', + id: 'guides/create-custom-blocks/define/extensions', + }, + { + type: 'doc', + label: 'Modify block definitions', + id: 'guides/create-custom-blocks/define/modify-definitions', + }, + ], + }, + { + type: 'category', + label: 'Block structure', + items: [ + { + type: 'doc', + label: 'Anatomy of a block', + id: 'guides/create-custom-blocks/define/block-anatomy', + }, + { + type: 'doc', + label: 'Top-level connections', + id: 'guides/create-custom-blocks/define/top-level-connections', + }, + { + type: 'doc', + label: 'Block structure in JSON', + id: 'guides/create-custom-blocks/define/structure-json', + }, + { + type: 'doc', + label: 'Block structure in JavaScript', + id: 'guides/create-custom-blocks/define/structure-js', + }, + { + type: 'doc', + label: 'Inline vs external inputs', + id: 'guides/create-custom-blocks/define/inline-vs-external', + }, + ], + }, + { + type: 'doc', + label: 'Block state', + id: 'guides/create-custom-blocks/define/block-state', + }, + { + type: 'doc', + label: 'Destroy hook', + id: 'guides/create-custom-blocks/define/destroy', + }, + { + type: 'doc', + label: 'Block help', + id: 'guides/create-custom-blocks/define/block-help', + }, + ], + }, + { + type: 'category', + label: 'Code generation', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/code-generation/overview', + }, + { + type: 'doc', + label: 'Block-code generators', + id: 'guides/create-custom-blocks/code-generation/block-code', + }, + { + type: 'doc', + label: 'Transform field values', + id: 'guides/create-custom-blocks/code-generation/fields', + }, + { + type: 'doc', + label: 'Add parentheses', + id: 'guides/create-custom-blocks/code-generation/operator-precedence', + }, + { + type: 'doc', + label: 'Cache inner value block code', + id: 'guides/create-custom-blocks/code-generation/caching-arguments', + }, + ], + }, + { + type: 'category', + label: 'Connections', + items: [ + { + type: 'doc', + label: 'Connection checks', + id: 'guides/create-custom-blocks/inputs/connection-checks', + }, + { + type: 'doc', + label: 'Connection check playbook', + id: 'guides/create-custom-blocks/inputs/connection-check-playbook', + }, + { + type: 'doc', + label: 'Custom connection checkers', + id: 'guides/create-custom-blocks/inputs/connection_checker', + }, + { + type: 'doc', + label: 'Connection previewers', + id: 'guides/create-custom-blocks/inputs/connection-previews', + }, + ], + }, + { + type: 'category', + label: 'Inputs', + items: [ + { + type: 'doc', + label: 'Create custom inputs', + id: 'guides/create-custom-blocks/inputs/creating-custom-inputs', + }, + ], + }, + { + type: 'category', + label: 'Fields', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/fields/overview', + }, + { + type: 'doc', + label: 'Fields vs icons', + id: 'guides/create-custom-blocks/fields/fields-vs-icons', + }, + { + type: 'doc', + label: 'Anatomy of a field', + id: 'guides/create-custom-blocks/fields/anatomy-of-a-field', + }, + { + type: 'doc', + label: 'Validators', + id: 'guides/create-custom-blocks/fields/validators', + }, + { + type: 'category', + label: 'Built-in fields', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/fields/built-in-fields/overview', + }, + { + type: 'doc', + label: 'Checkbox', + id: 'guides/create-custom-blocks/fields/built-in-fields/checkbox', + }, + { + type: 'doc', + label: 'Dropdown', + id: 'guides/create-custom-blocks/fields/built-in-fields/dropdown', + }, + { + type: 'doc', + label: 'Image', + id: 'guides/create-custom-blocks/fields/built-in-fields/image', + }, + { + type: 'doc', + label: 'Label', + id: 'guides/create-custom-blocks/fields/built-in-fields/label', + }, + { + type: 'doc', + label: 'Label (serializable)', + id: 'guides/create-custom-blocks/fields/built-in-fields/label-serializable', + }, + { + type: 'doc', + label: 'Number', + id: 'guides/create-custom-blocks/fields/built-in-fields/number', + }, + { + type: 'doc', + label: 'Text input', + id: 'guides/create-custom-blocks/fields/built-in-fields/text-input', + }, + { + type: 'doc', + label: 'Variable', + id: 'guides/create-custom-blocks/fields/built-in-fields/variable', + }, + ], + }, + { + type: 'category', + label: 'Custom fields', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/fields/customizing-fields/overview', + }, + { + type: 'doc', + label: 'Extend an existing field', + id: 'guides/create-custom-blocks/fields/customizing-fields/extending', + }, + { + type: 'doc', + label: 'Create a custom field', + id: 'guides/create-custom-blocks/fields/customizing-fields/creating', + }, + { + type: 'doc', + label: 'Upgrade a custom field', + id: 'guides/create-custom-blocks/fields/customizing-fields/upgrading', + }, + ], + }, + ], + }, + { + type: 'doc', + label: 'Variables', + id: 'guides/create-custom-blocks/variables', + }, + { + type: 'category', + label: 'Procedures', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/procedures/overview', + }, + { + type: 'doc', + label: 'Use built-in procedure blocks', + id: 'guides/create-custom-blocks/procedures/using-procedures', + }, + { + type: 'doc', + label: 'Create custom procedure blocks', + id: 'guides/create-custom-blocks/procedures/creating-custom-procedure-blocks', + }, + { + type: 'doc', + label: 'Create custom procedure data models', + id: 'guides/create-custom-blocks/procedures/creating-custom-procedure-data-models', + }, + ], + }, + { + type: 'category', + label: 'Icons', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/icons/overview', + }, + { + type: 'doc', + label: 'Fields vs icons', + id: 'guides/create-custom-blocks/fields/fields-vs-icons', + }, + { + type: 'doc', + label: 'Override comment icon', + id: 'guides/create-custom-blocks/icons/creating-custom-icons/override-built-in', + }, + { + type: 'category', + label: 'Create custom icons', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/icons/creating-custom-icons/basic-implementation', + }, + { + type: 'doc', + label: 'Save and load icons', + id: 'guides/create-custom-blocks/icons/creating-custom-icons/save-and-load', + }, + { + type: 'doc', + label: 'Use pop-up bubbles', + id: 'guides/create-custom-blocks/icons/creating-custom-icons/use-bubbles', + }, + { + type: 'doc', + label: 'Create custom bubbles', + id: 'guides/create-custom-blocks/icons/creating-custom-icons/creating-custom-bubbles', + }, + { + type: 'doc', + label: 'Use custom icons', + id: 'guides/create-custom-blocks/icons/creating-custom-icons/use-custom-icons', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Block shape', + items: [ + { + type: 'doc', + label: 'Mutators', + id: 'guides/create-custom-blocks/mutators', + }, + { + type: 'category', + label: 'Renderers', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/renderers/overview', + }, + { + type: 'category', + label: 'Concepts', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/create-custom-blocks/renderers/concepts/overview', + }, + { + type: 'doc', + label: 'Renderer', + id: 'guides/create-custom-blocks/renderers/concepts/renderer', + }, + { + type: 'doc', + label: 'Constant provider', + id: 'guides/create-custom-blocks/renderers/concepts/constants', + }, + { + type: 'doc', + label: 'Render info', + id: 'guides/create-custom-blocks/renderers/concepts/info', + }, + { + type: 'doc', + label: 'Path object', + id: 'guides/create-custom-blocks/renderers/concepts/path-object', + }, + { + type: 'doc', + label: 'Drawer', + id: 'guides/create-custom-blocks/renderers/concepts/drawer', + }, + { + type: 'doc', + label: 'Rows', + id: 'guides/create-custom-blocks/renderers/concepts/rows', + }, + { + type: 'doc', + label: 'Elements', + id: 'guides/create-custom-blocks/renderers/concepts/elements', + }, + ], + }, + { + type: 'doc', + label: 'Create custom renderers', + id: 'guides/create-custom-blocks/renderers/create-custom-renderers/basic-implementation', + }, + { + type: 'doc', + label: 'Connection shapes', + id: 'guides/create-custom-blocks/renderers/create-custom-renderers/connection-shapes', + }, + ], + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Build your application', + items: [ + { + type: 'category', + label: 'Generate and run code', + items: [ + { + type: 'doc', + label: 'Generate and run code', + id: 'guides/app-integration/run-code', + }, + { + type: 'doc', + label: 'Generate and run JavaScript', + id: 'guides/app-integration/running-javascript', + }, + ], + }, + { + type: 'doc', + label: 'Attribute Blockly', + id: 'guides/app-integration/attribution', + }, + ], + }, + { + type: 'category', + label: 'Contribute to Blockly', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/contribute/index', + }, + { + type: 'category', + label: 'Get started', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/contribute/get-started/index', + }, + { + type: 'doc', + label: 'Development tools', + id: 'guides/contribute/get-started/development_tools', + }, + { + type: 'doc', + label: 'Write a good issue', + id: 'guides/contribute/get-started/write_a_good_issue', + }, + { + type: 'doc', + label: 'Write a good pull request', + id: 'guides/contribute/get-started/write_a_good_pr', + }, + { + type: 'doc', + label: 'Commit message guide', + id: 'guides/contribute/get-started/commits', + }, + { + type: 'doc', + label: 'Code review process', + id: 'guides/contribute/get-started/pr_review_process', + }, + { + type: 'doc', + label: 'Issue labels', + id: 'guides/contribute/get-started/issue_labels', + }, + { + type: 'doc', + label: 'Use the playground', + id: 'guides/contribute/get-started/playground', + }, + ], + }, + { + type: 'category', + label: 'Contribute to core', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/contribute/core/index', + }, + { + type: 'category', + label: 'Core architecture', + items: [ + { + type: 'doc', + label: 'Render management', + id: 'guides/contribute/core-architecture/render-management', + }, + ], + }, + { + type: 'doc', + label: 'Style guide', + id: 'guides/contribute/core/style_guide', + }, + { + type: 'doc', + label: 'Build scripts', + id: 'guides/contribute/core/building', + }, + { + type: 'doc', + label: 'Advanced compilation', + id: 'guides/contribute/core/advanced', + }, + { + type: 'category', + label: 'Localization', + items: [ + { + type: 'doc', + label: 'Add a new localization token', + id: 'guides/contribute/core/add_localization_token', + }, + { + type: 'doc', + label: 'Translate text', + id: 'guides/contribute/core/translating', + }, + { + type: 'doc', + label: 'Klingon', + id: 'guides/contribute/core/klingon', + }, + ], + }, + { + type: 'doc', + label: 'Unit tests', + id: 'guides/contribute/core/unit_testing', + }, + { + type: 'doc', + label: 'Write a codelab', + id: 'guides/contribute/core/write_a_codelab', + }, + ], + }, + { + type: 'category', + label: 'Contribute to samples', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'guides/contribute/samples/index', + }, + { + type: 'doc', + label: 'Repository structure', + id: 'guides/contribute/samples/repository_structure', + }, + { + type: 'category', + label: 'Plugins', + items: [ + { + type: 'doc', + label: 'Add a plugin', + id: 'guides/contribute/samples/add_a_plugin', + }, + { + type: 'doc', + label: 'Plugin naming conventions', + id: 'guides/contribute/samples/naming', + }, + { + type: 'doc', + label: 'Debug plugins', + id: 'guides/contribute/samples/debugging', + }, + { + type: 'doc', + label: 'Publish block libraries', + id: 'guides/contribute/samples/block_libraries', + }, + { + type: 'doc', + label: 'Add a plugin field to Block Factory', + id: 'guides/contribute/samples/block_factory', + }, + ], + }, + ], + }, + ], + }, + ], + referenceSidebar: referenceSidebar, +}; + +export default sidebars; diff --git a/packages/docs/src/components/CodelabCards.js b/packages/docs/src/components/CodelabCards.js new file mode 100644 index 00000000000..9e77467539e --- /dev/null +++ b/packages/docs/src/components/CodelabCards.js @@ -0,0 +1,28 @@ +import React from 'react'; +import Link from '@docusaurus/Link'; +import styles from './styles.module.css'; + +// This component renders the grid layout +export function CodelabGrid({ children }) { + return
{children}
; +} + +// This component renders a single card +export function CodelabCard({ href, title, description, children, level }) { + return ( +
+
+ {children} +
+
+ {level} +
+
+

{title}

+ + Start + +
+
+ ); +} diff --git a/packages/docs/src/components/CodelabImage.js b/packages/docs/src/components/CodelabImage.js new file mode 100644 index 00000000000..88216625ac5 --- /dev/null +++ b/packages/docs/src/components/CodelabImage.js @@ -0,0 +1,5 @@ +import React from 'react'; + +export default function CodelabImage({ children }) { + return

{children}

; +} diff --git a/packages/docs/src/components/CompareBlock.js b/packages/docs/src/components/CompareBlock.js new file mode 100644 index 00000000000..8bb0df421fb --- /dev/null +++ b/packages/docs/src/components/CompareBlock.js @@ -0,0 +1,5 @@ +import React from 'react'; + +export default function CompareBlock({ variant, children }) { + return

{children}

; +} diff --git a/packages/docs/src/components/HomepageFeatures/index.js b/packages/docs/src/components/HomepageFeatures/index.js new file mode 100644 index 00000000000..ce350441ae0 --- /dev/null +++ b/packages/docs/src/components/HomepageFeatures/index.js @@ -0,0 +1,65 @@ +import clsx from 'clsx'; +import Heading from '@theme/Heading'; +import styles from './styles.module.css'; + +const FeatureList = [ + { + title: 'Accessible by design', + Svg: require('@site/static/images/HomePage/Accessibility-tier-4.svg') + .default, + description: ( + <> + Built so everyone can engage with visual code — helping developers + create experiences that are inclusive by default. + + ), + }, + { + title: 'Built for flexibility', + Svg: require('@site/static/images/HomePage/Explore-tier-4.svg').default, + description: ( + <> + An open-source library that adapts to your needs. With APIs, generators, + and integrations, Blockly fits into most platforms, and environments. + + ), + }, + { + title: 'Driven by community', + Svg: require('@site/static/images/HomePage/Connect-tier-4.svg').default, + description: ( + <> + A global community of passionate developers and educators helps Blockly + stay open, innovative, and ready for what’s next. + + ), + }, +]; + +function Feature({ Svg, title, description }) { + return ( +
+
+ +
+
+ {title} +

{description}

+
+
+ ); +} + +export default function HomepageFeatures() { + return ( +
+
+
+ {FeatureList.map((props, idx) => ( + + ))} +
+
+
+ ); +} diff --git a/packages/docs/src/components/HomepageFeatures/styles.module.css b/packages/docs/src/components/HomepageFeatures/styles.module.css new file mode 100644 index 00000000000..9bf3d69dc04 --- /dev/null +++ b/packages/docs/src/components/HomepageFeatures/styles.module.css @@ -0,0 +1,11 @@ +.features { + display: flex; + align-items: center; + padding: 3rem 0 5rem 0; + width: 100%; +} + +.featureSvg { + height: 200px; + width: 200px; +} diff --git a/packages/docs/src/components/Image.js b/packages/docs/src/components/Image.js new file mode 100644 index 00000000000..4dc9552680c --- /dev/null +++ b/packages/docs/src/components/Image.js @@ -0,0 +1,58 @@ +import React from 'react'; +import { useColorMode } from '@docusaurus/theme-common'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +/** + * Image component for use in MDX docs + * Wraps HTML img tag with additional styling and responsiveness + * Supports theme-based image loading (light/dark mode) + * + * @param {string} src - Image source path (for light mode) + * @param {string} srcDark - Optional image source path for dark mode + * @param {string} alt - Alt text for accessibility + * @param {number|string} width - Optional width (in pixels) + * @param {number|string} height - Optional height (in pixels) + * @param {string} className - Optional CSS class for custom styling + * @param {object} style - Optional inline styles + */ +export default function Image({ + src, + srcDark, + alt, + width, + height, + className, + style = {}, + ...props +}) { + const { colorMode } = useColorMode(); + + // Select image source based on current theme + const imageSrc = colorMode === 'dark' && srcDark ? srcDark : src; + + // Prepend baseUrl to the image path + const resolvedSrc = useBaseUrl(imageSrc); + + const imgStyle = { + maxWidth: '100%', + height: 'auto', + ...style, + }; + + if (width) { + imgStyle.width = typeof width === 'number' ? `${width}px` : width; + } + if (height) { + imgStyle.height = typeof height === 'number' ? `${height}px` : height; + } + + return ( + {alt} + ); +} diff --git a/packages/docs/src/components/styles.module.css b/packages/docs/src/components/styles.module.css new file mode 100644 index 00000000000..3a9ad8ba782 --- /dev/null +++ b/packages/docs/src/components/styles.module.css @@ -0,0 +1,117 @@ +/* + Styles for the Codelab landing page components. +*/ + +:root { + --codelab-card-background-color: #ffffff; + --codelab-card-title: #3c4043; +} + +[data-theme='dark'] { + --codelab-card-background-color: #1c1e21; + --codelab-card-title: #ffffff; +} + +.codelabGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 1.5rem; + margin-top: 2rem; +} + +.codelabCard { + display: flex; + flex-direction: column; + background-color: var(--codelab-card-background-color); + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 3px; + border-bottom: 2px solid #9aa0a6; + text-decoration: none; + color: #3c4043; + overflow: hidden; + padding: 1.5rem; + min-height: 180px; +} + +.cardHeader { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.cardTitle { + font-size: 1.25rem; + font-weight: 500; + margin: 0; + color: var(--codelab-card-title); + font-family: + -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', + Arial, sans-serif; + line-height: 1.4; +} + +.cardIcon { + display: flex; + align-items: center; + color: #4285f4; + font-size: 1.5rem; +} + +.cardContent { + padding: 1.5rem; + flex-grow: 1; +} + +.cardDescription { + margin: 0; + font-size: 1rem; + color: var(--ifm-color-emphasis-600); +} + +.cardFooter { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: auto; + padding-top: 1rem; + gap: 20px; +} + +.cardButton { + border: 1px solid #4285f4; + background-color: #4285f4; + color: #fff; + text-align: center; + border-radius: 4px; + padding: 0.5rem 1.25rem; + font-weight: 500; + text-decoration: none; + transition: + background-color 0.2s cubic-bezier(0.55, 0.085, 0.68, 0.53), + border-color 0.2s cubic-bezier(0.55, 0.055, 0.675, 0.19), + color 0.2s cubic-bezier(0.55, 0.085, 0.68, 0.53), + transform 0.3s; +} + +.cardButton:hover { + border-color: #1a73e8; + background-color: #1a73e8; + transform: scale(1.05); +} + +.eyebrow { + padding: 0.25rem 0.5rem; + background-color: #e8eaed; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 500; + text-transform: uppercase; +} + +h2 { + font-size: 24px; +} + +h3 { + font-size: 20px; +} diff --git a/packages/docs/src/css/custom.css b/packages/docs/src/css/custom.css new file mode 100644 index 00000000000..b100cbc85c4 --- /dev/null +++ b/packages/docs/src/css/custom.css @@ -0,0 +1,360 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +@import url('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700|Google+Sans:400,500|Google+Sans+Text:400,500,700,400i,500i,700i|Product+Sans:400&lang=en&display=swap'); + +/* You can override the default Infima variables here. */ +:root { + --ifm-color-primary: #4285f4; + --ifm-color-primary-dark: #2b77f3; + --ifm-color-primary-darker: #1d6df2; + --ifm-color-primary-darkest: #0b56d4; + --ifm-color-primary-light: #5993f5; + --ifm-color-primary-lighter: #67a0f6; + --ifm-color-primary-lightest: #91bbf9; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); + + /* --docusaurus-font-family-base is the variable for the main font */ + --ifm-font-family-base: 'Google Sans Text', sans-serif; + + /*--ifm-font-family-heading: 'Google Sans', sans-serif;*/ + --ifm-heading-font-family: 'Google Sans', sans-serif; + + --background-color-footer: #e8f0fe; + --font-color-footer: #202124; + --font-color-hover-footer: #1a73e8; + --border-divider-footer: #dadce0; + --tabs-border: #dadce0; + --codeblock-background-color: #f1f3f4; +} + +/* For readability concerns, you should choose a lighter palette in dark mode. */ +[data-theme='dark'] { + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #21af90; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); + + --background-color-footer: #1c1e21; + --font-color-footer: #dadde1; + --font-color-hover-footer: #25c2a0; + --border-divider-footer: #dadce042; + --tabs-border: #3c4043; + --codeblock-background-color: #282a36; +} + +[class*='docs-doc-id-guides/'] .pagination-nav, +[class*='docs-doc-id-reference/'] .pagination-nav { + display: none; +} + +.menu__caret { + display: none; +} + +/* Override Infima's default H1 font size for first-child H1 in markdown */ +/* The default 3rem comes from Infima theme's .markdown h1:first-child rule */ +.markdown h1:first-child, +.theme-doc-markdown h1:first-child { + --ifm-h1-font-size: 32px; + --ifm-h2-font-size: 24px; + --ifm-h3-font-size: 20px; +} + +.screenshotImg { + width: 200px; +} + +table th { + text-align: left; +} + +table th p { + margin-bottom: 0; +} + +[data-theme]:not([data-theme='dark']) .alert--secondary { + --ifm-alert-background-color: #e8f0fe; + --ifm-alert-background-color-highlight: #54c7ec26; + --ifm-alert-foreground-color: var(--ifm-color-info-contrast-foreground); + --ifm-alert-border-color: #4285f4; +} + +.DocSearch-Button-Keys { + min-width: 0 !important; +} + +/* Navbar title styling */ +.navbar__title { + font-family: 'Google Sans', sans-serif; + font-weight: 500; + font-size: 19px; +} + +/* footer CSS */ +.footer { + background-color: var(--background-color-footer); +} + +.footer__links { + border-block-end: 1px solid var(--border-divider-footer); + padding-block-end: 16px; +} + +.footer__title { + font-weight: bold; + font-family: 'Google Sans', sans-serif; + font-size: 16px; + text-align: center; +} + +.footer__link-item { + font-size: 14px; + color: var(--font-color-footer); +} + +.footer__link-item:hover { + text-decoration: none; + color: var(--font-color-hover-footer); +} + +.footer__copyright { + font-size: 16px; +} + +.footer__col { + display: flex; + flex-direction: column; + align-items: flex-start; + text-align: left; +} + +.footer__items, +.footer__item { + padding: 0; + margin: 0; + list-style: none; +} + +.footer__items { + display: flex; + flex-direction: column; + align-items: flex-start; + text-align: left; +} + +/* Responsive footer styles */ +@media (max-width: 768px) { + .footer__col, + .footer__title, + .footer__link-item { + text-align: center; + } + + .footer__col, + .footer__items { + align-items: center; + } + + .footer__col { + width: 100%; + } + + .footer__title { + margin-bottom: 12px; + } + + .footer__copyright { + padding: 16px 0; + } + + .footer__bottom { + padding: 16px 0; + } + + .footer .container { + padding-left: 16px; + padding-right: 16px; + } +} + +@media (min-width: 769px) and (max-width: 996px) { + .footer__col, + .footer__title, + .footer__link-item { + text-align: center; + } + + .footer__col, + .footer__items { + align-items: center; + } + + .footer__col { + width: 100%; + } + + .footer__title { + margin-bottom: 16px; + } +} + +/** Added changes for hide level 3 menus **/ +.theme-doc-sidebar-menu .hide-level-3 .theme-doc-sidebar-item-link-level-3 { + display: none !important; +} + +.DocSearch-Button-Keys .DocSearch-Button-Key { + display: none !important; +} + +.DocSearch-Button-Keys::before { + content: '/'; + align-items: center; + justify-content: center; + font-size: 0.75rem !important; + background-color: var(--ifm-color-emphasis-100); + line-height: 1.5rem !important; + border: 0; + border-radius: 3px; + box-shadow: var(--docsearch-key-shadow); + color: var(--docsearch-muted-color); + display: flex; + height: 18px; + margin-right: 0.4em; + padding: 0 0 2px; + position: relative; + top: -1px; + transition-duration: 0.1s; + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + width: 20px; +} + +.DocSearch-Container { + z-index: calc(var(--ifm-z-index-fixed) + 1); +} + +/* --- Hide Duplicate Breadcrumb on Reference Pages --- */ +[class*='docs-doc-id-reference/'] .theme-doc-breadcrumbs { + display: none; +} + +.downloadAsset { + border: 1px solid #4285f4; + background-color: #4285f4; + color: #fff; + text-align: center; + border-radius: 4px; + padding: 0.5rem 1.25rem; + font-weight: 500; + text-decoration: none; + transition: + background-color 0.2s cubic-bezier(0.55, 0.085, 0.68, 0.53), + border-color 0.2s cubic-bezier(0.55, 0.055, 0.675, 0.19), + color 0.2s cubic-bezier(0.55, 0.085, 0.68, 0.53), + transform 0.3s; +} + +.downloadAsset:hover { + border-color: #1a73e8; + background-color: #1a73e8; + transform: scale(1.05); +} + +.compare-better:before { + content: 'thumb_up'; + color: #1e8e3e; + font-family: 'Material Icons' !important; + font-weight: normal; + font-style: normal; + font-size: 24px; + margin-inline: 0 4px; + vertical-align: middle; + width: 24px; +} + +.compare-worse:before { + content: 'thumb_down'; + color: #d50000; + font-family: 'Material Icons' !important; + font-weight: normal; + font-style: normal; + font-size: 24px; + margin-inline: 0 4px; + vertical-align: middle; + width: 24px; +} + +.compare-better, +.compare-worse { + font-weight: 700; +} + +.compare-better p, +.compare-worse p { + margin-top: 0; +} + +.appendInputImg { + width: 145px !important; +} + +h2 { + font-size: 24px; +} + +h3 { + font-size: 20px; +} + +.codelabImages { + text-align: center; +} + +.tabs-container { + border: 1px solid var(--tabs-border); + border-radius: 8px; +} + +.tabs-container p { + padding: 0 0 16px 16px; +} + +.tabs { + border-bottom: 1px solid var(--tabs-border); +} + +.prism-code { + background-color: var(--codeblock-background-color) !important; +} + +/* Hide dark badge by default */ +.blockly-badge-dark { + display: none; +} + +/* When theme is dark, swap visibility */ +[data-theme='dark'] .blockly-badge-light { + display: none; +} + +[data-theme='dark'] .blockly-badge-dark { + display: block; +} + +td { + vertical-align: top; +} + +th { + text-align: left; +} diff --git a/packages/docs/src/pages/index.js b/packages/docs/src/pages/index.js new file mode 100644 index 00000000000..f853dc8650a --- /dev/null +++ b/packages/docs/src/pages/index.js @@ -0,0 +1,63 @@ +import React from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import Layout from '@theme/Layout'; +import HomepageFeatures from '@site/src/components/HomepageFeatures'; + +import Heading from '@theme/Heading'; +import styles from './index.module.css'; + +function HomepageHeader() { + const { siteConfig } = useDocusaurusContext(); + const homePageGif = useBaseUrl('/images/HomePage/home-animation.gif'); + + return ( +
+
+
+
+
Developer docs
+ + Build with Blockly + +

+ An open-source, flexible library for developers to build visual + programming editors with drag-and-drop blocks - powering the + world’s most popular block-based coding platforms. +

+
+ + Get started + +
+
+
+ Blockly code block example +
+
+
+
+ ); +} + +export default function Home() { + const { siteConfig } = useDocusaurusContext(); + return ( + + +
+ +
+
+ ); +} diff --git a/packages/docs/src/pages/index.module.css b/packages/docs/src/pages/index.module.css new file mode 100644 index 00000000000..8cdb4f4d28c --- /dev/null +++ b/packages/docs/src/pages/index.module.css @@ -0,0 +1,134 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +:root { + --hero-description-color: #000000; + --get-started-button: #1967d2; +} + +[data-theme='dark'] { + --hero-description-color: #e3e3e3; + --get-started-button: #25c2a0; +} + +.heroBanner { + padding: 5rem 0 4rem 0; + position: relative; + overflow: hidden; +} + +.heroContent { + display: flex; + align-items: center; + gap: 4rem; + justify-content: space-between; +} + +.heroText { + flex: 1; + text-align: left; +} + +.developerDocsLabel { + display: inline-block; + padding: 0.25rem 0.5rem; + background-color: #e8eaed; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 500; + text-transform: uppercase; + margin-bottom: 16px; + vertical-align: middle; + text-transform: uppercase; + color: #3c4043; +} + +.heroDescription { + font-size: 1rem; + color: var(--hero-description-color); + line-height: 1.6; + margin-bottom: 2rem; + max-width: 600px; +} + +.buttons { + display: flex; + align-items: center; + justify-content: flex-start; +} + +.button { + border: 1px solid #4285f4; + background-color: #4285f4; + color: #fff; + text-align: center; + border-radius: 4px; + padding: 0.5rem 1.25rem; + font-weight: 500; + text-decoration: none; + transition: + background-color 0.2s cubic-bezier(0.55, 0.085, 0.68, 0.53), + border-color 0.2s cubic-bezier(0.55, 0.055, 0.675, 0.19), + color 0.2s cubic-bezier(0.55, 0.085, 0.68, 0.53), + transform 0.3s; +} + +.button:hover { + border-color: #1a73e8; + background-color: #1a73e8; + transform: scale(1.05); +} + +.heroVisual { + flex: 0 0 auto; + display: flex; + align-items: center; + justify-content: center; + max-width: 400px; + min-width: 300px; +} + +.blocklyGif { + max-width: 100%; + max-height: 250px; + width: auto; + height: auto; + display: block; + object-fit: contain; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } + + .heroContent { + flex-direction: column; + gap: 2rem; + text-align: center; + } + + .heroText { + text-align: center; + } + + .heroTitle { + font-size: 2.5rem; + } + + .buttons { + justify-content: center; + } + + .heroVisual { + max-width: 100%; + min-width: auto; + } + + .blocklyGif { + max-width: 60%; + max-height: 200px; + } +} diff --git a/packages/docs/src/theme/Root/index.js b/packages/docs/src/theme/Root/index.js new file mode 100644 index 00000000000..fc613d7f4bf --- /dev/null +++ b/packages/docs/src/theme/Root/index.js @@ -0,0 +1,293 @@ +/** + * Root theme component - wraps the entire app + * Handles client-side tracking + */ + +import React, { useEffect } from 'react'; +import { + trackSiteSearch, + trackCTAClick, + trackCopyCode, + extractFunctionName, +} from '../../utils/tracking'; + +export default function Root({ children }) { + useEffect(() => { + if (typeof window === 'undefined') { + return; + } + + if (!window.dataLayer) { + window.dataLayer = []; + } + + let lastTrackedQuery = ''; + let searchTimeout = null; + + const handleDocSearchQuery = (event) => { + if (event.detail && event.detail.query) { + const query = event.detail.query.trim(); + if (query && query !== lastTrackedQuery && query.length > 0) { + trackSiteSearch(query); + lastTrackedQuery = query; + } + } + }; + + document.addEventListener('docsearch:query', handleDocSearchQuery); + + const setupInputTracking = (searchInput) => { + if (searchInput.hasAttribute('data-tracking-setup')) { + return; + } + + searchInput.setAttribute('data-tracking-setup', 'true'); + + const handleInput = (e) => { + const query = e.target.value.trim(); + + if (searchTimeout) { + clearTimeout(searchTimeout); + } + + if (query.length > 0 && query !== lastTrackedQuery) { + searchTimeout = setTimeout(() => { + trackSiteSearch(query); + lastTrackedQuery = query; + }, 800); + } + }; + + const handleKeyDown = (e) => { + if (e.key === 'Enter') { + const query = e.target.value.trim(); + if (query && query !== lastTrackedQuery && query.length > 0) { + if (searchTimeout) { + clearTimeout(searchTimeout); + } + trackSiteSearch(query); + lastTrackedQuery = query; + } + } + }; + + searchInput.addEventListener('input', handleInput); + searchInput.addEventListener('keydown', handleKeyDown); + }; + + const observer = new MutationObserver(() => { + const searchInput = document.querySelector('.DocSearch-Input'); + if (searchInput) { + setupInputTracking(searchInput); + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true, + }); + + const initialSearchInput = document.querySelector('.DocSearch-Input'); + if (initialSearchInput) { + setupInputTracking(initialSearchInput); + } + + const handleResultClick = (e) => { + const hitElement = e.target.closest('.DocSearch-Hit'); + if (hitElement) { + const searchInput = document.querySelector('.DocSearch-Input'); + if (searchInput && searchInput.value) { + const query = searchInput.value.trim(); + if (query && query !== lastTrackedQuery && query.length > 0) { + trackSiteSearch(query); + lastTrackedQuery = query; + } + } + } + }; + + document.addEventListener('click', handleResultClick); + + // CTA Click Tracking + // Track clicks on buttons and links that should be treated as CTAs + const handleCTAClick = (e) => { + // Find the clicked element (could be button, link, or child element) + let target = e.target; + + // Traverse up to find the actual button/link element + while (target && target !== document.body) { + // Check if it's a button or link with CTA classes + const ctaSelector = + 'a.getStarted, a.button, button.button, .button, a.cardButton, .cardButton, .downloadAsset, a.downloadAsset, .assetDownloadLink, a.assetDownloadLink'; + const isCTA = + target.matches && + (target.matches(ctaSelector) || target.closest(ctaSelector)); + + if (isCTA) { + const ctaElement = target.matches(ctaSelector) + ? target + : target.closest(ctaSelector); + + if (ctaElement) { + let clickUrl = ''; + if (ctaElement.href) { + clickUrl = ctaElement.href; + } else if (ctaElement.getAttribute('href')) { + const href = ctaElement.getAttribute('href'); + clickUrl = href.startsWith('http') + ? href + : window.location.origin + href; + } else if (ctaElement.getAttribute('to')) { + // Docusaurus Link component uses 'to' attribute + const to = ctaElement.getAttribute('to'); + clickUrl = to.startsWith('http') + ? to + : window.location.origin + to; + } else { + clickUrl = window.location.href; + } + + // Get the text content + let clickText = + ctaElement.textContent?.trim() || + ctaElement.innerText?.trim() || + ctaElement.getAttribute('aria-label') || + ctaElement.getAttribute('title') || + 'CTA Click'; + + // Clean up the text (remove extra whitespace) + clickText = clickText.replace(/\s+/g, ' ').trim(); + + // Track the CTA click + if (clickUrl && clickText) { + trackCTAClick(clickUrl, clickText); + } + } + break; + } + target = target.parentElement; + } + }; + + document.addEventListener('click', handleCTAClick); + + // Code Copy Tracking + const handleCodeCopyClick = (e) => { + // Find the copy button (Docusaurus uses a button with aria-label containing "copy") + const copyButton = e.target.closest( + 'button[aria-label*="copy" i], button[aria-label*="copier" i]', + ); + + if (copyButton) { + const codeBlock = copyButton.closest( + 'div[class*="codeBlock"], .theme-code-block, .prism-code, pre', + ); + + if (codeBlock) { + let codeElement = codeBlock.querySelector('code'); + + if (!codeElement) { + const preElement = + codeBlock.querySelector('pre code') || + codeBlock.closest('pre')?.querySelector('code'); + if (preElement) { + codeElement = preElement; + } + } + + if (codeElement) { + // Extract language from class names (recursive search) + const findLanguage = (element) => { + if (!element || element === document.body) return 'unknown'; + + const classList = Array.from(element.classList); + const langClass = classList.find((cls) => + cls.startsWith('language-'), + ); + + if (langClass) { + return langClass.replace('language-', ''); + } + + return findLanguage(element.parentElement); + }; + + // Also check pre element and container for language class + let languageName = findLanguage(codeElement); + if (languageName === 'unknown') { + const preElement = codeElement.closest('pre'); + if (preElement) { + languageName = findLanguage(preElement); + } + } + if (languageName === 'unknown') { + languageName = findLanguage(codeBlock); + } + + const codeContent = + codeElement.textContent || codeElement.innerText || ''; + + const functionName = extractFunctionName(codeContent, languageName); + + trackCopyCode(functionName, languageName); + } + } + } + }; + + // Also listen for copy events to catch any copy operations + const handleCopyEvent = (e) => { + const selection = window.getSelection(); + if (!selection || selection.rangeCount === 0) return; + + const range = selection.getRangeAt(0); + let node = range.commonAncestorContainer; + + if (node.nodeType === Node.TEXT_NODE) { + node = node.parentElement; + } + + const codeElement = node?.closest?.('code'); + if (!codeElement) return; + + // Extract language + const findLanguage = (element) => { + const classList = Array.from(element.classList); + const langClass = classList.find((cls) => cls.startsWith('language-')); + console.log('hello', langClass); + + if (langClass) return langClass.replace('language-', ''); + + const parent = element.parentElement; + if (parent && parent !== document.body) { + return findLanguage(parent); + } + return 'unknown'; + }; + + const languageName = findLanguage(codeElement); + const codeContent = selection.toString() || codeElement.textContent || ''; + const functionName = extractFunctionName(codeContent, languageName); + + trackCopyCode(functionName, languageName); + }; + + document.addEventListener('click', handleCodeCopyClick); + document.addEventListener('copy', handleCopyEvent); + + // Cleanup + return () => { + document.removeEventListener('docsearch:query', handleDocSearchQuery); + document.removeEventListener('click', handleResultClick); + document.removeEventListener('click', handleCTAClick); + document.removeEventListener('click', handleCodeCopyClick); + document.removeEventListener('copy', handleCopyEvent); + observer.disconnect(); + if (searchTimeout) { + clearTimeout(searchTimeout); + } + }; + }, []); + + return <>{children}; +} diff --git a/packages/docs/src/utils/tracking.js b/packages/docs/src/utils/tracking.js new file mode 100644 index 00000000000..cc245feacf9 --- /dev/null +++ b/packages/docs/src/utils/tracking.js @@ -0,0 +1,210 @@ +/** + * Utility functions for pushing custom events to dataLayer for GA4 tracking via GTM + */ + +/** + * Push custom events to dataLayer for GA4 tracking + * @param {string} eventName - The name of the event (e.g., 'site_search', 'cta_click', 'copy_code') + * @param {object} eventParams - Additional parameters to send with the event + */ +export function pushToDataLayer(eventName, eventParams = {}) { + if (typeof window === 'undefined') { + return; + } + + // Ensure dataLayer exists + if (!window.dataLayer) { + window.dataLayer = []; + } + + const eventData = { + event: eventName, + ...eventParams, + }; + + window.dataLayer.push(eventData); +} + +/** + * Track site search with query + * @param {string} searchQuery - The search query entered by the user + */ +export function trackSiteSearch(searchQuery) { + if ( + !searchQuery || + typeof searchQuery !== 'string' || + searchQuery.trim() === '' + ) { + return; + } + + const trimmedQuery = searchQuery.trim(); + + pushToDataLayer('site_search', { + search_query: trimmedQuery, + }); +} + +/** + * Track CTA button clicks + * @param {string} clickUrl - The URL the CTA links to (cta_location) + * @param {string} clickText - The text/label of the CTA button (cta_label) + */ +export function trackCTAClick(clickUrl, clickText) { + if (!clickUrl || !clickText) { + return; + } + + pushToDataLayer('cta_click', { + cta_location: clickUrl, + cta_label: clickText, + }); +} + +/** + * Extract function/method/class/enum name from code + * @param {string} code - The code content + * @param {string} language - The programming language (optional, helps with extraction) + * @returns {string} - The function/method/class/enum name or meaningful identifier + */ +function extractFunctionName(code, language = '') { + if (!code || typeof code !== 'string') { + return 'unknown'; + } + + const trimmedCode = code.trim(); + if (trimmedCode.length === 0) { + return 'unknown'; + } + + // Common keywords and variable names to skip + const skipNames = new Set([ + 'code', + 'let', + 'const', + 'var', + 'import', + 'export', + 'function', + 'preamble', + 'postscript', + 'result', + 'value', + 'data', + 'item', + 'element', + 'obj', + 'arr', + 'str', + 'num', + 'bool', + 'temp', + 'if', + 'for', + 'while', + 'new', + 'return', + 'class', + 'enum', + 'def', + 'try', + 'catch', + 'then', + 'else', + 'async', + 'await', + 'from', + 'as', + ]); + + // For JSON/XML: Extract meaningful keys or identifiers + if (language === 'json' || language === 'xml') { + const jsonKeyPattern = /"([a-zA-Z_$][a-zA-Z0-9_$]{2,})"\s*:/; + const jsonMatch = trimmedCode.match(jsonKeyPattern); + if ( + jsonMatch && + jsonMatch[1] && + !skipNames.has(jsonMatch[1].toLowerCase()) + ) { + return jsonMatch[1]; + } + + // XML: Extract tag name or attribute + const xmlTagPattern = /<([a-zA-Z_$][a-zA-Z0-9_$]{2,})/; + const xmlMatch = trimmedCode.match(xmlTagPattern); + if (xmlMatch && xmlMatch[1] && !skipNames.has(xmlMatch[1].toLowerCase())) { + return xmlMatch[1]; + } + + // Fallback: Extract any meaningful identifier + const identifierPattern = /\b([a-zA-Z_$][a-zA-Z0-9_$]{3,})\b/; + const identifierMatch = trimmedCode.match(identifierPattern); + if ( + identifierMatch && + identifierMatch[1] && + !skipNames.has(identifierMatch[1].toLowerCase()) + ) { + return identifierMatch[1]; + } + + return 'unknown'; + } + + // Priority 1: Method calls with object (e.g., javascriptGenerator.workspaceToCode()) + const methodCallPattern = + /([a-zA-Z_$][a-zA-Z0-9_$]*\.)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/; + const methodMatch = trimmedCode.match(methodCallPattern); + if ( + methodMatch && + methodMatch[2] && + !skipNames.has(methodMatch[2].toLowerCase()) + ) { + return methodMatch[2]; + } + + // Priority 2: Function/Method/Class declarations + const declPattern = + /(?:function|const|let|var|class|enum|def)\s+([a-zA-Z_$][a-zA-Z0-9_$]{2,})/; + const declMatch = trimmedCode.match(declPattern); + if (declMatch && declMatch[1] && !skipNames.has(declMatch[1].toLowerCase())) { + return declMatch[1]; + } + + // Priority 3: Function calls without object (e.g., myFunction()) + const functionCallPattern = /\b([a-zA-Z_$][a-zA-Z0-9_$]{3,})\s*\(/; + const funcMatch = trimmedCode.match(functionCallPattern); + if (funcMatch && funcMatch[1] && !skipNames.has(funcMatch[1].toLowerCase())) { + return funcMatch[1]; + } + + // Last resort: First meaningful identifier + const identifierPattern = /\b([a-zA-Z_$][a-zA-Z0-9_$]{3,})\b/; + const identifierMatch = trimmedCode.match(identifierPattern); + if ( + identifierMatch && + identifierMatch[1] && + !skipNames.has(identifierMatch[1].toLowerCase()) + ) { + return identifierMatch[1]; + } + + return 'unknown'; +} + +/** + * Track code copy events + * @param {string} functionName + * @param {string} languageName + */ +export function trackCopyCode(functionName, languageName) { + if (!functionName || !languageName) { + return; + } + + pushToDataLayer('copy_code', { + function_name: functionName, + language_name: languageName, + }); +} + +export { extractFunctionName }; diff --git a/packages/docs/static/.nojekyll b/packages/docs/static/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/docs/static/algolia-verification.html b/packages/docs/static/algolia-verification.html new file mode 100644 index 00000000000..01b97ddb03a --- /dev/null +++ b/packages/docs/static/algolia-verification.html @@ -0,0 +1,8 @@ + + + + + Algolia Verification + + + diff --git a/packages/docs/static/images/0.png b/packages/docs/static/images/0.png new file mode 100644 index 00000000000..4e48db4cefc Binary files /dev/null and b/packages/docs/static/images/0.png differ diff --git a/packages/docs/static/images/1plus1.png b/packages/docs/static/images/1plus1.png new file mode 100644 index 00000000000..43ac76d3871 Binary files /dev/null and b/packages/docs/static/images/1plus1.png differ diff --git a/packages/docs/static/images/42.png b/packages/docs/static/images/42.png new file mode 100644 index 00000000000..8c45d5eaf47 Binary files /dev/null and b/packages/docs/static/images/42.png differ diff --git a/packages/docs/static/images/CategoryColours-dark.png b/packages/docs/static/images/CategoryColours-dark.png new file mode 100644 index 00000000000..aa8e47dbb85 Binary files /dev/null and b/packages/docs/static/images/CategoryColours-dark.png differ diff --git a/packages/docs/static/images/CategoryColours.png b/packages/docs/static/images/CategoryColours.png new file mode 100644 index 00000000000..30795f3171a Binary files /dev/null and b/packages/docs/static/images/CategoryColours.png differ diff --git a/packages/docs/static/images/ColourExplanation-dark.png b/packages/docs/static/images/ColourExplanation-dark.png new file mode 100644 index 00000000000..d73898f0869 Binary files /dev/null and b/packages/docs/static/images/ColourExplanation-dark.png differ diff --git a/packages/docs/static/images/ColourExplanation.png b/packages/docs/static/images/ColourExplanation.png new file mode 100644 index 00000000000..aca2cd1a158 Binary files /dev/null and b/packages/docs/static/images/ColourExplanation.png differ diff --git a/packages/docs/static/images/HomePage/Accessibility-tier-4.svg b/packages/docs/static/images/HomePage/Accessibility-tier-4.svg new file mode 100644 index 00000000000..325e3c16ca6 --- /dev/null +++ b/packages/docs/static/images/HomePage/Accessibility-tier-4.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/HomePage/Connect-tier-4.svg b/packages/docs/static/images/HomePage/Connect-tier-4.svg new file mode 100644 index 00000000000..68636ab4c61 --- /dev/null +++ b/packages/docs/static/images/HomePage/Connect-tier-4.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/HomePage/Explore-tier-4.svg b/packages/docs/static/images/HomePage/Explore-tier-4.svg new file mode 100644 index 00000000000..03bfd31351c --- /dev/null +++ b/packages/docs/static/images/HomePage/Explore-tier-4.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/HomePage/home-animation.gif b/packages/docs/static/images/HomePage/home-animation.gif new file mode 100644 index 00000000000..5401b4c5aed Binary files /dev/null and b/packages/docs/static/images/HomePage/home-animation.gif differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/accessibility-video-thumbnail.png b/packages/docs/static/images/accessibility-fund-recipients/accessibility-video-thumbnail.png new file mode 100644 index 00000000000..92701d7491d Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/accessibility-video-thumbnail.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/american_printing _house.png b/packages/docs/static/images/accessibility-fund-recipients/american_printing _house.png new file mode 100644 index 00000000000..7b41258a4a2 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/american_printing _house.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/appinventorfoundation.png b/packages/docs/static/images/accessibility-fund-recipients/appinventorfoundation.png new file mode 100644 index 00000000000..022ddcbb0c7 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/appinventorfoundation.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/blockly-accessibility-fund-page-metaImage.png b/packages/docs/static/images/accessibility-fund-recipients/blockly-accessibility-fund-page-metaImage.png new file mode 100644 index 00000000000..dee88ce77d6 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/blockly-accessibility-fund-page-metaImage.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/california-school-for-the-blind.png b/packages/docs/static/images/accessibility-fund-recipients/california-school-for-the-blind.png new file mode 100644 index 00000000000..bd0a6278618 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/california-school-for-the-blind.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/carnegie-mellon-university.png b/packages/docs/static/images/accessibility-fund-recipients/carnegie-mellon-university.png new file mode 100644 index 00000000000..9f1c703e8dc Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/carnegie-mellon-university.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/cits.png b/packages/docs/static/images/accessibility-fund-recipients/cits.png new file mode 100644 index 00000000000..5ab2e5b241c Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/cits.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/codeorg.png b/packages/docs/static/images/accessibility-fund-recipients/codeorg.png new file mode 100644 index 00000000000..de64f8a750d Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/codeorg.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/deaf-kids-code.png b/packages/docs/static/images/accessibility-fund-recipients/deaf-kids-code.png new file mode 100644 index 00000000000..cce271ea193 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/deaf-kids-code.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/first-horz.png b/packages/docs/static/images/accessibility-fund-recipients/first-horz.png new file mode 100644 index 00000000000..76f08d09672 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/first-horz.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/kmcn.png b/packages/docs/static/images/accessibility-fund-recipients/kmcn.png new file mode 100644 index 00000000000..9489d68ac4d Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/kmcn.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/microbit-educational-foundation.png b/packages/docs/static/images/accessibility-fund-recipients/microbit-educational-foundation.png new file mode 100644 index 00000000000..3cc5e356a99 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/microbit-educational-foundation.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/nss.png b/packages/docs/static/images/accessibility-fund-recipients/nss.png new file mode 100644 index 00000000000..9b43d772a65 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/nss.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/scratch.png b/packages/docs/static/images/accessibility-fund-recipients/scratch.png new file mode 100644 index 00000000000..733dc05fb50 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/scratch.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/sistema-thead.png b/packages/docs/static/images/accessibility-fund-recipients/sistema-thead.png new file mode 100644 index 00000000000..49a6f505975 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/sistema-thead.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/university-of-florida.png b/packages/docs/static/images/accessibility-fund-recipients/university-of-florida.png new file mode 100644 index 00000000000..46ed9d53cb8 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/university-of-florida.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/university-of-nevada.png b/packages/docs/static/images/accessibility-fund-recipients/university-of-nevada.png new file mode 100644 index 00000000000..7b1ed38096e Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/university-of-nevada.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/university-of-north-texas.png b/packages/docs/static/images/accessibility-fund-recipients/university-of-north-texas.png new file mode 100644 index 00000000000..61226bd4707 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/university-of-north-texas.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/university-of-washington.png b/packages/docs/static/images/accessibility-fund-recipients/university-of-washington.png new file mode 100644 index 00000000000..580940bed94 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/university-of-washington.png differ diff --git a/packages/docs/static/images/accessibility-fund-recipients/zeroday.png b/packages/docs/static/images/accessibility-fund-recipients/zeroday.png new file mode 100644 index 00000000000..7c5a67c758b Binary files /dev/null and b/packages/docs/static/images/accessibility-fund-recipients/zeroday.png differ diff --git a/packages/docs/static/images/accessibility-fund/accessibility-application-tilt.png b/packages/docs/static/images/accessibility-fund/accessibility-application-tilt.png new file mode 100644 index 00000000000..ea752844423 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/accessibility-application-tilt.png differ diff --git a/packages/docs/static/images/accessibility-fund/accessibility-application.png b/packages/docs/static/images/accessibility-fund/accessibility-application.png new file mode 100644 index 00000000000..e81c5bc2166 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/accessibility-application.png differ diff --git a/packages/docs/static/images/accessibility-fund/accessibility-tilt.png b/packages/docs/static/images/accessibility-fund/accessibility-tilt.png new file mode 100644 index 00000000000..ce01558fc36 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/accessibility-tilt.png differ diff --git a/packages/docs/static/images/accessibility-fund/accessibility-tools.png b/packages/docs/static/images/accessibility-fund/accessibility-tools.png new file mode 100644 index 00000000000..46d83ac175a Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/accessibility-tools.png differ diff --git a/packages/docs/static/images/accessibility-fund/accessibility.png b/packages/docs/static/images/accessibility-fund/accessibility.png new file mode 100644 index 00000000000..81d20266bfa Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/accessibility.png differ diff --git a/packages/docs/static/images/accessibility-fund/blockly-latest-version.png b/packages/docs/static/images/accessibility-fund/blockly-latest-version.png new file mode 100644 index 00000000000..38a425cbf3a Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/blockly-latest-version.png differ diff --git a/packages/docs/static/images/accessibility-fund/effective-solution.png b/packages/docs/static/images/accessibility-fund/effective-solution.png new file mode 100644 index 00000000000..82bbc32cbf0 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/effective-solution.png differ diff --git a/packages/docs/static/images/accessibility-fund/event_96.png b/packages/docs/static/images/accessibility-fund/event_96.png new file mode 100644 index 00000000000..6115c7cf2db Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/event_96.png differ diff --git a/packages/docs/static/images/accessibility-fund/mark_email_unread.png b/packages/docs/static/images/accessibility-fund/mark_email_unread.png new file mode 100644 index 00000000000..0f482cca9d6 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/mark_email_unread.png differ diff --git a/packages/docs/static/images/accessibility-fund/upcoming_96.png b/packages/docs/static/images/accessibility-fund/upcoming_96.png new file mode 100644 index 00000000000..465526d2701 Binary files /dev/null and b/packages/docs/static/images/accessibility-fund/upcoming_96.png differ diff --git a/packages/docs/static/images/accessibility/accessibility-tilt-at.png b/packages/docs/static/images/accessibility/accessibility-tilt-at.png new file mode 100644 index 00000000000..ce01558fc36 Binary files /dev/null and b/packages/docs/static/images/accessibility/accessibility-tilt-at.png differ diff --git a/packages/docs/static/images/accessibility/csta-logo.png b/packages/docs/static/images/accessibility/csta-logo.png new file mode 100644 index 00000000000..6521f71202a Binary files /dev/null and b/packages/docs/static/images/accessibility/csta-logo.png differ diff --git a/packages/docs/static/images/accessibility/design1.png b/packages/docs/static/images/accessibility/design1.png new file mode 100644 index 00000000000..8e98a626eef Binary files /dev/null and b/packages/docs/static/images/accessibility/design1.png differ diff --git a/packages/docs/static/images/accessibility/design2.png b/packages/docs/static/images/accessibility/design2.png new file mode 100644 index 00000000000..644bc681bdb Binary files /dev/null and b/packages/docs/static/images/accessibility/design2.png differ diff --git a/packages/docs/static/images/accessibility/design3.png b/packages/docs/static/images/accessibility/design3.png new file mode 100644 index 00000000000..b5d5282c8e3 Binary files /dev/null and b/packages/docs/static/images/accessibility/design3.png differ diff --git a/packages/docs/static/images/accessibility/elissa-hozore.png b/packages/docs/static/images/accessibility/elissa-hozore.png new file mode 100644 index 00000000000..89bdd096b70 Binary files /dev/null and b/packages/docs/static/images/accessibility/elissa-hozore.png differ diff --git a/packages/docs/static/images/accessibility/keyword-blog.png b/packages/docs/static/images/accessibility/keyword-blog.png new file mode 100644 index 00000000000..5eb7d571a8a Binary files /dev/null and b/packages/docs/static/images/accessibility/keyword-blog.png differ diff --git a/packages/docs/static/images/accessibility/misc.png b/packages/docs/static/images/accessibility/misc.png new file mode 100644 index 00000000000..75dd5c6c6a4 Binary files /dev/null and b/packages/docs/static/images/accessibility/misc.png differ diff --git a/packages/docs/static/images/accessibility/rectangle-hero.jpg b/packages/docs/static/images/accessibility/rectangle-hero.jpg new file mode 100644 index 00000000000..0ff81cd3b56 Binary files /dev/null and b/packages/docs/static/images/accessibility/rectangle-hero.jpg differ diff --git a/packages/docs/static/images/accessibility/section-left-eyebrow.png b/packages/docs/static/images/accessibility/section-left-eyebrow.png new file mode 100644 index 00000000000..ed9655da776 Binary files /dev/null and b/packages/docs/static/images/accessibility/section-left-eyebrow.png differ diff --git a/packages/docs/static/images/angle-picker.png b/packages/docs/static/images/angle-picker.png new file mode 100644 index 00000000000..d7e335f4ffa Binary files /dev/null and b/packages/docs/static/images/angle-picker.png differ diff --git a/packages/docs/static/images/append-field-label.png b/packages/docs/static/images/append-field-label.png new file mode 100644 index 00000000000..852c6d626c0 Binary files /dev/null and b/packages/docs/static/images/append-field-label.png differ diff --git a/packages/docs/static/images/append-field.png b/packages/docs/static/images/append-field.png new file mode 100644 index 00000000000..468fae42664 Binary files /dev/null and b/packages/docs/static/images/append-field.png differ diff --git a/packages/docs/static/images/append-input.png b/packages/docs/static/images/append-input.png new file mode 100644 index 00000000000..fd1f1975951 Binary files /dev/null and b/packages/docs/static/images/append-input.png differ diff --git a/packages/docs/static/images/application-overview/games-maze-dark.png b/packages/docs/static/images/application-overview/games-maze-dark.png new file mode 100644 index 00000000000..b848094d2cf Binary files /dev/null and b/packages/docs/static/images/application-overview/games-maze-dark.png differ diff --git a/packages/docs/static/images/application-overview/games-maze.png b/packages/docs/static/images/application-overview/games-maze.png new file mode 100644 index 00000000000..88f40c46cdc Binary files /dev/null and b/packages/docs/static/images/application-overview/games-maze.png differ diff --git a/packages/docs/static/images/application-overview/graph-sample-dark.png b/packages/docs/static/images/application-overview/graph-sample-dark.png new file mode 100644 index 00000000000..b2f28ba7966 Binary files /dev/null and b/packages/docs/static/images/application-overview/graph-sample-dark.png differ diff --git a/packages/docs/static/images/application-overview/graph-sample.png b/packages/docs/static/images/application-overview/graph-sample.png new file mode 100644 index 00000000000..b4a3f9cb743 Binary files /dev/null and b/packages/docs/static/images/application-overview/graph-sample.png differ diff --git a/packages/docs/static/images/application-overview/makecode-arcade-dark.png b/packages/docs/static/images/application-overview/makecode-arcade-dark.png new file mode 100644 index 00000000000..02727077fdc Binary files /dev/null and b/packages/docs/static/images/application-overview/makecode-arcade-dark.png differ diff --git a/packages/docs/static/images/application-overview/makecode-arcade.png b/packages/docs/static/images/application-overview/makecode-arcade.png new file mode 100644 index 00000000000..68e4be1d54a Binary files /dev/null and b/packages/docs/static/images/application-overview/makecode-arcade.png differ diff --git a/packages/docs/static/images/application-overview/mit-app-inventor-blockly-dark.png b/packages/docs/static/images/application-overview/mit-app-inventor-blockly-dark.png new file mode 100644 index 00000000000..869cc16654c Binary files /dev/null and b/packages/docs/static/images/application-overview/mit-app-inventor-blockly-dark.png differ diff --git a/packages/docs/static/images/application-overview/mit-app-inventor-blockly.png b/packages/docs/static/images/application-overview/mit-app-inventor-blockly.png new file mode 100644 index 00000000000..9ada35302bf Binary files /dev/null and b/packages/docs/static/images/application-overview/mit-app-inventor-blockly.png differ diff --git a/packages/docs/static/images/application-overview/mit-app-inventor-gui-dark.png b/packages/docs/static/images/application-overview/mit-app-inventor-gui-dark.png new file mode 100644 index 00000000000..f6e8ef2f7b4 Binary files /dev/null and b/packages/docs/static/images/application-overview/mit-app-inventor-gui-dark.png differ diff --git a/packages/docs/static/images/application-overview/mit-app-inventor-gui.png b/packages/docs/static/images/application-overview/mit-app-inventor-gui.png new file mode 100644 index 00000000000..28a65108633 Binary files /dev/null and b/packages/docs/static/images/application-overview/mit-app-inventor-gui.png differ diff --git a/packages/docs/static/images/application-overview/mit-scratch-dark.png b/packages/docs/static/images/application-overview/mit-scratch-dark.png new file mode 100644 index 00000000000..df65445cb8b Binary files /dev/null and b/packages/docs/static/images/application-overview/mit-scratch-dark.png differ diff --git a/packages/docs/static/images/application-overview/mit-scratch.png b/packages/docs/static/images/application-overview/mit-scratch.png new file mode 100644 index 00000000000..53a7a9174b4 Binary files /dev/null and b/packages/docs/static/images/application-overview/mit-scratch.png differ diff --git a/packages/docs/static/images/block-anatomy/comment-icon-dark.png b/packages/docs/static/images/block-anatomy/comment-icon-dark.png new file mode 100644 index 00000000000..1b52978b75b Binary files /dev/null and b/packages/docs/static/images/block-anatomy/comment-icon-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/comment-icon.png b/packages/docs/static/images/block-anatomy/comment-icon.png new file mode 100644 index 00000000000..2f591ee186c Binary files /dev/null and b/packages/docs/static/images/block-anatomy/comment-icon.png differ diff --git a/packages/docs/static/images/block-anatomy/controls-for.png b/packages/docs/static/images/block-anatomy/controls-for.png new file mode 100644 index 00000000000..d0dbb0df6dc Binary files /dev/null and b/packages/docs/static/images/block-anatomy/controls-for.png differ diff --git a/packages/docs/static/images/block-anatomy/dummy-input-1-3-dark.png b/packages/docs/static/images/block-anatomy/dummy-input-1-3-dark.png new file mode 100644 index 00000000000..37d0cab5ee9 Binary files /dev/null and b/packages/docs/static/images/block-anatomy/dummy-input-1-3-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/dummy-input-1-3.png b/packages/docs/static/images/block-anatomy/dummy-input-1-3.png new file mode 100644 index 00000000000..06dd36774ad Binary files /dev/null and b/packages/docs/static/images/block-anatomy/dummy-input-1-3.png differ diff --git a/packages/docs/static/images/block-anatomy/dummy-input-3-1-dark.png b/packages/docs/static/images/block-anatomy/dummy-input-3-1-dark.png new file mode 100644 index 00000000000..7d20c0a8200 Binary files /dev/null and b/packages/docs/static/images/block-anatomy/dummy-input-3-1-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/dummy-input-3-1.png b/packages/docs/static/images/block-anatomy/dummy-input-3-1.png new file mode 100644 index 00000000000..be36e7ebcd9 Binary files /dev/null and b/packages/docs/static/images/block-anatomy/dummy-input-3-1.png differ diff --git a/packages/docs/static/images/block-anatomy/dummy-input-simple-dark.png b/packages/docs/static/images/block-anatomy/dummy-input-simple-dark.png new file mode 100644 index 00000000000..80fdffe12ef Binary files /dev/null and b/packages/docs/static/images/block-anatomy/dummy-input-simple-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/dummy-input-simple.png b/packages/docs/static/images/block-anatomy/dummy-input-simple.png new file mode 100644 index 00000000000..a5529e8d54a Binary files /dev/null and b/packages/docs/static/images/block-anatomy/dummy-input-simple.png differ diff --git a/packages/docs/static/images/block-anatomy/end-of-row-inputs-dark.png b/packages/docs/static/images/block-anatomy/end-of-row-inputs-dark.png new file mode 100644 index 00000000000..f1b313b7142 Binary files /dev/null and b/packages/docs/static/images/block-anatomy/end-of-row-inputs-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/end-of-row-inputs.png b/packages/docs/static/images/block-anatomy/end-of-row-inputs.png new file mode 100644 index 00000000000..ab4bea28fec Binary files /dev/null and b/packages/docs/static/images/block-anatomy/end-of-row-inputs.png differ diff --git a/packages/docs/static/images/block-anatomy/loop-dark.png b/packages/docs/static/images/block-anatomy/loop-dark.png new file mode 100644 index 00000000000..ed8f54fa319 Binary files /dev/null and b/packages/docs/static/images/block-anatomy/loop-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/loop.png b/packages/docs/static/images/block-anatomy/loop.png new file mode 100644 index 00000000000..bb0373ca48c Binary files /dev/null and b/packages/docs/static/images/block-anatomy/loop.png differ diff --git a/packages/docs/static/images/block-anatomy/output-connection-dark.png b/packages/docs/static/images/block-anatomy/output-connection-dark.png new file mode 100644 index 00000000000..6b7ac437b1e Binary files /dev/null and b/packages/docs/static/images/block-anatomy/output-connection-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/output-connection.png b/packages/docs/static/images/block-anatomy/output-connection.png new file mode 100644 index 00000000000..235526c0fbe Binary files /dev/null and b/packages/docs/static/images/block-anatomy/output-connection.png differ diff --git a/packages/docs/static/images/block-anatomy/prev-next-connection-dark.png b/packages/docs/static/images/block-anatomy/prev-next-connection-dark.png new file mode 100644 index 00000000000..a9d619e5a7d Binary files /dev/null and b/packages/docs/static/images/block-anatomy/prev-next-connection-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/prev-next-connection.png b/packages/docs/static/images/block-anatomy/prev-next-connection.png new file mode 100644 index 00000000000..0696ac4ce9a Binary files /dev/null and b/packages/docs/static/images/block-anatomy/prev-next-connection.png differ diff --git a/packages/docs/static/images/block-anatomy/statement-input-dark.png b/packages/docs/static/images/block-anatomy/statement-input-dark.png new file mode 100644 index 00000000000..035b0316a1d Binary files /dev/null and b/packages/docs/static/images/block-anatomy/statement-input-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/statement-input-ite-dark.png b/packages/docs/static/images/block-anatomy/statement-input-ite-dark.png new file mode 100644 index 00000000000..03987b46634 Binary files /dev/null and b/packages/docs/static/images/block-anatomy/statement-input-ite-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/statement-input-ite.png b/packages/docs/static/images/block-anatomy/statement-input-ite.png new file mode 100644 index 00000000000..3a6cf9d63aa Binary files /dev/null and b/packages/docs/static/images/block-anatomy/statement-input-ite.png differ diff --git a/packages/docs/static/images/block-anatomy/statement-input-repeat-dark.png b/packages/docs/static/images/block-anatomy/statement-input-repeat-dark.png new file mode 100644 index 00000000000..35cb5d759cd Binary files /dev/null and b/packages/docs/static/images/block-anatomy/statement-input-repeat-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/statement-input-repeat.png b/packages/docs/static/images/block-anatomy/statement-input-repeat.png new file mode 100644 index 00000000000..07ff8e9b737 Binary files /dev/null and b/packages/docs/static/images/block-anatomy/statement-input-repeat.png differ diff --git a/packages/docs/static/images/block-anatomy/value-inputs-addition-dark.png b/packages/docs/static/images/block-anatomy/value-inputs-addition-dark.png new file mode 100644 index 00000000000..098174f5b1f Binary files /dev/null and b/packages/docs/static/images/block-anatomy/value-inputs-addition-dark.png differ diff --git a/packages/docs/static/images/block-anatomy/value-inputs-addition.png b/packages/docs/static/images/block-anatomy/value-inputs-addition.png new file mode 100644 index 00000000000..7f206f73a25 Binary files /dev/null and b/packages/docs/static/images/block-anatomy/value-inputs-addition.png differ diff --git a/packages/docs/static/images/block-factory/block_factory_configuration.png b/packages/docs/static/images/block-factory/block_factory_configuration.png new file mode 100644 index 00000000000..0590ac768ed Binary files /dev/null and b/packages/docs/static/images/block-factory/block_factory_configuration.png differ diff --git a/packages/docs/static/images/block-factory/block_factory_import.png b/packages/docs/static/images/block-factory/block_factory_import.png new file mode 100644 index 00000000000..c55832f9213 Binary files /dev/null and b/packages/docs/static/images/block-factory/block_factory_import.png differ diff --git a/packages/docs/static/images/block-factory/block_factory_legacy_export.png b/packages/docs/static/images/block-factory/block_factory_legacy_export.png new file mode 100644 index 00000000000..b245ffc51d5 Binary files /dev/null and b/packages/docs/static/images/block-factory/block_factory_legacy_export.png differ diff --git a/packages/docs/static/images/block-factory/block_factory_overview.png b/packages/docs/static/images/block-factory/block_factory_overview.png new file mode 100644 index 00000000000..e474d86ce45 Binary files /dev/null and b/packages/docs/static/images/block-factory/block_factory_overview.png differ diff --git a/packages/docs/static/images/block-icons/comment-icon-outline.png b/packages/docs/static/images/block-icons/comment-icon-outline.png new file mode 100644 index 00000000000..a8e4814b6a9 Binary files /dev/null and b/packages/docs/static/images/block-icons/comment-icon-outline.png differ diff --git a/packages/docs/static/images/block_exporter_select.png b/packages/docs/static/images/block_exporter_select.png new file mode 100644 index 00000000000..e67b257518c Binary files /dev/null and b/packages/docs/static/images/block_exporter_select.png differ diff --git a/packages/docs/static/images/block_exporter_tab.png b/packages/docs/static/images/block_exporter_tab.png new file mode 100644 index 00000000000..4187de84d95 Binary files /dev/null and b/packages/docs/static/images/block_exporter_tab.png differ diff --git a/packages/docs/static/images/block_manage_buttons.png b/packages/docs/static/images/block_manage_buttons.png new file mode 100644 index 00000000000..ba17a3db347 Binary files /dev/null and b/packages/docs/static/images/block_manage_buttons.png differ diff --git a/packages/docs/static/images/block_save_as.png b/packages/docs/static/images/block_save_as.png new file mode 100644 index 00000000000..47b001b5299 Binary files /dev/null and b/packages/docs/static/images/block_save_as.png differ diff --git a/packages/docs/static/images/blocklib_button.png b/packages/docs/static/images/blocklib_button.png new file mode 100644 index 00000000000..675fb9f33a7 Binary files /dev/null and b/packages/docs/static/images/blocklib_button.png differ diff --git a/packages/docs/static/images/blockly-dark-theme-logo.png b/packages/docs/static/images/blockly-dark-theme-logo.png new file mode 100644 index 00000000000..5d7a05a8400 Binary files /dev/null and b/packages/docs/static/images/blockly-dark-theme-logo.png differ diff --git a/packages/docs/static/images/blockly_banner.png b/packages/docs/static/images/blockly_banner.png new file mode 100644 index 00000000000..465f8b39a58 Binary files /dev/null and b/packages/docs/static/images/blockly_banner.png differ diff --git a/packages/docs/static/images/bubbles/bubble_head_tail.png b/packages/docs/static/images/bubbles/bubble_head_tail.png new file mode 100644 index 00000000000..e66cad4dbb6 Binary files /dev/null and b/packages/docs/static/images/bubbles/bubble_head_tail.png differ diff --git a/packages/docs/static/images/bubbles/bubbles.png b/packages/docs/static/images/bubbles/bubbles.png new file mode 100644 index 00000000000..7cfa199201d Binary files /dev/null and b/packages/docs/static/images/bubbles/bubbles.png differ diff --git a/packages/docs/static/images/category_menu.png b/packages/docs/static/images/category_menu.png new file mode 100644 index 00000000000..7fb5acb4ab1 Binary files /dev/null and b/packages/docs/static/images/category_menu.png differ diff --git a/packages/docs/static/images/code-generation/custom-compare.png b/packages/docs/static/images/code-generation/custom-compare.png new file mode 100644 index 00000000000..3b6d8ce21bf Binary files /dev/null and b/packages/docs/static/images/code-generation/custom-compare.png differ diff --git a/packages/docs/static/images/code-generation/custom-if.png b/packages/docs/static/images/code-generation/custom-if.png new file mode 100644 index 00000000000..1122dbafae7 Binary files /dev/null and b/packages/docs/static/images/code-generation/custom-if.png differ diff --git a/packages/docs/static/images/code-generation/parentheses/negate-plus-two-with-child.png b/packages/docs/static/images/code-generation/parentheses/negate-plus-two-with-child.png new file mode 100644 index 00000000000..eadd56694db Binary files /dev/null and b/packages/docs/static/images/code-generation/parentheses/negate-plus-two-with-child.png differ diff --git a/packages/docs/static/images/code-generation/parentheses/negate-plus-two.png b/packages/docs/static/images/code-generation/parentheses/negate-plus-two.png new file mode 100644 index 00000000000..6041732005b Binary files /dev/null and b/packages/docs/static/images/code-generation/parentheses/negate-plus-two.png differ diff --git a/packages/docs/static/images/code-generation/parentheses/negation-and-addition.png b/packages/docs/static/images/code-generation/parentheses/negation-and-addition.png new file mode 100644 index 00000000000..a8d6063dcf8 Binary files /dev/null and b/packages/docs/static/images/code-generation/parentheses/negation-and-addition.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_blockly-toolbox-dark.png b/packages/docs/static/images/codelabs/card_thumbnails_blockly-toolbox-dark.png new file mode 100644 index 00000000000..89abb76eaa2 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_blockly-toolbox-dark.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_blockly-toolbox.png b/packages/docs/static/images/codelabs/card_thumbnails_blockly-toolbox.png new file mode 100644 index 00000000000..780030334a3 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_blockly-toolbox.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_context-menus-dark.png b/packages/docs/static/images/codelabs/card_thumbnails_context-menus-dark.png new file mode 100644 index 00000000000..8285ee2cc86 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_context-menus-dark.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_context-menus.png b/packages/docs/static/images/codelabs/card_thumbnails_context-menus.png new file mode 100644 index 00000000000..081d4f16789 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_context-menus.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_css-dark.png b/packages/docs/static/images/codelabs/card_thumbnails_css-dark.png new file mode 100644 index 00000000000..cd03309abbf Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_css-dark.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_css.png b/packages/docs/static/images/codelabs/card_thumbnails_css.png new file mode 100644 index 00000000000..2c14f758fec Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_css.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_custom-generator-dark.png b/packages/docs/static/images/codelabs/card_thumbnails_custom-generator-dark.png new file mode 100644 index 00000000000..321c3b344b1 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_custom-generator-dark.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_custom-generator.png b/packages/docs/static/images/codelabs/card_thumbnails_custom-generator.png new file mode 100644 index 00000000000..28b02ded005 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_custom-generator.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_custom-renderers-dark.png b/packages/docs/static/images/codelabs/card_thumbnails_custom-renderers-dark.png new file mode 100644 index 00000000000..e29cd16ce72 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_custom-renderers-dark.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_custom-renderers.png b/packages/docs/static/images/codelabs/card_thumbnails_custom-renderers.png new file mode 100644 index 00000000000..f122f96823c Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_custom-renderers.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_getting-started-dark.png b/packages/docs/static/images/codelabs/card_thumbnails_getting-started-dark.png new file mode 100644 index 00000000000..e17e83cdeb6 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_getting-started-dark.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_getting-started.png b/packages/docs/static/images/codelabs/card_thumbnails_getting-started.png new file mode 100644 index 00000000000..83a455c4511 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_getting-started.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_themes-dark.png b/packages/docs/static/images/codelabs/card_thumbnails_themes-dark.png new file mode 100644 index 00000000000..4362a40bf2e Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_themes-dark.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_themes.png b/packages/docs/static/images/codelabs/card_thumbnails_themes.png new file mode 100644 index 00000000000..ba52addce79 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_themes.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_validating-and-displaying-dark.png b/packages/docs/static/images/codelabs/card_thumbnails_validating-and-displaying-dark.png new file mode 100644 index 00000000000..3f065998105 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_validating-and-displaying-dark.png differ diff --git a/packages/docs/static/images/codelabs/card_thumbnails_validating-and-displaying.png b/packages/docs/static/images/codelabs/card_thumbnails_validating-and-displaying.png new file mode 100644 index 00000000000..0d8b35e9026 Binary files /dev/null and b/packages/docs/static/images/codelabs/card_thumbnails_validating-and-displaying.png differ diff --git a/packages/docs/static/images/codelabs/context-menu-option/hello_world.png b/packages/docs/static/images/codelabs/context-menu-option/hello_world.png new file mode 100644 index 00000000000..628f8b99968 Binary files /dev/null and b/packages/docs/static/images/codelabs/context-menu-option/hello_world.png differ diff --git a/packages/docs/static/images/codelabs/context-menu-option/hello_world_block.png b/packages/docs/static/images/codelabs/context-menu-option/hello_world_block.png new file mode 100644 index 00000000000..0f85c7b5fe6 Binary files /dev/null and b/packages/docs/static/images/codelabs/context-menu-option/hello_world_block.png differ diff --git a/packages/docs/static/images/codelabs/context-menu-option/hello_world_grey.png b/packages/docs/static/images/codelabs/context-menu-option/hello_world_grey.png new file mode 100644 index 00000000000..f398b0cfc48 Binary files /dev/null and b/packages/docs/static/images/codelabs/context-menu-option/hello_world_grey.png differ diff --git a/packages/docs/static/images/codelabs/context-menu-option/starter_workspace.png b/packages/docs/static/images/codelabs/context-menu-option/starter_workspace.png new file mode 100644 index 00000000000..538b8dea1af Binary files /dev/null and b/packages/docs/static/images/codelabs/context-menu-option/starter_workspace.png differ diff --git a/packages/docs/static/images/codelabs/context-menu-option/there_is_a_block.png b/packages/docs/static/images/codelabs/context-menu-option/there_is_a_block.png new file mode 100644 index 00000000000..d1032ad6d32 Binary files /dev/null and b/packages/docs/static/images/codelabs/context-menu-option/there_is_a_block.png differ diff --git a/packages/docs/static/images/codelabs/css/blocks-arrow-right.png b/packages/docs/static/images/codelabs/css/blocks-arrow-right.png new file mode 100644 index 00000000000..3ff0f5e76c3 Binary files /dev/null and b/packages/docs/static/images/codelabs/css/blocks-arrow-right.png differ diff --git a/packages/docs/static/images/codelabs/css/blocks-arrow-wrong.png b/packages/docs/static/images/codelabs/css/blocks-arrow-wrong.png new file mode 100644 index 00000000000..130a2b94096 Binary files /dev/null and b/packages/docs/static/images/codelabs/css/blocks-arrow-wrong.png differ diff --git a/packages/docs/static/images/codelabs/css/blocks-disabled-right.png b/packages/docs/static/images/codelabs/css/blocks-disabled-right.png new file mode 100644 index 00000000000..40881b3558a Binary files /dev/null and b/packages/docs/static/images/codelabs/css/blocks-disabled-right.png differ diff --git a/packages/docs/static/images/codelabs/css/blocks-disabled-wrong.png b/packages/docs/static/images/codelabs/css/blocks-disabled-wrong.png new file mode 100644 index 00000000000..b63a55f9971 Binary files /dev/null and b/packages/docs/static/images/codelabs/css/blocks-disabled-wrong.png differ diff --git a/packages/docs/static/images/codelabs/css/blocks-logic.png b/packages/docs/static/images/codelabs/css/blocks-logic.png new file mode 100644 index 00000000000..8a703717df4 Binary files /dev/null and b/packages/docs/static/images/codelabs/css/blocks-logic.png differ diff --git a/packages/docs/static/images/codelabs/css/blocks-loops.png b/packages/docs/static/images/codelabs/css/blocks-loops.png new file mode 100644 index 00000000000..b829b7b1399 Binary files /dev/null and b/packages/docs/static/images/codelabs/css/blocks-loops.png differ diff --git a/packages/docs/static/images/codelabs/css/categories-halloween.png b/packages/docs/static/images/codelabs/css/categories-halloween.png new file mode 100644 index 00000000000..a856466f6cf Binary files /dev/null and b/packages/docs/static/images/codelabs/css/categories-halloween.png differ diff --git a/packages/docs/static/images/codelabs/css/categories-logic.png b/packages/docs/static/images/codelabs/css/categories-logic.png new file mode 100644 index 00000000000..039ecda02e4 Binary files /dev/null and b/packages/docs/static/images/codelabs/css/categories-logic.png differ diff --git a/packages/docs/static/images/codelabs/css/components-halloween.png b/packages/docs/static/images/codelabs/css/components-halloween.png new file mode 100644 index 00000000000..a6b00f65bf8 Binary files /dev/null and b/packages/docs/static/images/codelabs/css/components-halloween.png differ diff --git a/packages/docs/static/images/codelabs/css/components-mutator.png b/packages/docs/static/images/codelabs/css/components-mutator.png new file mode 100644 index 00000000000..f6583f79a39 Binary files /dev/null and b/packages/docs/static/images/codelabs/css/components-mutator.png differ diff --git a/packages/docs/static/images/codelabs/css/components-workspace.png b/packages/docs/static/images/codelabs/css/components-workspace.png new file mode 100644 index 00000000000..d4d3231b5fe Binary files /dev/null and b/packages/docs/static/images/codelabs/css/components-workspace.png differ diff --git a/packages/docs/static/images/codelabs/css/setup-starter.png b/packages/docs/static/images/codelabs/css/setup-starter.png new file mode 100644 index 00000000000..ff7b2b16f10 Binary files /dev/null and b/packages/docs/static/images/codelabs/css/setup-starter.png differ diff --git a/packages/docs/static/images/codelabs/css/tour-dev-tools.png b/packages/docs/static/images/codelabs/css/tour-dev-tools.png new file mode 100644 index 00000000000..ad8241e5deb Binary files /dev/null and b/packages/docs/static/images/codelabs/css/tour-dev-tools.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/array_block.png b/packages/docs/static/images/codelabs/custom-generator/array_block.png new file mode 100644 index 00000000000..8712a1a93a9 Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/array_block.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/boolean_block.png b/packages/docs/static/images/codelabs/custom-generator/boolean_block.png new file mode 100644 index 00000000000..e2541b3610e Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/boolean_block.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/generate_simple_code.png b/packages/docs/static/images/codelabs/custom-generator/generate_simple_code.png new file mode 100644 index 00000000000..2c39c9f308e Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/generate_simple_code.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/json_workspace.png b/packages/docs/static/images/codelabs/custom-generator/json_workspace.png new file mode 100644 index 00000000000..1c3916bd446 Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/json_workspace.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/member_block.png b/packages/docs/static/images/codelabs/custom-generator/member_block.png new file mode 100644 index 00000000000..213cf02e40c Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/member_block.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/null_block.png b/packages/docs/static/images/codelabs/custom-generator/null_block.png new file mode 100644 index 00000000000..6c3b7df95df Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/null_block.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/number_block.png b/packages/docs/static/images/codelabs/custom-generator/number_block.png new file mode 100644 index 00000000000..269cdfb625f Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/number_block.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/object_block.png b/packages/docs/static/images/codelabs/custom-generator/object_block.png new file mode 100644 index 00000000000..b29b2253747 Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/object_block.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/text_block.png b/packages/docs/static/images/codelabs/custom-generator/text_block.png new file mode 100644 index 00000000000..83780c8b4a7 Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/text_block.png differ diff --git a/packages/docs/static/images/codelabs/custom-generator/toolbox_blocks.png b/packages/docs/static/images/codelabs/custom-generator/toolbox_blocks.png new file mode 100644 index 00000000000..9a792e8067f Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-generator/toolbox_blocks.png differ diff --git a/packages/docs/static/images/codelabs/custom-renderer/custom_constants.png b/packages/docs/static/images/codelabs/custom-renderer/custom_constants.png new file mode 100644 index 00000000000..f15c34bfb8e Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-renderer/custom_constants.png differ diff --git a/packages/docs/static/images/codelabs/custom-renderer/custom_notches.png b/packages/docs/static/images/codelabs/custom-renderer/custom_notches.png new file mode 100644 index 00000000000..ffd484c68ec Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-renderer/custom_notches.png differ diff --git a/packages/docs/static/images/codelabs/custom-renderer/custom_renderer.png b/packages/docs/static/images/codelabs/custom-renderer/custom_renderer.png new file mode 100644 index 00000000000..9a557dcd646 Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-renderer/custom_renderer.png differ diff --git a/packages/docs/static/images/codelabs/custom-renderer/typed_connection_shapes.png b/packages/docs/static/images/codelabs/custom-renderer/typed_connection_shapes.png new file mode 100644 index 00000000000..43121197b48 Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-renderer/typed_connection_shapes.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/base_toolbox.png b/packages/docs/static/images/codelabs/custom-toolbox/base_toolbox.png new file mode 100644 index 00000000000..138e069abef Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/base_toolbox.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/category_gear.png b/packages/docs/static/images/codelabs/custom-toolbox/category_gear.png new file mode 100644 index 00000000000..d26eb6c901f Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/category_gear.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/category_gear_selected.png b/packages/docs/static/images/codelabs/custom-toolbox/category_gear_selected.png new file mode 100644 index 00000000000..41f56e0e30a Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/category_gear_selected.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/category_selected.png b/packages/docs/static/images/codelabs/custom-toolbox/category_selected.png new file mode 100644 index 00000000000..c494fa422c4 Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/category_selected.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/colored_toolbox.png b/packages/docs/static/images/codelabs/custom-toolbox/colored_toolbox.png new file mode 100644 index 00000000000..80c2a2c1c12 Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/colored_toolbox.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/custom_label.png b/packages/docs/static/images/codelabs/custom-toolbox/custom_label.png new file mode 100644 index 00000000000..ef64708a50a Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/custom_label.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/final_toolbox.png b/packages/docs/static/images/codelabs/custom-toolbox/final_toolbox.png new file mode 100644 index 00000000000..a44e35b69da Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/final_toolbox.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/image_toolbox.png b/packages/docs/static/images/codelabs/custom-toolbox/image_toolbox.png new file mode 100644 index 00000000000..f855303ed8e Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/image_toolbox.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/starter_workspace.png b/packages/docs/static/images/codelabs/custom-toolbox/starter_workspace.png new file mode 100644 index 00000000000..00f859634dd Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/starter_workspace.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/styled_toolbox.png b/packages/docs/static/images/codelabs/custom-toolbox/styled_toolbox.png new file mode 100644 index 00000000000..3683b32bc4c Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/styled_toolbox.png differ diff --git a/packages/docs/static/images/codelabs/custom-toolbox/toolbox_label.png b/packages/docs/static/images/codelabs/custom-toolbox/toolbox_label.png new file mode 100644 index 00000000000..ee59229e626 Binary files /dev/null and b/packages/docs/static/images/codelabs/custom-toolbox/toolbox_label.png differ diff --git a/packages/docs/static/images/codelabs/getting-started/d4_three_times.png b/packages/docs/static/images/codelabs/getting-started/d4_three_times.png new file mode 100644 index 00000000000..095e597799f Binary files /dev/null and b/packages/docs/static/images/codelabs/getting-started/d4_three_times.png differ diff --git a/packages/docs/static/images/codelabs/getting-started/edit_mode_unimplemented.png b/packages/docs/static/images/codelabs/getting-started/edit_mode_unimplemented.png new file mode 100644 index 00000000000..6a5ea33cdf0 Binary files /dev/null and b/packages/docs/static/images/codelabs/getting-started/edit_mode_unimplemented.png differ diff --git a/packages/docs/static/images/codelabs/getting-started/play_mode.png b/packages/docs/static/images/codelabs/getting-started/play_mode.png new file mode 100644 index 00000000000..399991303e2 Binary files /dev/null and b/packages/docs/static/images/codelabs/getting-started/play_mode.png differ diff --git a/packages/docs/static/images/codelabs/getting-started/play_sound_block.png b/packages/docs/static/images/codelabs/getting-started/play_sound_block.png new file mode 100644 index 00000000000..6f5623c5515 Binary files /dev/null and b/packages/docs/static/images/codelabs/getting-started/play_sound_block.png differ diff --git a/packages/docs/static/images/codelabs/getting-started/toolbox_two_blocks.png b/packages/docs/static/images/codelabs/getting-started/toolbox_two_blocks.png new file mode 100644 index 00000000000..9552a1f7b2c Binary files /dev/null and b/packages/docs/static/images/codelabs/getting-started/toolbox_two_blocks.png differ diff --git a/packages/docs/static/images/codelabs/getting-started/workspace_with_loop.png b/packages/docs/static/images/codelabs/getting-started/workspace_with_loop.png new file mode 100644 index 00000000000..431562c08bc Binary files /dev/null and b/packages/docs/static/images/codelabs/getting-started/workspace_with_loop.png differ diff --git a/packages/docs/static/images/codelabs/getting-started/workspace_with_loops.png b/packages/docs/static/images/codelabs/getting-started/workspace_with_loops.png new file mode 100644 index 00000000000..ac9ea1f6bc4 Binary files /dev/null and b/packages/docs/static/images/codelabs/getting-started/workspace_with_loops.png differ diff --git a/packages/docs/static/images/codelabs/getting-started/workspace_with_toolbox.png b/packages/docs/static/images/codelabs/getting-started/workspace_with_toolbox.png new file mode 100644 index 00000000000..5272b95a94a Binary files /dev/null and b/packages/docs/static/images/codelabs/getting-started/workspace_with_toolbox.png differ diff --git a/packages/docs/static/images/codelabs/theme-extension/block_styles.png b/packages/docs/static/images/codelabs/theme-extension/block_styles.png new file mode 100644 index 00000000000..fb3c71e2206 Binary files /dev/null and b/packages/docs/static/images/codelabs/theme-extension/block_styles.png differ diff --git a/packages/docs/static/images/codelabs/theme-extension/customized_categories.png b/packages/docs/static/images/codelabs/theme-extension/customized_categories.png new file mode 100644 index 00000000000..29cb8df48b3 Binary files /dev/null and b/packages/docs/static/images/codelabs/theme-extension/customized_categories.png differ diff --git a/packages/docs/static/images/codelabs/theme-extension/starter_workspace.png b/packages/docs/static/images/codelabs/theme-extension/starter_workspace.png new file mode 100644 index 00000000000..57a52d0cdad Binary files /dev/null and b/packages/docs/static/images/codelabs/theme-extension/starter_workspace.png differ diff --git a/packages/docs/static/images/codelabs/theme-extension/theme_components_workspace.png b/packages/docs/static/images/codelabs/theme-extension/theme_components_workspace.png new file mode 100644 index 00000000000..cd6664bee0a Binary files /dev/null and b/packages/docs/static/images/codelabs/theme-extension/theme_components_workspace.png differ diff --git a/packages/docs/static/images/codelabs/validation-and-warnings/completed_toolbox.png b/packages/docs/static/images/codelabs/validation-and-warnings/completed_toolbox.png new file mode 100644 index 00000000000..7dcd0edb8ef Binary files /dev/null and b/packages/docs/static/images/codelabs/validation-and-warnings/completed_toolbox.png differ diff --git a/packages/docs/static/images/codelabs/validation-and-warnings/disabled_block.png b/packages/docs/static/images/codelabs/validation-and-warnings/disabled_block.png new file mode 100644 index 00000000000..97fa6f7ea19 Binary files /dev/null and b/packages/docs/static/images/codelabs/validation-and-warnings/disabled_block.png differ diff --git a/packages/docs/static/images/codelabs/validation-and-warnings/disabled_break.png b/packages/docs/static/images/codelabs/validation-and-warnings/disabled_break.png new file mode 100644 index 00000000000..120b3658047 Binary files /dev/null and b/packages/docs/static/images/codelabs/validation-and-warnings/disabled_break.png differ diff --git a/packages/docs/static/images/codelabs/validation-and-warnings/final_range_blocks.png b/packages/docs/static/images/codelabs/validation-and-warnings/final_range_blocks.png new file mode 100644 index 00000000000..b50160d1bc9 Binary files /dev/null and b/packages/docs/static/images/codelabs/validation-and-warnings/final_range_blocks.png differ diff --git a/packages/docs/static/images/codelabs/validation-and-warnings/generated_javascript.png b/packages/docs/static/images/codelabs/validation-and-warnings/generated_javascript.png new file mode 100644 index 00000000000..3c65ead5be8 Binary files /dev/null and b/packages/docs/static/images/codelabs/validation-and-warnings/generated_javascript.png differ diff --git a/packages/docs/static/images/codelabs/validation-and-warnings/starter_workspace.png b/packages/docs/static/images/codelabs/validation-and-warnings/starter_workspace.png new file mode 100644 index 00000000000..abf842e57a8 Binary files /dev/null and b/packages/docs/static/images/codelabs/validation-and-warnings/starter_workspace.png differ diff --git a/packages/docs/static/images/codelabs/validation-and-warnings/warning_message.png b/packages/docs/static/images/codelabs/validation-and-warnings/warning_message.png new file mode 100644 index 00000000000..dd51e8b8c29 Binary files /dev/null and b/packages/docs/static/images/codelabs/validation-and-warnings/warning_message.png differ diff --git a/packages/docs/static/images/configuration.png b/packages/docs/static/images/configuration.png new file mode 100644 index 00000000000..2614dada389 Binary files /dev/null and b/packages/docs/static/images/configuration.png differ diff --git a/packages/docs/static/images/configure_workspace.png b/packages/docs/static/images/configure_workspace.png new file mode 100644 index 00000000000..17bfd1c6726 Binary files /dev/null and b/packages/docs/static/images/configure_workspace.png differ diff --git a/packages/docs/static/images/connection-checks/statements-either-or.png b/packages/docs/static/images/connection-checks/statements-either-or.png new file mode 100644 index 00000000000..f32f6d48618 Binary files /dev/null and b/packages/docs/static/images/connection-checks/statements-either-or.png differ diff --git a/packages/docs/static/images/connection-checks/statements-multiple-middle-blocks.png b/packages/docs/static/images/connection-checks/statements-multiple-middle-blocks.png new file mode 100644 index 00000000000..ebbef86275f Binary files /dev/null and b/packages/docs/static/images/connection-checks/statements-multiple-middle-blocks.png differ diff --git a/packages/docs/static/images/connection-checks/statements-no-middle-blocks.png b/packages/docs/static/images/connection-checks/statements-no-middle-blocks.png new file mode 100644 index 00000000000..b121bd08c92 Binary files /dev/null and b/packages/docs/static/images/connection-checks/statements-no-middle-blocks.png differ diff --git a/packages/docs/static/images/connection-checks/statements-ordered.png b/packages/docs/static/images/connection-checks/statements-ordered.png new file mode 100644 index 00000000000..8bb050f1210 Binary files /dev/null and b/packages/docs/static/images/connection-checks/statements-ordered.png differ diff --git a/packages/docs/static/images/connection-checks/values-any-type.jpg b/packages/docs/static/images/connection-checks/values-any-type.jpg new file mode 100644 index 00000000000..184b2b661d5 Binary files /dev/null and b/packages/docs/static/images/connection-checks/values-any-type.jpg differ diff --git a/packages/docs/static/images/connection-checks/values-multiple.jpg b/packages/docs/static/images/connection-checks/values-multiple.jpg new file mode 100644 index 00000000000..679a014b446 Binary files /dev/null and b/packages/docs/static/images/connection-checks/values-multiple.jpg differ diff --git a/packages/docs/static/images/connection-checks/values-parameterized-type.png b/packages/docs/static/images/connection-checks/values-parameterized-type.png new file mode 100644 index 00000000000..b8e22d10049 Binary files /dev/null and b/packages/docs/static/images/connection-checks/values-parameterized-type.png differ diff --git a/packages/docs/static/images/connection-checks/values-single.jpg b/packages/docs/static/images/connection-checks/values-single.jpg new file mode 100644 index 00000000000..822c919760a Binary files /dev/null and b/packages/docs/static/images/connection-checks/values-single.jpg differ diff --git a/packages/docs/static/images/connection-checks/values-subtype.png b/packages/docs/static/images/connection-checks/values-subtype.png new file mode 100644 index 00000000000..e1cf568f49b Binary files /dev/null and b/packages/docs/static/images/connection-checks/values-subtype.png differ diff --git a/packages/docs/static/images/connections/built-in-insertion-preview.png b/packages/docs/static/images/connections/built-in-insertion-preview.png new file mode 100644 index 00000000000..ee72719cbd8 Binary files /dev/null and b/packages/docs/static/images/connections/built-in-insertion-preview.png differ diff --git a/packages/docs/static/images/connections/built-in-previewer.gif b/packages/docs/static/images/connections/built-in-previewer.gif new file mode 100644 index 00000000000..455c3059a0d Binary files /dev/null and b/packages/docs/static/images/connections/built-in-previewer.gif differ diff --git a/packages/docs/static/images/connections/built-in-replacement-preview.png b/packages/docs/static/images/connections/built-in-replacement-preview.png new file mode 100644 index 00000000000..5c900d9fc62 Binary files /dev/null and b/packages/docs/static/images/connections/built-in-replacement-preview.png differ diff --git a/packages/docs/static/images/connections/dummy-input-dark.png b/packages/docs/static/images/connections/dummy-input-dark.png new file mode 100644 index 00000000000..a5a29314734 Binary files /dev/null and b/packages/docs/static/images/connections/dummy-input-dark.png differ diff --git a/packages/docs/static/images/connections/dummy-input.png b/packages/docs/static/images/connections/dummy-input.png new file mode 100644 index 00000000000..b732c0c1d07 Binary files /dev/null and b/packages/docs/static/images/connections/dummy-input.png differ diff --git a/packages/docs/static/images/connections/input-connection-dark.png b/packages/docs/static/images/connections/input-connection-dark.png new file mode 100644 index 00000000000..ec99c073373 Binary files /dev/null and b/packages/docs/static/images/connections/input-connection-dark.png differ diff --git a/packages/docs/static/images/connections/input-connection.png b/packages/docs/static/images/connections/input-connection.png new file mode 100644 index 00000000000..6bf51ae8068 Binary files /dev/null and b/packages/docs/static/images/connections/input-connection.png differ diff --git a/packages/docs/static/images/connections/next-connection.png b/packages/docs/static/images/connections/next-connection.png new file mode 100644 index 00000000000..528f8425cd1 Binary files /dev/null and b/packages/docs/static/images/connections/next-connection.png differ diff --git a/packages/docs/static/images/connections/output-connection.png b/packages/docs/static/images/connections/output-connection.png new file mode 100644 index 00000000000..7ef2761b68e Binary files /dev/null and b/packages/docs/static/images/connections/output-connection.png differ diff --git a/packages/docs/static/images/connections/previous-connection.png b/packages/docs/static/images/connections/previous-connection.png new file mode 100644 index 00000000000..597790a34be Binary files /dev/null and b/packages/docs/static/images/connections/previous-connection.png differ diff --git a/packages/docs/static/images/connections/statement-input-dark.png b/packages/docs/static/images/connections/statement-input-dark.png new file mode 100644 index 00000000000..035b0316a1d Binary files /dev/null and b/packages/docs/static/images/connections/statement-input-dark.png differ diff --git a/packages/docs/static/images/connections/statement-input.png b/packages/docs/static/images/connections/statement-input.png new file mode 100644 index 00000000000..be9e9801cc5 Binary files /dev/null and b/packages/docs/static/images/connections/statement-input.png differ diff --git a/packages/docs/static/images/context-menus/block-default-menu.png b/packages/docs/static/images/context-menus/block-default-menu.png new file mode 100644 index 00000000000..43703f9ad00 Binary files /dev/null and b/packages/docs/static/images/context-menus/block-default-menu.png differ diff --git a/packages/docs/static/images/context-menus/disabled-option.png b/packages/docs/static/images/context-menus/disabled-option.png new file mode 100644 index 00000000000..03ded0ca536 Binary files /dev/null and b/packages/docs/static/images/context-menus/disabled-option.png differ diff --git a/packages/docs/static/images/context-menus/enabled-option.png b/packages/docs/static/images/context-menus/enabled-option.png new file mode 100644 index 00000000000..a3f9a56b171 Binary files /dev/null and b/packages/docs/static/images/context-menus/enabled-option.png differ diff --git a/packages/docs/static/images/count-with.png b/packages/docs/static/images/count-with.png new file mode 100644 index 00000000000..55188fbeca4 Binary files /dev/null and b/packages/docs/static/images/count-with.png differ diff --git a/packages/docs/static/images/createlist-ar.png b/packages/docs/static/images/createlist-ar.png new file mode 100644 index 00000000000..f06a36734de Binary files /dev/null and b/packages/docs/static/images/createlist-ar.png differ diff --git a/packages/docs/static/images/createlist-en.png b/packages/docs/static/images/createlist-en.png new file mode 100644 index 00000000000..c67e982fc2c Binary files /dev/null and b/packages/docs/static/images/createlist-en.png differ diff --git a/packages/docs/static/images/createlist-es.png b/packages/docs/static/images/createlist-es.png new file mode 100644 index 00000000000..2e0727f15a3 Binary files /dev/null and b/packages/docs/static/images/createlist-es.png differ diff --git a/packages/docs/static/images/createlist-ko.png b/packages/docs/static/images/createlist-ko.png new file mode 100644 index 00000000000..9591afb4bab Binary files /dev/null and b/packages/docs/static/images/createlist-ko.png differ diff --git a/packages/docs/static/images/disabled.png b/packages/docs/static/images/disabled.png new file mode 100644 index 00000000000..a9d2dedce50 Binary files /dev/null and b/packages/docs/static/images/disabled.png differ diff --git a/packages/docs/static/images/download.png b/packages/docs/static/images/download.png new file mode 100644 index 00000000000..4b336a1ae7c Binary files /dev/null and b/packages/docs/static/images/download.png differ diff --git a/packages/docs/static/images/edit_category.png b/packages/docs/static/images/edit_category.png new file mode 100644 index 00000000000..5211851a17a Binary files /dev/null and b/packages/docs/static/images/edit_category.png differ diff --git a/packages/docs/static/images/event1.png b/packages/docs/static/images/event1.png new file mode 100644 index 00000000000..e1b161923e1 Binary files /dev/null and b/packages/docs/static/images/event1.png differ diff --git a/packages/docs/static/images/event2.png b/packages/docs/static/images/event2.png new file mode 100644 index 00000000000..a89cc80f8af Binary files /dev/null and b/packages/docs/static/images/event2.png differ diff --git a/packages/docs/static/images/example-blocks/move-forward.png b/packages/docs/static/images/example-blocks/move-forward.png new file mode 100644 index 00000000000..b93e50bb518 Binary files /dev/null and b/packages/docs/static/images/example-blocks/move-forward.png differ diff --git a/packages/docs/static/images/example-image.png b/packages/docs/static/images/example-image.png new file mode 100644 index 00000000000..61014886ed1 Binary files /dev/null and b/packages/docs/static/images/example-image.png differ diff --git a/packages/docs/static/images/external.svg b/packages/docs/static/images/external.svg new file mode 100644 index 00000000000..35521a2e69f --- /dev/null +++ b/packages/docs/static/images/external.svg @@ -0,0 +1,4 @@ + + + diff --git a/packages/docs/static/images/favicon.svg b/packages/docs/static/images/favicon.svg new file mode 100644 index 00000000000..4616ee99f98 --- /dev/null +++ b/packages/docs/static/images/favicon.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + logo-only + + + + + + + + logo-only + + + + + diff --git a/packages/docs/static/images/field-angle.png b/packages/docs/static/images/field-angle.png new file mode 100644 index 00000000000..00739bfb4aa Binary files /dev/null and b/packages/docs/static/images/field-angle.png differ diff --git a/packages/docs/static/images/fields/angle/collapsed.png b/packages/docs/static/images/fields/angle/collapsed.png new file mode 100644 index 00000000000..9149f012cc2 Binary files /dev/null and b/packages/docs/static/images/fields/angle/collapsed.png differ diff --git a/packages/docs/static/images/fields/angle/compass.gif b/packages/docs/static/images/fields/angle/compass.gif new file mode 100644 index 00000000000..ac5c1d44553 Binary files /dev/null and b/packages/docs/static/images/fields/angle/compass.gif differ diff --git a/packages/docs/static/images/fields/angle/on_block.png b/packages/docs/static/images/fields/angle/on_block.png new file mode 100644 index 00000000000..ddc1d9b93c9 Binary files /dev/null and b/packages/docs/static/images/fields/angle/on_block.png differ diff --git a/packages/docs/static/images/fields/angle/validator.gif b/packages/docs/static/images/fields/angle/validator.gif new file mode 100644 index 00000000000..4257c56eafa Binary files /dev/null and b/packages/docs/static/images/fields/angle/validator.gif differ diff --git a/packages/docs/static/images/fields/angle/with_editor.png b/packages/docs/static/images/fields/angle/with_editor.png new file mode 100644 index 00000000000..415a151cc13 Binary files /dev/null and b/packages/docs/static/images/fields/angle/with_editor.png differ diff --git a/packages/docs/static/images/fields/angle/wrap.gif b/packages/docs/static/images/fields/angle/wrap.gif new file mode 100644 index 00000000000..146f7b29e3e Binary files /dev/null and b/packages/docs/static/images/fields/angle/wrap.gif differ diff --git a/packages/docs/static/images/fields/checkbox/collapsed.png b/packages/docs/static/images/fields/checkbox/collapsed.png new file mode 100644 index 00000000000..269ff11dbba Binary files /dev/null and b/packages/docs/static/images/fields/checkbox/collapsed.png differ diff --git a/packages/docs/static/images/fields/checkbox/customized.png b/packages/docs/static/images/fields/checkbox/customized.png new file mode 100644 index 00000000000..73cc91f61f5 Binary files /dev/null and b/packages/docs/static/images/fields/checkbox/customized.png differ diff --git a/packages/docs/static/images/fields/checkbox/on_block.png b/packages/docs/static/images/fields/checkbox/on_block.png new file mode 100644 index 00000000000..70b24fa6b56 Binary files /dev/null and b/packages/docs/static/images/fields/checkbox/on_block.png differ diff --git a/packages/docs/static/images/fields/checkbox/validator.gif b/packages/docs/static/images/fields/checkbox/validator.gif new file mode 100644 index 00000000000..782da15260e Binary files /dev/null and b/packages/docs/static/images/fields/checkbox/validator.gif differ diff --git a/packages/docs/static/images/fields/colour/collapsed.png b/packages/docs/static/images/fields/colour/collapsed.png new file mode 100644 index 00000000000..6ea18d4fae2 Binary files /dev/null and b/packages/docs/static/images/fields/colour/collapsed.png differ diff --git a/packages/docs/static/images/fields/colour/customized.png b/packages/docs/static/images/fields/colour/customized.png new file mode 100644 index 00000000000..04b9c74b04d Binary files /dev/null and b/packages/docs/static/images/fields/colour/customized.png differ diff --git a/packages/docs/static/images/fields/colour/on_block.png b/packages/docs/static/images/fields/colour/on_block.png new file mode 100644 index 00000000000..52905008103 Binary files /dev/null and b/packages/docs/static/images/fields/colour/on_block.png differ diff --git a/packages/docs/static/images/fields/colour/validator.gif b/packages/docs/static/images/fields/colour/validator.gif new file mode 100644 index 00000000000..bfcd87d72b5 Binary files /dev/null and b/packages/docs/static/images/fields/colour/validator.gif differ diff --git a/packages/docs/static/images/fields/colour/with_editor.png b/packages/docs/static/images/fields/colour/with_editor.png new file mode 100644 index 00000000000..960f0fa02d8 Binary files /dev/null and b/packages/docs/static/images/fields/colour/with_editor.png differ diff --git a/packages/docs/static/images/fields/date/collapsed.png b/packages/docs/static/images/fields/date/collapsed.png new file mode 100644 index 00000000000..1c3c114398e Binary files /dev/null and b/packages/docs/static/images/fields/date/collapsed.png differ diff --git a/packages/docs/static/images/fields/date/on_block.png b/packages/docs/static/images/fields/date/on_block.png new file mode 100644 index 00000000000..7fa09a77a28 Binary files /dev/null and b/packages/docs/static/images/fields/date/on_block.png differ diff --git a/packages/docs/static/images/fields/date/validator.gif b/packages/docs/static/images/fields/date/validator.gif new file mode 100644 index 00000000000..d9166b6432c Binary files /dev/null and b/packages/docs/static/images/fields/date/validator.gif differ diff --git a/packages/docs/static/images/fields/date/with_editor.png b/packages/docs/static/images/fields/date/with_editor.png new file mode 100644 index 00000000000..fee150ee728 Binary files /dev/null and b/packages/docs/static/images/fields/date/with_editor.png differ diff --git a/packages/docs/static/images/fields/dropdown/collapsed.png b/packages/docs/static/images/fields/dropdown/collapsed.png new file mode 100644 index 00000000000..54a2976a132 Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/collapsed.png differ diff --git a/packages/docs/static/images/fields/dropdown/customized_arrow.png b/packages/docs/static/images/fields/dropdown/customized_arrow.png new file mode 100644 index 00000000000..63f383482c4 Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/customized_arrow.png differ diff --git a/packages/docs/static/images/fields/dropdown/dynamic.png b/packages/docs/static/images/fields/dropdown/dynamic.png new file mode 100644 index 00000000000..e1d073fb320 Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/dynamic.png differ diff --git a/packages/docs/static/images/fields/dropdown/on_block.png b/packages/docs/static/images/fields/dropdown/on_block.png new file mode 100644 index 00000000000..8c78dd50965 Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/on_block.png differ diff --git a/packages/docs/static/images/fields/dropdown/prefix_matched.png b/packages/docs/static/images/fields/dropdown/prefix_matched.png new file mode 100644 index 00000000000..cd4cd683db5 Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/prefix_matched.png differ diff --git a/packages/docs/static/images/fields/dropdown/validator.gif b/packages/docs/static/images/fields/dropdown/validator.gif new file mode 100644 index 00000000000..7de6ba71bff Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/validator.gif differ diff --git a/packages/docs/static/images/fields/dropdown/with_editor.png b/packages/docs/static/images/fields/dropdown/with_editor.png new file mode 100644 index 00000000000..df3ddad24a8 Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/with_editor.png differ diff --git a/packages/docs/static/images/fields/dropdown/with_html.png b/packages/docs/static/images/fields/dropdown/with_html.png new file mode 100644 index 00000000000..e89ed21c275 Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/with_html.png differ diff --git a/packages/docs/static/images/fields/dropdown/with_images.png b/packages/docs/static/images/fields/dropdown/with_images.png new file mode 100644 index 00000000000..24182df5292 Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/with_images.png differ diff --git a/packages/docs/static/images/fields/dropdown/with_separator.png b/packages/docs/static/images/fields/dropdown/with_separator.png new file mode 100644 index 00000000000..d1433c3c6a5 Binary files /dev/null and b/packages/docs/static/images/fields/dropdown/with_separator.png differ diff --git a/packages/docs/static/images/fields/field_construction_flowchart.jpg b/packages/docs/static/images/fields/field_construction_flowchart.jpg new file mode 100644 index 00000000000..b9c884572d4 Binary files /dev/null and b/packages/docs/static/images/fields/field_construction_flowchart.jpg differ diff --git a/packages/docs/static/images/fields/image/click_handler.gif b/packages/docs/static/images/fields/image/click_handler.gif new file mode 100644 index 00000000000..bbb2a37b4f4 Binary files /dev/null and b/packages/docs/static/images/fields/image/click_handler.gif differ diff --git a/packages/docs/static/images/fields/image/collapsed.png b/packages/docs/static/images/fields/image/collapsed.png new file mode 100644 index 00000000000..1cf00af083a Binary files /dev/null and b/packages/docs/static/images/fields/image/collapsed.png differ diff --git a/packages/docs/static/images/fields/image/on_block.png b/packages/docs/static/images/fields/image/on_block.png new file mode 100644 index 00000000000..be9edc208ab Binary files /dev/null and b/packages/docs/static/images/fields/image/on_block.png differ diff --git a/packages/docs/static/images/fields/label-serializable/collapsed.png b/packages/docs/static/images/fields/label-serializable/collapsed.png new file mode 100644 index 00000000000..e7344d72e3c Binary files /dev/null and b/packages/docs/static/images/fields/label-serializable/collapsed.png differ diff --git a/packages/docs/static/images/fields/label-serializable/on_block.png b/packages/docs/static/images/fields/label-serializable/on_block.png new file mode 100644 index 00000000000..b2ce13f966f Binary files /dev/null and b/packages/docs/static/images/fields/label-serializable/on_block.png differ diff --git a/packages/docs/static/images/fields/label/collapsed.png b/packages/docs/static/images/fields/label/collapsed.png new file mode 100644 index 00000000000..ac2b18d554e Binary files /dev/null and b/packages/docs/static/images/fields/label/collapsed.png differ diff --git a/packages/docs/static/images/fields/label/on_block.png b/packages/docs/static/images/fields/label/on_block.png new file mode 100644 index 00000000000..85ad43bf5b2 Binary files /dev/null and b/packages/docs/static/images/fields/label/on_block.png differ diff --git a/packages/docs/static/images/fields/modifying_validator.gif b/packages/docs/static/images/fields/modifying_validator.gif new file mode 100644 index 00000000000..01a89076c64 Binary files /dev/null and b/packages/docs/static/images/fields/modifying_validator.gif differ diff --git a/packages/docs/static/images/fields/multiline-text-input/collapsed.png b/packages/docs/static/images/fields/multiline-text-input/collapsed.png new file mode 100644 index 00000000000..a227642a705 Binary files /dev/null and b/packages/docs/static/images/fields/multiline-text-input/collapsed.png differ diff --git a/packages/docs/static/images/fields/multiline-text-input/on_block.png b/packages/docs/static/images/fields/multiline-text-input/on_block.png new file mode 100644 index 00000000000..6a52a4aa926 Binary files /dev/null and b/packages/docs/static/images/fields/multiline-text-input/on_block.png differ diff --git a/packages/docs/static/images/fields/multiline-text-input/spellcheck.gif b/packages/docs/static/images/fields/multiline-text-input/spellcheck.gif new file mode 100644 index 00000000000..3f1ae53fa9e Binary files /dev/null and b/packages/docs/static/images/fields/multiline-text-input/spellcheck.gif differ diff --git a/packages/docs/static/images/fields/multiline-text-input/validator.gif b/packages/docs/static/images/fields/multiline-text-input/validator.gif new file mode 100644 index 00000000000..b9e18a1dc06 Binary files /dev/null and b/packages/docs/static/images/fields/multiline-text-input/validator.gif differ diff --git a/packages/docs/static/images/fields/multiline-text-input/with_editor.png b/packages/docs/static/images/fields/multiline-text-input/with_editor.png new file mode 100644 index 00000000000..98dacf3a907 Binary files /dev/null and b/packages/docs/static/images/fields/multiline-text-input/with_editor.png differ diff --git a/packages/docs/static/images/fields/nulling_validator.gif b/packages/docs/static/images/fields/nulling_validator.gif new file mode 100644 index 00000000000..057c342dfb4 Binary files /dev/null and b/packages/docs/static/images/fields/nulling_validator.gif differ diff --git a/packages/docs/static/images/fields/number/collapsed.png b/packages/docs/static/images/fields/number/collapsed.png new file mode 100644 index 00000000000..21fc3ecfe96 Binary files /dev/null and b/packages/docs/static/images/fields/number/collapsed.png differ diff --git a/packages/docs/static/images/fields/number/on_block.png b/packages/docs/static/images/fields/number/on_block.png new file mode 100644 index 00000000000..965375c372d Binary files /dev/null and b/packages/docs/static/images/fields/number/on_block.png differ diff --git a/packages/docs/static/images/fields/number/validator.gif b/packages/docs/static/images/fields/number/validator.gif new file mode 100644 index 00000000000..c1cf8af8526 Binary files /dev/null and b/packages/docs/static/images/fields/number/validator.gif differ diff --git a/packages/docs/static/images/fields/number/with_editor.png b/packages/docs/static/images/fields/number/with_editor.png new file mode 100644 index 00000000000..9cdab925278 Binary files /dev/null and b/packages/docs/static/images/fields/number/with_editor.png differ diff --git a/packages/docs/static/images/fields/text-input/collapsed.png b/packages/docs/static/images/fields/text-input/collapsed.png new file mode 100644 index 00000000000..0b327173a47 Binary files /dev/null and b/packages/docs/static/images/fields/text-input/collapsed.png differ diff --git a/packages/docs/static/images/fields/text-input/on_block.png b/packages/docs/static/images/fields/text-input/on_block.png new file mode 100644 index 00000000000..0f17c0b3047 Binary files /dev/null and b/packages/docs/static/images/fields/text-input/on_block.png differ diff --git a/packages/docs/static/images/fields/text-input/spellcheck.gif b/packages/docs/static/images/fields/text-input/spellcheck.gif new file mode 100644 index 00000000000..f31be897e3a Binary files /dev/null and b/packages/docs/static/images/fields/text-input/spellcheck.gif differ diff --git a/packages/docs/static/images/fields/text-input/validator.gif b/packages/docs/static/images/fields/text-input/validator.gif new file mode 100644 index 00000000000..01a89076c64 Binary files /dev/null and b/packages/docs/static/images/fields/text-input/validator.gif differ diff --git a/packages/docs/static/images/fields/text-input/with_editor.png b/packages/docs/static/images/fields/text-input/with_editor.png new file mode 100644 index 00000000000..2c534975d28 Binary files /dev/null and b/packages/docs/static/images/fields/text-input/with_editor.png differ diff --git a/packages/docs/static/images/fields/tooltip.gif b/packages/docs/static/images/fields/tooltip.gif new file mode 100644 index 00000000000..7c368481b8a Binary files /dev/null and b/packages/docs/static/images/fields/tooltip.gif differ diff --git a/packages/docs/static/images/fields/variable/collapsed.png b/packages/docs/static/images/fields/variable/collapsed.png new file mode 100644 index 00000000000..0d73705a7df Binary files /dev/null and b/packages/docs/static/images/fields/variable/collapsed.png differ diff --git a/packages/docs/static/images/fields/variable/on_block.png b/packages/docs/static/images/fields/variable/on_block.png new file mode 100644 index 00000000000..222f911cff6 Binary files /dev/null and b/packages/docs/static/images/fields/variable/on_block.png differ diff --git a/packages/docs/static/images/fields/variable/validator.gif b/packages/docs/static/images/fields/variable/validator.gif new file mode 100644 index 00000000000..88ed127c7de Binary files /dev/null and b/packages/docs/static/images/fields/variable/validator.gif differ diff --git a/packages/docs/static/images/fields/variable/with_editor.png b/packages/docs/static/images/fields/variable/with_editor.png new file mode 100644 index 00000000000..648599ea354 Binary files /dev/null and b/packages/docs/static/images/fields/variable/with_editor.png differ diff --git a/packages/docs/static/images/fields/yertle_collapsing.gif b/packages/docs/static/images/fields/yertle_collapsing.gif new file mode 100644 index 00000000000..4b025c183cd Binary files /dev/null and b/packages/docs/static/images/fields/yertle_collapsing.gif differ diff --git a/packages/docs/static/images/fruit-salad.png b/packages/docs/static/images/fruit-salad.png new file mode 100644 index 00000000000..40a6502ed9d Binary files /dev/null and b/packages/docs/static/images/fruit-salad.png differ diff --git a/packages/docs/static/images/gap.png b/packages/docs/static/images/gap.png new file mode 100644 index 00000000000..27e394356e8 Binary files /dev/null and b/packages/docs/static/images/gap.png differ diff --git a/packages/docs/static/images/getter-and-setter.png b/packages/docs/static/images/getter-and-setter.png new file mode 100644 index 00000000000..ac43b264a63 Binary files /dev/null and b/packages/docs/static/images/getter-and-setter.png differ diff --git a/packages/docs/static/images/glossary/block-stack.png b/packages/docs/static/images/glossary/block-stack.png new file mode 100644 index 00000000000..3ff97131aa2 Binary files /dev/null and b/packages/docs/static/images/glossary/block-stack.png differ diff --git a/packages/docs/static/images/glossary/blocks.png b/packages/docs/static/images/glossary/blocks.png new file mode 100644 index 00000000000..19e5c3e4a3f Binary files /dev/null and b/packages/docs/static/images/glossary/blocks.png differ diff --git a/packages/docs/static/images/glossary/category-toolbox.png b/packages/docs/static/images/glossary/category-toolbox.png new file mode 100644 index 00000000000..13ebe3f746d Binary files /dev/null and b/packages/docs/static/images/glossary/category-toolbox.png differ diff --git a/packages/docs/static/images/glossary/category-with-flyout-toolbox.png b/packages/docs/static/images/glossary/category-with-flyout-toolbox.png new file mode 100644 index 00000000000..a8eab34746a Binary files /dev/null and b/packages/docs/static/images/glossary/category-with-flyout-toolbox.png differ diff --git a/packages/docs/static/images/glossary/context-menu.png b/packages/docs/static/images/glossary/context-menu.png new file mode 100644 index 00000000000..d41e4dd8bb6 Binary files /dev/null and b/packages/docs/static/images/glossary/context-menu.png differ diff --git a/packages/docs/static/images/glossary/fields.png b/packages/docs/static/images/glossary/fields.png new file mode 100644 index 00000000000..f1a6cc2e633 Binary files /dev/null and b/packages/docs/static/images/glossary/fields.png differ diff --git a/packages/docs/static/images/glossary/flyout-toolbox.png b/packages/docs/static/images/glossary/flyout-toolbox.png new file mode 100644 index 00000000000..d64ec7988d8 Binary files /dev/null and b/packages/docs/static/images/glossary/flyout-toolbox.png differ diff --git a/packages/docs/static/images/glossary/icons.png b/packages/docs/static/images/glossary/icons.png new file mode 100644 index 00000000000..71d9932ac94 Binary files /dev/null and b/packages/docs/static/images/glossary/icons.png differ diff --git a/packages/docs/static/images/glossary/inputs-dark.png b/packages/docs/static/images/glossary/inputs-dark.png new file mode 100644 index 00000000000..66fb7ef9b5e Binary files /dev/null and b/packages/docs/static/images/glossary/inputs-dark.png differ diff --git a/packages/docs/static/images/glossary/inputs.png b/packages/docs/static/images/glossary/inputs.png new file mode 100644 index 00000000000..116fdeaeb64 Binary files /dev/null and b/packages/docs/static/images/glossary/inputs.png differ diff --git a/packages/docs/static/images/glossary/insertion-marker.png b/packages/docs/static/images/glossary/insertion-marker.png new file mode 100644 index 00000000000..994de4df002 Binary files /dev/null and b/packages/docs/static/images/glossary/insertion-marker.png differ diff --git a/packages/docs/static/images/glossary/shadow-blocks.png b/packages/docs/static/images/glossary/shadow-blocks.png new file mode 100644 index 00000000000..2fec86b16f8 Binary files /dev/null and b/packages/docs/static/images/glossary/shadow-blocks.png differ diff --git a/packages/docs/static/images/glossary/trashcan.png b/packages/docs/static/images/glossary/trashcan.png new file mode 100644 index 00000000000..5280ba90c92 Binary files /dev/null and b/packages/docs/static/images/glossary/trashcan.png differ diff --git a/packages/docs/static/images/glossary/workspace.png b/packages/docs/static/images/glossary/workspace.png new file mode 100644 index 00000000000..1b8de0f32b8 Binary files /dev/null and b/packages/docs/static/images/glossary/workspace.png differ diff --git a/packages/docs/static/images/glossary/zoom-controls.png b/packages/docs/static/images/glossary/zoom-controls.png new file mode 100644 index 00000000000..356b7f6afb6 Binary files /dev/null and b/packages/docs/static/images/glossary/zoom-controls.png differ diff --git a/packages/docs/static/images/google-io24/dance-party-activity-ai-edition.png b/packages/docs/static/images/google-io24/dance-party-activity-ai-edition.png new file mode 100644 index 00000000000..c60c0236086 Binary files /dev/null and b/packages/docs/static/images/google-io24/dance-party-activity-ai-edition.png differ diff --git a/packages/docs/static/images/google-io24/image-ai-rotated-resized.png b/packages/docs/static/images/google-io24/image-ai-rotated-resized.png new file mode 100644 index 00000000000..7350e3c02e3 Binary files /dev/null and b/packages/docs/static/images/google-io24/image-ai-rotated-resized.png differ diff --git a/packages/docs/static/images/grid-colour.png b/packages/docs/static/images/grid-colour.png new file mode 100644 index 00000000000..719a124744b Binary files /dev/null and b/packages/docs/static/images/grid-colour.png differ diff --git a/packages/docs/static/images/grid-length.png b/packages/docs/static/images/grid-length.png new file mode 100644 index 00000000000..9d605563875 Binary files /dev/null and b/packages/docs/static/images/grid-length.png differ diff --git a/packages/docs/static/images/grid-snap.png b/packages/docs/static/images/grid-snap.png new file mode 100644 index 00000000000..d7c20010404 Binary files /dev/null and b/packages/docs/static/images/grid-snap.png differ diff --git a/packages/docs/static/images/grid-spacing.png b/packages/docs/static/images/grid-spacing.png new file mode 100644 index 00000000000..5471e7ca137 Binary files /dev/null and b/packages/docs/static/images/grid-spacing.png differ diff --git a/packages/docs/static/images/hsv.png b/packages/docs/static/images/hsv.png new file mode 100644 index 00000000000..03dba4f5e5c Binary files /dev/null and b/packages/docs/static/images/hsv.png differ diff --git a/packages/docs/static/images/icons/1.png b/packages/docs/static/images/icons/1.png new file mode 100644 index 00000000000..d693583e464 Binary files /dev/null and b/packages/docs/static/images/icons/1.png differ diff --git a/packages/docs/static/images/icons/2.png b/packages/docs/static/images/icons/2.png new file mode 100644 index 00000000000..24224d6d546 Binary files /dev/null and b/packages/docs/static/images/icons/2.png differ diff --git a/packages/docs/static/images/icons/3.png b/packages/docs/static/images/icons/3.png new file mode 100644 index 00000000000..a8bfaa7ee63 Binary files /dev/null and b/packages/docs/static/images/icons/3.png differ diff --git a/packages/docs/static/images/icons/blockly.svg b/packages/docs/static/images/icons/blockly.svg new file mode 100644 index 00000000000..626dd7d2b24 --- /dev/null +++ b/packages/docs/static/images/icons/blockly.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/docs/static/images/icons/codelabs.svg b/packages/docs/static/images/icons/codelabs.svg new file mode 100644 index 00000000000..4f1f2d5c5ce --- /dev/null +++ b/packages/docs/static/images/icons/codelabs.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/docs/static/images/icons/cross-platform.png b/packages/docs/static/images/icons/cross-platform.png new file mode 100644 index 00000000000..0c2ab952f8b Binary files /dev/null and b/packages/docs/static/images/icons/cross-platform.png differ diff --git a/packages/docs/static/images/icons/examples.svg b/packages/docs/static/images/icons/examples.svg new file mode 100644 index 00000000000..09be0a556a8 --- /dev/null +++ b/packages/docs/static/images/icons/examples.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/docs/static/images/icons/forum.svg b/packages/docs/static/images/icons/forum.svg new file mode 100644 index 00000000000..6092c659924 --- /dev/null +++ b/packages/docs/static/images/icons/forum.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/docs/static/images/icons/googleio-logo.svg b/packages/docs/static/images/icons/googleio-logo.svg new file mode 100644 index 00000000000..9c96549d9f7 --- /dev/null +++ b/packages/docs/static/images/icons/googleio-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/docs/static/images/icons/plugins.svg b/packages/docs/static/images/icons/plugins.svg new file mode 100644 index 00000000000..1b3f201bf44 --- /dev/null +++ b/packages/docs/static/images/icons/plugins.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/docs/static/images/icons/robust-library.png b/packages/docs/static/images/icons/robust-library.png new file mode 100644 index 00000000000..29f5d215265 Binary files /dev/null and b/packages/docs/static/images/icons/robust-library.png differ diff --git a/packages/docs/static/images/icons/visual-interface.png b/packages/docs/static/images/icons/visual-interface.png new file mode 100644 index 00000000000..60041378114 Binary files /dev/null and b/packages/docs/static/images/icons/visual-interface.png differ diff --git a/packages/docs/static/images/if-mutated.png b/packages/docs/static/images/if-mutated.png new file mode 100644 index 00000000000..56e0bd85bcc Binary files /dev/null and b/packages/docs/static/images/if-mutated.png differ diff --git a/packages/docs/static/images/is-divisible-by.png b/packages/docs/static/images/is-divisible-by.png new file mode 100644 index 00000000000..01ad6e1480f Binary files /dev/null and b/packages/docs/static/images/is-divisible-by.png differ diff --git a/packages/docs/static/images/is-even.png b/packages/docs/static/images/is-even.png new file mode 100644 index 00000000000..f8142eaec47 Binary files /dev/null and b/packages/docs/static/images/is-even.png differ diff --git a/packages/docs/static/images/item.png b/packages/docs/static/images/item.png new file mode 100644 index 00000000000..9742baf0eb2 Binary files /dev/null and b/packages/docs/static/images/item.png differ diff --git a/packages/docs/static/images/keyboard_nav/Field.gif b/packages/docs/static/images/keyboard_nav/Field.gif new file mode 100644 index 00000000000..5630cf33f18 Binary files /dev/null and b/packages/docs/static/images/keyboard_nav/Field.gif differ diff --git a/packages/docs/static/images/klingon.png b/packages/docs/static/images/klingon.png new file mode 100644 index 00000000000..8602e41d392 Binary files /dev/null and b/packages/docs/static/images/klingon.png differ diff --git a/packages/docs/static/images/label-and-button.png b/packages/docs/static/images/label-and-button.png new file mode 100644 index 00000000000..78113a4d570 Binary files /dev/null and b/packages/docs/static/images/label-and-button.png differ diff --git a/packages/docs/static/images/landing/1.png b/packages/docs/static/images/landing/1.png new file mode 100644 index 00000000000..55e283985de Binary files /dev/null and b/packages/docs/static/images/landing/1.png differ diff --git a/packages/docs/static/images/landing/2.png b/packages/docs/static/images/landing/2.png new file mode 100644 index 00000000000..f7c34f6ba0b Binary files /dev/null and b/packages/docs/static/images/landing/2.png differ diff --git a/packages/docs/static/images/landing/3.png b/packages/docs/static/images/landing/3.png new file mode 100644 index 00000000000..1496b72f0d4 Binary files /dev/null and b/packages/docs/static/images/landing/3.png differ diff --git a/packages/docs/static/images/landing/4.png b/packages/docs/static/images/landing/4.png new file mode 100644 index 00000000000..3c3886dc8c1 Binary files /dev/null and b/packages/docs/static/images/landing/4.png differ diff --git a/packages/docs/static/images/landing/5.png b/packages/docs/static/images/landing/5.png new file mode 100644 index 00000000000..26d7ce8e079 Binary files /dev/null and b/packages/docs/static/images/landing/5.png differ diff --git a/packages/docs/static/images/landing/6.png b/packages/docs/static/images/landing/6.png new file mode 100644 index 00000000000..759c7afa16f Binary files /dev/null and b/packages/docs/static/images/landing/6.png differ diff --git a/packages/docs/static/images/landing/7.png b/packages/docs/static/images/landing/7.png new file mode 100644 index 00000000000..25ad5cd1b7d Binary files /dev/null and b/packages/docs/static/images/landing/7.png differ diff --git a/packages/docs/static/images/landing/blockly.png b/packages/docs/static/images/landing/blockly.png new file mode 100644 index 00000000000..b9f95c8271b Binary files /dev/null and b/packages/docs/static/images/landing/blockly.png differ diff --git a/packages/docs/static/images/landing/code-your-hero.png b/packages/docs/static/images/landing/code-your-hero.png new file mode 100644 index 00000000000..64720be1f44 Binary files /dev/null and b/packages/docs/static/images/landing/code-your-hero.png differ diff --git a/packages/docs/static/images/landing/csf.jpg b/packages/docs/static/images/landing/csf.jpg new file mode 100644 index 00000000000..7eb016ae595 Binary files /dev/null and b/packages/docs/static/images/landing/csf.jpg differ diff --git a/packages/docs/static/images/landing/everyone.png b/packages/docs/static/images/landing/everyone.png new file mode 100644 index 00000000000..ad6cd1ed62d Binary files /dev/null and b/packages/docs/static/images/landing/everyone.png differ diff --git a/packages/docs/static/images/landing/force.png b/packages/docs/static/images/landing/force.png new file mode 100644 index 00000000000..2efa87c068b Binary files /dev/null and b/packages/docs/static/images/landing/force.png differ diff --git a/packages/docs/static/images/landing/hero-mobile-1.png b/packages/docs/static/images/landing/hero-mobile-1.png new file mode 100644 index 00000000000..418dcba4b43 Binary files /dev/null and b/packages/docs/static/images/landing/hero-mobile-1.png differ diff --git a/packages/docs/static/images/landing/hero-mobile-2.png b/packages/docs/static/images/landing/hero-mobile-2.png new file mode 100644 index 00000000000..276fc723903 Binary files /dev/null and b/packages/docs/static/images/landing/hero-mobile-2.png differ diff --git a/packages/docs/static/images/landing/hero.png b/packages/docs/static/images/landing/hero.png new file mode 100644 index 00000000000..e1ecc56edff Binary files /dev/null and b/packages/docs/static/images/landing/hero.png differ diff --git a/packages/docs/static/images/landing/quote-1-mobile.png b/packages/docs/static/images/landing/quote-1-mobile.png new file mode 100644 index 00000000000..7018f0651f9 Binary files /dev/null and b/packages/docs/static/images/landing/quote-1-mobile.png differ diff --git a/packages/docs/static/images/landing/quote-1.png b/packages/docs/static/images/landing/quote-1.png new file mode 100644 index 00000000000..a8eff21c63a Binary files /dev/null and b/packages/docs/static/images/landing/quote-1.png differ diff --git a/packages/docs/static/images/landing/quote-2-mobile.png b/packages/docs/static/images/landing/quote-2-mobile.png new file mode 100644 index 00000000000..20adcae99b1 Binary files /dev/null and b/packages/docs/static/images/landing/quote-2-mobile.png differ diff --git a/packages/docs/static/images/landing/quote-2.png b/packages/docs/static/images/landing/quote-2.png new file mode 100644 index 00000000000..bdb1511a169 Binary files /dev/null and b/packages/docs/static/images/landing/quote-2.png differ diff --git a/packages/docs/static/images/landing/quote-color-1-mobile.png b/packages/docs/static/images/landing/quote-color-1-mobile.png new file mode 100644 index 00000000000..cc2639b0837 Binary files /dev/null and b/packages/docs/static/images/landing/quote-color-1-mobile.png differ diff --git a/packages/docs/static/images/landing/quote-color-2-mobile.png b/packages/docs/static/images/landing/quote-color-2-mobile.png new file mode 100644 index 00000000000..3e054a3964e Binary files /dev/null and b/packages/docs/static/images/landing/quote-color-2-mobile.png differ diff --git a/packages/docs/static/images/landing/red-block.png b/packages/docs/static/images/landing/red-block.png new file mode 100644 index 00000000000..62b57a040bc Binary files /dev/null and b/packages/docs/static/images/landing/red-block.png differ diff --git a/packages/docs/static/images/landing/scratch.jpeg b/packages/docs/static/images/landing/scratch.jpeg new file mode 100644 index 00000000000..58df3bdef38 Binary files /dev/null and b/packages/docs/static/images/landing/scratch.jpeg differ diff --git a/packages/docs/static/images/landing/subscribe-mobile.png b/packages/docs/static/images/landing/subscribe-mobile.png new file mode 100644 index 00000000000..d5f20c86f9f Binary files /dev/null and b/packages/docs/static/images/landing/subscribe-mobile.png differ diff --git a/packages/docs/static/images/landing/subscribe.png b/packages/docs/static/images/landing/subscribe.png new file mode 100644 index 00000000000..40aa71df1d4 Binary files /dev/null and b/packages/docs/static/images/landing/subscribe.png differ diff --git a/packages/docs/static/images/landing/web.png b/packages/docs/static/images/landing/web.png new file mode 100644 index 00000000000..bfa04ce3d58 Binary files /dev/null and b/packages/docs/static/images/landing/web.png differ diff --git a/packages/docs/static/images/landing/yellow-block.png b/packages/docs/static/images/landing/yellow-block.png new file mode 100644 index 00000000000..eb17916946a Binary files /dev/null and b/packages/docs/static/images/landing/yellow-block.png differ diff --git a/packages/docs/static/images/landing/yellow-puzzle-mobile.png b/packages/docs/static/images/landing/yellow-puzzle-mobile.png new file mode 100644 index 00000000000..8b3a7f40611 Binary files /dev/null and b/packages/docs/static/images/landing/yellow-puzzle-mobile.png differ diff --git a/packages/docs/static/images/landing/yellow-puzzle.png b/packages/docs/static/images/landing/yellow-puzzle.png new file mode 100644 index 00000000000..2e6d6d6f84d Binary files /dev/null and b/packages/docs/static/images/landing/yellow-puzzle.png differ diff --git a/packages/docs/static/images/language01.png b/packages/docs/static/images/language01.png new file mode 100644 index 00000000000..da86488c5ae Binary files /dev/null and b/packages/docs/static/images/language01.png differ diff --git a/packages/docs/static/images/language02.png b/packages/docs/static/images/language02.png new file mode 100644 index 00000000000..c3baf694cea Binary files /dev/null and b/packages/docs/static/images/language02.png differ diff --git a/packages/docs/static/images/language03.png b/packages/docs/static/images/language03.png new file mode 100644 index 00000000000..8398a1a6da3 Binary files /dev/null and b/packages/docs/static/images/language03.png differ diff --git a/packages/docs/static/images/language04.png b/packages/docs/static/images/language04.png new file mode 100644 index 00000000000..6e2d0fc7f5a Binary files /dev/null and b/packages/docs/static/images/language04.png differ diff --git a/packages/docs/static/images/language05.png b/packages/docs/static/images/language05.png new file mode 100644 index 00000000000..7ad259dc1d1 Binary files /dev/null and b/packages/docs/static/images/language05.png differ diff --git a/packages/docs/static/images/lists-mutated.png b/packages/docs/static/images/lists-mutated.png new file mode 100644 index 00000000000..ea599b8725c Binary files /dev/null and b/packages/docs/static/images/lists-mutated.png differ diff --git a/packages/docs/static/images/load_workspace_blocks.png b/packages/docs/static/images/load_workspace_blocks.png new file mode 100644 index 00000000000..73c95b9b6d0 Binary files /dev/null and b/packages/docs/static/images/load_workspace_blocks.png differ diff --git a/packages/docs/static/images/logo.png b/packages/docs/static/images/logo.png new file mode 100644 index 00000000000..f52d8cfc2b1 Binary files /dev/null and b/packages/docs/static/images/logo.png differ diff --git a/packages/docs/static/images/logo.svg b/packages/docs/static/images/logo.svg new file mode 100644 index 00000000000..a93014f264e --- /dev/null +++ b/packages/docs/static/images/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/docs/static/images/logos/blockly-badge-dark.png b/packages/docs/static/images/logos/blockly-badge-dark.png new file mode 100644 index 00000000000..bff35576d7a Binary files /dev/null and b/packages/docs/static/images/logos/blockly-badge-dark.png differ diff --git a/packages/docs/static/images/logos/blockly-badge.png b/packages/docs/static/images/logos/blockly-badge.png new file mode 100644 index 00000000000..1e022c9f6a5 Binary files /dev/null and b/packages/docs/static/images/logos/blockly-badge.png differ diff --git a/packages/docs/static/images/logos/blockly_logos_all.zip b/packages/docs/static/images/logos/blockly_logos_all.zip new file mode 100644 index 00000000000..b592fe7f985 Binary files /dev/null and b/packages/docs/static/images/logos/blockly_logos_all.zip differ diff --git a/packages/docs/static/images/logos/blockly_logos_png.zip b/packages/docs/static/images/logos/blockly_logos_png.zip new file mode 100644 index 00000000000..156d90a729f Binary files /dev/null and b/packages/docs/static/images/logos/blockly_logos_png.zip differ diff --git a/packages/docs/static/images/logos/blockly_logos_svg.zip b/packages/docs/static/images/logos/blockly_logos_svg.zip new file mode 100644 index 00000000000..05b23e3a458 Binary files /dev/null and b/packages/docs/static/images/logos/blockly_logos_svg.zip differ diff --git a/packages/docs/static/images/logos/built-with-blockly-badge-black.png b/packages/docs/static/images/logos/built-with-blockly-badge-black.png new file mode 100644 index 00000000000..e617fffa1c3 Binary files /dev/null and b/packages/docs/static/images/logos/built-with-blockly-badge-black.png differ diff --git a/packages/docs/static/images/logos/built-with-blockly-badge-black.svg b/packages/docs/static/images/logos/built-with-blockly-badge-black.svg new file mode 100644 index 00000000000..288d3a4292f --- /dev/null +++ b/packages/docs/static/images/logos/built-with-blockly-badge-black.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/docs/static/images/logos/built-with-blockly-badge-white.png b/packages/docs/static/images/logos/built-with-blockly-badge-white.png new file mode 100644 index 00000000000..87a456078af Binary files /dev/null and b/packages/docs/static/images/logos/built-with-blockly-badge-white.png differ diff --git a/packages/docs/static/images/logos/built-with-blockly-badge-white.svg b/packages/docs/static/images/logos/built-with-blockly-badge-white.svg new file mode 100644 index 00000000000..24e0329d463 --- /dev/null +++ b/packages/docs/static/images/logos/built-with-blockly-badge-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/docs/static/images/logos/logo_built_on.svg b/packages/docs/static/images/logos/logo_built_on.svg new file mode 100644 index 00000000000..35695f8faf8 --- /dev/null +++ b/packages/docs/static/images/logos/logo_built_on.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_built_on_dark.svg b/packages/docs/static/images/logos/logo_built_on_dark.svg new file mode 100644 index 00000000000..06a4be5243c --- /dev/null +++ b/packages/docs/static/images/logos/logo_built_on_dark.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_built_on_dark_with_bg.svg b/packages/docs/static/images/logos/logo_built_on_dark_with_bg.svg new file mode 100644 index 00000000000..ddd8bf53e4f --- /dev/null +++ b/packages/docs/static/images/logos/logo_built_on_dark_with_bg.svg @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + Blockly + Built on + + + diff --git a/packages/docs/static/images/logos/logo_built_on_knockout.png b/packages/docs/static/images/logos/logo_built_on_knockout.png new file mode 100644 index 00000000000..36bd99d2459 Binary files /dev/null and b/packages/docs/static/images/logos/logo_built_on_knockout.png differ diff --git a/packages/docs/static/images/logos/logo_built_on_knockout.svg b/packages/docs/static/images/logos/logo_built_on_knockout.svg new file mode 100644 index 00000000000..6bb518ebc20 --- /dev/null +++ b/packages/docs/static/images/logos/logo_built_on_knockout.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_built_on_knockout_with_bg.svg b/packages/docs/static/images/logos/logo_built_on_knockout_with_bg.svg new file mode 100644 index 00000000000..2da49ddf3a9 --- /dev/null +++ b/packages/docs/static/images/logos/logo_built_on_knockout_with_bg.svg @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Blockly + Built on + + + + + + diff --git a/packages/docs/static/images/logos/logo_built_with.svg b/packages/docs/static/images/logos/logo_built_with.svg new file mode 100644 index 00000000000..ffe0e7f418d --- /dev/null +++ b/packages/docs/static/images/logos/logo_built_with.svg @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_built_with_dark.svg b/packages/docs/static/images/logos/logo_built_with_dark.svg new file mode 100644 index 00000000000..246f33e4b1d --- /dev/null +++ b/packages/docs/static/images/logos/logo_built_with_dark.svg @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_built_with_knockout.svg b/packages/docs/static/images/logos/logo_built_with_knockout.svg new file mode 100644 index 00000000000..efbbf3fa2e3 --- /dev/null +++ b/packages/docs/static/images/logos/logo_built_with_knockout.svg @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_dark.png b/packages/docs/static/images/logos/logo_dark.png new file mode 100644 index 00000000000..919e70e334f Binary files /dev/null and b/packages/docs/static/images/logos/logo_dark.png differ diff --git a/packages/docs/static/images/logos/logo_dark.svg b/packages/docs/static/images/logos/logo_dark.svg new file mode 100644 index 00000000000..300a881ec93 --- /dev/null +++ b/packages/docs/static/images/logos/logo_dark.svg @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_knockout.png b/packages/docs/static/images/logos/logo_knockout.png new file mode 100644 index 00000000000..83091380365 Binary files /dev/null and b/packages/docs/static/images/logos/logo_knockout.png differ diff --git a/packages/docs/static/images/logos/logo_knockout.svg b/packages/docs/static/images/logos/logo_knockout.svg new file mode 100644 index 00000000000..374eb9257e5 --- /dev/null +++ b/packages/docs/static/images/logos/logo_knockout.svg @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_knockout_vertical.svg b/packages/docs/static/images/logos/logo_knockout_vertical.svg new file mode 100644 index 00000000000..6079a55269f --- /dev/null +++ b/packages/docs/static/images/logos/logo_knockout_vertical.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_knockout_with_bg.png b/packages/docs/static/images/logos/logo_knockout_with_bg.png new file mode 100644 index 00000000000..e703b38b9ca Binary files /dev/null and b/packages/docs/static/images/logos/logo_knockout_with_bg.png differ diff --git a/packages/docs/static/images/logos/logo_knockout_with_bg.svg b/packages/docs/static/images/logos/logo_knockout_with_bg.svg new file mode 100644 index 00000000000..08bac140b70 --- /dev/null +++ b/packages/docs/static/images/logos/logo_knockout_with_bg.svg @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Blockly + + + diff --git a/packages/docs/static/images/logos/logo_only.png b/packages/docs/static/images/logos/logo_only.png new file mode 100644 index 00000000000..c16f261ee0f Binary files /dev/null and b/packages/docs/static/images/logos/logo_only.png differ diff --git a/packages/docs/static/images/logos/logo_only.svg b/packages/docs/static/images/logos/logo_only.svg new file mode 100644 index 00000000000..4616ee99f98 --- /dev/null +++ b/packages/docs/static/images/logos/logo_only.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + logo-only + + + + + + + + logo-only + + + + + diff --git a/packages/docs/static/images/logos/logo_standard.png b/packages/docs/static/images/logos/logo_standard.png new file mode 100644 index 00000000000..24f5a752a3f Binary files /dev/null and b/packages/docs/static/images/logos/logo_standard.png differ diff --git a/packages/docs/static/images/logos/logo_standard.svg b/packages/docs/static/images/logos/logo_standard.svg new file mode 100644 index 00000000000..100b88cc043 --- /dev/null +++ b/packages/docs/static/images/logos/logo_standard.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_vertical.png b/packages/docs/static/images/logos/logo_vertical.png new file mode 100644 index 00000000000..93c95b0baa7 Binary files /dev/null and b/packages/docs/static/images/logos/logo_vertical.png differ diff --git a/packages/docs/static/images/logos/logo_vertical.svg b/packages/docs/static/images/logos/logo_vertical.svg new file mode 100644 index 00000000000..5e7e10d547b --- /dev/null +++ b/packages/docs/static/images/logos/logo_vertical.svg @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_vertical_dark.svg b/packages/docs/static/images/logos/logo_vertical_dark.svg new file mode 100644 index 00000000000..40d17d9a1e1 --- /dev/null +++ b/packages/docs/static/images/logos/logo_vertical_dark.svg @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/docs/static/images/logos/logo_x_height.png b/packages/docs/static/images/logos/logo_x_height.png new file mode 100644 index 00000000000..2abd1a09b81 Binary files /dev/null and b/packages/docs/static/images/logos/logo_x_height.png differ diff --git a/packages/docs/static/images/mark_email_unread.png b/packages/docs/static/images/mark_email_unread.png new file mode 100644 index 00000000000..0f482cca9d6 Binary files /dev/null and b/packages/docs/static/images/mark_email_unread.png differ diff --git a/packages/docs/static/images/math-number.png b/packages/docs/static/images/math-number.png new file mode 100644 index 00000000000..dd3483e00bc Binary files /dev/null and b/packages/docs/static/images/math-number.png differ diff --git a/packages/docs/static/images/metrics_manager/absolute_metrics.png b/packages/docs/static/images/metrics_manager/absolute_metrics.png new file mode 100644 index 00000000000..be36e217a01 Binary files /dev/null and b/packages/docs/static/images/metrics_manager/absolute_metrics.png differ diff --git a/packages/docs/static/images/metrics_manager/absolute_metrics_2.png b/packages/docs/static/images/metrics_manager/absolute_metrics_2.png new file mode 100644 index 00000000000..6ddff629dc4 Binary files /dev/null and b/packages/docs/static/images/metrics_manager/absolute_metrics_2.png differ diff --git a/packages/docs/static/images/metrics_manager/content_metrics.png b/packages/docs/static/images/metrics_manager/content_metrics.png new file mode 100644 index 00000000000..5051b11be15 Binary files /dev/null and b/packages/docs/static/images/metrics_manager/content_metrics.png differ diff --git a/packages/docs/static/images/metrics_manager/flyout_toolbox_metrics.png b/packages/docs/static/images/metrics_manager/flyout_toolbox_metrics.png new file mode 100644 index 00000000000..907fcff5a84 Binary files /dev/null and b/packages/docs/static/images/metrics_manager/flyout_toolbox_metrics.png differ diff --git a/packages/docs/static/images/metrics_manager/scroll_metrics.png b/packages/docs/static/images/metrics_manager/scroll_metrics.png new file mode 100644 index 00000000000..5957a677328 Binary files /dev/null and b/packages/docs/static/images/metrics_manager/scroll_metrics.png differ diff --git a/packages/docs/static/images/metrics_manager/svg_metrics.png b/packages/docs/static/images/metrics_manager/svg_metrics.png new file mode 100644 index 00000000000..5f03d77d5a7 Binary files /dev/null and b/packages/docs/static/images/metrics_manager/svg_metrics.png differ diff --git a/packages/docs/static/images/metrics_manager/toolbox_metrics.png b/packages/docs/static/images/metrics_manager/toolbox_metrics.png new file mode 100644 index 00000000000..5ff009a0e8f Binary files /dev/null and b/packages/docs/static/images/metrics_manager/toolbox_metrics.png differ diff --git a/packages/docs/static/images/metrics_manager/view_metrics.png b/packages/docs/static/images/metrics_manager/view_metrics.png new file mode 100644 index 00000000000..c5a1dd2300f Binary files /dev/null and b/packages/docs/static/images/metrics_manager/view_metrics.png differ diff --git a/packages/docs/static/images/metrics_manager/view_metrics_origin.png b/packages/docs/static/images/metrics_manager/view_metrics_origin.png new file mode 100644 index 00000000000..ef62475d04e Binary files /dev/null and b/packages/docs/static/images/metrics_manager/view_metrics_origin.png differ diff --git a/packages/docs/static/images/mistakes02.png b/packages/docs/static/images/mistakes02.png new file mode 100644 index 00000000000..911c0719583 Binary files /dev/null and b/packages/docs/static/images/mistakes02.png differ diff --git a/packages/docs/static/images/mistakes03a.png b/packages/docs/static/images/mistakes03a.png new file mode 100644 index 00000000000..6c2c20b33f3 Binary files /dev/null and b/packages/docs/static/images/mistakes03a.png differ diff --git a/packages/docs/static/images/mistakes03b.png b/packages/docs/static/images/mistakes03b.png new file mode 100644 index 00000000000..8f285cbe555 Binary files /dev/null and b/packages/docs/static/images/mistakes03b.png differ diff --git a/packages/docs/static/images/mistakes06.png b/packages/docs/static/images/mistakes06.png new file mode 100644 index 00000000000..7492f9a5b03 Binary files /dev/null and b/packages/docs/static/images/mistakes06.png differ diff --git a/packages/docs/static/images/mistakes07.png b/packages/docs/static/images/mistakes07.png new file mode 100644 index 00000000000..7725f4167bf Binary files /dev/null and b/packages/docs/static/images/mistakes07.png differ diff --git a/packages/docs/static/images/mistakes08a.png b/packages/docs/static/images/mistakes08a.png new file mode 100644 index 00000000000..325405209d9 Binary files /dev/null and b/packages/docs/static/images/mistakes08a.png differ diff --git a/packages/docs/static/images/mistakes08b.png b/packages/docs/static/images/mistakes08b.png new file mode 100644 index 00000000000..9a295586adb Binary files /dev/null and b/packages/docs/static/images/mistakes08b.png differ diff --git a/packages/docs/static/images/mistakes09.png b/packages/docs/static/images/mistakes09.png new file mode 100644 index 00000000000..5616b1f8de5 Binary files /dev/null and b/packages/docs/static/images/mistakes09.png differ diff --git a/packages/docs/static/images/mistakes99.png b/packages/docs/static/images/mistakes99.png new file mode 100644 index 00000000000..b24f0e55f82 Binary files /dev/null and b/packages/docs/static/images/mistakes99.png differ diff --git a/packages/docs/static/images/mutate-add-minus.png b/packages/docs/static/images/mutate-add-minus.png new file mode 100644 index 00000000000..f79a8bb956f Binary files /dev/null and b/packages/docs/static/images/mutate-add-minus.png differ diff --git a/packages/docs/static/images/mutate-bubble.png b/packages/docs/static/images/mutate-bubble.png new file mode 100644 index 00000000000..e074b87ce8b Binary files /dev/null and b/packages/docs/static/images/mutate-bubble.png differ diff --git a/packages/docs/static/images/mutate-compound.png b/packages/docs/static/images/mutate-compound.png new file mode 100644 index 00000000000..aef2e61aef4 Binary files /dev/null and b/packages/docs/static/images/mutate-compound.png differ diff --git a/packages/docs/static/images/mutate-extra.png b/packages/docs/static/images/mutate-extra.png new file mode 100644 index 00000000000..c2916e7275e Binary files /dev/null and b/packages/docs/static/images/mutate-extra.png differ diff --git a/packages/docs/static/images/mutator-annot.png b/packages/docs/static/images/mutator-annot.png new file mode 100644 index 00000000000..fdbba384bba Binary files /dev/null and b/packages/docs/static/images/mutator-annot.png differ diff --git a/packages/docs/static/images/override-render-decision-dark.svg b/packages/docs/static/images/override-render-decision-dark.svg new file mode 100644 index 00000000000..8d176224c97 --- /dev/null +++ b/packages/docs/static/images/override-render-decision-dark.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/docs/static/images/override-render-decision.svg b/packages/docs/static/images/override-render-decision.svg new file mode 100644 index 00000000000..6027e063f1f --- /dev/null +++ b/packages/docs/static/images/override-render-decision.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/docs/static/images/procedures.png b/packages/docs/static/images/procedures.png new file mode 100644 index 00000000000..fc023bdcfcd Binary files /dev/null and b/packages/docs/static/images/procedures.png differ diff --git a/packages/docs/static/images/rendering/connection-shapes/connection-check-specific-shapes.png b/packages/docs/static/images/rendering/connection-shapes/connection-check-specific-shapes.png new file mode 100644 index 00000000000..17703c655b4 Binary files /dev/null and b/packages/docs/static/images/rendering/connection-shapes/connection-check-specific-shapes.png differ diff --git a/packages/docs/static/images/rendering/connection-shapes/drawing-direction.png b/packages/docs/static/images/rendering/connection-shapes/drawing-direction.png new file mode 100644 index 00000000000..65aca97ebd5 Binary files /dev/null and b/packages/docs/static/images/rendering/connection-shapes/drawing-direction.png differ diff --git a/packages/docs/static/images/rendering/connection-shapes/internal-inputs.png b/packages/docs/static/images/rendering/connection-shapes/internal-inputs.png new file mode 100644 index 00000000000..21b4236b5bb Binary files /dev/null and b/packages/docs/static/images/rendering/connection-shapes/internal-inputs.png differ diff --git a/packages/docs/static/images/rendering/connection-shapes/outline-inputs.png b/packages/docs/static/images/rendering/connection-shapes/outline-inputs.png new file mode 100644 index 00000000000..3411f45607f Binary files /dev/null and b/packages/docs/static/images/rendering/connection-shapes/outline-inputs.png differ diff --git a/packages/docs/static/images/rendering/connection-shapes/overridden-connection-constants.png b/packages/docs/static/images/rendering/connection-shapes/overridden-connection-constants.png new file mode 100644 index 00000000000..523c0603a5c Binary files /dev/null and b/packages/docs/static/images/rendering/connection-shapes/overridden-connection-constants.png differ diff --git a/packages/docs/static/images/rendering/connection-shapes/overridden-connection-shapes.png b/packages/docs/static/images/rendering/connection-shapes/overridden-connection-shapes.png new file mode 100644 index 00000000000..c073b3c1502 Binary files /dev/null and b/packages/docs/static/images/rendering/connection-shapes/overridden-connection-shapes.png differ diff --git a/packages/docs/static/images/rendering/connection-shapes/shape-direction.png b/packages/docs/static/images/rendering/connection-shapes/shape-direction.png new file mode 100644 index 00000000000..47b9267a558 Binary files /dev/null and b/packages/docs/static/images/rendering/connection-shapes/shape-direction.png differ diff --git a/packages/docs/static/images/rendering/debug-renderer/connection.png b/packages/docs/static/images/rendering/debug-renderer/connection.png new file mode 100644 index 00000000000..16acaa8215e Binary files /dev/null and b/packages/docs/static/images/rendering/debug-renderer/connection.png differ diff --git a/packages/docs/static/images/rendering/debug-renderer/element-spacer.png b/packages/docs/static/images/rendering/debug-renderer/element-spacer.png new file mode 100644 index 00000000000..d264d784fb9 Binary files /dev/null and b/packages/docs/static/images/rendering/debug-renderer/element-spacer.png differ diff --git a/packages/docs/static/images/rendering/debug-renderer/element.png b/packages/docs/static/images/rendering/debug-renderer/element.png new file mode 100644 index 00000000000..801654125a9 Binary files /dev/null and b/packages/docs/static/images/rendering/debug-renderer/element.png differ diff --git a/packages/docs/static/images/rendering/debug-renderer/row-spacer.png b/packages/docs/static/images/rendering/debug-renderer/row-spacer.png new file mode 100644 index 00000000000..a400ca5dfbe Binary files /dev/null and b/packages/docs/static/images/rendering/debug-renderer/row-spacer.png differ diff --git a/packages/docs/static/images/rendering/debug-renderer/row.png b/packages/docs/static/images/rendering/debug-renderer/row.png new file mode 100644 index 00000000000..81185823863 Binary files /dev/null and b/packages/docs/static/images/rendering/debug-renderer/row.png differ diff --git a/packages/docs/static/images/rendering/renderers/base-renderer.png b/packages/docs/static/images/rendering/renderers/base-renderer.png new file mode 100644 index 00000000000..f0c614ee08c Binary files /dev/null and b/packages/docs/static/images/rendering/renderers/base-renderer.png differ diff --git a/packages/docs/static/images/rendering/renderers/geras-paths.png b/packages/docs/static/images/rendering/renderers/geras-paths.png new file mode 100644 index 00000000000..0fd75351fca Binary files /dev/null and b/packages/docs/static/images/rendering/renderers/geras-paths.png differ diff --git a/packages/docs/static/images/rendering/renderers/geras.png b/packages/docs/static/images/rendering/renderers/geras.png new file mode 100644 index 00000000000..fc5426cbabd Binary files /dev/null and b/packages/docs/static/images/rendering/renderers/geras.png differ diff --git a/packages/docs/static/images/rendering/renderers/thrasos-paths.png b/packages/docs/static/images/rendering/renderers/thrasos-paths.png new file mode 100644 index 00000000000..d9515a10301 Binary files /dev/null and b/packages/docs/static/images/rendering/renderers/thrasos-paths.png differ diff --git a/packages/docs/static/images/rendering/renderers/thrasos.png b/packages/docs/static/images/rendering/renderers/thrasos.png new file mode 100644 index 00000000000..c0a9101f671 Binary files /dev/null and b/packages/docs/static/images/rendering/renderers/thrasos.png differ diff --git a/packages/docs/static/images/rendering/renderers/zelos.png b/packages/docs/static/images/rendering/renderers/zelos.png new file mode 100644 index 00000000000..bb8e1a9566a Binary files /dev/null and b/packages/docs/static/images/rendering/renderers/zelos.png differ diff --git a/packages/docs/static/images/repeat.png b/packages/docs/static/images/repeat.png new file mode 100644 index 00000000000..c019f84ec91 Binary files /dev/null and b/packages/docs/static/images/repeat.png differ diff --git a/packages/docs/static/images/return1.png b/packages/docs/static/images/return1.png new file mode 100644 index 00000000000..7c86e020d8e Binary files /dev/null and b/packages/docs/static/images/return1.png differ diff --git a/packages/docs/static/images/return2.png b/packages/docs/static/images/return2.png new file mode 100644 index 00000000000..5868b8b4e0b Binary files /dev/null and b/packages/docs/static/images/return2.png differ diff --git a/packages/docs/static/images/return3.png b/packages/docs/static/images/return3.png new file mode 100644 index 00000000000..e53bc0317fd Binary files /dev/null and b/packages/docs/static/images/return3.png differ diff --git a/packages/docs/static/images/rodents.png b/packages/docs/static/images/rodents.png new file mode 100644 index 00000000000..fc630198e94 Binary files /dev/null and b/packages/docs/static/images/rodents.png differ diff --git a/packages/docs/static/images/rotate.png b/packages/docs/static/images/rotate.png new file mode 100644 index 00000000000..9ba49175201 Binary files /dev/null and b/packages/docs/static/images/rotate.png differ diff --git a/packages/docs/static/images/sample.png b/packages/docs/static/images/sample.png new file mode 100644 index 00000000000..aaf7067cafe Binary files /dev/null and b/packages/docs/static/images/sample.png differ diff --git a/packages/docs/static/images/send-email.png b/packages/docs/static/images/send-email.png new file mode 100644 index 00000000000..9e9aa18752c Binary files /dev/null and b/packages/docs/static/images/send-email.png differ diff --git a/packages/docs/static/images/set-inputs-inline.png b/packages/docs/static/images/set-inputs-inline.png new file mode 100644 index 00000000000..c08fd08c86b Binary files /dev/null and b/packages/docs/static/images/set-inputs-inline.png differ diff --git a/packages/docs/static/images/set-next-statement.png b/packages/docs/static/images/set-next-statement.png new file mode 100644 index 00000000000..37b5b281c9f Binary files /dev/null and b/packages/docs/static/images/set-next-statement.png differ diff --git a/packages/docs/static/images/set-output.png b/packages/docs/static/images/set-output.png new file mode 100644 index 00000000000..c4b072688ed Binary files /dev/null and b/packages/docs/static/images/set-output.png differ diff --git a/packages/docs/static/images/set-previous-statement.png b/packages/docs/static/images/set-previous-statement.png new file mode 100644 index 00000000000..37d6967bfc4 Binary files /dev/null and b/packages/docs/static/images/set-previous-statement.png differ diff --git a/packages/docs/static/images/stack.png b/packages/docs/static/images/stack.png new file mode 100644 index 00000000000..da2d67f2601 Binary files /dev/null and b/packages/docs/static/images/stack.png differ diff --git a/packages/docs/static/images/standard-block-colors.png b/packages/docs/static/images/standard-block-colors.png new file mode 100644 index 00000000000..27cadbc730b Binary files /dev/null and b/packages/docs/static/images/standard-block-colors.png differ diff --git a/packages/docs/static/images/structure-codelab.png b/packages/docs/static/images/structure-codelab.png new file mode 100644 index 00000000000..67765cafea5 Binary files /dev/null and b/packages/docs/static/images/structure-codelab.png differ diff --git a/packages/docs/static/images/structure-codelabs.png b/packages/docs/static/images/structure-codelabs.png new file mode 100644 index 00000000000..c8446b0ddf9 Binary files /dev/null and b/packages/docs/static/images/structure-codelabs.png differ diff --git a/packages/docs/static/images/structure-examples.png b/packages/docs/static/images/structure-examples.png new file mode 100644 index 00000000000..bd70608a3c7 Binary files /dev/null and b/packages/docs/static/images/structure-examples.png differ diff --git a/packages/docs/static/images/structure-json/controls-repeat-ext-dark.png b/packages/docs/static/images/structure-json/controls-repeat-ext-dark.png new file mode 100644 index 00000000000..619567466be Binary files /dev/null and b/packages/docs/static/images/structure-json/controls-repeat-ext-dark.png differ diff --git a/packages/docs/static/images/structure-json/controls-repeat-ext.png b/packages/docs/static/images/structure-json/controls-repeat-ext.png new file mode 100644 index 00000000000..d5ce12d8f94 Binary files /dev/null and b/packages/docs/static/images/structure-json/controls-repeat-ext.png differ diff --git a/packages/docs/static/images/structure-json/is-empty-dark.png b/packages/docs/static/images/structure-json/is-empty-dark.png new file mode 100644 index 00000000000..83de766b856 Binary files /dev/null and b/packages/docs/static/images/structure-json/is-empty-dark.png differ diff --git a/packages/docs/static/images/structure-json/is-empty-dummy-dark.png b/packages/docs/static/images/structure-json/is-empty-dummy-dark.png new file mode 100644 index 00000000000..87a9bf0802a Binary files /dev/null and b/packages/docs/static/images/structure-json/is-empty-dummy-dark.png differ diff --git a/packages/docs/static/images/structure-json/is-empty-dummy.png b/packages/docs/static/images/structure-json/is-empty-dummy.png new file mode 100644 index 00000000000..8a9c5725eb4 Binary files /dev/null and b/packages/docs/static/images/structure-json/is-empty-dummy.png differ diff --git a/packages/docs/static/images/structure-json/is-empty.png b/packages/docs/static/images/structure-json/is-empty.png new file mode 100644 index 00000000000..4df042478df Binary files /dev/null and b/packages/docs/static/images/structure-json/is-empty.png differ diff --git a/packages/docs/static/images/structure-json/newline-character-dark.png b/packages/docs/static/images/structure-json/newline-character-dark.png new file mode 100644 index 00000000000..6eeada7a50b Binary files /dev/null and b/packages/docs/static/images/structure-json/newline-character-dark.png differ diff --git a/packages/docs/static/images/structure-json/newline-character.png b/packages/docs/static/images/structure-json/newline-character.png new file mode 100644 index 00000000000..b8c87224300 Binary files /dev/null and b/packages/docs/static/images/structure-json/newline-character.png differ diff --git a/packages/docs/static/images/structure-json/one-plus-two-dark.png b/packages/docs/static/images/structure-json/one-plus-two-dark.png new file mode 100644 index 00000000000..8805761ec1e Binary files /dev/null and b/packages/docs/static/images/structure-json/one-plus-two-dark.png differ diff --git a/packages/docs/static/images/structure-json/one-plus-two-three-dark.png b/packages/docs/static/images/structure-json/one-plus-two-three-dark.png new file mode 100644 index 00000000000..3b866276fce Binary files /dev/null and b/packages/docs/static/images/structure-json/one-plus-two-three-dark.png differ diff --git a/packages/docs/static/images/structure-json/one-plus-two-three.png b/packages/docs/static/images/structure-json/one-plus-two-three.png new file mode 100644 index 00000000000..0e2e943dcb5 Binary files /dev/null and b/packages/docs/static/images/structure-json/one-plus-two-three.png differ diff --git a/packages/docs/static/images/structure-json/one-plus-two.png b/packages/docs/static/images/structure-json/one-plus-two.png new file mode 100644 index 00000000000..df074a1d46c Binary files /dev/null and b/packages/docs/static/images/structure-json/one-plus-two.png differ diff --git a/packages/docs/static/images/structure-json/set-one-to-two-dark.png b/packages/docs/static/images/structure-json/set-one-to-two-dark.png new file mode 100644 index 00000000000..5663f46833e Binary files /dev/null and b/packages/docs/static/images/structure-json/set-one-to-two-dark.png differ diff --git a/packages/docs/static/images/structure-json/set-one-to-two.png b/packages/docs/static/images/structure-json/set-one-to-two.png new file mode 100644 index 00000000000..febf99ef0fe Binary files /dev/null and b/packages/docs/static/images/structure-json/set-one-to-two.png differ diff --git a/packages/docs/static/images/structure-plugin.png b/packages/docs/static/images/structure-plugin.png new file mode 100644 index 00000000000..0d024b3d392 Binary files /dev/null and b/packages/docs/static/images/structure-plugin.png differ diff --git a/packages/docs/static/images/summits/summit-cards-01.png b/packages/docs/static/images/summits/summit-cards-01.png new file mode 100644 index 00000000000..a40b30984ed Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-01.png differ diff --git a/packages/docs/static/images/summits/summit-cards-02.png b/packages/docs/static/images/summits/summit-cards-02.png new file mode 100644 index 00000000000..dc5383870d1 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-02.png differ diff --git a/packages/docs/static/images/summits/summit-cards-03.png b/packages/docs/static/images/summits/summit-cards-03.png new file mode 100644 index 00000000000..5a9280f8c49 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-03.png differ diff --git a/packages/docs/static/images/summits/summit-cards-04.png b/packages/docs/static/images/summits/summit-cards-04.png new file mode 100644 index 00000000000..531747db579 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-04.png differ diff --git a/packages/docs/static/images/summits/summit-cards-05.png b/packages/docs/static/images/summits/summit-cards-05.png new file mode 100644 index 00000000000..cfa04148ff0 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-05.png differ diff --git a/packages/docs/static/images/summits/summit-cards-06.png b/packages/docs/static/images/summits/summit-cards-06.png new file mode 100644 index 00000000000..c269d165e47 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-06.png differ diff --git a/packages/docs/static/images/summits/summit-cards-07.png b/packages/docs/static/images/summits/summit-cards-07.png new file mode 100644 index 00000000000..6a859b96733 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-07.png differ diff --git a/packages/docs/static/images/summits/summit-cards-08.png b/packages/docs/static/images/summits/summit-cards-08.png new file mode 100644 index 00000000000..33d9a12f89c Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-08.png differ diff --git a/packages/docs/static/images/summits/summit-cards-09.png b/packages/docs/static/images/summits/summit-cards-09.png new file mode 100644 index 00000000000..fc3fd7e8809 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-09.png differ diff --git a/packages/docs/static/images/summits/summit-cards-10.png b/packages/docs/static/images/summits/summit-cards-10.png new file mode 100644 index 00000000000..163db1a4736 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-10.png differ diff --git a/packages/docs/static/images/summits/summit-cards-11.png b/packages/docs/static/images/summits/summit-cards-11.png new file mode 100644 index 00000000000..bfec17fafef Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-11.png differ diff --git a/packages/docs/static/images/summits/summit-cards-12.png b/packages/docs/static/images/summits/summit-cards-12.png new file mode 100644 index 00000000000..968af45cc5a Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-12.png differ diff --git a/packages/docs/static/images/summits/summit-cards-13.png b/packages/docs/static/images/summits/summit-cards-13.png new file mode 100644 index 00000000000..e3640e6b7bc Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-13.png differ diff --git a/packages/docs/static/images/summits/summit-cards-14.png b/packages/docs/static/images/summits/summit-cards-14.png new file mode 100644 index 00000000000..7431797a54e Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-14.png differ diff --git a/packages/docs/static/images/summits/summit-cards-15.png b/packages/docs/static/images/summits/summit-cards-15.png new file mode 100644 index 00000000000..9394b41f30a Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-15.png differ diff --git a/packages/docs/static/images/summits/summit-cards-16.png b/packages/docs/static/images/summits/summit-cards-16.png new file mode 100644 index 00000000000..8bf6de5902b Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-16.png differ diff --git a/packages/docs/static/images/summits/summit-cards-17.png b/packages/docs/static/images/summits/summit-cards-17.png new file mode 100644 index 00000000000..a09bd52baea Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-17.png differ diff --git a/packages/docs/static/images/summits/summit-cards-18.png b/packages/docs/static/images/summits/summit-cards-18.png new file mode 100644 index 00000000000..a2ede1963f6 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-18.png differ diff --git a/packages/docs/static/images/summits/summit-cards-19.png b/packages/docs/static/images/summits/summit-cards-19.png new file mode 100644 index 00000000000..7c530de0524 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-19.png differ diff --git a/packages/docs/static/images/summits/summit-cards-20.png b/packages/docs/static/images/summits/summit-cards-20.png new file mode 100644 index 00000000000..94434e46a07 Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-20.png differ diff --git a/packages/docs/static/images/summits/summit-cards-21.png b/packages/docs/static/images/summits/summit-cards-21.png new file mode 100644 index 00000000000..a565526194b Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-21.png differ diff --git a/packages/docs/static/images/summits/summit-cards-22.png b/packages/docs/static/images/summits/summit-cards-22.png new file mode 100644 index 00000000000..3dac30c803d Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-22.png differ diff --git a/packages/docs/static/images/summits/summit-cards-24.png b/packages/docs/static/images/summits/summit-cards-24.png new file mode 100644 index 00000000000..9b9c93d7ecc Binary files /dev/null and b/packages/docs/static/images/summits/summit-cards-24.png differ diff --git a/packages/docs/static/images/summits/summit-hero.png b/packages/docs/static/images/summits/summit-hero.png new file mode 100644 index 00000000000..0473db78939 Binary files /dev/null and b/packages/docs/static/images/summits/summit-hero.png differ diff --git a/packages/docs/static/images/text-input-editor.png b/packages/docs/static/images/text-input-editor.png new file mode 100644 index 00000000000..efae5f22ceb Binary files /dev/null and b/packages/docs/static/images/text-input-editor.png differ diff --git a/packages/docs/static/images/text-length.png b/packages/docs/static/images/text-length.png new file mode 100644 index 00000000000..251efbfc0bf Binary files /dev/null and b/packages/docs/static/images/text-length.png differ diff --git a/packages/docs/static/images/toolbox-categories.png b/packages/docs/static/images/toolbox-categories.png new file mode 100644 index 00000000000..5c1457c443d Binary files /dev/null and b/packages/docs/static/images/toolbox-categories.png differ diff --git a/packages/docs/static/images/toolbox-colours.png b/packages/docs/static/images/toolbox-colours.png new file mode 100644 index 00000000000..94609255434 Binary files /dev/null and b/packages/docs/static/images/toolbox-colours.png differ diff --git a/packages/docs/static/images/toolbox-css.png b/packages/docs/static/images/toolbox-css.png new file mode 100644 index 00000000000..8ce2120f28d Binary files /dev/null and b/packages/docs/static/images/toolbox-css.png differ diff --git a/packages/docs/static/images/toolbox-disabled.png b/packages/docs/static/images/toolbox-disabled.png new file mode 100644 index 00000000000..a9d2dedce50 Binary files /dev/null and b/packages/docs/static/images/toolbox-disabled.png differ diff --git a/packages/docs/static/images/toolbox-gap.png b/packages/docs/static/images/toolbox-gap.png new file mode 100644 index 00000000000..27e394356e8 Binary files /dev/null and b/packages/docs/static/images/toolbox-gap.png differ diff --git a/packages/docs/static/images/toolbox-minimal.png b/packages/docs/static/images/toolbox-minimal.png new file mode 100644 index 00000000000..201d8b158e0 Binary files /dev/null and b/packages/docs/static/images/toolbox-minimal.png differ diff --git a/packages/docs/static/images/toolbox-separator.png b/packages/docs/static/images/toolbox-separator.png new file mode 100644 index 00000000000..1fa102f5067 Binary files /dev/null and b/packages/docs/static/images/toolbox-separator.png differ diff --git a/packages/docs/static/images/type-bad.png b/packages/docs/static/images/type-bad.png new file mode 100644 index 00000000000..62254c4d56e Binary files /dev/null and b/packages/docs/static/images/type-bad.png differ diff --git a/packages/docs/static/images/update_button.png b/packages/docs/static/images/update_button.png new file mode 100644 index 00000000000..353680090c5 Binary files /dev/null and b/packages/docs/static/images/update_button.png differ diff --git a/packages/docs/static/images/validation-order-dark.svg b/packages/docs/static/images/validation-order-dark.svg new file mode 100644 index 00000000000..538fae66e35 --- /dev/null +++ b/packages/docs/static/images/validation-order-dark.svg @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/docs/static/images/validation-order.svg b/packages/docs/static/images/validation-order.svg new file mode 100644 index 00000000000..4ae3d26ae41 --- /dev/null +++ b/packages/docs/static/images/validation-order.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/docs/static/images/variable-dropdown.png b/packages/docs/static/images/variable-dropdown.png new file mode 100644 index 00000000000..bf1d9760feb Binary files /dev/null and b/packages/docs/static/images/variable-dropdown.png differ diff --git a/packages/docs/static/images/variables-category-filled.png b/packages/docs/static/images/variables-category-filled.png new file mode 100644 index 00000000000..761bef355a5 Binary files /dev/null and b/packages/docs/static/images/variables-category-filled.png differ diff --git a/packages/docs/static/images/variables-category.png b/packages/docs/static/images/variables-category.png new file mode 100644 index 00000000000..e109dca8e2b Binary files /dev/null and b/packages/docs/static/images/variables-category.png differ diff --git a/packages/docs/static/images/variables-put.png b/packages/docs/static/images/variables-put.png new file mode 100644 index 00000000000..43682163566 Binary files /dev/null and b/packages/docs/static/images/variables-put.png differ diff --git a/packages/docs/static/images/variables-set.png b/packages/docs/static/images/variables-set.png new file mode 100644 index 00000000000..5c1693b9cec Binary files /dev/null and b/packages/docs/static/images/variables-set.png differ diff --git a/packages/docs/static/images/vietnam.jpg b/packages/docs/static/images/vietnam.jpg new file mode 100644 index 00000000000..c351187dbb3 Binary files /dev/null and b/packages/docs/static/images/vietnam.jpg differ diff --git a/packages/docs/static/images/workspace-comments/block-comment.png b/packages/docs/static/images/workspace-comments/block-comment.png new file mode 100644 index 00000000000..de417f56808 Binary files /dev/null and b/packages/docs/static/images/workspace-comments/block-comment.png differ diff --git a/packages/docs/static/images/workspace-comments/blue-preview-text.png b/packages/docs/static/images/workspace-comments/blue-preview-text.png new file mode 100644 index 00000000000..03ad41a2332 Binary files /dev/null and b/packages/docs/static/images/workspace-comments/blue-preview-text.png differ diff --git a/packages/docs/static/images/workspace-comments/blue-text.png b/packages/docs/static/images/workspace-comments/blue-text.png new file mode 100644 index 00000000000..46cf442190b Binary files /dev/null and b/packages/docs/static/images/workspace-comments/blue-text.png differ diff --git a/packages/docs/static/images/workspace-comments/collapsed-outline.png b/packages/docs/static/images/workspace-comments/collapsed-outline.png new file mode 100644 index 00000000000..205dcf90638 Binary files /dev/null and b/packages/docs/static/images/workspace-comments/collapsed-outline.png differ diff --git a/packages/docs/static/images/workspace-comments/coloured-comment.png b/packages/docs/static/images/workspace-comments/coloured-comment.png new file mode 100644 index 00000000000..cbae9aba68a Binary files /dev/null and b/packages/docs/static/images/workspace-comments/coloured-comment.png differ diff --git a/packages/docs/static/images/workspace-comments/delete-icon-outline.png b/packages/docs/static/images/workspace-comments/delete-icon-outline.png new file mode 100644 index 00000000000..f365c561e34 Binary files /dev/null and b/packages/docs/static/images/workspace-comments/delete-icon-outline.png differ diff --git a/packages/docs/static/images/workspace-comments/foldout-icon-outline.png b/packages/docs/static/images/workspace-comments/foldout-icon-outline.png new file mode 100644 index 00000000000..5e1b97a9ef1 Binary files /dev/null and b/packages/docs/static/images/workspace-comments/foldout-icon-outline.png differ diff --git a/packages/docs/static/images/workspace-comments/preview-text-outline.png b/packages/docs/static/images/workspace-comments/preview-text-outline.png new file mode 100644 index 00000000000..0cb8728dc6c Binary files /dev/null and b/packages/docs/static/images/workspace-comments/preview-text-outline.png differ diff --git a/packages/docs/static/images/workspace-comments/resize-handle-outline.png b/packages/docs/static/images/workspace-comments/resize-handle-outline.png new file mode 100644 index 00000000000..e1227d0715e Binary files /dev/null and b/packages/docs/static/images/workspace-comments/resize-handle-outline.png differ diff --git a/packages/docs/static/images/workspace-comments/selected-collapsed.png b/packages/docs/static/images/workspace-comments/selected-collapsed.png new file mode 100644 index 00000000000..76540270fe9 Binary files /dev/null and b/packages/docs/static/images/workspace-comments/selected-collapsed.png differ diff --git a/packages/docs/static/images/workspace-comments/selected-comment.png b/packages/docs/static/images/workspace-comments/selected-comment.png new file mode 100644 index 00000000000..69aecec90da Binary files /dev/null and b/packages/docs/static/images/workspace-comments/selected-comment.png differ diff --git a/packages/docs/static/images/workspace-comments/tall-top-bar.png b/packages/docs/static/images/workspace-comments/tall-top-bar.png new file mode 100644 index 00000000000..8b09a5a736b Binary files /dev/null and b/packages/docs/static/images/workspace-comments/tall-top-bar.png differ diff --git a/packages/docs/static/images/workspace-comments/text-input-outline.png b/packages/docs/static/images/workspace-comments/text-input-outline.png new file mode 100644 index 00000000000..0a98abf9798 Binary files /dev/null and b/packages/docs/static/images/workspace-comments/text-input-outline.png differ diff --git a/packages/docs/static/images/workspace-comments/top-bar-outline.png b/packages/docs/static/images/workspace-comments/top-bar-outline.png new file mode 100644 index 00000000000..5feee8eb5bd Binary files /dev/null and b/packages/docs/static/images/workspace-comments/top-bar-outline.png differ diff --git a/packages/docs/static/images/workspace-comments/workspace-comment-outline.png b/packages/docs/static/images/workspace-comments/workspace-comment-outline.png new file mode 100644 index 00000000000..356d39e9bc3 Binary files /dev/null and b/packages/docs/static/images/workspace-comments/workspace-comment-outline.png differ diff --git a/packages/docs/static/images/workspace-comments/workspace-comment.png b/packages/docs/static/images/workspace-comments/workspace-comment.png new file mode 100644 index 00000000000..598a034ad64 Binary files /dev/null and b/packages/docs/static/images/workspace-comments/workspace-comment.png differ diff --git a/packages/docs/static/images/workspace_export_opt.png b/packages/docs/static/images/workspace_export_opt.png new file mode 100644 index 00000000000..f4ad3853d58 Binary files /dev/null and b/packages/docs/static/images/workspace_export_opt.png differ diff --git a/packages/docs/static/images/workspace_fac_no_cat.png b/packages/docs/static/images/workspace_fac_no_cat.png new file mode 100644 index 00000000000..ce81ade93e9 Binary files /dev/null and b/packages/docs/static/images/workspace_fac_no_cat.png differ diff --git a/packages/docs/static/images/ws_fac_tb_ws_buttons.png b/packages/docs/static/images/ws_fac_tb_ws_buttons.png new file mode 100644 index 00000000000..853c6ad5a3f Binary files /dev/null and b/packages/docs/static/images/ws_fac_tb_ws_buttons.png differ diff --git a/packages/docs/static/images/zoom-controls.png b/packages/docs/static/images/zoom-controls.png new file mode 100644 index 00000000000..01923fb6237 Binary files /dev/null and b/packages/docs/static/images/zoom-controls.png differ diff --git a/packages/docs/static/publications/papers/TenThingsWeveLearnedFromBlockly.pdf b/packages/docs/static/publications/papers/TenThingsWeveLearnedFromBlockly.pdf new file mode 100644 index 00000000000..d697b0f82e0 Binary files /dev/null and b/packages/docs/static/publications/papers/TenThingsWeveLearnedFromBlockly.pdf differ diff --git a/packages/docs/static/publications/papers/TipsForCreatingABlockLanguage.pdf b/packages/docs/static/publications/papers/TipsForCreatingABlockLanguage.pdf new file mode 100644 index 00000000000..25117d37b0d Binary files /dev/null and b/packages/docs/static/publications/papers/TipsForCreatingABlockLanguage.pdf differ diff --git a/packages/docs/static/robots.txt b/packages/docs/static/robots.txt new file mode 100644 index 00000000000..a2cf1da2399 --- /dev/null +++ b/packages/docs/static/robots.txt @@ -0,0 +1,8 @@ +# Algolia-Crawler-Verif: 836ECEE0BC07004B + +# Allow the Algolia Crawler to access the entire site +User-agent: Algolia Crawler +Allow: / + +User-agent: * +Allow: /