From 40e4a97b2449dd3c0898814f7d924b0a88aaaba0 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Sun, 8 Mar 2026 15:14:03 +0800 Subject: [PATCH 01/29] :wrench: chore: remove our svg-renderer Signed-off-by: SimonShiki --- .github/workflows/lint.yml | 14 - UPSTREAM | 1 - package.json | 3 +- packages/gui/package.json | 12 +- .../src/containers/paint-editor-wrapper.jsx | 2 +- packages/gui/src/containers/stage.jsx | 2 +- packages/gui/src/lib/file-uploader.js | 4 +- packages/gui/src/lib/get-costume-url.js | 2 +- packages/gui/src/playground/index.jsx | 6 - packages/gui/webpack.config.js | 7 +- packages/render/package.json | 2 +- packages/render/src/SVGSkin.js | 2 +- .../render/test/integration/cpu-render.html | 2 +- packages/render/test/integration/index.html | 2 +- packages/render/webpack.config.js | 2 +- packages/storage/webpack.config.js | 2 +- packages/svg-renderer/.editorconfig | 15 - packages/svg-renderer/.gitattributes | 38 - packages/svg-renderer/.github/CONTRIBUTING.md | 66 -- .../svg-renderer/.github/ISSUE_TEMPLATE.md | 15 - .../.github/PULL_REQUEST_TEMPLATE.md | 15 - .../svg-renderer/.github/workflows/ci-cd.yml | 55 -- .../.github/workflows/commitlint.yml | 12 - packages/svg-renderer/.gitignore | 20 - packages/svg-renderer/.npmignore | 7 - packages/svg-renderer/LICENSE | 12 - packages/svg-renderer/README.md | 89 -- packages/svg-renderer/TRADEMARK | 1 - packages/svg-renderer/eslint.config.js | 38 - packages/svg-renderer/package.json | 67 -- packages/svg-renderer/renovate.json5 | 7 - packages/svg-renderer/src/bitmap-adapter.ts | 174 ---- packages/svg-renderer/src/fixup-svg-string.ts | 61 -- packages/svg-renderer/src/font-converter.ts | 37 - packages/svg-renderer/src/font-inliner.ts | 48 -- packages/svg-renderer/src/index.ts | 22 - packages/svg-renderer/src/load-svg-string.ts | 336 -------- .../svg-renderer/src/playground/index.html | 132 --- packages/svg-renderer/src/sanitize-svg.ts | 105 --- .../src/serialize-svg-to-string.ts | 19 - packages/svg-renderer/src/svg-element.ts | 83 -- packages/svg-renderer/src/svg-renderer.ts | 183 ---- .../svg-renderer/src/transform-applier.ts | 669 --------------- packages/svg-renderer/src/types/global.d.ts | 6 - .../src/types/scratch-render-fonts.d.ts | 3 - .../src/types/transformation-matrix.d.ts | 3 - packages/svg-renderer/src/util/log.ts | 4 - .../test/bitmapAdapter_getResized.ts | 102 --- .../test/fixtures/css-import.sanitized.svg | 5 - .../svg-renderer/test/fixtures/css-import.svg | 11 - .../fixtures/embedded-cat-foo.sanitized.svg | 3 - .../test/fixtures/embedded-cat-foo.svg | 3 - .../test/fixtures/embedded-cat-xlink.svg | 3 - .../svg-renderer/test/fixtures/hearts.svg | 31 - .../test/fixtures/invalid-cloud.svg | 1 - .../test/fixtures/metadata-body.svg | 6 - .../fixtures/metadata-onload.sanitized.svg | 3 - .../test/fixtures/metadata-onload.svg | 7 - .../test/fixtures/onload-script.svg | 7 - ...white-carousel-pound-in-href.sanitized.svg | 74 -- .../red-and-white-carousel-pound-in-href.svg | 74 -- .../fixtures/reserved-namespace.sanitized.svg | 3 - .../test/fixtures/reserved-namespace.svg | 4 - ...cratch_cat_bitmap_within_svg.sanitized.svg | 1 - .../scratch_cat_bitmap_within_svg.svg | 1 - .../test/fixtures/script.sanitized.svg | 4 - .../svg-renderer/test/fixtures/script.svg | 8 - .../test/fixtures/svg-tag-prefixes.svg | 37 - .../svg-renderer/test/fixup-svg-string.ts | 144 ---- packages/svg-renderer/test/sanitize-svg.ts | 34 - .../test-output/transform-applier-test.html | 373 -------- .../svg-renderer/test/transform-applier.ts | 797 ------------------ packages/svg-renderer/tsconfig.json | 111 --- packages/svg-renderer/tsconfig.node.json | 8 - packages/svg-renderer/webpack.config.js | 88 -- packages/vm/package.json | 9 +- .../src/extensions/scratch3_gdx_for/index.js | 2 +- packages/vm/src/import/load-costume.js | 12 +- packages/vm/src/playground/benchmark.js | 2 +- packages/vm/src/virtual-machine.js | 2 +- .../vm/test/fixtures/fake-bitmap-adapter.js | 2 +- packages/vm/webpack.config.js | 2 - yarn.lock | 267 +++--- 83 files changed, 175 insertions(+), 4473 deletions(-) delete mode 100644 packages/svg-renderer/.editorconfig delete mode 100644 packages/svg-renderer/.gitattributes delete mode 100644 packages/svg-renderer/.github/CONTRIBUTING.md delete mode 100644 packages/svg-renderer/.github/ISSUE_TEMPLATE.md delete mode 100644 packages/svg-renderer/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 packages/svg-renderer/.github/workflows/ci-cd.yml delete mode 100644 packages/svg-renderer/.github/workflows/commitlint.yml delete mode 100644 packages/svg-renderer/.gitignore delete mode 100644 packages/svg-renderer/.npmignore delete mode 100644 packages/svg-renderer/LICENSE delete mode 100644 packages/svg-renderer/README.md delete mode 100644 packages/svg-renderer/TRADEMARK delete mode 100644 packages/svg-renderer/eslint.config.js delete mode 100644 packages/svg-renderer/package.json delete mode 100644 packages/svg-renderer/renovate.json5 delete mode 100644 packages/svg-renderer/src/bitmap-adapter.ts delete mode 100644 packages/svg-renderer/src/fixup-svg-string.ts delete mode 100644 packages/svg-renderer/src/font-converter.ts delete mode 100644 packages/svg-renderer/src/font-inliner.ts delete mode 100644 packages/svg-renderer/src/index.ts delete mode 100644 packages/svg-renderer/src/load-svg-string.ts delete mode 100644 packages/svg-renderer/src/playground/index.html delete mode 100644 packages/svg-renderer/src/sanitize-svg.ts delete mode 100644 packages/svg-renderer/src/serialize-svg-to-string.ts delete mode 100644 packages/svg-renderer/src/svg-element.ts delete mode 100644 packages/svg-renderer/src/svg-renderer.ts delete mode 100644 packages/svg-renderer/src/transform-applier.ts delete mode 100644 packages/svg-renderer/src/types/global.d.ts delete mode 100644 packages/svg-renderer/src/types/scratch-render-fonts.d.ts delete mode 100644 packages/svg-renderer/src/types/transformation-matrix.d.ts delete mode 100644 packages/svg-renderer/src/util/log.ts delete mode 100644 packages/svg-renderer/test/bitmapAdapter_getResized.ts delete mode 100644 packages/svg-renderer/test/fixtures/css-import.sanitized.svg delete mode 100644 packages/svg-renderer/test/fixtures/css-import.svg delete mode 100644 packages/svg-renderer/test/fixtures/embedded-cat-foo.sanitized.svg delete mode 100644 packages/svg-renderer/test/fixtures/embedded-cat-foo.svg delete mode 100644 packages/svg-renderer/test/fixtures/embedded-cat-xlink.svg delete mode 100644 packages/svg-renderer/test/fixtures/hearts.svg delete mode 100644 packages/svg-renderer/test/fixtures/invalid-cloud.svg delete mode 100644 packages/svg-renderer/test/fixtures/metadata-body.svg delete mode 100644 packages/svg-renderer/test/fixtures/metadata-onload.sanitized.svg delete mode 100644 packages/svg-renderer/test/fixtures/metadata-onload.svg delete mode 100644 packages/svg-renderer/test/fixtures/onload-script.svg delete mode 100644 packages/svg-renderer/test/fixtures/red-and-white-carousel-pound-in-href.sanitized.svg delete mode 100644 packages/svg-renderer/test/fixtures/red-and-white-carousel-pound-in-href.svg delete mode 100644 packages/svg-renderer/test/fixtures/reserved-namespace.sanitized.svg delete mode 100644 packages/svg-renderer/test/fixtures/reserved-namespace.svg delete mode 100644 packages/svg-renderer/test/fixtures/scratch_cat_bitmap_within_svg.sanitized.svg delete mode 100644 packages/svg-renderer/test/fixtures/scratch_cat_bitmap_within_svg.svg delete mode 100644 packages/svg-renderer/test/fixtures/script.sanitized.svg delete mode 100644 packages/svg-renderer/test/fixtures/script.svg delete mode 100644 packages/svg-renderer/test/fixtures/svg-tag-prefixes.svg delete mode 100644 packages/svg-renderer/test/fixup-svg-string.ts delete mode 100644 packages/svg-renderer/test/sanitize-svg.ts delete mode 100644 packages/svg-renderer/test/test-output/transform-applier-test.html delete mode 100644 packages/svg-renderer/test/transform-applier.ts delete mode 100644 packages/svg-renderer/tsconfig.json delete mode 100644 packages/svg-renderer/tsconfig.node.json delete mode 100644 packages/svg-renderer/webpack.config.js diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7be977b2a..a44acdce0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -153,17 +153,3 @@ jobs: - name: Lint run: yarn storage test:lint - - svg-renderer: - name: Lint SVG Renderer - needs: [build] - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Setup dependencies - uses: ./.github/actions/setup-deps - - - name: Lint - run: yarn svg-renderer test:lint diff --git a/UPSTREAM b/UPSTREAM index 63b988752..29bcf51e6 100644 --- a/UPSTREAM +++ b/UPSTREAM @@ -7,5 +7,4 @@ scratch-paint 6d241ec scratch-storage 80b258d scratch-parser 7244904 scratch-audio 50b7ade -scratch-svg-renderer 5ad1d41 eslint-config-scratch 87ee420 diff --git a/package.json b/package.json index 7e1d91d53..34d664fe3 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "start": "yarn gui start", "prepare": "husky", "build:dist": "cross-env NODE_ENV=production yarn build:full", - "build:full": "yarn l10n build && yarn audio build && yarn storage build && yarn svg-renderer build && yarn render build && yarn block build && yarn vm build && yarn paint build && node packages/gui/scripts/prepublish.mjs && yarn gui build", + "build:full": "yarn l10n build && yarn audio build && yarn storage build && yarn render build && yarn block build && yarn vm build && yarn paint build && node packages/gui/scripts/prepublish.mjs && yarn gui build", "build": "yarn block build && yarn gui build", "test": "yarn gui test:unit && yarn block test && yarn vm test", "performance": "yarn vm performance", @@ -36,7 +36,6 @@ "block": "yarn workspace clipcc-block", "l10n": "yarn workspace clipcc-l10n", "render": "yarn workspace clipcc-render", - "svg-renderer": "yarn workspace clipcc-svg-renderer", "lint-config": "yarn workspace eslint-config-clipcc", "storage": "yarn workspace clipcc-storage", "paint": "yarn workspace clipcc-paint", diff --git a/packages/gui/package.json b/packages/gui/package.json index 7f260cdca..28477560f 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -24,6 +24,7 @@ }, "dependencies": { "@microbit/microbit-universal-hex": "0.2.2", + "@turbowarp/nanolog": "^1.0.1", "arraybuffer-loader": "1.0.8", "autoprefixer": "^9.0.1", "balance-text": "3.3.1", @@ -36,19 +37,16 @@ "clipcc-paint": "3.2.0", "clipcc-render": "3.2.0", "clipcc-storage": "3.2.0", - "clipcc-svg-renderer": "3.2.0", + "scratch-svg-renderer": "3.1.19", "clipcc-vm": "3.2.0", "computed-style-to-inline-style": "3.0.0", "copy-webpack-plugin": "^14.0.0", - "core-js": "2.5.7", "css-loader": "6.7.3", "dapjs": "2.3.0", - "es6-object-assign": "1.1.0", "fastestsmallesttextencoderdecoder": "^1.0.22", "get-float-time-domain-data": "0.1.0", "get-user-media-promise": "1.1.4", "immutable": "5.1.5", - "intl": "1.2.5", "js-base64": "2.4.9", "keymirror": "0.1.1", "lodash.bindall": "4.4.0", @@ -56,7 +54,6 @@ "lodash.defaultsdeep": "4.6.1", "lodash.omit": "4.5.0", "lodash.throttle": "4.0.1", - "@turbowarp/nanolog": "^1.0.1", "node-polyfill-webpack-plugin": "^3.0.0", "omggif": "1.0.9", "papaparse": "5.3.0", @@ -101,6 +98,7 @@ "@babel/preset-env": "7.29.0", "@babel/preset-react": "7.14.5", "@babel/preset-typescript": "^7.24.7", + "@eslint/js": "^9.39.2", "babel-core": "7.0.0-bridge.0", "babel-eslint": "10.0.3", "babel-jest": "23.6.0", @@ -108,13 +106,12 @@ "cross-fetch": "^3.1.8", "enzyme": "3.11.0", "enzyme-adapter-react-16": "1.15.7", - "@eslint/js": "^9.39.2", "eslint": "^9.39.2", "eslint-import-resolver-webpack": "0.13.10", "eslint-plugin-import": "2.32.0", - "globals": "^16.5.0", "eslint-plugin-jest": "22.17.0", "eslint-plugin-react": "7.37.5", + "globals": "^16.5.0", "html-webpack-plugin": "^5.6.6", "jest": "21.2.1", "jest-junit": "7.0.0", @@ -130,6 +127,7 @@ "ts-loader": "^9.5.4", "typescript": "^5.9.3", "webpack": "^5.105.4", + "webpack-bundle-analyzer": "^5.2.0", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3", "yauzl": "2.10.0" diff --git a/packages/gui/src/containers/paint-editor-wrapper.jsx b/packages/gui/src/containers/paint-editor-wrapper.jsx index 6591e52a4..2ac6d34b5 100644 --- a/packages/gui/src/containers/paint-editor-wrapper.jsx +++ b/packages/gui/src/containers/paint-editor-wrapper.jsx @@ -3,7 +3,7 @@ import React from 'react'; import bindAll from 'lodash.bindall'; import VM from 'clipcc-vm'; import PaintEditor from 'clipcc-paint'; -import {inlineSvgFonts} from 'clipcc-svg-renderer'; +import {inlineSvgFonts} from 'scratch-svg-renderer'; import {connect} from 'react-redux'; diff --git a/packages/gui/src/containers/stage.jsx b/packages/gui/src/containers/stage.jsx index 00d0b00cd..f744b30d6 100644 --- a/packages/gui/src/containers/stage.jsx +++ b/packages/gui/src/containers/stage.jsx @@ -8,7 +8,7 @@ import {connect} from 'react-redux'; import {STAGE_DISPLAY_SIZES} from '../lib/layout-constants'; import {getEventXY} from '../lib/touch-utils'; import VideoProvider from '../lib/video/video-provider'; -import {BitmapAdapter as V2BitmapAdapter} from 'clipcc-svg-renderer'; +import {BitmapAdapter as V2BitmapAdapter} from 'scratch-svg-renderer'; import StageComponent from '../components/stage/stage.jsx'; diff --git a/packages/gui/src/lib/file-uploader.js b/packages/gui/src/lib/file-uploader.js index ce6f3c160..3a93d6bd0 100644 --- a/packages/gui/src/lib/file-uploader.js +++ b/packages/gui/src/lib/file-uploader.js @@ -1,4 +1,4 @@ -import {BitmapAdapter, sanitizeSvg} from 'clipcc-svg-renderer'; +import {BitmapAdapter, sanitizeSvg} from 'scratch-svg-renderer'; import randomizeSpritePosition from './randomize-sprite-position.js'; import bmpConverter from './bmp-converter'; import gifDecoder from './gif-decoder'; @@ -107,7 +107,7 @@ const costumeUpload = async function (fileData, fileType, storage, handleCostume let assetType = null; switch (fileType) { case 'image/svg+xml': { - // run svg bytes through clipcc-svg-renderer's sanitization code + // run svg bytes through scratch-svg-renderer's sanitization code fileData = sanitizeSvg.sanitizeByteStream(fileData); costumeFormat = storage.DataFormat.SVG; diff --git a/packages/gui/src/lib/get-costume-url.js b/packages/gui/src/lib/get-costume-url.js index e8941c83e..7c4b66572 100644 --- a/packages/gui/src/lib/get-costume-url.js +++ b/packages/gui/src/lib/get-costume-url.js @@ -1,5 +1,5 @@ import storage from './storage'; -import {inlineSvgFonts} from 'clipcc-svg-renderer'; +import {inlineSvgFonts} from 'scratch-svg-renderer'; // Contains 'font-family', but doesn't only contain 'font-family="none"' const HAS_FONT_REGEXP = 'font-family(?!="none")'; diff --git a/packages/gui/src/playground/index.jsx b/packages/gui/src/playground/index.jsx index 18df6f169..2ccc64271 100644 --- a/packages/gui/src/playground/index.jsx +++ b/packages/gui/src/playground/index.jsx @@ -1,9 +1,3 @@ -// Polyfills -import 'es6-object-assign/auto'; -import 'core-js/fn/array/includes'; -import 'core-js/fn/promise/finally'; -import 'intl'; // For Safari 9 - import React from 'react'; import ReactDOM from 'react-dom'; diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index a1bfb8b0e..a434ab042 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -8,6 +8,7 @@ const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); +const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); const STATIC_PATH = process.env.STATIC_PATH || '/static'; @@ -45,8 +46,7 @@ const base = { path.resolve(__dirname, 'src'), path.resolve(__dirname, '../vm/src'), path.resolve(__dirname, '../block/src'), - path.resolve(__dirname, '../audio/src'), - path.resolve(__dirname, '../svg-renderer/src') + path.resolve(__dirname, '../audio/src') ], test: /\.([cm]?ts|tsx)$/, loader: 'ts-loader', @@ -260,7 +260,8 @@ module.exports = [ context: '../vm/dist/web' } ] - }) + }), + new BundleAnalyzerPlugin() ]) }) ].concat( diff --git a/packages/render/package.json b/packages/render/package.json index 5878dbc76..b7456c0ad 100644 --- a/packages/render/package.json +++ b/packages/render/package.json @@ -55,7 +55,7 @@ "dependencies": { "@turbowarp/nanolog": "^0.2.0", "clipcc-storage": "3.2.0", - "clipcc-svg-renderer": "3.2.0", + "scratch-svg-renderer": "3.1.19", "grapheme-breaker": "0.3.2", "hull.js": "1.0.6", "ify-loader": "1.1.0", diff --git a/packages/render/src/SVGSkin.js b/packages/render/src/SVGSkin.js index c5bd76c50..52317fb8f 100644 --- a/packages/render/src/SVGSkin.js +++ b/packages/render/src/SVGSkin.js @@ -1,7 +1,7 @@ const twgl = require('twgl.js'); const Skin = require('./Skin'); -const {loadSvgString, serializeSvgToString} = require('clipcc-svg-renderer'); +const {loadSvgString, serializeSvgToString} = require('scratch-svg-renderer'); const ShaderManager = require('./ShaderManager'); const MAX_TEXTURE_DIMENSION = 2048; diff --git a/packages/render/test/integration/cpu-render.html b/packages/render/test/integration/cpu-render.html index a8fde32e2..f83517fe4 100644 --- a/packages/render/test/integration/cpu-render.html +++ b/packages/render/test/integration/cpu-render.html @@ -1,7 +1,7 @@ - + diff --git a/packages/render/test/integration/index.html b/packages/render/test/integration/index.html index ee1f56b51..51313b9d1 100644 --- a/packages/render/test/integration/index.html +++ b/packages/render/test/integration/index.html @@ -1,7 +1,7 @@ - + diff --git a/packages/render/webpack.config.js b/packages/render/webpack.config.js index 762d2cb5c..59a188a93 100644 --- a/packages/render/webpack.config.js +++ b/packages/render/webpack.config.js @@ -110,7 +110,7 @@ module.exports = [ '!ify-loader!grapheme-breaker': 'grapheme-breaker', '!ify-loader!linebreak': 'linebreak', 'hull.js': true, - 'clipcc-svg-renderer': true, + 'scratch-svg-renderer': true, 'twgl.js': true, 'xml-escape': true } diff --git a/packages/storage/webpack.config.js b/packages/storage/webpack.config.js index 44f141542..0afb63218 100644 --- a/packages/storage/webpack.config.js +++ b/packages/storage/webpack.config.js @@ -116,7 +116,7 @@ const nodeConfig = { 'base64-js': true, 'js-md5': true, 'localforage': true, - 'text-encoding': true + 'fastestsmallesttextencoderdecoder': true }, plugins: baseConfig.plugins.concat([ new webpack.ProvidePlugin({ diff --git a/packages/svg-renderer/.editorconfig b/packages/svg-renderer/.editorconfig deleted file mode 100644 index 3bfc9360a..000000000 --- a/packages/svg-renderer/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -root = true - -[*] -end_of_line = lf -insert_final_newline = true -charset = utf-8 -indent_size = 4 -trim_trailing_whitespace = true - -[*.{js}] -indent_style = space - -[*.{json,json5}] -indent_style = space -indent_size = 2 diff --git a/packages/svg-renderer/.gitattributes b/packages/svg-renderer/.gitattributes deleted file mode 100644 index 71521c9c5..000000000 --- a/packages/svg-renderer/.gitattributes +++ /dev/null @@ -1,38 +0,0 @@ -# Set the default behavior, in case people don't have core.autocrlf set. -* text=auto - -# Explicitly specify line endings for as many files as possible. -# People who (for example) rsync between Windows and Linux need this. - -# File types which we know are binary -*.sb2 binary - -# Prefer LF for most file types -*.css text eol=lf -*.frag text eol=lf -*.htm text eol=lf -*.html text eol=lf -*.iml text eol=lf -*.js text eol=lf -*.js.map text eol=lf -*.json text eol=lf -*.json5 text eol=lf -*.md text eol=lf -*.vert text eol=lf -*.xml text eol=lf -*.yml text eol=lf - -# Prefer LF for these files -.editorconfig text eol=lf -.eslintignore text eol=lf -.eslintrc text eol=lf -.gitattributes text eol=lf -.gitignore text eol=lf -.gitmodules text eol=lf -.npmignore text eol=lf -LICENSE text eol=lf -Makefile text eol=lf -README text eol=lf -TRADEMARK text eol=lf - -# Use CRLF for Windows-specific file types diff --git a/packages/svg-renderer/.github/CONTRIBUTING.md b/packages/svg-renderer/.github/CONTRIBUTING.md deleted file mode 100644 index f9713f44f..000000000 --- a/packages/svg-renderer/.github/CONTRIBUTING.md +++ /dev/null @@ -1,66 +0,0 @@ -## Contributing -The development of Scratch is an ongoing process, and we love to have people in the Scratch and open source communities help us along the way. - -### Ways to Help - -* **Documenting bugs** - * If you've identified a bug in Scratch you should first check to see if it's been filed as an issue, if not you can file one. Make sure you follow the issue template. - * It's important that we can consistently reproduce issues. When writing an issue, be sure to follow our [reproduction step guidelines](https://github.com/LLK/scratch-gui/wiki/Writing-good-repro-steps). - * Some issues are marked "Needs Repro". Adding a comment with good reproduction steps to those issues is a great way to help. - * If you don't have an issue in mind already, you can look through the [Bugs & Glitches forum.](https://scratch.mit.edu/discuss/3/) Look for users reporting problems, reproduce the problem yourself, and file new issues following our guidelines. - -* **Fixing bugs** - * You can request to fix a bug in a comment on the issue if you at mention the repo coordinator, who for this repo is @fsih. - * If the issue is marked "Help Wanted" you can go ahead and start working on it! - * **We will only accept Pull Requests for bugs that have an issue filed that has a priority label** - * If you're interested in fixing a bug with no issue, file the issue first and wait for it to have a priority added to it. - - * We are not looking for Pull Requests ("PR") for every issue and may deny a PR if it doesn't fit our criteria. - * We are far more likely to accept a PR if it is for an issue marked with Help Wanted. - * We will not accept PRs for issues marked with "Needs Discussion" or "Needs Design." - * Wait until the Repo Coordinator assigns the issue to you before you begin work or submit a PR. - -### Learning Git and Github - -If you want to work on fixing issues, you should be familiar with Git and Github. - -* [Learn Git branching](https://learngitbranching.js.org/) includes an introduction to basic git commands and useful branching features. -* Here's a general introduction to [contributing to an open source project](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github). - -**Important:** we follow the [Github Flow process](https://guides.github.com/introduction/flow/) as our development process. - -### How to Fix Bugs -1. Identify which Github issue you are working on. Leave a comment on the issue to let us (and other contributors) know you're working on it. -2. Make sure you have a fork of this repo (see [Github's forking a repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) for details) -3. Switch to the `develop` branch, and pull down the latest changes from upstream -4. Run the code, and reproduce the problem -5. Create your branch from the `develop` branch -6. Make code changes to fix the problem -7. Run `npm test` to make sure that your changes pass our tests -8. Commit your changes -9. Push your branch to your fork -10. Create your pull request - 1. Make sure to follow the template in the PR description - 1. Remember to check the “[Allow edits from maintainers](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork)” box - -When submitting pull requests keep in mind: -* please be patient -- it can take a while to find time to review them -* try to change the least amount of code necessary to fix the bug -* the code can't be radically changed without significant coordination with the Scratch Team, so these types of changes should be avoided -* if you find yourself changing a substantial amount of code or considering radical changes, please ask for clarification -- we may have envisioned a different approach, or underestimated the amount of effort - -### Suggestions -![Block sketch](https://user-images.githubusercontent.com/3431616/77192550-1dcebe00-6ab3-11ea-9606-8ecd8500c958.png) - -Please note: **_we are unlikely to accept PRs with new features that haven't been thought through and discussed as a group_**. - -Why? Because we have a strong belief in the value of keeping things simple for new users. It's been said that the Scratch Team spends about one hour of design discussion for every pixel in Scratch. To learn more about our design philosophy, see [the Scratch Developers page](https://scratch.mit.edu/developers), or [this paper](http://web.media.mit.edu/~mres/papers/Scratch-CACM-final.pdf). - -We welcome suggestions! If you want to suggest a feature, please post in our [suggestions forum](https://scratch.mit.edu/discuss/1/). Your suggestion will be helped if you include a mockup design; this can be simple, even hand-drawn. - -### Other resources -Beyond this repo, there are also some other resources that you might want to take a look at: -* [Community Guidelines](https://github.com/LLK/scratch-www/wiki/Community-Guidelines) (we find it important to maintain a constructive and welcoming community, just like on Scratch) -* [Open Source forum](https://scratch.mit.edu/discuss/49/) on Scratch -* [Suggestions forum](https://scratch.mit.edu/discuss/1/) on Scratch -* [Bugs & Glitches forum](https://scratch.mit.edu/discuss/3/) on Scratch diff --git a/packages/svg-renderer/.github/ISSUE_TEMPLATE.md b/packages/svg-renderer/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 38756937c..000000000 --- a/packages/svg-renderer/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,15 +0,0 @@ -### Expected Behavior - -_Please describe what should happen_ - -### Actual Behavior - -_Describe what actually happens_ - -### Steps to Reproduce - -_Explain what someone needs to do in order to see what's described in *Actual behavior* above_ - -### Operating System and Browser - -_e.g. Mac OS 10.11.6 Safari 10.0_ diff --git a/packages/svg-renderer/.github/PULL_REQUEST_TEMPLATE.md b/packages/svg-renderer/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 33ff6dfde..000000000 --- a/packages/svg-renderer/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,15 +0,0 @@ -### Resolves - -_What Github issue does this resolve (please include link)?_ - -### Proposed Changes - -_Describe what this Pull Request does_ - -### Reason for Changes - -_Explain why these changes should be made_ - -### Test Coverage - -_Please show how you have added tests to cover your changes_ diff --git a/packages/svg-renderer/.github/workflows/ci-cd.yml b/packages/svg-renderer/.github/workflows/ci-cd.yml deleted file mode 100644 index c5ee813ed..000000000 --- a/packages/svg-renderer/.github/workflows/ci-cd.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: CI/CD - -on: - workflow_dispatch: # Allows you to run this workflow manually from the Actions tab - pull_request: # Runs whenever a pull request is created or updated - push: # Runs whenever a commit is pushed to the repository - branches: [master, develop, hotfix/*] - -concurrency: - group: "${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" - cancel-in-progress: true - -permissions: - contents: write # publish a GitHub release - pages: write # deploy to GitHub Pages - issues: write # comment on released issues - pull-requests: write # comment on released pull requests - -jobs: - ci-cd: - runs-on: ubuntu-latest - env: - TRIGGER_DEPLOY: ${{ startsWith(github.ref, 'refs/heads/master') || startsWith(github.ref, 'refs/heads/hotfix') || startsWith(github.ref, 'refs/heads/develop') }} - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: wagoid/commitlint-github-action@5ce82f5d814d4010519d15f0552aec4f17a1e1fe # v5 - if: github.event_name == 'pull_request' - - uses: actions/setup-node@1a4442cacd436585916779262731d5b162bc6ec7 # v3 - with: - cache: "npm" - node-version-file: ".nvmrc" - - - name: Info - run: | - cat < { - svgRenderer.draw(scale); - doSomethingWith(svgRenderer.canvas); -}); -``` - -## How to run locally as part of scratch-gui - -To run scratch-svg-renderer locally as part of scratch-gui, for development: - -1. Set up local repositories (or pull updated code): - 1. scratch-svg-renderer (this repo) - 2. [scratch-render](https://github.com/scratchfoundation/scratch-render) - 3. [scratch-paint](https://github.com/scratchfoundation/scratch-paint) - 4. [scratch-gui](https://github.com/scratchfoundation/scratch-gui) -2. In each of the local repos above, run `npm install` -3. Run `npm link` in each of these local repos: - 1. scratch-svg-renderer - 2. scratch-render - 3. scratch-paint -4. Run `npm link scratch-svg-renderer` in each of these local repos: - 1. scratch-render - 2. scratch-paint - 3. scratch-gui -5. In your local scratch-gui repo: - 1. run `npm link scratch-render` - 2. run `npm link scratch-paint` -6. In scratch-gui, follow its instructions to run it or build its code - -## Donate - -We provide [Scratch](https://scratch.mit.edu) free of charge, and want to keep it that way! Please consider making a -[donation](https://secure.donationpay.org/scratchfoundation/) to support our continued engineering, design, community, -and resource development efforts. Donations of any size are appreciated. Thank you! - -## Committing - -This project uses [semantic release](https://github.com/semantic-release/semantic-release) to ensure version bumps -follow semver so that projects depending on it don't break unexpectedly. - -In order to automatically determine version updates, semantic release expects commit messages to follow the -[conventional-changelog](https://github.com/bcoe/conventional-changelog-standard/blob/master/convention.md) -specification. - -You can use the [commitizen CLI](https://github.com/commitizen/cz-cli) to make commits formatted in this way: - -```bash -npm install -g commitizen@latest cz-conventional-changelog@latest -``` - -Now you're ready to make commits using `git cz`. diff --git a/packages/svg-renderer/TRADEMARK b/packages/svg-renderer/TRADEMARK deleted file mode 100644 index 17b5d4c91..000000000 --- a/packages/svg-renderer/TRADEMARK +++ /dev/null @@ -1 +0,0 @@ -The Scratch trademarks, including the Scratch name, logo, the Scratch Cat, Gobo, Pico, Nano, Tera and Giga graphics (the "Marks"), are property of the Massachusetts Institute of Technology (MIT). Marks may not be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/packages/svg-renderer/eslint.config.js b/packages/svg-renderer/eslint.config.js deleted file mode 100644 index b31506e7b..000000000 --- a/packages/svg-renderer/eslint.config.js +++ /dev/null @@ -1,38 +0,0 @@ -const clipccConfig = require('eslint-config-clipcc'); -const clipccES6 = require('eslint-config-clipcc/es6'); -const clipccNode = require('eslint-config-clipcc/node'); -const clipccTS = require('eslint-config-clipcc/ts'); -const globals = require('globals'); - -module.exports = [ - ...clipccConfig, - ...clipccES6, - ...clipccNode, - ...clipccTS, - { - languageOptions: { - globals: { - ...globals.browser, - document: true, - window: true, - DOMParser: true, - Image: true, - XMLSerializer: true - } - } - }, - { - files: ['src/**/*.ts', 'test/**/*.ts'], - rules: { - '@typescript-eslint/ban-ts-comment': 'off' - } - }, - { - ignores: [ - 'node_modules/**', - 'dist/**', - 'playground/**', - '**/*.min.js' - ] - } -]; diff --git a/packages/svg-renderer/package.json b/packages/svg-renderer/package.json deleted file mode 100644 index 4e7dc8804..000000000 --- a/packages/svg-renderer/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "clipcc-svg-renderer", - "version": "3.2.0", - "description": "SVG renderer for ClipCC", - "main": "./dist/node/index.js", - "browser": "./dist/web/scratch-svg-renderer.js", - "types": "./dist/types/index.d.ts", - "scripts": { - "build": "yarn run clean && tsc --project ./tsconfig.node.json && webpack", - "clean": "rimraf ./dist", - "start": "webpack-dev-server", - "test": "yarn run test:types && yarn run test:lint && yarn run test:unit", - "test:types": "tsc --noEmit", - "test:lint": "eslint . --ext .ts", - "test:unit": "tap ./test/*.ts --allow-incomplete-coverage --allow-empty-coverage", - "watch": "webpack --watch" - }, - "author": "Massachusetts Institute of Technology", - "license": "AGPL-3.0-only", - "homepage": "https://github.com/Clipteam/clipcc/packages/svg-renderer#readme", - "peerDependencies": { - "scratch-render-fonts": "^1.0.252" - }, - "dependencies": { - "@turbowarp/nanolog": "^0.2.0", - "base64-js": "^1.5.1", - "base64-loader": "^1.0.0", - "css-tree": "^1.1.3", - "fastestsmallesttextencoderdecoder": "^1.0.22", - "isomorphic-dompurify": "^2.14.0", - "transformation-matrix": "^2.16.1" - }, - "devDependencies": { - "@babel/cli": "7.28.6", - "@babel/core": "7.29.0", - "@babel/eslint-parser": "7.28.6", - "@babel/preset-env": "7.29.0", - "@types/css-tree": "^2.3.8", - "@types/jsdom": "^28.0.0", - "babel-core": "7.0.0-bridge.0", - "babel-loader": "^10.1.0", - "copy-webpack-plugin": "^14.0.0", - "eslint": "^9.39.2", - "eslint-config-clipcc": "9.0.9", - "eslint-plugin-import": "2.29.1", - "globals": "^16.5.0", - "jsdom": "28.1.0", - "json": "9.0.6", - "mkdirp": "3.0.1", - "rimraf": "3.0.2", - "scratch-render-fonts": "1.0.252", - "tap": "21.0.1", - "terser-webpack-plugin": "^5.3.17", - "ts-loader": "^9.5.4", - "typescript": "^5.9.3", - "webpack": "5.105.4", - "webpack-cli": "6.0.1", - "webpack-dev-server": "5.2.3", - "@xmldom/xmldom": "0.8.11" - }, - "browserslist": [ - "Chrome >= 63", - "Edge >= 15", - "Firefox >= 57", - "Safari >= 11" - ] -} diff --git a/packages/svg-renderer/renovate.json5 b/packages/svg-renderer/renovate.json5 deleted file mode 100644 index 6dc461c62..000000000 --- a/packages/svg-renderer/renovate.json5 +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - - "extends": [ - "github>scratchfoundation/scratch-renovate-config:js-lib-bundled" - ] -} diff --git a/packages/svg-renderer/src/bitmap-adapter.ts b/packages/svg-renderer/src/bitmap-adapter.ts deleted file mode 100644 index c3ebeffa2..000000000 --- a/packages/svg-renderer/src/bitmap-adapter.ts +++ /dev/null @@ -1,174 +0,0 @@ -import base64js from 'base64-js'; - -type ResolutionConvertCallback = (error: string | null, dataURI?: string) => void; - -/** - * Adapts Scratch 2.0 bitmaps for use in scratch 3.0 - */ -class BitmapAdapter { - private _makeImage: () => HTMLImageElement; - private _makeCanvas: () => HTMLCanvasElement; - stageWidth = 480; - stageHeight = 360; - /** - * @param makeImage HTML image constructor. Tests can provide this. - * @param makeCanvas HTML canvas constructor. Tests can provide this. - */ - constructor (makeImage?: () => HTMLImageElement, makeCanvas?: () => HTMLCanvasElement) { - this._makeImage = makeImage ? makeImage : () => new Image(); - this._makeCanvas = makeCanvas ? makeCanvas : () => document.createElement('canvas'); - } - - /** - * Set current stage size. - * @param width The stage width. - * @param height The stage height. - */ - setStageSize (width: number, height: number) { - this.stageWidth = width; - this.stageHeight = height; - } - - /** - * Return a canvas with the resized version of the given image, done using nearest-neighbor interpolation - * @param image The image to resize - * @param newWidth The desired post-resize width of the image - * @param newHeight The desired post-resize height of the image - * @returns A canvas with the resized image drawn on it. - */ - resize ( - image: Exclude, - newWidth: int, - newHeight: int - ): HTMLCanvasElement { - // We want to always resize using nearest-neighbor interpolation. However, canvas implementations are free to - // use linear interpolation (or other "smooth" interpolation methods) when downscaling: - // https://bugzilla.mozilla.org/show_bug.cgi?id=1360415 - // It seems we can get around this by resizing in two steps: first width, then height. This will always result - // in nearest-neighbor interpolation, even when downscaling. - const stretchWidthCanvas = this._makeCanvas(); - stretchWidthCanvas.width = newWidth; - stretchWidthCanvas.height = image.height; - let context = stretchWidthCanvas.getContext('2d')!; - context.imageSmoothingEnabled = false; - context.drawImage(image, 0, 0, stretchWidthCanvas.width, stretchWidthCanvas.height); - const stretchHeightCanvas = this._makeCanvas(); - stretchHeightCanvas.width = newWidth; - stretchHeightCanvas.height = newHeight; - context = stretchHeightCanvas.getContext('2d')!; - context.imageSmoothingEnabled = false; - context.drawImage(stretchWidthCanvas, 0, 0, stretchHeightCanvas.width, stretchHeightCanvas.height); - return stretchHeightCanvas; - } - - /** - * Scratch 2.0 had resolution 1 and 2 bitmaps. All bitmaps in Scratch 3.0 are equivalent - * to resolution 2 bitmaps. Therefore, converting a resolution 1 bitmap means doubling - * it in width and height. - * @param dataURI Base 64 encoded image data of the bitmap - * @param callback Node-style callback that returns updated dataURI if conversion succeeded - */ - convertResolution1Bitmap (dataURI: string, callback: ResolutionConvertCallback) { - const image = this._makeImage(); - image.src = dataURI; - image.onload = () => { - callback(null, this.resize(image, image.width * 2, image.height * 2).toDataURL()); - }; - image.onerror = () => { - callback('Image load failed'); - }; - } - - /** - * Given width/height of an uploaded item, return width/height the image will be resized - * to in Scratch 3.0 - * @param oldWidth original width - * @param oldHeight original height - * @returns Array of new width, new height - */ - getResizedWidthHeight (oldWidth: number, oldHeight: number) { - const STAGE_RATIO = this.stageWidth / this.stageHeight; - - // If both dimensions are smaller than or equal to corresponding stage dimension, - // double both dimensions - if ((oldWidth <= this.stageWidth) && (oldHeight <= this.stageHeight)) { - return {width: oldWidth * 2, height: oldHeight * 2}; - } - - // If neither dimension is larger than 2x corresponding stage dimension, - // this is an in-between image, return it as is - if ((oldWidth <= this.stageWidth * 2) && (oldHeight <= this.stageHeight * 2)) { - return {width: oldWidth, height: oldHeight}; - } - - const imageRatio = oldWidth / oldHeight; - // Otherwise, figure out how to resize - if (imageRatio >= STAGE_RATIO) { - // Wide Image - return {width: this.stageWidth * 2, height: this.stageWidth * 2 / imageRatio}; - } - // In this case we have either: - // - A wide image, but not with as big a ratio between width and height, - // making it so that fitting the width to double stage size would leave - // the height too big to fit in double the stage height - // - A square image that's still larger than the double at least - // one of the stage dimensions, so pick the smaller of the two dimensions (to fit) - // - A tall image - // In any of these cases, resize the image to fit the height to double the stage height - return {width: this.stageHeight * 2 * imageRatio, height: this.stageHeight * 2}; - } - - /** - * Given bitmap data, resize as necessary. - * @param fileData Base 64 encoded image data of the bitmap - * @param fileType The MIME type of this file - * @returns Resolves to resized image data Uint8Array - */ - importBitmap (fileData: ArrayBuffer | string, fileType: string) { - let dataURI = fileData; - if (fileData instanceof ArrayBuffer) { - dataURI = this.convertBinaryToDataURI(fileData, fileType); - } - return new Promise((resolve, reject) => { - const image = this._makeImage(); - image.src = dataURI as string; - image.onload = () => { - const newSize = this.getResizedWidthHeight(image.width, image.height); - if (newSize.width === image.width && newSize.height === image.height) { - // No change - resolve(this.convertDataURIToBinary(dataURI as string)); - } else { - const resizedDataURI = this.resize(image, newSize.width, newSize.height).toDataURL(); - resolve(this.convertDataURIToBinary(resizedDataURI)); - } - }; - image.onerror = () => { - // TODO: reject with an Error (breaking API change!) - // eslint-disable-next-line prefer-promise-reject-errors - reject('Image load failed'); - }; - }); - } - - // TODO consolidate with scratch-vm/src/util/base64-util.js - // From https://gist.github.com/borismus/1032746 - convertDataURIToBinary (dataURI: string) { - const BASE64_MARKER = ';base64,'; - const base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length; - const base64 = dataURI.substring(base64Index); - const raw = window.atob(base64); - const rawLength = raw.length; - const array = new Uint8Array(new ArrayBuffer(rawLength)); - - for (let i = 0; i < rawLength; i++) { - array[i] = raw.charCodeAt(i); - } - return array; - } - - convertBinaryToDataURI (arrayBuffer: ArrayBuffer, contentType: string) { - return `data:${contentType};base64,${base64js.fromByteArray(new Uint8Array(arrayBuffer))}`; - } -} - -export default BitmapAdapter; diff --git a/packages/svg-renderer/src/fixup-svg-string.ts b/packages/svg-renderer/src/fixup-svg-string.ts deleted file mode 100644 index 3e3aaa05e..000000000 --- a/packages/svg-renderer/src/fixup-svg-string.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Fixup svg string prior to parsing. - * @param svgString String of the svg to fix. - * @returns fixed svg that should be parseable. - */ -export default function (svgString: string): string { - // Add root svg namespace if it does not exist. - const svgAttrs = svgString.match(/]*>/); - if (svgAttrs && svgAttrs[0].indexOf('xmlns=') === -1) { - svgString = svgString.replace(']+?xlink:href=["'])data:img\/png/g, - // use the captured ]+?xmlns:(?!xml=)[^ ]+=)"http:\/\/www.w3.org\/XML\/1998\/namespace"/g; - if (svgString.match(xmlnsRegex) !== null) { - svgString = svgString.replace( - // capture the entire attribute - xmlnsRegex, - // use the captured attribute name; replace only the URL - ($0, $1) => `${$1}"http://dummy.namespace"` - ); - } - - // Strip `svg:` prefix (sometimes added by Inkscape) from all tags. They interfere with DOMPurify (prefixed tag - // names are not recognized) and the paint editor. - // This matches opening and closing tags--the capture group captures the slash if it exists, and it is reinserted - // in the replacement text. - svgString = svgString.replace(/<(\/?)\s*svg:/g, '<$1'); - - // The element is not needed for rendering and sometimes contains - // unparseable garbage from Illustrator :( Empty out the contents. - // Note: [\s\S] matches everything including newlines, which .* does not - svgString = svgString.replace(/[\s\S]*<\/metadata>/, ''); - - // Empty script tags and javascript executing - svgString = svgString.replace(/[\s\S]*<\/script>/, ''); - - return svgString; -} diff --git a/packages/svg-renderer/src/font-converter.ts b/packages/svg-renderer/src/font-converter.ts deleted file mode 100644 index ed28af49d..000000000 --- a/packages/svg-renderer/src/font-converter.ts +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @fileoverview Convert 2.0 fonts to 3.0 fonts. - */ - -/** - * Given an SVG, replace Scratch 2.0 fonts with new 3.0 fonts. Add defaults where there are none. - * @param svgTag The SVG dom object - */ -const convertFonts = function (svgTag: SVGElement) { - // Collect all text elements into a list. - const textElements: Element[] = []; - const collectText = (domElement: Element | Node) => { - if (domElement instanceof Element && domElement.localName === 'text') { - textElements.push(domElement); - } - for (let i = 0; i < domElement.childNodes.length; i++) { - collectText(domElement.childNodes[i]); - } - }; - collectText(svgTag); - // If there's an old font-family, switch to the new one. - for (const textElement of textElements) { - // If there's no font-family provided, provide one. - if (!textElement.getAttribute('font-family') || - textElement.getAttribute('font-family') === 'Helvetica') { - textElement.setAttribute('font-family', 'Sans Serif'); - } else if (textElement.getAttribute('font-family') === 'Mystery') { - textElement.setAttribute('font-family', 'Curly'); - } else if (textElement.getAttribute('font-family') === 'Gloria') { - textElement.setAttribute('font-family', 'Handwriting'); - } else if (textElement.getAttribute('font-family') === 'Donegal') { - textElement.setAttribute('font-family', 'Serif'); - } - } -}; - -export default convertFonts; diff --git a/packages/svg-renderer/src/font-inliner.ts b/packages/svg-renderer/src/font-inliner.ts deleted file mode 100644 index c29ef0ad9..000000000 --- a/packages/svg-renderer/src/font-inliner.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @fileoverview Import bitmap data into Scratch 3.0, resizing image as necessary. - */ -import getFonts from 'scratch-render-fonts'; - -/** - * Given SVG data, inline the fonts. This allows them to be rendered correctly when set - * as the source of an HTMLImageElement. Here is a note from tmickel: - * // Inject fonts that are needed. - * // It would be nice if there were another way to get the SVG-in-canvas - * // to render the correct font family, but I couldn't find any other way. - * // Other things I tried: - * // Just injecting the font-family into the document: no effect. - * // External stylesheet linked to by SVG: no effect. - * // Using a or to link to font-family - * // injected into the document: no effect. - * @param {string} svgString The string representation of the svg to modify - * @returns {string} The svg with any needed fonts inlined - */ -export default function inlineSvgFonts (svgString: string): string { - const FONTS = getFonts(); - // Make it clear that this function only operates on strings. - // If we don't explicitly throw this here, the function silently fails. - if (typeof svgString !== 'string') { - throw new Error('SVG to be inlined is not a string'); - } - - // Collect fonts that need injection. - const fontsNeeded = new Set(); - const fontRegex = /font-family="([^"]*)"/g; - let matches = fontRegex.exec(svgString); - while (matches) { - fontsNeeded.add(matches[1]); - matches = fontRegex.exec(svgString); - } - if (fontsNeeded.size > 0) { - let str = ''; - svgString = svgString.replace(/]*>/, `$&${str}`); - return svgString; - } - return svgString; -}; diff --git a/packages/svg-renderer/src/index.ts b/packages/svg-renderer/src/index.ts deleted file mode 100644 index a502ff27b..000000000 --- a/packages/svg-renderer/src/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import SVGRenderer from './svg-renderer'; -import BitmapAdapter from './bitmap-adapter'; -import inlineSvgFonts from './font-inliner'; -import loadSvgString from './load-svg-string'; -import sanitizeSvg from './sanitize-svg'; -import serializeSvgToString from './serialize-svg-to-string'; -import SvgElement from './svg-element'; -import convertFonts from './font-converter'; -// /** -// * Export for NPM & Node.js -// * @type {RenderWebGL} -// */ -export { - BitmapAdapter, - convertFonts, - inlineSvgFonts, - loadSvgString, - sanitizeSvg, - serializeSvgToString, - SvgElement, - SVGRenderer -}; diff --git a/packages/svg-renderer/src/load-svg-string.ts b/packages/svg-renderer/src/load-svg-string.ts deleted file mode 100644 index 67c78e4f8..000000000 --- a/packages/svg-renderer/src/load-svg-string.ts +++ /dev/null @@ -1,336 +0,0 @@ -import DOMPurify from 'isomorphic-dompurify'; -import SvgElement from './svg-element'; -import convertFonts from './font-converter'; -import fixupSvgString from './fixup-svg-string'; -import transformStrokeWidths from './transform-applier'; - -/** - * @param svgTag the tag to search within - * @param tagName svg tag to search for (or collect all elements if not given) - * @returns a list of elements with the given tagname - */ -const collectElements = (svgTag: SVGElement, tagName?: string) => { - const elts: Element[] = []; - const collectElementsInner = (domElement: Element) => { - if ((domElement.localName === tagName || typeof tagName === 'undefined') && 'getAttribute' in domElement) { - elts.push(domElement); - } - for (let i = 0; i < domElement.childNodes.length; i++) { - collectElementsInner(domElement.childNodes[i] as Element); - } - }; - collectElementsInner(svgTag); - return elts; -}; - -/** - * Fix SVGs to comply with SVG spec. Scratch 2 defaults to x2 = 0 when x2 is missing, but - * SVG defaults to x2 = 1 when missing. - * @param {SVGSVGElement} svgTag the SVG tag to apply the transformation to - */ -const transformGradients = (svgTag: SVGSVGElement) => { - const linearGradientElements = collectElements(svgTag, 'linearGradient'); - - // For each gradient element, supply x2 if necessary. - for (const gradientElement of linearGradientElements) { - if (!gradientElement.getAttribute('x2')) { - gradientElement.setAttribute('x2', '0'); - } - } -}; - -/** - * Fix SVGs to match appearance in Scratch 2, which used nearest neighbor scaling for bitmaps - * within SVGs. - * @param {SVGSVGElement} svgTag the SVG tag to apply the transformation to - */ -const transformImages = (svgTag: SVGSVGElement) => { - const imageElements = collectElements(svgTag, 'image'); - - // For each image element, set image rendering to pixelated - const pixelatedImages = 'image-rendering: optimizespeed; image-rendering: pixelated;'; - for (const elt of imageElements) { - if (elt.getAttribute('style')) { - elt.setAttribute('style', - `${pixelatedImages} ${elt.getAttribute('style')}`); - } else { - elt.setAttribute('style', pixelatedImages); - } - } -}; - -/** - * Transforms an SVG's text elements for Scratch 2.0 quirks. - * These quirks include: - * 1. `x` and `y` properties are removed/ignored. - * 2. Alignment is set to `text-before-edge`. - * 3. Line-breaks are converted to explicit elements. - * 4. Any required fonts are injected. - * @param {SVGSVGElement} svgTag the SVG tag to apply the transformation to - */ -const transformText = (svgTag: SVGSVGElement) => { - // Collect all text elements into a list. - const textElements: SVGTextElement[] = []; - const collectText = (domElement: SVGElement) => { - if (domElement.localName === 'text') { - textElements.push(domElement as SVGTextElement); - } - for (let i = 0; i < domElement.childNodes.length; i++) { - collectText(domElement.childNodes[i] as SVGElement); - } - }; - collectText(svgTag); - convertFonts(svgTag); - // For each text element, apply quirks. - for (const textElement of textElements) { - // Remove x and y attributes - they are not used in Scratch. - textElement.removeAttribute('x'); - textElement.removeAttribute('y'); - // Set text-before-edge alignment: - // Scratch renders all text like this. - textElement.setAttribute('alignment-baseline', 'text-before-edge'); - textElement.setAttribute('xml:space', 'preserve'); - // If there's no font size provided, provide one. - if (!textElement.getAttribute('font-size')) { - textElement.setAttribute('font-size', '18'); - } - let text = textElement.textContent; - - // Fix line breaks in text, which are not natively supported by SVG. - // Only fix if text does not have child tspans. - // @todo this will not work for font sizes with units such as em, percent - // However, text made in scratch 2 should only ever export size 22 font. - const fontSize = parseFloat(textElement.getAttribute('font-size') ?? ''); - const tx = 2; - let ty = 0; - let spacing = 1.2; - // Try to match the position and spacing of Scratch 2.0's fonts. - // Different fonts seem to use different line spacing. - // Scratch 2 always uses alignment-baseline=text-before-edge - // However, most SVG readers don't support this attribute - // or don't support it alongside use of tspan, so the translations - // here are to make up for that. - if (textElement.getAttribute('font-family') === 'Handwriting') { - spacing = 2; - ty = -11 * fontSize / 22; - } else if (textElement.getAttribute('font-family') === 'Scratch') { - spacing = 0.89; - ty = -3 * fontSize / 22; - } else if (textElement.getAttribute('font-family') === 'Curly') { - spacing = 1.38; - ty = -6 * fontSize / 22; - } else if (textElement.getAttribute('font-family') === 'Marker') { - spacing = 1.45; - ty = -6 * fontSize / 22; - } else if (textElement.getAttribute('font-family') === 'Sans Serif') { - spacing = 1.13; - ty = -3 * fontSize / 22; - } else if (textElement.getAttribute('font-family') === 'Serif') { - spacing = 1.25; - ty = -4 * fontSize / 22; - } - - if (textElement.transform.baseVal.numberOfItems === 0) { - const transform = svgTag.createSVGTransform(); - textElement.transform.baseVal.appendItem(transform); - } - - // Right multiply matrix by a translation of (tx, ty) - const mtx = textElement.transform.baseVal.getItem(0).matrix; - mtx.e += (mtx.a * tx) + (mtx.c * ty); - mtx.f += (mtx.b * tx) + (mtx.d * ty); - - if (text && textElement.childElementCount === 0) { - textElement.textContent = ''; - const lines = text.split('\n'); - text = ''; - for (const line of lines) { - const tspanNode = SvgElement.create('tspan'); - tspanNode.setAttribute('x', '0'); - tspanNode.setAttribute('style', 'white-space: pre'); - tspanNode.setAttribute('dy', `${spacing}em`); - tspanNode.textContent = line ? line : ' '; - textElement.appendChild(tspanNode); - } - } - } -}; - -/** - * Find the largest stroke width in the svg. If a shape has no - * `stroke` property, it has a stroke-width of 0. If it has a `stroke`, - * it is by default a stroke-width of 1. - * This is used to enlarge the computed bounding box, which doesn't take - * stroke width into account. - * @param {SVGSVGElement} rootNode The root SVG node to traverse. - * @returns {number} The largest stroke width in the SVG. - */ -const findLargestStrokeWidth = (rootNode: SVGSVGElement) => { - let largestStrokeWidth = 0; - const collectStrokeWidths = (domElement: SVGElement) => { - if (domElement.getAttribute) { - if (domElement.getAttribute('stroke')) { - largestStrokeWidth = Math.max(largestStrokeWidth, 1); - } - if (domElement.getAttribute('stroke-width')) { - largestStrokeWidth = Math.max( - largestStrokeWidth, - Number(domElement.getAttribute('stroke-width')) || 0 - ); - } - } - for (let i = 0; i < domElement.childNodes.length; i++) { - collectStrokeWidths(domElement.childNodes[i] as SVGElement); - } - }; - collectStrokeWidths(rootNode); - return largestStrokeWidth; -}; - -/** - * Transform the measurements of the SVG. - * In Scratch 2.0, SVGs are drawn without respect to the width, - * height, and viewBox attribute on the tag. The exporter - * does output these properties - but they appear to be incorrect often. - * To address the incorrect measurements, we append the DOM to the - * document, and then use SVG's native `getBBox` to find the real - * drawn dimensions. This ensures things drawn in negative dimensions, - * outside the given viewBox, etc., are all eventually drawn to the canvas. - * I tried to do this several other ways: stripping the width/height/viewBox - * attributes and then drawing (Firefox won't draw anything), - * or inflating them and then measuring a canvas. But this seems to be - * a natural and performant way. - * @param {SVGSVGElement} svgTag the SVG tag to apply the transformation to - */ -const transformMeasurements = (svgTag: SVGSVGElement) => { - // Append the SVG dom to the document. - // This allows us to use `getBBox` on the page, - // which returns the full bounding-box of all drawn SVG - // elements, similar to how Scratch 2.0 did measurement. - const svgSpot = document.createElement('span'); - // Since we're adding user-provided SVG to document.body, - // sanitizing is required. This should not affect bounding box calculation. - // outerHTML is attribute of Element (and not HTMLElement), so use it instead of - // calling serializer or toString() - // NOTE: svgTag remains untouched! - const rawValue = svgTag.outerHTML; - const sanitizedValue = DOMPurify.sanitize(rawValue, { - // Use SVG profile (no HTML elements) - USE_PROFILES: {svg: true}, - // Remove some tags that Scratch does not use. - FORBID_TAGS: ['a', 'audio', 'canvas', 'video'], - // Allow data URI in image tags (e.g. SVGs converted from bitmap) - ADD_DATA_URI_TAGS: ['image'] - }); - let bbox; - try { - // Insert sanitized value. - svgSpot.innerHTML = sanitizedValue; - document.body.appendChild(svgSpot); - // Take the bounding box. We have to get elements via svgSpot - // because we added it via innerHTML. - bbox = (svgSpot.children[0] as SVGSVGElement).getBBox(); - } finally { - // Always destroy the element, even if, for example, getBBox throws. - document.body.removeChild(svgSpot); - } - - // Enlarge the bbox from the largest found stroke width - // This may have false-positives, but at least the bbox will always - // contain the full graphic including strokes. - // If the width or height is zero however, don't enlarge since - // they won't have a stroke width that needs to be enlarged. - let halfStrokeWidth; - if (bbox.width === 0 || bbox.height === 0) { - halfStrokeWidth = 0; - } else { - halfStrokeWidth = findLargestStrokeWidth(svgTag) / 2; - } - const width = bbox.width + (halfStrokeWidth * 2); - const height = bbox.height + (halfStrokeWidth * 2); - const x = bbox.x - halfStrokeWidth; - const y = bbox.y - halfStrokeWidth; - - // Set the correct measurements on the SVG tag - svgTag.setAttribute('width', String(width)); - svgTag.setAttribute('height', String(height)); - svgTag.setAttribute('viewBox', - `${x} ${y} ${width} ${height}`); -}; - -/** - * Find all instances of a URL-referenced `stroke` in the svg. In 2.0, all gradient strokes - * have a round `stroke-linejoin` and `stroke-linecap`... for some reason. - * @param {SVGSVGElement} svgTag the SVG tag to apply the transformation to - */ -const setGradientStrokeRoundedness = (svgTag: SVGSVGElement) => { - const elements = collectElements(svgTag) as SVGElement[]; - - for (const elt of elements) { - if (!elt.style) continue; - const stroke = elt.style.stroke || elt.getAttribute('stroke'); - if (stroke && stroke.match(/^url\(#.*\)$/)) { - // @ts-expect-error ignore - elt.style['stroke-linejoin'] = 'round'; - // @ts-expect-error ignore - elt.style['stroke-linecap'] = 'round'; - } - } -}; - -/** - * In-place, convert passed SVG to something consistent that will be rendered the way we want them to be. - * @param {SVGSvgElement} svgTag root SVG node to operate upon - * @param {boolean} [fromVersion2] True if we should perform conversion from version 2 to version 3 svg. - */ -const normalizeSvg = (svgTag: SVGSVGElement, fromVersion2?: boolean) => { - if (fromVersion2) { - // Fix gradients. Scratch 2 exports no x2 when x2 = 0, but - // SVG default is that x2 is 1. This must be done before - // transformStrokeWidths since transformStrokeWidths affects - // gradients. - transformGradients(svgTag); - } - transformStrokeWidths(svgTag, window); - transformImages(svgTag); - if (fromVersion2) { - // Transform all text elements. - transformText(svgTag); - // Transform measurements. - transformMeasurements(svgTag); - // Fix stroke roundedness. - setGradientStrokeRoundedness(svgTag); - } else if (!svgTag.getAttribute('viewBox')) { - // Renderer expects a view box. - transformMeasurements(svgTag); - } else if (!svgTag.getAttribute('width') || !svgTag.getAttribute('height')) { - svgTag.setAttribute('width', String(svgTag.viewBox.baseVal.width)); - svgTag.setAttribute('height', String(svgTag.viewBox.baseVal.height)); - } -}; - -/** - * Load an SVG string and normalize it. All the steps before drawing/measuring. - * Currently, this will normalize stroke widths (see transform-applier.js) and render all embedded images pixelated. - * The returned SVG will be guaranteed to always have a `width`, `height` and `viewBox`. - * In addition, if the `fromVersion2` parameter is `true`, several "quirks-mode" transformations will be applied which - * mimic Scratch 2.0's SVG rendering. - * @param {!string} svgString String of SVG data to draw in quirks-mode. - * @param {boolean} [fromVersion2] True if we should perform conversion from version 2 to version 3 svg. - * @returns {SVGSVGElement} The normalized SVG element. - */ -const loadSvgString = (svgString: string, fromVersion2?: boolean) => { - // Parse string into SVG XML. - const parser = new DOMParser(); - svgString = fixupSvgString(svgString); - const svgDom = parser.parseFromString(svgString, 'text/xml'); - if (svgDom.childNodes.length < 1 || - svgDom.documentElement.localName !== 'svg') { - throw new Error('Document does not appear to be SVG.'); - } - const svgTag = svgDom.documentElement as unknown as SVGSVGElement; - normalizeSvg(svgTag, fromVersion2); - return svgTag; -}; - -export default loadSvgString; diff --git a/packages/svg-renderer/src/playground/index.html b/packages/svg-renderer/src/playground/index.html deleted file mode 100644 index 6f8fe3451..000000000 --- a/packages/svg-renderer/src/playground/index.html +++ /dev/null @@ -1,132 +0,0 @@ - - - - - Scratch SVG rendering playground - - - -

- -

-

- - - -

-

- - -

- -
-
-
Rendered Result
- -
-
-
Reference
- -
-
-
-
-
Rendered Content
- -
-
-
Reference
- - -
-
- - - - - diff --git a/packages/svg-renderer/src/sanitize-svg.ts b/packages/svg-renderer/src/sanitize-svg.ts deleted file mode 100644 index d013c9f28..000000000 --- a/packages/svg-renderer/src/sanitize-svg.ts +++ /dev/null @@ -1,105 +0,0 @@ -// @ts-nocheck - -/** - * @fileoverview Sanitize the content of an SVG aggressively, to make it as safe - * as possible - */ -import fixupSvgString from './fixup-svg-string'; -import {generate, parse, walk} from 'css-tree'; -import DOMPurify from 'isomorphic-dompurify'; - -DOMPurify.addHook( - 'beforeSanitizeAttributes', - currentNode => { - - if (currentNode && currentNode.href && currentNode.href.baseVal) { - const href = currentNode.href.baseVal.replace(/\s/g, ''); - // "data:" and "#" are valid hrefs - if ((href.slice(0, 5) !== 'data:') && (href.slice(0, 1) !== '#')) { - - if (currentNode.attributes.getNamedItem('xlink:href')) { - currentNode.attributes.removeNamedItem('xlink:href'); - delete currentNode['xlink:href']; - } - if (currentNode.attributes.getNamedItem('href')) { - currentNode.attributes.removeNamedItem('href'); - delete currentNode.href; - } - } - } - return currentNode; - } -); - -DOMPurify.addHook( - 'uponSanitizeElement', - (node, data) => { - if (data.tagName === 'style') { - const ast = parse(node.textContent); - let isModified = false; - // Remove any @import rules as it could leak HTTP requests - walk(ast, (astNode, item, list) => { - if (astNode.type === 'Atrule' && astNode.name === 'import') { - list.remove(item); - isModified = true; - } - }); - if (isModified) { - node.textContent = generate(ast); - } - } - } -); - -// Use JS implemented TextDecoder and TextEncoder if it is not provided by the -// browser. -let _TextDecoder; -let _TextEncoder; -if (typeof TextDecoder === 'undefined' || typeof TextEncoder === 'undefined') { - // Wait to require the text encoding polyfill until we know it's needed. - // eslint-disable-next-line global-require, @typescript-eslint/no-require-imports - const encoding = require('fastestsmallesttextencoderdecoder'); - _TextDecoder = encoding.TextDecoder; - _TextEncoder = encoding.TextEncoder; -} else { - _TextDecoder = TextDecoder; - _TextEncoder = TextEncoder; -} - -const sanitizeSvg = { - /** - * Load an SVG Uint8Array of bytes and "sanitize" it - * @param rawData unsanitized SVG daata - * @returns sanitized SVG data - */ - sanitizeByteStream (rawData: Uint8Array): Uint8Array { - const decoder = new _TextDecoder(); - const encoder = new _TextEncoder(); - const sanitizedText = sanitizeSvg.sanitizeSvgText(decoder.decode(rawData)); - return encoder.encode(sanitizedText); - }, - /** - * Load an SVG string and "sanitize" it. This is more aggressive than the handling in - * fixup-svg-string.js, and thus more risky; there are known examples of SVGs that - * it will clobber. We use DOMPurify's svg profile, which restricts many types of tag. - * @param rawSvgText unsanitized SVG string - * @returns sanitized SVG text - */ - sanitizeSvgText (rawSvgText: string): string { - let sanitizedText = DOMPurify.sanitize(rawSvgText, { - USE_PROFILES: {svg: true} - }); - - // Remove partial XML comment that is sometimes left in the HTML - const badTag = sanitizedText.indexOf(']>'); - if (badTag >= 0) { - sanitizedText = sanitizedText.substring(5, sanitizedText.length); - } - - // also use our custom fixup rules - sanitizedText = fixupSvgString(sanitizedText); - return sanitizedText; - } -}; - -export default sanitizeSvg; diff --git a/packages/svg-renderer/src/serialize-svg-to-string.ts b/packages/svg-renderer/src/serialize-svg-to-string.ts deleted file mode 100644 index 1ca1ef495..000000000 --- a/packages/svg-renderer/src/serialize-svg-to-string.ts +++ /dev/null @@ -1,19 +0,0 @@ -import inlineSvgFonts from './font-inliner'; - -/** - * Serialize a given SVG DOM to a string. - * @param svgTag The SVG element to serialize. - * @param shouldInjectFonts True if fonts should be included in the SVG as - * base64 data. - * @returns String representing current SVG data. - */ -const serializeSvgToString = (svgTag: SVGElement, shouldInjectFonts?: boolean): string => { - const serializer = new XMLSerializer(); - let string = serializer.serializeToString(svgTag); - if (shouldInjectFonts) { - string = inlineSvgFonts(string); - } - return string; -}; - -export default serializeSvgToString; diff --git a/packages/svg-renderer/src/svg-element.ts b/packages/svg-renderer/src/svg-element.ts deleted file mode 100644 index 29f8250d1..000000000 --- a/packages/svg-renderer/src/svg-element.ts +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Adapted from - * Paper.js - The Swiss Army Knife of Vector Graphics Scripting. - * http://paperjs.org/ - * - * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey - * http://scratchdisk.com/ & http://jonathanpuckey.com/ - * - * Distributed under the MIT license. See LICENSE file for details. - * - * All rights reserved. - */ - -/** - * @name SvgElement - * @namespace - * @private - */ -class SvgElement { - // SVG related namespaces - static get svg (): string { - return 'http://www.w3.org/2000/svg'; - } - - static get xmlns (): string { - return 'http://www.w3.org/2000/xmlns'; - } - - static get xlink (): string { - return 'http://www.w3.org/1999/xlink'; - } - - // Mapping of attribute names to required namespaces: - static attributeNamespace (): Record { - return { - 'href': SvgElement.xlink, - 'xlink': SvgElement.xmlns, - // Only the xmlns attribute needs the trailing slash. See #984 - 'xmlns': `${SvgElement.xmlns}/`, - // IE needs the xmlns namespace when setting 'xmlns:xlink'. See #984 - 'xmlns:xlink': `${SvgElement.xmlns}/` - }; - } - - static create ( - tag: string, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - attributes?: Record, - formatter?: { number: (num: number) => string } - ): SVGElement { - return SvgElement.set(document.createElementNS(SvgElement.svg, tag) as SVGElement, attributes, formatter); - } - - static get (node: SVGElement, name: string): string | null { - const namespace = SvgElement.attributeNamespace()[name]; - const value = namespace ? - node.getAttributeNS(namespace, name) : - node.getAttribute(name); - return value === 'null' ? null : value; - } - - static set ( - node: SVGElement, - attributes?: Record, - formatter?: { number: (num: number) => string } - ): SVGElement { - for (const name in attributes) { - let value = attributes[name]; - const namespace = SvgElement.attributeNamespace()[name]; - if (typeof value === 'number' && formatter) { - value = formatter.number(value); - } - if (namespace) { - node.setAttributeNS(namespace, name, value as string); - } else { - node.setAttribute(name, value as string); - } - } - return node; - } -} - -export default SvgElement; diff --git a/packages/svg-renderer/src/svg-renderer.ts b/packages/svg-renderer/src/svg-renderer.ts deleted file mode 100644 index a82d5e687..000000000 --- a/packages/svg-renderer/src/svg-renderer.ts +++ /dev/null @@ -1,183 +0,0 @@ -import loadSvgString from './load-svg-string'; -import serializeSvgToString from './serialize-svg-to-string'; - -/** - * A measured SVG "viewbox" - */ -interface SvgMeasurements { - /** - * The left edge of the SVG viewbox. - */ - x: number; - /** - * The top edge of the SVG viewbox. - */ - y: number; - /** - * The width of the SVG viewbox. - */ - width: number; - /** - * The height of the SVG viewbox. - */ - height: number; -} - -/** - * Main quirks-mode SVG rendering code. - * @deprecated Call into individual methods exported from this library instead. - */ -class SvgRenderer { - private _canvas: HTMLCanvasElement; - private _context: CanvasRenderingContext2D; - private _measurements: SvgMeasurements; - private _cachedImage: HTMLImageElement | null; - private _svgTag?: SVGElement; - loaded: boolean; - /** - * Create a quirks-mode SVG renderer for a particular canvas. - * @param {HTMLCanvasElement} [canvas] An optional canvas element to draw to. If this is not provided, the renderer - * will create a new canvas. - * @class - */ - constructor (canvas: HTMLCanvasElement) { - /** - * The canvas that this SVG renderer will render to. - * @type {HTMLCanvasElement} - * @private - */ - this._canvas = canvas || document.createElement('canvas'); - this._context = this._canvas.getContext('2d')!; - - /** - * The measurement box of the currently loaded SVG. - */ - this._measurements = {x: 0, y: 0, width: 0, height: 0}; - - /** - * The `` element with the contents of the currently loaded SVG. - */ - this._cachedImage = null; - - /** - * True if this renderer's current SVG is loaded and can be rendered to the canvas. - */ - this.loaded = false; - } - - get canvas () { - return this._canvas; - } - - /** - * @returns the natural size, in Scratch units, of this SVG. - */ - get size (): [number, number] { - return [this._measurements.width, this._measurements.height]; - } - - /** - * @returns {Array} the offset (upper left corner) of the SVG's view box. - */ - get viewOffset () { - return [this._measurements.x, this._measurements.y]; - } - - /** - * Load an SVG string and normalize it. All the steps before drawing/measuring. - * @param {!string} svgString String of SVG data to draw in quirks-mode. - * @param {?boolean} fromVersion2 True if we should perform conversion from - * version 2 to version 3 svg. - */ - loadString (svgString: string, fromVersion2?: boolean) { - // New svg string invalidates the cached image - this._cachedImage = null; - const svgTag = loadSvgString(svgString, fromVersion2); - - this._svgTag = svgTag; - this._measurements = { - width: svgTag.viewBox.baseVal.width, - height: svgTag.viewBox.baseVal.height, - x: svgTag.viewBox.baseVal.x, - y: svgTag.viewBox.baseVal.y - }; - } - - /** - * Load an SVG string, normalize it, and prepare it for (synchronous) rendering. - * @param svgString String of SVG data to draw in quirks-mode. - * @param fromVersion2 True if we should perform conversion from version 2 to version 3 svg. - * @param onFinish - An optional callback to call when the SVG is loaded and can be rendered. - */ - loadSVG (svgString: string, fromVersion2: boolean | undefined, onFinish: () => void) { - this.loadString(svgString, fromVersion2); - this._createSVGImage(onFinish); - } - - /** - * Creates an element for the currently loaded SVG string, then calls the callback once it's loaded. - * @param {Function} [onFinish] - An optional callback to call when the has loaded. - */ - _createSVGImage (onFinish: () => void) { - if (this._cachedImage === null) this._cachedImage = new Image(); - const img = this._cachedImage; - - img.onload = () => { - this.loaded = true; - if (onFinish) onFinish(); - }; - const svgText = this.toString(true /* shouldInjectFonts */); - img.src = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`; - this.loaded = false; - } - - /** - * Serialize the active SVG DOM to a string. - * @param {?boolean} shouldInjectFonts True if fonts should be included in the SVG as - * base64 data. - * @returns {string} String representing current SVG data. - * @deprecated Use the standalone `serializeSvgToString` export instead. - */ - toString (shouldInjectFonts?: boolean) { - if (!this._svgTag) { - throw new Error('SVG not loaded'); - } - return serializeSvgToString(this._svgTag, shouldInjectFonts); - } - - /** - * Synchronously draw the loaded SVG to this renderer's `canvas`. - * @param {number} [scale] - Optionally, also scale the image by this factor. - */ - draw (scale: number) { - if (!this.loaded) throw new Error('SVG image has not finished loading'); - this._drawFromImage(scale); - } - - /** - * Draw to the canvas from a loaded image element. - * @param {number} [scale] - Optionally, also scale the image by this factor. - */ - _drawFromImage (scale: number) { - if (this._cachedImage === null) return; - - const ratio = Number.isFinite(scale) ? scale : 1; - const bbox = this._measurements; - this._canvas.width = bbox.width * ratio; - this._canvas.height = bbox.height * ratio; - // Even if the canvas at the current scale has a nonzero size, the image's dimensions are floored pre-scaling. - // e.g. if an image has a width of 0.4 and is being rendered at 3x scale, the canvas will have a width of 1, but - // the image's width will be rounded down to 0 on some browsers (Firefox) prior to being drawn at that scale. - if ( - this._canvas.width <= 0 || - this._canvas.height <= 0 || - this._cachedImage.naturalWidth <= 0 || - this._cachedImage.naturalHeight <= 0 - ) return; - this._context.clearRect(0, 0, this._canvas.width, this._canvas.height); - this._context.setTransform(ratio, 0, 0, ratio, 0, 0); - this._context.drawImage(this._cachedImage, 0, 0); - } -} - -export default SvgRenderer; diff --git a/packages/svg-renderer/src/transform-applier.ts b/packages/svg-renderer/src/transform-applier.ts deleted file mode 100644 index e04e892fb..000000000 --- a/packages/svg-renderer/src/transform-applier.ts +++ /dev/null @@ -1,669 +0,0 @@ -import * as Matrix from 'transformation-matrix'; -import SvgElement from './svg-element'; -import log from './util/log'; - -interface BBox { - x: number; - y: number; - width: number; - height: number; -} - -/** - * @fileoverview Apply transforms to match stroke width appearance in 2.0 and 3.0 - */ - -// Adapted from paper.js's Path.applyTransform -const _parseTransform = function (domElement: Element): Matrix.Matrix { - let matrix: Matrix.Matrix = Matrix.identity(); - const string = domElement.attributes?.getNamedItem('transform')?.value; - if (!string) return matrix; - - const transforms = string.split(/\)\s*/g); - for (const transform of transforms) { - if (!transform) break; - - const parts = transform.split(/\(\s*/); - const command = parts[0].trim(); - const v = parts[1].split(/[\s,]+/g).map(parseFloat); - - switch (command) { - case 'matrix': - matrix = Matrix.compose(matrix, {a: v[0], b: v[1], c: v[2], d: v[3], e: v[4], f: v[5]}); - break; - case 'rotate': - matrix = Matrix.compose(matrix, Matrix.rotateDEG(v[0], v[1] || 0, v[2] || 0)); - break; - case 'translate': - matrix = Matrix.compose(matrix, Matrix.translate(v[0], v[1] || 0)); - break; - case 'scale': - matrix = Matrix.compose(matrix, Matrix.scale(v[0], v[1] || v[0])); - break; - case 'skewX': - matrix = Matrix.compose(matrix, Matrix.skewDEG(v[0], 0)); - break; - case 'skewY': - matrix = Matrix.compose(matrix, Matrix.skewDEG(0, v[0])); - break; - default: - log.error(`Couldn't parse: ${command}`); - } - } - return matrix; -}; - -// Adapted from paper.js's Matrix.decompose -// Given a matrix, return the x and y scale factors of the matrix -const _getScaleFactor = function (matrix: Matrix.Matrix) { - const a = matrix.a; - const b = matrix.b; - const c = matrix.c; - const d = matrix.d; - const det = (a * d) - (b * c); - - if (a !== 0 || b !== 0) { - const r = Math.sqrt((a * a) + (b * b)); - return {x: r, y: det / r}; - } - if (c !== 0 || d !== 0) { - const s = Math.sqrt((c * c) + (d * d)); - return {x: det / s, y: s}; - } - // a = b = c = d = 0 - return {x: 0, y: 0}; -}; - -// Returns null if matrix is not invertible. Otherwise returns given ellipse -// transformed by transform, an object {radiusX, radiusY, rotation}. -const _calculateTransformedEllipse = function ( - radiusX: number, radiusY: number, theta: number, transform: Matrix.Matrix -) { - theta = -theta * Math.PI / 180; - const a = transform.a; - const b = -transform.c; - const c = -transform.b; - const d = transform.d; - // Since other parameters determine the translation of the ellipse in SVG, we do not need to worry - // about what e and f are. - const det = (a * d) - (b * c); - // Non-invertible matrix - if (det === 0) return null; - - // rotA, rotB, and rotC represent Ax^2 + Bxy + Cy^2 = 1 coefficients for a rotated ellipse formula - const sinT = Math.sin(theta); - const cosT = Math.cos(theta); - const sin2T = Math.sin(2 * theta); - const rotA = (cosT * cosT / radiusX / radiusX) + (sinT * sinT / radiusY / radiusY); - const rotB = (sin2T / radiusX / radiusX) - (sin2T / radiusY / radiusY); - const rotC = (sinT * sinT / radiusX / radiusX) + (cosT * cosT / radiusY / radiusY); - - // Calculate the ellipse formula of the transformed ellipse - // A, B, and C represent Ax^2 + Bxy + Cy^2 = 1 / det / det coefficients in a transformed ellipse formula - // scaled by inverse det squared (to preserve accuracy) - const A = ((rotA * d * d) - (rotB * d * c) + (rotC * c * c)); - const B = ((-2 * rotA * b * d) + (rotB * a * d) + (rotB * b * c) - (2 * rotC * a * c)); - const C = ((rotA * b * b) - (rotB * a * b) + (rotC * a * a)); - - // Derive new radii and theta from the transformed ellipse formula - const newRadiusXOverDet = Math.sqrt(2) * - Math.sqrt( - (A + C - Math.sqrt((A * A) + (B * B) - (2 * A * C) + (C * C))) / - ((-B * B) + (4 * A * C)) - ); - const newRadiusYOverDet = 1 / Math.sqrt(A + C - (1 / newRadiusXOverDet / newRadiusXOverDet)); - let temp = (A - (1 / newRadiusXOverDet / newRadiusXOverDet)) / - ((1 / newRadiusYOverDet / newRadiusYOverDet) - (1 / newRadiusXOverDet / newRadiusXOverDet)); - if (temp < 0 && Math.abs(temp) < 1e-8) temp = 0; // Fix floating point issue - temp = Math.sqrt(temp); - if (Math.abs(1 - temp) < 1e-8) temp = 1; // Fix floating point issue - // Solve for which of the two possible thetas is correct - let newTheta = Math.asin(temp); - temp = (B / ( - (1 / newRadiusXOverDet / newRadiusXOverDet) - - (1 / newRadiusYOverDet / newRadiusYOverDet))); - const newTheta2 = -newTheta; - if (Math.abs(Math.sin(2 * newTheta2) - temp) < - Math.abs(Math.sin(2 * newTheta) - temp)) { - newTheta = newTheta2; - } - - return { - radiusX: newRadiusXOverDet * det, - radiusY: newRadiusYOverDet * det, - rotation: -newTheta * 180 / Math.PI - }; -}; - -// Adapted from paper.js's PathItem.setPathData -const _transformPath = function (pathString: string, transform: Matrix.Matrix) { - if (!transform || Matrix.toString(transform) === Matrix.toString(Matrix.identity())) return pathString; - // First split the path data into parts of command-coordinates pairs - // Commands are any of these characters: mzlhvcsqta - // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain - const parts = pathString?.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig)!; - let coords: RegExpMatchArray; - let relative = false; - let previous: string | undefined = undefined; - let control: PointObjectNotation; - let current: PointObjectNotation = {x: 0, y: 0}; - let start: PointObjectNotation = {x: 0, y: 0}; - let result = ''; - - const getCoord = function (index: number, coord: keyof PointObjectNotation) { - let val = +coords[index]; - if (relative) { - val += current[coord]; - } - return val; - }; - - const getPoint = function (index: number) { - return {x: getCoord(index, 'x'), y: getCoord(index + 1, 'y')}; - }; - - const roundTo4Places = function (num: number) { - return Number(num.toFixed(4)); - }; - - // Returns the transformed point as a string - const getString = function (point: PointObjectNotation) { - const transformed = Matrix.applyToPoint(transform, point); - return `${roundTo4Places(transformed.x)} ${roundTo4Places(transformed.y)} `; - }; - - for (let i = 0, l = parts && parts.length; i < l; i++) { - const part = parts[i]; - const command = part[0]; - const lower = command.toLowerCase(); - // Match all coordinate values - coords = part.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g)!; - const length = coords && coords.length; - relative = command === lower; - // Fix issues with z in the middle of SVG path data, not followed by - // a m command, see paper.js#413: - if (previous === 'z' && !/[mz]/.test(lower)) { - result += `M ${current.x} ${current.y} `; - } - switch (lower) { - case 'm': // Move to - case 'l': // Line to - { - let move = lower === 'm'; - for (let j = 0; j < length; j += 2) { - result += move ? 'M ' : 'L '; - current = getPoint(j); - result += getString(current); - if (move) { - start = current; - move = false; - } - } - control = current; - break; - } - case 'h': // Horizontal line - case 'v': // Vertical line - { - const coord = lower === 'h' ? 'x' : 'y'; - current = {x: current.x, y: current.y}; // Clone as we're going to modify it. - for (let j = 0; j < length; j++) { - current[coord] = getCoord(j, coord); - result += `L ${getString(current)}`; - } - control = current; - break; - } - case 'c': - // Cubic Bezier curve - for (let j = 0; j < length; j += 6) { - const handle1 = getPoint(j); - control = getPoint(j + 2); - current = getPoint(j + 4); - result += `C ${getString(handle1)}${getString(control)}${getString(current)}`; - } - break; - case 's': - // Smooth cubic Bezier curve - for (let j = 0; j < length; j += 4) { - const handle1 = /[cs]/.test(previous!) ? - {x: (current.x * 2) - control!.x, y: (current.y * 2) - control!.y} : - current; - control = getPoint(j); - current = getPoint(j + 2); - - result += `C ${getString(handle1)}${getString(control)}${getString(current)}`; - previous = lower; - } - break; - case 'q': - // Quadratic Bezier curve - for (let j = 0; j < length; j += 4) { - control = getPoint(j); - current = getPoint(j + 2); - result += `Q ${getString(control)}${getString(current)}`; - } - break; - case 't': - // Smooth quadratic Bezier curve - for (let j = 0; j < length; j += 2) { - control = /[qt]/.test(previous!) ? - {x: (current.x * 2) - control!.x, y: (current.y * 2) - control!.y} : - current; - current = getPoint(j); - - result += `Q ${getString(control)}${getString(current)}`; - previous = lower; - } - break; - case 'a': - // Elliptical arc curve - for (let j = 0; j < length; j += 7) { - current = getPoint(j + 5); - const rx = +coords[j]; - const ry = +coords[j + 1]; - const rotation = +coords[j + 2]; - const largeArcFlag = +coords[j + 3]; - let clockwiseFlag = +coords[j + 4]; - const newEllipse = _calculateTransformedEllipse(rx, ry, rotation, transform); - const matrixScale = _getScaleFactor(transform); - if (newEllipse) { - if ((matrixScale.x > 0 && matrixScale.y < 0) || - (matrixScale.x < 0 && matrixScale.y > 0)) { - clockwiseFlag = clockwiseFlag ^ 1; - } - result += `A ${roundTo4Places(Math.abs(newEllipse.radiusX))} ` + - `${roundTo4Places(Math.abs(newEllipse.radiusY))} ` + - `${roundTo4Places(newEllipse.rotation)} ${largeArcFlag} ` + - `${clockwiseFlag} ${getString(current)}`; - } else { - result += `L ${getString(current)}`; - } - } - break; - case 'z': - // Close path - result += `Z `; - // Correctly handle relative m commands, see paper.js#1101: - current = start; - break; - } - previous = lower; - } - return result; -}; - -const GRAPHICS_ELEMENTS = ['circle', 'ellipse', 'image', 'line', 'path', 'polygon', 'polyline', 'rect', 'text', 'use']; -const CONTAINER_ELEMENTS = ['a', 'defs', 'g', 'marker', 'glyph', 'missing-glyph', 'pattern', 'svg', 'switch', 'symbol']; -const _isContainerElement = function (element: Element) { - return element.tagName && CONTAINER_ELEMENTS.includes(element.tagName.toLowerCase()); -}; -const _isGraphicsElement = function (element: Element) { - return element.tagName && GRAPHICS_ELEMENTS.includes(element.tagName.toLowerCase()); -}; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const _isPathWithTransformAndStroke = function (element: any, strokeWidth: number) { - if (!element.attributes) return false; - strokeWidth = element.attributes['stroke-width'] ? - Number(element.attributes['stroke-width'].value) : Number(strokeWidth); - return strokeWidth && - element.tagName && element.tagName.toLowerCase() === 'path' && - element.attributes.d && element.attributes.d.value; -}; -const _quadraticMean = function (a: number, b: number) { - return Math.sqrt(((a * a) + (b * b)) / 2); -}; - -const _createGradient = function (gradientId: string, svgTag: SVGElement, bbox: BBox, matrix: Matrix.Matrix) { - // Adapted from Paper.js's SvgImport.getValue - const getValue = function ( - node: SVGElement, - name: string, - isString?: boolean, - allowNull?: boolean, - allowPercent?: boolean, - defaultValue?: string - ) { - // Interpret value as number. Never return NaN, but 0 instead. - // If the value is a sequence of numbers, parseFloat will - // return the first occurring number, which is enough for now. - let value = SvgElement.get(node, name); - let res; - if (value === null) { - if (defaultValue) { - res = defaultValue; - if (/%\s*$/.test(res)) { - value = defaultValue; - res = parseFloat(value!); - } - } else if (allowNull) { - res = null; - } else if (isString) { - res = ''; - } else { - res = 0; - } - } else if (isString) { - res = value; - } else { - res = parseFloat(value); - } - // Support for dimensions in percentage of the root size. If root-size - // is not set (e.g. during ), just scale the percentage value to - // 0..1, as required by gradients with gradientUnits="objectBoundingBox" - if (/%\s*$/.test(value!)) { - const size = allowPercent ? 1 : bbox[/x|^width/.test(name) ? 'width' : 'height']; - return Number(res) / 100 * size; - } - return res; - }; - const getPoint = function ( - node: SVGElement, - x: string, - y: string, - allowNull?: boolean, - allowPercent?: boolean, - defaultX?: string, - defaultY?: string - ) { - const resultX = Number(getValue(node, x || 'x', false, allowNull, allowPercent, defaultX)); - const resultY = Number(getValue(node, y || 'y', false, allowNull, allowPercent, defaultY)); - return allowNull && (x === null || y === null) ? null : {x: resultX, y: resultY}; - }; - - let [defs] = svgTag.getElementsByTagName('defs'); - if (!defs) { - defs = SvgElement.create('defs') as SVGDefsElement; - svgTag.appendChild(defs); - } - - // Clone the old gradient. We'll make a new one, since the gradient might be reused elsewhere - // with different transform matrix - // @ts-expect-error ignore it - const oldGradient = svgTag.getElementById(gradientId); - if (!oldGradient) return; - - const radial = oldGradient.tagName.toLowerCase() === 'radialgradient'; - // @ts-expect-error ignore it - const newGradient = svgTag.getElementById(gradientId).cloneNode(true /* deep */); - - // Give the new gradient a new ID - let matrixString = Matrix.toString(matrix); - matrixString = matrixString.substring(8, matrixString.length - 1); - const newGradientId = `${gradientId}-${matrixString}`; - newGradient.setAttribute('id', newGradientId); - - // This gradient already exists and was transformed before. Just reuse the already-transformed one. - // @ts-expect-error ignore it - if (svgTag.getElementById(newGradientId)) { - // This is the same code as in the end of the function, but I don't feel like wrapping the next 80 lines - // in an `if (!svgTag.getElementById(newGradientId))` block - return `url(#${newGradientId})`; - } - - const scaleToBounds = getValue(newGradient, 'gradientUnits', true) !== - 'userSpaceOnUse'; - let origin; - let destination; - let radius; - let focal; - if (radial) { - origin = getPoint(newGradient, 'cx', 'cy', false, scaleToBounds, '50%', '50%'); - radius = Number(getValue(newGradient, 'r', false, false, scaleToBounds, '50%')); - focal = getPoint(newGradient, 'fx', 'fy', true, scaleToBounds); - } else { - origin = getPoint(newGradient, 'x1', 'y1', false, scaleToBounds); - destination = getPoint(newGradient, 'x2', 'y2', false, scaleToBounds, '1'); - if (origin!.x === destination!.x && origin!.y === destination!.y) { - // If it's degenerate, use the color of the last stop, as described by - // https://www.w3.org/TR/SVG/pservers.html#LinearGradientNotes - const stops = newGradient.getElementsByTagName('stop'); - if (!stops.length || !stops[stops.length - 1].attributes || - !stops[stops.length - 1].attributes['stop-color']) { - return null; - } - return stops[stops.length - 1].attributes['stop-color'].value; - } - } - - // Transform points - // Emulate SVG's gradientUnits="objectBoundingBox" - if (scaleToBounds) { - const boundsMatrix = Matrix.compose(Matrix.translate(bbox.x, bbox.y), Matrix.scale(bbox.width, bbox.height)); - origin = Matrix.applyToPoint(boundsMatrix, origin!); - if (destination) destination = Matrix.applyToPoint(boundsMatrix, destination); - if (radius) { - radius = _quadraticMean(bbox.width, bbox.height) * radius; - } - if (focal) focal = Matrix.applyToPoint(boundsMatrix, focal); - } - - if (radial) { - origin = Matrix.applyToPoint(matrix, origin!); - const matrixScale = _getScaleFactor(matrix); - radius = _quadraticMean(matrixScale.x, matrixScale.y) * radius!; - if (focal) focal = Matrix.applyToPoint(matrix, focal); - } else { - const dot = (a: PointObjectNotation, b: PointObjectNotation) => (a.x * b.x) + (a.y * b.y); - const multiply = - (coefficient: number, v: PointObjectNotation) => ({x: coefficient * v.x, y: coefficient * v.y}); - const add = (a: PointObjectNotation, b: PointObjectNotation) => ({x: a.x + b.x, y: a.y + b.y}); - const subtract = (a: PointObjectNotation, b: PointObjectNotation) => ({x: a.x - b.x, y: a.y - b.y}); - - // The line through origin and gradientPerpendicular is the line at which the gradient starts - let gradientPerpendicular = Math.abs(origin!.x - destination!.x) < 1e-8 ? - add(origin!, {x: 1, y: (origin!.x - destination!.x) / (destination!.y - origin!.y)}) : - add(origin!, {x: (destination!.y - origin!.y) / (origin!.x - destination!.x), y: 1}); - - // Transform points - gradientPerpendicular = Matrix.applyToPoint(matrix, gradientPerpendicular); - origin = Matrix.applyToPoint(matrix, origin!); - destination = Matrix.applyToPoint(matrix, destination!); - - // Calculate the direction that the gradient has changed to - const originToPerpendicular = subtract(gradientPerpendicular, origin); - const originToDestination = subtract(destination, origin); - const gradientDirection = Math.abs(originToPerpendicular.x) < 1e-8 ? - {x: 1, y: -originToPerpendicular.x / originToPerpendicular.y} : - {x: -originToPerpendicular.y / originToPerpendicular.x, y: 1}; - - // Set the destination so that the gradient moves in the correct direction, by projecting the destination vector - // onto the gradient direction vector - const projectionCoeff = dot(originToDestination, gradientDirection) / dot(gradientDirection, gradientDirection); - const projection = multiply(projectionCoeff, gradientDirection); - destination = {x: origin.x + projection.x, y: origin.y + projection.y}; - } - - // Put values back into svg - if (radial) { - newGradient.setAttribute('cx', Number(origin.x.toFixed(4))); - newGradient.setAttribute('cy', Number(origin.y.toFixed(4))); - newGradient.setAttribute('r', Number(radius!.toFixed(4))); - if (focal) { - newGradient.setAttribute('fx', Number(focal.x.toFixed(4))); - newGradient.setAttribute('fy', Number(focal.y.toFixed(4))); - } - } else { - newGradient.setAttribute('x1', Number(origin.x.toFixed(4))); - newGradient.setAttribute('y1', Number(origin.y.toFixed(4))); - newGradient.setAttribute('x2', Number(destination!.x.toFixed(4))); - newGradient.setAttribute('y2', Number(destination!.y.toFixed(4))); - } - newGradient.setAttribute('gradientUnits', 'userSpaceOnUse'); - defs.appendChild(newGradient); - - return `url(#${newGradientId})`; -}; - -// Adapted from paper.js's SvgImport.getDefinition -const _parseUrl = (value: string | undefined, windowRef: Window) => { - // When url() comes from a style property, '#'' seems to be missing on - // WebKit. We also get variations of quotes or no quotes, single or - // double, so handle it all with one regular expression: - const match = value && value.match(/\((?:["'#]*)([^"')]+)/); - const name = match && match[1]; - const res = name && windowRef ? - // This is required by Firefox, which can produce absolute - // urls for local gradients, see paperjs#1001: - name.replace(`${windowRef.location.href.split('#')[0]}#`, '') : - name; - return res; -}; - -/** - * Scratch 2.0 displays stroke widths in a "normalized" way, that is, - * if a shape with a stroke width has a transform applied, it will be - * rendered with a stroke that is the same width all the way around, - * instead of stretched looking. - * - * The vector paint editor also prefers to normalize the stroke width, - * rather than keep track of transforms at the group level, as this - * simplifies editing (e.g. stroke width 3 always means the same thickness) - * - * This function performs that normalization process, pushing transforms - * on groups down to the leaf level and averaging out the stroke width - * around the shapes. Note that this doens't just change stroke widths, it - * changes path data and attributes throughout the SVG. - * - * @param {SVGElement} svgTag The SVG dom object - * @param {Window} windowRef The window to use. Need to pass in for - * tests to work, as they get angry at even the mention of window. - * @param {object} bboxForTesting The bounds to use. Need to pass in for - * tests only, because getBBox doesn't work in Node. This should - * be the bounds of the svgTag without including stroke width or transforms. - * @returns {void} - */ -const transformStrokeWidths = function (svgTag: SVGElement, windowRef: Window, bboxForTesting?: BBox) { - const inherited = Matrix.identity(); - - const applyTransforms = ( - element: Element, matrix: Matrix.Matrix, strokeWidth: number, fill?: string, stroke?: string - ) => { - if (_isContainerElement(element)) { - // Push fills and stroke width down to leaves - // @ts-expect-error ignore it - if (element.attributes['stroke-width']) { - // @ts-expect-error ignore it - strokeWidth = element.attributes['stroke-width'].value; - } - if (element.attributes) { - // @ts-expect-error ignore it - if (element.attributes.fill) fill = element.attributes.fill.value; - // @ts-expect-error ignore it - if (element.attributes.stroke) stroke = element.attributes.stroke.value; - } - - // If any child nodes don't take attributes, leave the attributes - // at the parent level. - for (let i = 0; i < element.childNodes.length; i++) { - applyTransforms( - // @ts-expect-error ignore it - element.childNodes[i], - Matrix.compose(matrix, _parseTransform(element)), - strokeWidth, - fill, - stroke - ); - } - element.removeAttribute('transform'); - element.removeAttribute('stroke-width'); - element.removeAttribute('fill'); - element.removeAttribute('stroke'); - } else if (_isPathWithTransformAndStroke(element, strokeWidth)) { - // @ts-expect-error ignore it - if (element.attributes['stroke-width']) { - // @ts-expect-error ignore it - strokeWidth = element.attributes['stroke-width'].value; - } - // @ts-expect-error ignore it - if (element.attributes.fill) fill = element.attributes.fill.value; - // @ts-expect-error ignore it - if (element.attributes.stroke) stroke = element.attributes.stroke.value; - matrix = Matrix.compose(matrix, _parseTransform(element)); - if (Matrix.toString(matrix) === Matrix.toString(Matrix.identity())) { - element.removeAttribute('transform'); - element.setAttribute('stroke-width', String(strokeWidth)); - if (fill) element.setAttribute('fill', fill); - if (stroke) element.setAttribute('stroke', stroke); - return; - } - - // Transform gradient - const fillGradientId = _parseUrl(fill, windowRef); - const strokeGradientId = _parseUrl(stroke, windowRef); - - if (fillGradientId || strokeGradientId) { - const doc = windowRef.document; - // Need path bounds to transform gradient - const svgSpot = doc.createElement('span'); - let bbox; - if (bboxForTesting) { - bbox = bboxForTesting; - } else { - try { - doc.body.appendChild(svgSpot); - const svg = SvgElement.set(doc.createElementNS(SvgElement.svg, 'svg') as SVGElement); - const path = SvgElement.set(doc.createElementNS(SvgElement.svg, 'path') as SVGElement); - // @ts-expect-error ignore it - path.setAttribute('d', element.attributes.d.value); - svg.appendChild(path); - svgSpot.appendChild(svg); - // Take the bounding box. - // @ts-expect-error ignore it - bbox = svg.getBBox(); - } finally { - // Always destroy the element, even if, for example, getBBox throws. - doc.body.removeChild(svgSpot); - } - } - - if (fillGradientId) { - const newFillRef = _createGradient(fillGradientId, svgTag, bbox, matrix); - if (newFillRef) fill = newFillRef; - } - - if (strokeGradientId) { - const newStrokeRef = _createGradient(strokeGradientId, svgTag, bbox, matrix); - if (newStrokeRef) stroke = newStrokeRef; - } - } - - // Transform path data - // @ts-expect-error ignore it - element.setAttribute('d', _transformPath(element.attributes.d.value, matrix)); - element.removeAttribute('transform'); - - // Transform stroke width - const matrixScale = _getScaleFactor(matrix); - element.setAttribute('stroke-width', String(_quadraticMean(matrixScale.x, matrixScale.y) * strokeWidth)); - if (fill) element.setAttribute('fill', fill); - if (stroke) element.setAttribute('stroke', stroke); - } else if (_isGraphicsElement(element)) { - // Push stroke width, fill, and stroke down to leaves - // @ts-expect-error ignore it - if (strokeWidth && !element.attributes['stroke-width']) { - element.setAttribute('stroke-width', String(strokeWidth)); - } - - // @ts-expect-error ignore it - if (fill && !element.attributes.fill) { - element.setAttribute('fill', fill); - } - // @ts-expect-error ignore it - if (stroke && !element.attributes.stroke) { - element.setAttribute('stroke', stroke); - } - - // Push transform down to leaves - matrix = Matrix.compose(matrix, _parseTransform(element)); - if (Matrix.toString(matrix) === Matrix.toString(Matrix.identity())) { - element.removeAttribute('transform'); - } else { - element.setAttribute('transform', Matrix.toString(matrix)); - } - } - }; - applyTransforms(svgTag, inherited, 1 /* default SVG stroke width */); -}; - -export default transformStrokeWidths; diff --git a/packages/svg-renderer/src/types/global.d.ts b/packages/svg-renderer/src/types/global.d.ts deleted file mode 100644 index 8293c0a85..000000000 --- a/packages/svg-renderer/src/types/global.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import type {Matrix} from 'transformation-matrix'; - -declare global { - type int = number; -} diff --git a/packages/svg-renderer/src/types/scratch-render-fonts.d.ts b/packages/svg-renderer/src/types/scratch-render-fonts.d.ts deleted file mode 100644 index a36c32072..000000000 --- a/packages/svg-renderer/src/types/scratch-render-fonts.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'scratch-render-fonts' { - export default function getFonts(): Record; -} diff --git a/packages/svg-renderer/src/types/transformation-matrix.d.ts b/packages/svg-renderer/src/types/transformation-matrix.d.ts deleted file mode 100644 index 8a6c42398..000000000 --- a/packages/svg-renderer/src/types/transformation-matrix.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'transformation-matrix' { - export function skewDEG(ax: number, ay: number): Matrix; -} diff --git a/packages/svg-renderer/src/util/log.ts b/packages/svg-renderer/src/util/log.ts deleted file mode 100644 index b5a2a9a73..000000000 --- a/packages/svg-renderer/src/util/log.ts +++ /dev/null @@ -1,4 +0,0 @@ -import nanolog from '@turbowarp/nanolog'; -nanolog.enable(); - -export default nanolog('scratch-svg-render'); diff --git a/packages/svg-renderer/test/bitmapAdapter_getResized.ts b/packages/svg-renderer/test/bitmapAdapter_getResized.ts deleted file mode 100644 index de125a7a8..000000000 --- a/packages/svg-renderer/test/bitmapAdapter_getResized.ts +++ /dev/null @@ -1,102 +0,0 @@ -// Test getResizedWidthHeight function of bitmap adapter class - -import {test} from 'tap'; -import BitmapAdapter from '../src/bitmap-adapter'; - -test('zero', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(0, 0); - t.equal(0, size.width); - t.equal(0, size.height); - t.end(); -}); - -// Double (as if it is bitmap resolution 1) -test('smallImg', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(50, 50); - t.equal(100, size.width); - t.equal(100, size.height); - t.end(); -}); - -// Double (as if it is bitmap resolution 1) -test('stageSizeImage', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(480, 360); - t.equal(960, size.width); - t.equal(720, size.height); - t.end(); -}); - -// Don't resize -test('mediumHeightImage', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(50, 700); - t.equal(50, size.width); - t.equal(700, size.height); - t.end(); -}); - -// Don't resize -test('mediumWidthImage', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(700, 50); - t.equal(700, size.width); - t.equal(50, size.height); - t.end(); -}); - -// Don't resize -test('mediumImage', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(700, 700); - t.equal(700, size.width); - t.equal(700, size.height); - t.end(); -}); - -// Don't resize -test('doubleStageSizeImage', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(960, 720); - t.equal(960, size.width); - t.equal(720, size.height); - t.end(); -}); - -// Fit to stage width -test('wideImage', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(1000, 50); - t.equal(960, size.width); - t.equal(960 / 1000 * 50, size.height); - t.end(); -}); - -// Fit to stage height -test('tallImage', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(50, 1000); - t.equal(720, size.height); - t.equal(720 / 1000 * 50, size.width); - t.end(); -}); - -// Fit to stage height -test('largeImageHeightConstraint', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(1000, 1000); - t.equal(720, size.height); - t.equal(720 / 1000 * 1000, size.width); - t.end(); -}); - -// Fit to stage width -test('largeImageWidthConstraint', t => { - const bitmapAdapter = new BitmapAdapter(); - const size = bitmapAdapter.getResizedWidthHeight(2000, 1000); - t.equal(960, size.width); - t.equal(960 / 2000 * 1000, size.height); - t.end(); -}); diff --git a/packages/svg-renderer/test/fixtures/css-import.sanitized.svg b/packages/svg-renderer/test/fixtures/css-import.sanitized.svg deleted file mode 100644 index d570ed541..000000000 --- a/packages/svg-renderer/test/fixtures/css-import.sanitized.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/packages/svg-renderer/test/fixtures/css-import.svg b/packages/svg-renderer/test/fixtures/css-import.svg deleted file mode 100644 index f413f2e45..000000000 --- a/packages/svg-renderer/test/fixtures/css-import.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/packages/svg-renderer/test/fixtures/embedded-cat-foo.sanitized.svg b/packages/svg-renderer/test/fixtures/embedded-cat-foo.sanitized.svg deleted file mode 100644 index efd820ee7..000000000 --- a/packages/svg-renderer/test/fixtures/embedded-cat-foo.sanitized.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/packages/svg-renderer/test/fixtures/embedded-cat-foo.svg b/packages/svg-renderer/test/fixtures/embedded-cat-foo.svg deleted file mode 100644 index 274a0cfe0..000000000 --- a/packages/svg-renderer/test/fixtures/embedded-cat-foo.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/packages/svg-renderer/test/fixtures/embedded-cat-xlink.svg b/packages/svg-renderer/test/fixtures/embedded-cat-xlink.svg deleted file mode 100644 index 5c74ddf44..000000000 --- a/packages/svg-renderer/test/fixtures/embedded-cat-xlink.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/packages/svg-renderer/test/fixtures/hearts.svg b/packages/svg-renderer/test/fixtures/hearts.svg deleted file mode 100644 index e85b16055..000000000 --- a/packages/svg-renderer/test/fixtures/hearts.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/svg-renderer/test/fixtures/invalid-cloud.svg b/packages/svg-renderer/test/fixtures/invalid-cloud.svg deleted file mode 100644 index 374b1b645..000000000 --- a/packages/svg-renderer/test/fixtures/invalid-cloud.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/svg-renderer/test/fixtures/metadata-body.svg b/packages/svg-renderer/test/fixtures/metadata-body.svg deleted file mode 100644 index f902d7ae2..000000000 --- a/packages/svg-renderer/test/fixtures/metadata-body.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - stuff inside - diff --git a/packages/svg-renderer/test/fixtures/metadata-onload.sanitized.svg b/packages/svg-renderer/test/fixtures/metadata-onload.sanitized.svg deleted file mode 100644 index 6df228d06..000000000 --- a/packages/svg-renderer/test/fixtures/metadata-onload.sanitized.svg +++ /dev/null @@ -1,3 +0,0 @@ - - ad="alert('from the svg')"> - diff --git a/packages/svg-renderer/test/fixtures/metadata-onload.svg b/packages/svg-renderer/test/fixtures/metadata-onload.svg deleted file mode 100644 index 766ed08c9..000000000 --- a/packages/svg-renderer/test/fixtures/metadata-onload.svg +++ /dev/null @@ -1,7 +0,0 @@ - - ad="alert('from the svg')"> - diff --git a/packages/svg-renderer/test/fixtures/onload-script.svg b/packages/svg-renderer/test/fixtures/onload-script.svg deleted file mode 100644 index dab9a5710..000000000 --- a/packages/svg-renderer/test/fixtures/onload-script.svg +++ /dev/null @@ -1,7 +0,0 @@ - - ad="alert('from the svg')"> - diff --git a/packages/svg-renderer/test/fixtures/red-and-white-carousel-pound-in-href.sanitized.svg b/packages/svg-renderer/test/fixtures/red-and-white-carousel-pound-in-href.sanitized.svg deleted file mode 100644 index ec1192ec9..000000000 --- a/packages/svg-renderer/test/fixtures/red-and-white-carousel-pound-in-href.sanitized.svg +++ /dev/null @@ -1,74 +0,0 @@ - - red and white carousel - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Layer 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/svg-renderer/test/fixtures/red-and-white-carousel-pound-in-href.svg b/packages/svg-renderer/test/fixtures/red-and-white-carousel-pound-in-href.svg deleted file mode 100644 index c19a08102..000000000 --- a/packages/svg-renderer/test/fixtures/red-and-white-carousel-pound-in-href.svg +++ /dev/null @@ -1,74 +0,0 @@ - - red and white carousel - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Layer 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/svg-renderer/test/fixtures/reserved-namespace.sanitized.svg b/packages/svg-renderer/test/fixtures/reserved-namespace.sanitized.svg deleted file mode 100644 index 4f6aebd4f..000000000 --- a/packages/svg-renderer/test/fixtures/reserved-namespace.sanitized.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/packages/svg-renderer/test/fixtures/reserved-namespace.svg b/packages/svg-renderer/test/fixtures/reserved-namespace.svg deleted file mode 100644 index 4bad8db8b..000000000 --- a/packages/svg-renderer/test/fixtures/reserved-namespace.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/packages/svg-renderer/test/fixtures/scratch_cat_bitmap_within_svg.sanitized.svg b/packages/svg-renderer/test/fixtures/scratch_cat_bitmap_within_svg.sanitized.svg deleted file mode 100644 index b42e29903..000000000 --- a/packages/svg-renderer/test/fixtures/scratch_cat_bitmap_within_svg.sanitized.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/svg-renderer/test/fixtures/scratch_cat_bitmap_within_svg.svg b/packages/svg-renderer/test/fixtures/scratch_cat_bitmap_within_svg.svg deleted file mode 100644 index edb068b41..000000000 --- a/packages/svg-renderer/test/fixtures/scratch_cat_bitmap_within_svg.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/svg-renderer/test/fixtures/script.sanitized.svg b/packages/svg-renderer/test/fixtures/script.sanitized.svg deleted file mode 100644 index 15fa831ba..000000000 --- a/packages/svg-renderer/test/fixtures/script.sanitized.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/packages/svg-renderer/test/fixtures/script.svg b/packages/svg-renderer/test/fixtures/script.svg deleted file mode 100644 index 85cc86886..000000000 --- a/packages/svg-renderer/test/fixtures/script.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/packages/svg-renderer/test/fixtures/svg-tag-prefixes.svg b/packages/svg-renderer/test/fixtures/svg-tag-prefixes.svg deleted file mode 100644 index d2988b3ca..000000000 --- a/packages/svg-renderer/test/fixtures/svg-tag-prefixes.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/svg-renderer/test/fixup-svg-string.ts b/packages/svg-renderer/test/fixup-svg-string.ts deleted file mode 100644 index a41fae5a7..000000000 --- a/packages/svg-renderer/test/fixup-svg-string.ts +++ /dev/null @@ -1,144 +0,0 @@ -import {test} from 'tap'; -import fs from 'fs'; -import path from 'path'; -import {DOMParser} from '@xmldom/xmldom'; -import fixupSvgString from '../src/fixup-svg-string'; - -// The browser DOMParser throws on errors by default, replicate that here -// by customizing the error callback to throw (defaults to logging) -const domParser = new DOMParser({ - errorHandler: { - error: e => { - throw new Error(e); - } - } -}); - -test('fixupSvgString should make parsing fixtures not throw', t => { - const filePath = path.resolve(__dirname, './fixtures/hearts.svg'); - const svgString = fs.readFileSync(filePath) - .toString(); - const fixed = fixupSvgString(svgString); - - // Make sure undefineds aren't being written into the file - t.equal(fixed.indexOf('undefined'), -1); - t.doesNotThrow(() => { - domParser.parseFromString(fixed, 'text/xml'); - }); - t.end(); -}); - -test('fixupSvgString should correct namespace declarations bound to reserved namespace names', t => { - const filePath = path.resolve(__dirname, './fixtures/reserved-namespace.svg'); - const svgString = fs.readFileSync(filePath) - .toString(); - const fixed = fixupSvgString(svgString); - - // Make sure undefineds aren't being written into the file - t.equal(fixed.indexOf('undefined'), -1); - t.doesNotThrow(() => { - domParser.parseFromString(fixed, 'text/xml'); - }); - t.end(); -}); - -test('fixupSvgString shouldn\'t correct non-attributes', t => { - const dontFix = fixupSvgString('xmlns:test="http://www/w3.org/XML/1998/namespace" is not an xmlns attribute'); - - t.not(dontFix.indexOf('http://www/w3.org/XML/1998/namespace'), -1); - t.end(); -}); - -test('fixupSvgString should strip `svg:` prefix from tag names', t => { - const filePath = path.resolve(__dirname, './fixtures/svg-tag-prefixes.svg'); - const svgString = fs.readFileSync(filePath) - .toString(); - const fixed = fixupSvgString(svgString); - - const checkPrefixes = (element: Element) => { - t.not(element.prefix, 'svg'); - // JSDOM doesn't have element.children, only element.childNodes - if (element.childNodes) { - // JSDOM's childNodes is not iterable, so for...of cannot be used here - for (let i = 0; i < element.childNodes.length; i++) { - const child = element.childNodes[i]; - if (child.nodeType === 1 /* Node.ELEMENT_NODE */) checkPrefixes(child as Element); - } - } - }; - - // Make sure undefineds aren't being written into the file - t.equal(fixed.indexOf('undefined'), -1); - t.doesNotThrow(() => { - domParser.parseFromString(fixed, 'text/xml'); - }); - - checkPrefixes(domParser.parseFromString(fixed, 'text/xml') as unknown as Element); - - t.end(); -}); - -test('fixupSvgString should empty script tags', t => { - const filePath = path.resolve(__dirname, './fixtures/script.svg'); - const svgString = fs.readFileSync(filePath) - .toString(); - const fixed = fixupSvgString(svgString); - // Script tag should remain but have no contents. - t.equal(fixed.indexOf(''), 207); - // The contents of the script tag (e.g. the alert) are no longer there. - t.equal(fixed.indexOf('stuff inside'), -1); - t.end(); -}); - -test('fixupSvgString should empty script tags in onload', t => { - const filePath = path.resolve(__dirname, './fixtures/onload-script.svg'); - const svgString = fs.readFileSync(filePath) - .toString(); - const fixed = fixupSvgString(svgString); - // Script tag should remain but have no contents. - t.equal(fixed.indexOf(''), 792); - t.end(); -}); - -test('fixupSvgString strips contents of metadata', t => { - const filePath = path.resolve(__dirname, './fixtures/metadata-body.svg'); - const svgString = fs.readFileSync(filePath) - .toString(); - const fixed = fixupSvgString(svgString); - // Metadata tag should still exist, it'll just be empty. - t.equal(fixed.indexOf(''), 207); - // The contents of the metadata tag are gone. - t.equal(fixed.indexOf('stuff inside'), -1); - t.end(); -}); - -test('fixupSvgString strips contents of metadata in onload', t => { - const filePath = path.resolve(__dirname, './fixtures/metadata-onload.svg'); - const svgString = fs.readFileSync(filePath) - .toString(); - const fixed = fixupSvgString(svgString); - // Metadata tag should still exist, it'll just be empty. - t.equal(fixed.indexOf(''), 800); - t.end(); -}); - -test('fixupSvgString should correct invalid mime type', t => { - const filePath = path.resolve(__dirname, './fixtures/invalid-cloud.svg'); - const svgString = fs.readFileSync(filePath, 'utf8'); - const fixed = fixupSvgString(svgString); - - // Make sure we replace an invalid mime type from Photoshop exported SVGs - t.not(svgString.indexOf('img/png'), -1); - t.equal(fixed.indexOf('img/png'), -1); - t.doesNotThrow(() => { - domParser.parseFromString(fixed, 'text/xml'); - }); - t.end(); -}); - -test('fixupSvgString shouldn\'t correct non-image tags', t => { - const dontFix = fixupSvgString('data:img/png is not a mime type'); - - t.not(dontFix.indexOf('img/png'), -1); - t.end(); -}); diff --git a/packages/svg-renderer/test/sanitize-svg.ts b/packages/svg-renderer/test/sanitize-svg.ts deleted file mode 100644 index e14d320da..000000000 --- a/packages/svg-renderer/test/sanitize-svg.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {test} from 'tap'; -import fs from 'fs'; -import path from 'path'; - -import sanitizeSvg from '../src/sanitize-svg'; - -// find all svg fixtures with filenames ending '.sanitized.svg', and compare their -// content to the result when we run sanitizeSvg.sanitizeSvgText() on the raw -// versions -test('compare svg content before and after sanitize-svg sanitizes it', t => { - const dirPath = path.resolve(__dirname, './fixtures/'); - const fixtureFilenames = fs.readdirSync(dirPath); - // for simplicity, we'll call those existing '.sanitized.svg' files "correct" - const correctSvgFilenames: string[] = []; - fixtureFilenames.forEach(filename => { - if (/^.*.sanitized.svg$/.test(filename)) { - correctSvgFilenames.push(filename); - } - }); - correctSvgFilenames.forEach(correctSvgFilename => { - // load raw svg content and run it through sanitizeSvg.sanitizeSvgText() - const rawSvgFilename = correctSvgFilename.replace('.sanitized.svg', '.svg'); - const rawSvgFilePath = path.resolve(__dirname, `./fixtures/${rawSvgFilename}`); - const rawSvgString = fs.readFileSync(rawSvgFilePath).toString(); - const testSanitizedSvgString = sanitizeSvg.sanitizeSvgText(rawSvgString); - - // load "correct" content - const correctSvgFilePath = path.resolve(__dirname, `./fixtures/${correctSvgFilename}`); - const correctSvgString = fs.readFileSync(correctSvgFilePath).toString(); - - t.equal(testSanitizedSvgString, correctSvgString); - }); - t.end(); -}); diff --git a/packages/svg-renderer/test/test-output/transform-applier-test.html b/packages/svg-renderer/test/test-output/transform-applier-test.html deleted file mode 100644 index be0edfe1d..000000000 --- a/packages/svg-renderer/test/test-output/transform-applier-test.html +++ /dev/null @@ -1,373 +0,0 @@ - -

noTransformPath

-
- -
-
- -

noStrokeWidthPath

-
- -
-
- -

identityTransformPath

-
- -
-
- -

transformBox

-
- -
-
- -

transformPath

-
- -
-
- -

composedTransformPathIdentity

-
- -
-
- -

composedTransformPath

-
- -
-
- -

parentTransformPath

-
- -
-
- -

nestedNoTransformPath

-
- -
-
- -

nestedTransformPath

-
- -
-
- -

variousTransformsPath

-
- -
-
- -

siblingsTransformPath

-
- -
-
- -

siblingsStroke

-
- -
-
- -

transformedNestedStroke

-
- -
-
- -

variousTransformsRelativePath

-
- -
-
- -

scaleTransformEllipticalPath

-
- -
-
- -

invertTransformEllipticalPath

-
- -
-
- -

rotateTransformEllipticalPath

-
- -
-
- -

skewXTransformEllipticalPath

-
- -
-
- -

skewYTransformEllipticalPath

-
- -
-
- -

variousTransformsEllipticalPath

-
- -
-
- -

linearGradientTransformSquareSkewY

-
- -
-
- -

linearGradientTransformSquareSkewX

-
- -
-
- -

linearGradientTransform

-
- -
-
- -

reusedLinearGradientTransform

-
- -
-
- -

nestedLinearGradientTransform

-
- - - - - - - - - - - -
-
- - - - - - - - - - - - - - -

percentLinearGradientTransform

-
- - - - - - - - - -
-
- - - - - - - - - - - - -

userSpaceLinearGradientTransform

-
- - - - - - - - - -
-
- - - - - - - - - - - - -

linearGradientTransform

-
- -
-
- -

nestedRadialGradientTransform. Note that radial gradients are not expected to match exactly.

-
- - - - - - - - - - - -
-
- - - - - - - - - - - - - - -

focalRadialGradientTransform

-
- - - - - - - - - - - -
-
- - - - - - - - - - - - - - -

percentRadialGradientTransform

-
- - - - - - - - - - - -
-
- - - - - - - - - - - - - - -

userSpaceRadialGradientTransform

-
- - - - - - - - - -
-
- - - - - - - - - - - - -

blackFillsBugFix

-
- - - - - - - -
-
- - - - - - - -
- \ No newline at end of file diff --git a/packages/svg-renderer/test/transform-applier.ts b/packages/svg-renderer/test/transform-applier.ts deleted file mode 100644 index 5e86a7288..000000000 --- a/packages/svg-renderer/test/transform-applier.ts +++ /dev/null @@ -1,797 +0,0 @@ -// @ts-nocheck -// Test transform-applier - -import {test} from 'tap'; -import {JSDOM} from 'jsdom'; -import transformStrokeWidths from '../src/transform-applier'; -import log from '../src/util/log'; - -// PathData, absolute instructions only -const d = 'M -20 -20 0 10 ' + - 'L 5 5 H 10 V 10 ' + - 'C 10 10 20 10 15 25 ' + - 'S 15 30 15 40 ' + - 'Q 20 50 30 60 ' + - 'T 30 70 20 80 ' + - 'M 0 0 ' + - 'A 40 50 0 1 1 0 100 Z '; -// Path constructed specifically for testing elliptical arcs -const ellipticalPath = 'M10,300 l 50,-25 ' + - 'a25,25 -60 0,1 50,-25 l 50,-25 ' + - 'a25,50 -45 0,1 50,-25 l 50,-25 ' + - 'a25,75 -30 0,1 50,-25 l 50,-25 ' + - 'a25,100 -15 0,1 50,-25 l 50,-25 v 50 l -50,25 ' + - 'a25,25 60 1,1 -50,25 l -50,25 ' + - 'a25,50 45 1,1 -50,25 l -50,25 ' + - 'a25,75 30 1,1 -50,25 l -50,25 ' + - 'a25,100 15 1,1 -50,25 l -50,25 '; - -// This path is tricky because all of its bounds lie outside -// the 2 given points -const trickyBoundsPath = 'M 40 40 A 30 50 -45 1,1 80 80'; -// Because jsdom doesn't simulate SvgElement.getBBox(), we need to store -// the bounds for testing. -const trickyBoundsPathBounds = { - height: 82.46210479736328, - width: 82.46211242675781, - x: 36.26179885864258, - y: 1.2760814428329468 -}; - -const {window} = new JSDOM(); -const parser = new window.DOMParser(); -// eslint-disable-next-line @typescript-eslint/no-require-imports -const fs = require('fs'); -const OUTPUT_COMPARISON_FILES = false; -let comparisonFileString = ''; - -const comparisonFileAppend = function (svgString, svgElement, name) { - if (!OUTPUT_COMPARISON_FILES) return; - const newSvgString = new window.XMLSerializer().serializeToString(svgElement); - comparisonFileString += - `

${name}

-
- ${svgString} -
-
- ${newSvgString} -
`; -}; - -const outputComparisonFile = function () { - if (!OUTPUT_COMPARISON_FILES) return; - fs.writeFile( - `${__dirname}/test-output/transform-applier-test.html`, - `\n${comparisonFileString}\n`, - err => log.error(err) - ); -}; - -// No transform attribute on the path -test('noTransformPath', t => { - const svgString = - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'noTransformPath'); - - t.equal(d, svgElement.getElementById('path').attributes.d.value); - t.notOk(svgElement.getElementById('path').attributes.transform); - t.end(); -}); - -// No stroke width attribute on the path. Stroke width is 1 by default in SVG, so transform should increase it to 2. -test('transformedNoStrokeWidthPath', t => { - const svgString = - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'noStrokeWidthPath'); - - t.equal('2', svgElement.getElementById('path').attributes['stroke-width'].value); - t.end(); -}); - -// Transform is identity matrix -test('identityTransformPath', t => { - const svgString = - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'identityTransformPath'); - - t.equal(d, svgElement.getElementById('path').attributes.d.value); - t.notOk(svgElement.getElementById('path').attributes.transform); - t.end(); -}); - -// Transform on a simple box -test('transformBox', t => { - const svgString = - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'transformBox'); - - const transformed = `M 45 45 L 245 45 L 245 145 L 45 145 Z `; - t.equal(transformed, svgElement.getElementById('path').attributes.d.value); - // Transform is integrated into path, so the attribute should be gone - t.notOk(svgElement.getElementById('path').attributes.transform); - const quadraticMean = Math.sqrt(((20 * 20) + (10 * 10)) / 2); - t.equal(`${quadraticMean}`, svgElement.getElementById('path').attributes['stroke-width'].value); - t.end(); -}); - -// Transform is not identity matrix -test('transformPath', t => { - const svgString = - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'transformPath'); - - const doubled = 'M 5 5 L 45 65 L 55 55 L 65 55 L 65 65 C 65 65 85 65 75 95 C 65 125 75 105 75 125 ' + - 'Q 85 145 105 165 Q 125 185 105 185 Q 85 185 85 205 M 45 45 A 80 100 0 1 1 45 245 Z '; - t.equal(doubled, svgElement.getElementById('path').attributes.d.value); - // Transform is integrated into path, so the attribute should be gone - t.notOk(svgElement.getElementById('path').attributes.transform); - t.equal('2', svgElement.getElementById('path').attributes['stroke-width'].value); - t.end(); -}); - -// Transform has multiple matrices that compose to identity matrix -test('composedTransformPathIdentity', t => { - const svgString = - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'composedTransformPathIdentity'); - - t.equal(d, svgElement.getElementById('path').attributes.d.value); - t.notOk(svgElement.getElementById('path').attributes.transform); - t.end(); -}); - -// Transform has multiple matrices that don't compose to identity -test('composedTransformPath', t => { - const svgString = - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'composedTransformPath'); - - const transformedPath = 'M -29.5 -29 L 0.5 16 L 8 8.5 L 15.5 8.5 L 15.5 16 C 15.5 16 30.5 16 23 38.5 ' + - 'C 15.5 61 23 46 23 61 Q 30.5 76 45.5 91 Q 60.5 106 45.5 106 Q 30.5 106 30.5 121 M 0.5 1 ' + - 'A 60 75 0 1 1 0.5 151 Z '; - t.equal(transformedPath, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -// Transform is on parent group -test('parentTransformPath', t => { - const svgString = - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'parentTransformPath'); - - const doubled = 'M -40 -40 L 0 20 L 10 10 L 20 10 L 20 20 C 20 20 40 20 30 50 C 20 80 30 60 30 80 ' + - 'Q 40 100 60 120 Q 80 140 60 140 Q 40 140 40 160 M 0 0 A 80 100 0 1 1 0 200 Z '; - t.equal(doubled, svgElement.getElementById('path').attributes.d.value); - // Transform should be gone from both child and parent - t.notOk(svgElement.getElementById('group').attributes.transform); - t.notOk(svgElement.getElementById('path').attributes.transform); - t.equal('2', svgElement.getElementById('path').attributes['stroke-width'].value); - t.end(); -}); - -// Nested path -test('nestedNoTransformPath', t => { - const svgString = - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'nestedNoTransformPath'); - - t.equal(d, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -// Transforms on parents and children -test('nestedTransformPath', t => { - const svgString = - `` + - `` + - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'nestedTransformPath'); - - const quartered = 'M -45 -45 L 0 22.5 L 11.25 11.25 L 22.5 11.25 L 22.5 22.5 C 22.5 22.5 45 22.5 33.75 56.25 ' + - 'C 22.5 90 33.75 67.5 33.75 90 Q 45 112.5 67.5 135 Q 90 157.5 67.5 157.5 Q 45 157.5 45 180 M 0 0 ' + - 'A 90 112.5 0 1 1 0 225 Z '; - t.equal(quartered, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -// Transform combines all types of transforms -test('variousTransformsPath', t => { - const svgString = - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'variousTransformsPath'); - - const transformedPath = 'M 115.3172 96.7866 L 134.6908 171.2195 L 151.9584 175.6212 L 164.2563 185.7055 ' + - 'L 159.2866 191.3881 C 159.2866 191.3881 183.8824 211.5567 156.6755 218.5202 ' + - 'C 129.4685 225.4837 151.7058 224.2028 141.7664 235.568 Q 144.1249 257.0175 158.7814 288.5514 ' + - 'Q 173.4379 320.0852 148.842 299.9166 Q 124.2462 279.7479 114.3068 291.1131 M 144.6301 159.8543 ' + - 'A 75.4328 127.2656 -51.6345 1 1 45.2364 273.5062 Z '; - t.equal(transformedPath, svgElement.getElementById('path').attributes.d.value); - t.notOk(svgElement.getElementById('path').attributes.transform); - t.end(); -}); - -// Transform is pushed down to other children -test('siblingsTransformPath', t => { - const svgString = - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'siblingsTransformPath'); - - t.equal('matrix(0.5,0,0,0.5,5,10)', svgElement.getElementById('sibling').attributes.transform.value); - t.equal('matrix(0.5,0,0,0.5,-0.25,-0.25)', svgElement.getElementById('distantCousin1').attributes.transform.value); - t.equal('matrix(0.5,0,0,0.5,0,0)', svgElement.getElementById('distantCousin2').attributes.transform.value); - t.end(); -}); - -// Stroke width is pushed down to leaf level -test('siblingsStroke', t => { - const svgString = - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'siblingsStroke'); - - t.equal('10', svgElement.getElementById('sibling').attributes['stroke-width'].value); - t.equal('15', svgElement.getElementById('distantCousin1').attributes['stroke-width'].value); - t.equal('5', svgElement.getElementById('distantCousin2').attributes['stroke-width'].value); - t.end(); -}); - -// Nested stroke width is transformed -test('transformedNestedStroke', t => { - const svgString = - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'transformedNestedStroke'); - - const quadraticMean = Math.sqrt(((5 / 2 * 5 / 2) + (2 / 2 * 2 / 2)) / 2); - t.equal(`${quadraticMean}`, svgElement.getElementById('path').attributes['stroke-width'].value); - t.end(); -}); - -// Various transforms applied to a path with relative instructions -test('variousTransformsRelativePath', t => { - const pathData = 'm 20 20 0 20 10 0 l 5 5 h 10 v 10 c 0 10 0 20 15 5 z ' + - 'm -50 5 s 15 0 15 10 q 20 10 10 20 t 20 10 20 10 a 30 10 30 1 1 0 1 '; - const svgString = - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'variousTransformsRelativePath'); - - const transformed = 'M 44.0917 25.6869 L 55.7402 43.813 L 64.0581 39.5868 L 71.1292 42.0053 L 79.447 37.7791 ' + - 'L 85.2713 46.8422 C 91.0955 55.9052 96.9198 64.9683 100.6603 45.0344 Z M 5.4144 51.3493 ' + - 'C 5.4144 51.3493 17.8912 45.01 23.7155 54.0731 Q 46.1755 54.6838 43.6819 67.9731 ' + - 'Q 41.1882 81.2623 66.1419 68.5838 Q 91.0955 55.9052 88.6019 69.1945 ' + - 'A 9.8314 30.5145 -83.9007 1 1 89.1843 70.1008 '; - t.equal(transformed, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -// Testing scale transform, elliptical paths -test('scaleTransformEllipticalPath', t => { - const svgString = - ` ` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'scaleTransformEllipticalPath'); - - const scaled = 'M 5 150 L 30 137.5 A 12.5 12.5 -50.7685 0 1 55 125 L 80 112.5 A 12.5 25 -45 0 1 105 100 ' + - 'L 130 87.5 A 12.5 37.5 -30 0 1 155 75 L 180 62.5 A 12.5 50 -15 0 1 205 50 L 230 37.5 L 230 62.5 L 205 75 ' + - 'A 12.5 12.5 -50.7685 1 1 180 87.5 L 155 100 A 12.5 25 45 1 1 130 112.5 L 105 125 A 12.5 37.5 30 1 1 80 137.5 ' + - 'L 55 150 A 12.5 50 15 1 1 30 162.5 L 5 175 '; - t.equal(scaled, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -// Testing invert transform, elliptical paths -test('invertTransformEllipticalPath', t => { - const svgString = - ` ` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'invertTransformEllipticalPath'); - - const inverted = 'M 300 10 L 275 60 A 25 25 -50.7685 0 0 250 110 L 225 160 A 25 50 -45 0 0 200 210 ' + - 'L 175 260 A 25 75 -60 0 0 150 310 L 125 360 A 25 100 -75 0 0 100 410 L 75 460 L 125 460 L 150 410 ' + - 'A 25 25 -50.7685 1 0 175 360 L 200 310 A 25 50 45 1 0 225 260 L 250 210 A 25 75 60 1 0 275 160 L 300 110 ' + - 'A 25 100 75 1 0 325 60 L 350 10 '; - t.equal(inverted, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -// Testing rotate transform, elliptical paths -test('rotateTransformEllipticalPath', t => { - const svgString = - ` ` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'rotateTransformEllipticalPath'); - - const rotated = 'M 190.597 61.4231 L 201.8042 116.1898 A 25 25 -50.7685 0 1 213.0114 170.9566 ' + - 'L 224.2186 225.7234 A 25 50 60 0 1 235.4257 280.4901 L 246.6329 335.2569 A 25 75 75 0 1 257.8401 390.0237 ' + - 'L 269.0473 444.7904 A 25 100 90 0 1 280.2545 499.5572 L 291.4617 554.324 L 243.1654 541.383 ' + - 'L 231.9582 486.6163 A 25 25 -50.7685 1 1 220.751 431.8495 L 209.5438 377.0827 ' + - 'A 25 50 -30 1 1 198.3367 322.316 L 187.1295 267.5492 A 25 75 -45 1 1 175.9223 212.7824 L 164.7151 158.0156 ' + - 'A 25 100 -60 1 1 153.5079 103.2489 L 142.3007 48.4821 '; - t.equal(rotated, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -// Testing skewX transform, elliptical paths -test('skewXTransformEllipticalPath', t => { - const svgString = - ` ` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'skewXTransformEllipticalPath'); - - const skewed = 'M -99.1911 300 L -40.0918 275 A 20.861 29.9602 50.1571 0 1 19.0074 250 L 78.1067 225 ' + - 'A 29.7657 41.9946 -28.5971 0 1 137.206 200 L 196.3052 175 A 28.0557 66.8312 -9.069 0 1 255.4045 150 ' + - 'L 314.5037 125 A 25.6458 97.482 6.9831 0 1 373.603 100 L 432.7022 75 L 414.5037 125 L 355.4045 150 ' + - 'A 20.861 29.9602 50.1571 1 1 296.3052 175 L 237.206 200 A 20.8982 59.8139 53.2248 1 1 178.1067 225 ' + - 'L 119.0074 250 A 21.0102 89.2423 43.6881 1 1 59.9082 275 L 0.8089 300 ' + - 'A 21.8464 114.4351 32.9028 1 1 -58.2903 325 L -117.3896 350 '; - t.equal(skewed, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -// Testing skewY transform, elliptical paths -test('skewYTransformEllipticalPath', t => { - const svgString = - ` ` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'skewYTransformEllipticalPath'); - - const skewed = 'M 10 296.3603 L 60 253.1618 A 20.861 29.9602 39.8429 0 1 110 209.9633 L 160 166.7648 ' + - 'A 29.7657 41.9946 -61.4029 0 1 210 123.5663 L 260 80.3677 A 29.4429 63.6825 -34.2139 0 1 310 37.1692 ' + - 'L 360 -6.0293 A 27.3833 91.2964 -14.925 0 1 410 -49.2278 L 460 -92.4263 L 460 -42.4263 L 410 0.7722 ' + - 'A 20.861 29.9602 39.8429 1 1 360 43.9707 L 310 87.1692 A 20.8982 59.8139 36.7752 1 1 260 130.3677 ' + - 'L 210 173.5663 A 21.4899 87.2503 26.3947 1 1 160 216.7648 L 110 259.9633 ' + - 'A 22.8454 109.4312 14.6345 1 1 60 303.1618 L 10 346.3603 '; - t.equal(skewed, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -// Testing various transforms, elliptical paths -test('variousTransformsEllipticalPath', t => { - const svgString = - ` ` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window); - comparisonFileAppend(svgString, svgElement, 'variousTransformsEllipticalPath'); - - const transformed = 'M 24.9709 107.5355 L 51.9997 63.7469 A 22.8929 27.3011 -47.5192 0 1 79.0286 19.9583 ' + - 'L 106.0574 -23.8303 A 23.5927 52.9826 -69.05 0 1 133.0862 -67.6189 L 160.115 -111.4075 ' + - 'A 23.0486 81.3499 -57.6917 0 1 187.1438 -155.1961 L 214.1727 -198.9847 ' + - 'A 22.8991 109.1745 -45.4789 0 1 241.2015 -242.7734 L 268.2303 -286.562 L 297.3515 -241.2466 ' + - 'L 270.3227 -197.458 A 22.8929 27.3011 -47.5192 1 1 243.2939 -153.6694 L 216.2651 -109.8807 ' + - 'A 26.0319 48.0181 7.1283 1 1 189.2363 -66.0921 L 162.2074 -22.3035 ' + - 'A 24.9487 75.1544 -6.3334 1 1 135.1786 21.4851 L 108.1498 65.2737 ' + - 'A 23.9235 104.4996 -19.9344 1 1 81.121 109.0623 L 54.0922 152.8509 '; - t.equal(transformed, svgElement.getElementById('path').attributes.d.value); - t.end(); -}); - -test('linearGradientTransformSquareSkewY', t => { - const svgString = - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, {width: 100, height: 100, x: 0, y: 0}); - comparisonFileAppend(svgString, svgElement, 'linearGradientTransformSquareSkewY'); - t.equal('-50', svgElement.getElementById('grad_a-0.75,-0.2679491924311227,0,1,-50,50').attributes.x1.value); - t.equal('-81.6826', svgElement.getElementById('grad_a-0.75,-0.2679491924311227,0,1,-50,50').attributes.x2.value); - t.equal('50', svgElement.getElementById('grad_a-0.75,-0.2679491924311227,0,1,-50,50').attributes.y1.value); - t.equal('138.6809', svgElement.getElementById('grad_a-0.75,-0.2679491924311227,0,1,-50,50').attributes.y2.value); - - t.end(); -}); - -test('linearGradientTransformSquareSkewX', t => { - const svgString = - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, {width: 100, height: 100, x: 0, y: 0}); - comparisonFileAppend(svgString, svgElement, 'linearGradientTransformSquareSkewX'); - t.equal('-50', svgElement.getElementById('grad_b-0.75,0,0.20096189432334202,1,-50,50').attributes.x1.value); - t.equal('-50', svgElement.getElementById('grad_b-0.75,0,0.20096189432334202,1,-50,50').attributes.x2.value); - t.equal('50', svgElement.getElementById('grad_b-0.75,0,0.20096189432334202,1,-50,50').attributes.y1.value); - t.equal('150', svgElement.getElementById('grad_b-0.75,0,0.20096189432334202,1,-50,50').attributes.y2.value); - - t.end(); -}); - -test('linearGradientTransform', t => { - const svgString = - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, 'linearGradientTransform'); - t.equal('26.9399', svgElement.getElementById('grad_c-.75,0,-0.20096189432334202,0.75,0,0').attributes.x1.value); - t.equal('84.6436', svgElement.getElementById('grad_c-.75,0,-0.20096189432334202,0.75,0,0').attributes.x2.value); - t.equal('0.9571', svgElement.getElementById('grad_c-.75,0,-0.20096189432334202,0.75,0,0').attributes.y1.value); - t.equal('16.4187', svgElement.getElementById('grad_c-.75,0,-0.20096189432334202,0.75,0,0').attributes.y2.value); - - t.end(); -}); - -test('reusedLinearGradientTransform', t => { - const svgString = - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, 'reusedLinearGradientTransform'); - t.equal('26.9399', svgElement.getElementById('grad_1-.75,0,-0.20096189432334202,0.75,0,0').attributes.x1.value); - t.equal('84.6436', svgElement.getElementById('grad_1-.75,0,-0.20096189432334202,0.75,0,0').attributes.x2.value); - t.equal('0.9571', svgElement.getElementById('grad_1-.75,0,-0.20096189432334202,0.75,0,0').attributes.y1.value); - t.equal('16.4187', svgElement.getElementById('grad_1-.75,0,-0.20096189432334202,0.75,0,0').attributes.y2.value); - t.equal('113.7382', svgElement.getElementById('grad_1-1,1.2246467991473532e-16,-1.2246467991473532e-16,-1,150,150') - .attributes.x1.value); - t.equal('31.2761', svgElement.getElementById('grad_1-1,1.2246467991473532e-16,-1.2246467991473532e-16,-1,150,150') - .attributes.x2.value); - t.equal('148.7239', svgElement.getElementById('grad_1-1,1.2246467991473532e-16,-1.2246467991473532e-16,-1,150,150') - .attributes.y1.value); - t.equal('148.7239', svgElement.getElementById('grad_1-1,1.2246467991473532e-16,-1.2246467991473532e-16,-1,150,150') - .attributes.y2.value); - - t.end(); -}); - -test('nestedLinearGradientTransform', t => { - const svgString = - ` - - - - - - - - - - `; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, 'nestedLinearGradientTransform'); - t.equal('26.9399', svgElement.getElementById('grad_2-.75,0,-0.20096189432334202,0.75,0,0').attributes.x1.value); - t.equal('26.9399', svgElement.getElementById('grad_2-.75,0,-0.20096189432334202,0.75,0,0').attributes.x2.value); - t.equal('0.9571', svgElement.getElementById('grad_2-.75,0,-0.20096189432334202,0.75,0,0').attributes.y1.value); - t.equal('62.8036', svgElement.getElementById('grad_2-.75,0,-0.20096189432334202,0.75,0,0').attributes.y2.value); - - t.end(); -}); - -test('percentLinearGradientTransform', t => { - const svgString = - ` - - - - - - - - `; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, 'percentLinearGradientTransform'); - t.equal('26.9399', svgElement.getElementById('grad_3-.75,0,-0.20096189432334202,0.75,0,0').attributes.x1.value); - t.equal('50.6569', svgElement.getElementById('grad_3-.75,0,-0.20096189432334202,0.75,0,0').attributes.x2.value); - t.equal('0.9571', svgElement.getElementById('grad_3-.75,0,-0.20096189432334202,0.75,0,0').attributes.y1.value); - t.equal('31.029', svgElement.getElementById('grad_3-.75,0,-0.20096189432334202,0.75,0,0').attributes.y2.value); - - t.end(); -}); - -test('userSpaceLinearGradientTransform', t => { - const svgString = - ` - - - - - - - - `; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, 'userSpaceLinearGradientTransform'); - t.equal('10.9808', svgElement.getElementById('grad_4-.75,0,-0.20096189432334202,0.75,0,0').attributes.x1.value); - t.equal('45.494', svgElement.getElementById('grad_4-.75,0,-0.20096189432334202,0.75,0,0').attributes.x2.value); - t.equal('15', svgElement.getElementById('grad_4-.75,0,-0.20096189432334202,0.75,0,0').attributes.y1.value); - t.equal('58.761', svgElement.getElementById('grad_4-.75,0,-0.20096189432334202,0.75,0,0').attributes.y2.value); - - t.end(); -}); - -test('degenerateLinearGradientTransform', t => { - const svgString = - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - ``; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, 'linearGradientTransform'); - - t.end(); -}); - -test('nestedRadialGradientTransform', t => { - const svgString = - ` - - - - - - - - - - `; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, - 'nestedRadialGradientTransform. Note that radial gradients are not expected to match exactly.'); - t.equal('49.5773', svgElement.getElementById('grad_5-.75,0,-0.20096189432334202,0.75,0,0').attributes.cx.value); - t.equal('31.8804', svgElement.getElementById('grad_5-.75,0,-0.20096189432334202,0.75,0,0').attributes.cy.value); - t.equal('30.9233', svgElement.getElementById('grad_5-.75,0,-0.20096189432334202,0.75,0,0').attributes.r.value); - - t.end(); -}); - -test('focalRadialGradientTransform', t => { - const svgString = - ` - - - - - - - - - - `; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, 'focalRadialGradientTransform'); - t.equal('49.5773', svgElement.getElementById('grad_6-.75,0,-0.20096189432334202,0.75,0,0').attributes.cx.value); - t.equal('31.8804', svgElement.getElementById('grad_6-.75,0,-0.20096189432334202,0.75,0,0').attributes.cy.value); - t.equal('30.9233', svgElement.getElementById('grad_6-.75,0,-0.20096189432334202,0.75,0,0').attributes.r.value); - t.equal('60.896', svgElement.getElementById('grad_6-.75,0,-0.20096189432334202,0.75,0,0').attributes.fx.value); - t.equal('47.342', svgElement.getElementById('grad_6-.75,0,-0.20096189432334202,0.75,0,0').attributes.fy.value); - - t.end(); -}); - -test('percentRadialGradientTransform', t => { - const svgString = - ` - - - - - - - - - - `; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, 'percentRadialGradientTransform'); - t.equal('50.7905', svgElement.getElementById('grad_7-.75,0,-0.20096189432334202,0.75,0,0').attributes.cx.value); - t.equal('50.4343', svgElement.getElementById('grad_7-.75,0,-0.20096189432334202,0.75,0,0').attributes.cy.value); - t.equal('30.9233', svgElement.getElementById('grad_7-.75,0,-0.20096189432334202,0.75,0,0').attributes.r.value); - t.equal('59.2389', svgElement.getElementById('grad_7-.75,0,-0.20096189432334202,0.75,0,0').attributes.fx.value); - t.equal('53.5267', svgElement.getElementById('grad_7-.75,0,-0.20096189432334202,0.75,0,0').attributes.fy.value); - - t.end(); -}); - -test('userSpaceRadialGradientTransform', t => { - const svgString = - ` - - - - - - - - `; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, trickyBoundsPathBounds); - comparisonFileAppend(svgString, svgElement, 'userSpaceRadialGradientTransform'); - t.equal('47.9423', svgElement.getElementById('grad_8-.75,0,-0.20096189432334202,0.75,0,0').attributes.cx.value); - t.equal('45', svgElement.getElementById('grad_8-.75,0,-0.20096189432334202,0.75,0,0').attributes.cy.value); - t.equal('7.5', svgElement.getElementById('grad_8-.75,0,-0.20096189432334202,0.75,0,0').attributes.r.value); - - t.end(); -}); - -test('blackFillsBugFix', t => { - const svgString = - ` - - - - - - `; - const svgElement = parser.parseFromString(svgString, 'text/xml').documentElement; - transformStrokeWidths(svgElement, window, - { - height: 12.5, - width: 24.020904541015625, - x: 0.9896308183670044, - y: 0.75 - }); - comparisonFileAppend(svgString, svgElement, 'blackFillsBugFix'); - t.equal('none', svgElement.getElementById('Shape').attributes.fill.value); - t.equal('5', svgElement.getElementById('Shape').attributes['stroke-width'].value); - - t.end(); -}); - -outputComparisonFile(); diff --git a/packages/svg-renderer/tsconfig.json b/packages/svg-renderer/tsconfig.json deleted file mode 100644 index 726e69b0c..000000000 --- a/packages/svg-renderer/tsconfig.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "include": [ - "./src/**/*" - ], - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "ES2018", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - // "rootDir": "./src/", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - - /* Emit */ - "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist/types/", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ - // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} diff --git a/packages/svg-renderer/tsconfig.node.json b/packages/svg-renderer/tsconfig.node.json deleted file mode 100644 index 797356130..000000000 --- a/packages/svg-renderer/tsconfig.node.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig", - "compilerOptions": { - "outDir": "./dist/node/", - "declaration": false, - "sourceMap": false - } -} diff --git a/packages/svg-renderer/webpack.config.js b/packages/svg-renderer/webpack.config.js deleted file mode 100644 index 5dfc37aaa..000000000 --- a/packages/svg-renderer/webpack.config.js +++ /dev/null @@ -1,88 +0,0 @@ -const {IgnorePlugin} = require('webpack'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); -const TerserPlugin = require('terser-webpack-plugin'); -const defaultsDeep = require('lodash.defaultsdeep'); -const path = require('path'); - -const base = { - mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', - devServer: { - contentBase: false, - host: '0.0.0.0', - port: process.env.PORT || 8576 - }, - resolve: { - extensions: ['.ts', '.js'] - }, - devtool: 'cheap-module-source-map', - entry: { - 'scratch-svg-renderer': './src/index.ts' - }, - module: { - rules: [{ - include: [ - path.resolve('node_modules', 'scratch-render-fonts') - ], - test: /\.js$/, - loader: 'babel-loader', - options: { - presets: [['@babel/preset-env', { - targets: { - browsers: ['last 3 versions', 'Safari >= 8', 'iOS >= 8'] - } - }]] - } - }, { - include: [ - path.resolve('src') - ], - test: /\.([cm]?ts|tsx)$/, - loader: 'ts-loader' - }] - }, - optimization: { - minimizer: [ - new TerserPlugin({ - include: /\.js$/ - }) - ] - }, - plugins: [ - new IgnorePlugin({ - resourceRegExp: /canvas/, - contextRegExp: /jsdom$/ - }) - ] -}; - -module.exports = [ - defaultsDeep({}, base, { - target: 'web', - output: { - library: 'ScratchSVGRenderer', - libraryTarget: 'umd', - path: path.resolve('playground'), - publicPath: '/', - filename: '[name].js' - }, - plugins: base.plugins.concat([ - new CopyWebpackPlugin({ - patterns: [{ - from: 'src/playground' - }] - }) - ]) - }), - defaultsDeep({}, base, { - target: 'web', - output: { - library: 'ScratchSVGRenderer', - libraryTarget: 'umd', - path: path.resolve('dist', 'web'), - filename: '[name].js' - }, - optimization: { - minimize: process.env.NODE_ENV === 'production' - } - }) -]; diff --git a/packages/vm/package.json b/packages/vm/package.json index 4db19aa04..4ab50a772 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -29,7 +29,7 @@ "version": "json -f package.json -I -e \"this.repository.sha = '$(git log -n1 --pretty=format:%H)'\"" }, "dependencies": { - "@vernier/godirect": "1.5.0", + "@vernier/godirect": "1.8.3", "arraybuffer-loader": "1.0.8", "atob": "2.1.2", "btoa": "1.2.1", @@ -39,16 +39,17 @@ "diff-match-patch": "1.0.4", "fastestsmallesttextencoderdecoder": "^1.0.22", "format-message": "6.2.1", + "text-encoding": "0.7.0", "htmlparser2": "10.1.0", "immutable": "5.1.5", "jszip": "^3.10.1", "@turbowarp/nanolog": "^1.0.1", "node-polyfill-webpack-plugin": "^3.0.0", - "scratch-sb1-converter": "1.0.324", + "clipcc-sb1-converter": "1.0.324", "scratch-translate-extension-languages": "1.0.7" }, "peerDependencies": { - "clipcc-svg-renderer": "^3.2.0" + "scratch-svg-renderer": "3.1.19" }, "devDependencies": { "@babel/core": "7.29.0", @@ -64,7 +65,7 @@ "clipcc-l10n": "3.2.0", "clipcc-render": "3.2.0", "clipcc-storage": "3.2.0", - "clipcc-svg-renderer": "3.2.0", + "scratch-svg-renderer": "3.1.19", "codingclip-worker-loader": "^3.0.10", "copy-webpack-plugin": "^14.0.0", "eslint": "^9.39.2", diff --git a/packages/vm/src/extensions/scratch3_gdx_for/index.js b/packages/vm/src/extensions/scratch3_gdx_for/index.js index ec135a5aa..160e01d45 100644 --- a/packages/vm/src/extensions/scratch3_gdx_for/index.js +++ b/packages/vm/src/extensions/scratch3_gdx_for/index.js @@ -4,7 +4,7 @@ const log = require('../../util/log'); const formatMessage = require('format-message'); const MathUtil = require('../../util/math-util'); const BLE = require('../../io/ble'); -const godirect = require('@vernier/godirect/dist/godirect.min.umd.js'); +const godirect = require('@vernier/godirect'); const ScratchLinkDeviceAdapter = require('./scratch-link-device-adapter'); /** diff --git a/packages/vm/src/import/load-costume.js b/packages/vm/src/import/load-costume.js index af92b1a99..8351d4e4c 100644 --- a/packages/vm/src/import/load-costume.js +++ b/packages/vm/src/import/load-costume.js @@ -1,6 +1,6 @@ const StringUtil = require('../util/string-util'); const log = require('../util/log'); -const {loadSvgString, serializeSvgToString} = require('clipcc-svg-renderer'); +const {loadSvgString, serializeSvgToString} = require('scratch-svg-renderer'); const loadVector_ = function (costume, runtime, rotationCenter, optVersion) { return new Promise(resolve => { @@ -10,7 +10,7 @@ const loadVector_ = function (costume, runtime, rotationCenter, optVersion) { // scratch-svg-renderer fixes syntax that causes loading issues, // and if optVersion is 2, fixes "quirks" associated with Scratch 2 SVGs, const fixedSvgString = serializeSvgToString(loadSvgString(svgString, true /* fromVersion2 */)); - + // If the string changed, put back into storage if (svgString !== fixedSvgString) { svgString = fixedSvgString; @@ -261,14 +261,14 @@ const handleCostumeLoadError = function (costume, runtime) { const AssetType = runtime.storage.AssetType; const isVector = costume.dataFormat === AssetType.ImageVector.runtimeFormat; - + // Use default asset if original fails to load costume.assetId = isVector ? runtime.storage.defaultAssetId.ImageVector : runtime.storage.defaultAssetId.ImageBitmap; costume.asset = runtime.storage.get(costume.assetId); costume.md5 = `${costume.assetId}.${costume.asset.dataFormat}`; - + const defaultCostumePromise = (isVector) ? loadVector_(costume, runtime) : loadBitmap_(costume, runtime); @@ -280,7 +280,7 @@ const handleCostumeLoadError = function (costume, runtime) { // Should be null if we got here because the costume was missing loadedCostume.broken.asset = oldAsset; loadedCostume.broken.dataFormat = oldDataFormat; - + loadedCostume.broken.rotationCenterX = oldRotationX; loadedCostume.broken.rotationCenterY = oldRotationY; loadedCostume.broken.bitmapResolution = oldBitmapResolution; @@ -322,7 +322,7 @@ const loadCostumeFromAsset = function (costume, runtime, optVersion) { .catch(error => { log.warn(`Error loading vector image: ${error}`); return handleCostumeLoadError(costume, runtime); - + }); } return loadBitmap_(costume, runtime, rotationCenter, optVersion) diff --git a/packages/vm/src/playground/benchmark.js b/packages/vm/src/playground/benchmark.js index 2861c2185..417407293 100644 --- a/packages/vm/src/playground/benchmark.js +++ b/packages/vm/src/playground/benchmark.js @@ -49,7 +49,7 @@ const Runtime = require('../engine/runtime'); const ScratchRender = require('clipcc-render'); const AudioEngine = require('clipcc-audio'); -const ScratchSVGRenderer = require('clipcc-svg-renderer'); +const ScratchSVGRenderer = require('scratch-svg-renderer'); const Scratch = window.Scratch = window.Scratch || {}; diff --git a/packages/vm/src/virtual-machine.js b/packages/vm/src/virtual-machine.js index c3da49db5..813f92e52 100644 --- a/packages/vm/src/virtual-machine.js +++ b/packages/vm/src/virtual-machine.js @@ -440,7 +440,7 @@ class VirtualMachine extends EventEmitter { }) .catch(error => { // eslint-disable-next-line global-require - const {SB1File, ValidationError} = require('scratch-sb1-converter'); + const {SB1File, ValidationError} = require('clipcc-sb1-converter'); try { const sb1 = new SB1File(input); diff --git a/packages/vm/test/fixtures/fake-bitmap-adapter.js b/packages/vm/test/fixtures/fake-bitmap-adapter.js index ff2a860fc..a7e5c8aa7 100644 --- a/packages/vm/test/fixtures/fake-bitmap-adapter.js +++ b/packages/vm/test/fixtures/fake-bitmap-adapter.js @@ -1,4 +1,4 @@ -const FakeBitmapAdapter = require('clipcc-svg-renderer').BitmapAdapter; +const FakeBitmapAdapter = require('scratch-svg-renderer').BitmapAdapter; FakeBitmapAdapter.prototype.resize = function (canvas) { return canvas; diff --git a/packages/vm/webpack.config.js b/packages/vm/webpack.config.js index 94af81884..b2215eda4 100644 --- a/packages/vm/webpack.config.js +++ b/packages/vm/webpack.config.js @@ -140,8 +140,6 @@ module.exports = [ from: '../storage/dist/web' }, { from: '../render/dist/web' - }, { - from: '../svg-renderer/dist/web' }, { from: 'src/playground' }] diff --git a/yarn.lock b/yarn.lock index cd0494bd9..748ba0b12 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1592,6 +1592,11 @@ resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz#798a33950d11226a0ebb6acafa60f5594424967f" integrity sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA== +"@discoveryjs/json-ext@0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + "@discoveryjs/json-ext@^0.6.1": version "0.6.3" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz#f13c7c205915eb91ae54c557f5e92bddd8be0e83" @@ -2887,6 +2892,11 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== +"@polka/url@^1.0.0-next.24": + version "1.0.0-next.29" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.29.tgz#5a40109a1ab5f84d6fd8fc928b19f367cbe7e7b1" + integrity sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww== + "@rtsao/scc@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" @@ -3659,11 +3669,6 @@ dependencies: "@types/node" "*" -"@types/css-tree@^2.3.8": - version "2.3.11" - resolved "https://registry.yarnpkg.com/@types/css-tree/-/css-tree-2.3.11.tgz#c9457a54fe8ea02d2d72ddc864c1b9c5625f10d0" - integrity sha512-aEokibJOI77uIlqoBOkVbaQGC9zII0A+JH1kcTNKW2CwyYWD8KM6qdo+4c77wD3wZOQfJuNWAr9M4hdk+YhDIg== - "@types/eslint-scope@^3.7.7": version "3.7.7" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" @@ -3802,16 +3807,6 @@ "@types/tough-cookie" "*" parse5 "^7.0.0" -"@types/jsdom@^28.0.0": - version "28.0.0" - resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-28.0.0.tgz#387bcb5fe60c753ae0c58584b659a598319938f2" - integrity sha512-A8TBQQC/xAOojy9kM8E46cqT00sF0h7dWjV8t8BJhUi2rG6JRh7XXQo/oLoENuZIQEpXsxLccLCnknyQd7qssQ== - dependencies: - "@types/node" "*" - "@types/tough-cookie" "*" - parse5 "^7.0.0" - undici-types "^7.21.0" - "@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" @@ -4365,10 +4360,10 @@ resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777" integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g== -"@vernier/godirect@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@vernier/godirect/-/godirect-1.5.0.tgz#0c6f08dcf8ab90abda96c219b4f2dcbbcd29f778" - integrity sha512-vMS0fQubI3WSSLg1Ry3aey/qWCl9XoCsFzgwOWYkeJs45YxjPel+42pLh5pO7uP6oF47sjZUKx8kGOoTiiiirA== +"@vernier/godirect@1.8.3": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@vernier/godirect/-/godirect-1.8.3.tgz#3621c3238d50cb70ddff1bcdb3b59c27b86c86c8" + integrity sha512-poS0LZ3jAjH36gIAI0aNBBdsGGbmt11VFbLO+eGDJ/JDSPtMu1iUStvOi0UM/ZH6Jyh34SjVd8Cnxu/Wmcb8iQ== "@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": version "1.14.1" @@ -4506,11 +4501,6 @@ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-3.0.1.tgz#bd8b1f824d57e30faa19eb78e4c0951056f72f00" integrity sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg== -"@xmldom/xmldom@0.8.11": - version "0.8.11" - resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz#b79de2d67389734c57c52595f7a7305e30c2d608" - integrity sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw== - "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -4593,7 +4583,7 @@ acorn-walk@^6.0.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== -acorn-walk@^8.1.1: +acorn-walk@^8.0.0, acorn-walk@^8.1.1: version "8.3.5" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.5.tgz#8a6b8ca8fc5b34685af15dabb44118663c296496" integrity sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw== @@ -4625,7 +4615,7 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.11.0, acorn@^8.15.0, acorn@^8.16.0, acorn@^8.4.1: +acorn@^8.0.4, acorn@^8.11.0, acorn@^8.15.0, acorn@^8.16.0, acorn@^8.4.1: version "8.16.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a" integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== @@ -4909,7 +4899,7 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== -array-includes@^3.1.4, array-includes@^3.1.6, array-includes@^3.1.7, array-includes@^3.1.8, array-includes@^3.1.9: +array-includes@^3.1.4, array-includes@^3.1.6, array-includes@^3.1.8, array-includes@^3.1.9: version "3.1.9" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.9.tgz#1f0ccaa08e90cdbc3eb433210f903ad0f17c3f3a" integrity sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ== @@ -4973,7 +4963,7 @@ array.prototype.findlast@^1.2.5: es-object-atoms "^1.0.0" es-shim-unscopables "^1.0.2" -array.prototype.findlastindex@^1.2.3, array.prototype.findlastindex@^1.2.6: +array.prototype.findlastindex@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz#cfa1065c81dcb64e34557c9b81d012f6a421c564" integrity sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ== @@ -4986,7 +4976,7 @@ array.prototype.findlastindex@^1.2.3, array.prototype.findlastindex@^1.2.6: es-object-atoms "^1.1.1" es-shim-unscopables "^1.1.0" -array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.5, array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2, array.prototype.flat@^1.3.3: +array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.5, array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz#534aaf9e6e8dd79fb6b9a9917f839ef1ec63afe5" integrity sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg== @@ -4996,7 +4986,7 @@ array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.5, array.prototype.flat@^ es-abstract "^1.23.5" es-shim-unscopables "^1.0.2" -array.prototype.flatmap@^1.3.2, array.prototype.flatmap@^1.3.3: +array.prototype.flatmap@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz#712cc792ae70370ae40586264629e33aab5dd38b" integrity sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg== @@ -5682,7 +5672,7 @@ base64-js@0.0.8: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" integrity sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw== -base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1: +base64-js@^1.2.1, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -6444,6 +6434,15 @@ cli@~1.0.0: exit "0.1.2" glob "^7.1.1" +clipcc-sb1-converter@1.0.324: + version "1.0.324" + resolved "https://registry.yarnpkg.com/clipcc-sb1-converter/-/clipcc-sb1-converter-1.0.324.tgz#79a3a416ac40dabb631912bc6ff23826159f2dc0" + integrity sha512-cg8ZAjtQJngQzWD9DY3l0fG7U2+4pkgY4a1GxL1NKJA4t2vsvo4q4MtrmLr5Lmb1FNv+Pb6Ge2j/hk4tYQ3X2g== + dependencies: + "@turbowarp/nanolog" "^1.0.1" + fastestsmallesttextencoderdecoder "^1.0.22" + js-md5 "^0.8.3" + cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -6584,6 +6583,11 @@ commander@^6.1.0, commander@^6.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + commander@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" @@ -6783,11 +6787,6 @@ core-js-compat@^3.43.0, core-js-compat@^3.48.0: dependencies: browserslist "^4.28.1" -core-js@2.5.7: - version "2.5.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" - integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== - core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" @@ -7174,6 +7173,11 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha512-AsElvov3LoNB7tf5k37H2jYSB+ZZPMT5sG2QjJCcdlV5chIv6htBUBUui2IKRjgtKAKtCBN7Zbwa+MtwLjSeNw== +debounce@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -8024,11 +8028,6 @@ es6-map@^0.1.3: es6-symbol "~3.1.1" event-emitter "~0.3.5" -es6-object-assign@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" - integrity sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw== - es6-set@~0.1.5: version "0.1.6" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.6.tgz#5669e3b2aa01d61a50ba79964f733673574983b8" @@ -8159,7 +8158,7 @@ eslint-import-resolver-webpack@0.13.10: resolve "^2.0.0-next.5" semver "^5.7.2" -eslint-module-utils@^2.12.1, eslint-module-utils@^2.7.3, eslint-module-utils@^2.8.0: +eslint-module-utils@^2.12.1, eslint-module-utils@^2.7.3: version "2.12.1" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz#f76d3220bfb83c057651359295ab5854eaad75ff" integrity sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw== @@ -8196,29 +8195,6 @@ eslint-plugin-import@2.26.0: resolve "^1.22.0" tsconfig-paths "^3.14.1" -eslint-plugin-import@2.29.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" - semver "^6.3.1" - tsconfig-paths "^3.15.0" - eslint-plugin-import@2.32.0: version "2.32.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz#602b55faa6e4caeaa5e970c198b5c00a37708980" @@ -9994,7 +9970,7 @@ html-entities@^2.6.0: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== -html-escaper@^2.0.0: +html-escaper@^2.0.0, html-escaper@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== @@ -10466,11 +10442,6 @@ intl-relativeformat@^2.1.0: dependencies: intl-messageformat "^2.0.0" -intl@1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde" - integrity sha512-rK0KcPHeBFBcqsErKSpvZnrOmWOj+EmDkyJ57e90YWaQNqbcivcqmKDlHEeNprDWOsKzPsh1BfSpPQdDvclHVw== - invariant@^2.0.0, invariant@^2.1.1, invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -10594,7 +10565,7 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" -is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.15.1, is-core-module@^2.16.1, is-core-module@^2.8.1: +is-core-module@^2.13.0, is-core-module@^2.15.1, is-core-module@^2.16.1, is-core-module@^2.8.1: version "2.16.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== @@ -11077,7 +11048,7 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-dompurify@^2.14.0: +isomorphic-dompurify@^2.4.0: version "2.36.0" resolved "https://registry.yarnpkg.com/isomorphic-dompurify/-/isomorphic-dompurify-2.36.0.tgz#91e0e554cc3130cc4b7bfb77264f58e51ebd561e" integrity sha512-E8YkGyPY3a/U5s0WOoc8Ok+3SWL/33yn2IHCoxCFLBUUPVy9WGa++akJZFxQCcJIhI+UvYhbrbnTIFQkHKZbgA== @@ -12599,6 +12570,11 @@ js-md5@0.7.3, js-md5@^0.7.3: resolved "https://registry.yarnpkg.com/js-md5/-/js-md5-0.7.3.tgz#b4f2fbb0b327455f598d6727e38ec272cd09c3f2" integrity sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ== +js-md5@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/js-md5/-/js-md5-0.8.3.tgz#921bab7efa95bfc9d62b87ee08a57f8fe4305b69" + integrity sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -12665,33 +12641,6 @@ jsdom@26.1.0: ws "^8.18.0" xml-name-validator "^5.0.0" -jsdom@28.1.0, jsdom@^28.0.0, jsdom@^28.1.0: - version "28.1.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-28.1.0.tgz#ac4203e58fd24d7b0f34359ab00d6d9caebd4b62" - integrity sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug== - dependencies: - "@acemir/cssom" "^0.9.31" - "@asamuzakjp/dom-selector" "^6.8.1" - "@bramus/specificity" "^2.4.2" - "@exodus/bytes" "^1.11.0" - cssstyle "^6.0.1" - data-urls "^7.0.0" - decimal.js "^10.6.0" - html-encoding-sniffer "^6.0.0" - http-proxy-agent "^7.0.2" - https-proxy-agent "^7.0.6" - is-potential-custom-element-name "^1.0.1" - parse5 "^8.0.0" - saxes "^6.0.0" - symbol-tree "^3.2.4" - tough-cookie "^6.0.0" - undici "^7.21.0" - w3c-xmlserializer "^5.0.0" - webidl-conversions "^8.0.1" - whatwg-mimetype "^5.0.0" - whatwg-url "^16.0.0" - xml-name-validator "^5.0.0" - jsdom@^11.5.1: version "11.12.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" @@ -12724,6 +12673,33 @@ jsdom@^11.5.1: ws "^5.2.0" xml-name-validator "^3.0.0" +jsdom@^28.0.0, jsdom@^28.1.0: + version "28.1.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-28.1.0.tgz#ac4203e58fd24d7b0f34359ab00d6d9caebd4b62" + integrity sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug== + dependencies: + "@acemir/cssom" "^0.9.31" + "@asamuzakjp/dom-selector" "^6.8.1" + "@bramus/specificity" "^2.4.2" + "@exodus/bytes" "^1.11.0" + cssstyle "^6.0.1" + data-urls "^7.0.0" + decimal.js "^10.6.0" + html-encoding-sniffer "^6.0.0" + http-proxy-agent "^7.0.2" + https-proxy-agent "^7.0.6" + is-potential-custom-element-name "^1.0.1" + parse5 "^8.0.0" + saxes "^6.0.0" + symbol-tree "^3.2.4" + tough-cookie "^6.0.0" + undici "^7.21.0" + w3c-xmlserializer "^5.0.0" + webidl-conversions "^8.0.1" + whatwg-mimetype "^5.0.0" + whatwg-url "^16.0.0" + xml-name-validator "^5.0.0" + jsdom@^9.12.0: version "9.12.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4" @@ -13785,6 +13761,11 @@ mri@^1.2.0: resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== +mrmime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.1.tgz#bc3e87f7987853a54c9850eeb1f1078cd44adddc" + integrity sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -14334,7 +14315,7 @@ object.getownpropertydescriptors@^2.1.8: gopd "^1.2.0" safe-array-concat "^1.1.3" -object.groupby@^1.0.1, object.groupby@^1.0.3: +object.groupby@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== @@ -14358,7 +14339,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.1, object.values@^1.1.2, object.values@^1.1.5, object.values@^1.1.6, object.values@^1.1.7, object.values@^1.2.1: +object.values@^1.1.1, object.values@^1.1.2, object.values@^1.1.5, object.values@^1.1.6, object.values@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.1.tgz#deed520a50809ff7f75a7cfd4bc64c7a038c6216" integrity sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA== @@ -14955,7 +14936,7 @@ picocolors@^0.2.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== -picocolors@^1.1.0, picocolors@^1.1.1: +picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -16372,13 +16353,6 @@ rimraf@2.7.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: dependencies: glob "^7.1.3" -rimraf@3.0.2, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - rimraf@6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.0.1.tgz#ffb8ad8844dd60332ab15f52bc104bc3ed71ea4e" @@ -16387,6 +16361,13 @@ rimraf@6.0.1: glob "^11.0.0" package-json-from-dist "^1.0.0" +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + rimraf@^6.0.0, rimraf@^6.1.2: version "6.1.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.1.3.tgz#afbee236b3bd2be331d4e7ce4493bac1718981af" @@ -16587,14 +16568,18 @@ scratch-render-fonts@1.0.252: dependencies: base64-loader "^1.0.0" -scratch-sb1-converter@1.0.324: - version "1.0.324" - resolved "https://registry.yarnpkg.com/scratch-sb1-converter/-/scratch-sb1-converter-1.0.324.tgz#0b799842584fa5e160bf4ce1d059e51f4a4d2e0c" - integrity sha512-ZHIf2KCmYKchayLQFknni7QfXhOCI+w4Wq1wIQuN5D6xZwUyIe51/B4YO+pofOGr3tz4nnwQIjgs3AowdNKWDQ== +scratch-svg-renderer@3.1.19: + version "3.1.19" + resolved "https://registry.yarnpkg.com/scratch-svg-renderer/-/scratch-svg-renderer-3.1.19.tgz#c9259bd72560f6c8d29220a19dd82c26d624bec7" + integrity sha512-No4QMjxMb78LDfrOY+j22pMT94ypP0dGGAX9D2RDAhqx+l1uDlp4a5m5TmZJp/8lZ81bchejQhK1n4lOmfbI0A== dependencies: - js-md5 "^0.7.3" + base64-js "^1.2.1" + base64-loader "^1.0.0" + css-tree "^1.1.3" + fastestsmallesttextencoderdecoder "^1.0.22" + isomorphic-dompurify "^2.4.0" minilog "^3.1.0" - text-encoding "^0.7.0" + transformation-matrix "^1.15.0" scratch-translate-extension-languages@1.0.7: version "1.0.7" @@ -16905,6 +16890,15 @@ sigstore@^4.0.0: "@sigstore/tuf" "^4.0.1" "@sigstore/verify" "^3.1.0" +sirv@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-3.0.2.tgz#f775fccf10e22a40832684848d636346f41cd970" + integrity sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g== + dependencies: + "@polka/url" "^1.0.0-next.24" + mrmime "^2.0.0" + totalist "^3.0.0" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -17805,7 +17799,7 @@ test-exclude@^7.0.1: glob "^10.4.1" minimatch "^10.2.2" -text-encoding@^0.7.0: +text-encoding@0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.7.0.tgz#f895e836e45990624086601798ea98e8f36ee643" integrity sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA== @@ -17975,6 +17969,11 @@ toidentifier@1.0.1, toidentifier@~1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +totalist@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" + integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== + tough-cookie@^2.3.2, tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -18023,10 +18022,10 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -transformation-matrix@^2.16.1: - version "2.16.1" - resolved "https://registry.yarnpkg.com/transformation-matrix/-/transformation-matrix-2.16.1.tgz#4a2de06331b94ae953193d1b9a5ba002ec5f658a" - integrity sha512-tdtC3wxVEuzU7X/ydL131Q3JU5cPMEn37oqVLITjRDSDsnSHVFzW2JiCLfZLIQEgWzZHdSy3J6bZzvKEN24jGA== +transformation-matrix@^1.15.0: + version "1.15.3" + resolved "https://registry.yarnpkg.com/transformation-matrix/-/transformation-matrix-1.15.3.tgz#f47e42f7fbfe6869f2b662fb1518af08b36f360c" + integrity sha512-ThJH58GNFKhCw3gIoOtwf3tNwuYjbyEeiGdeq4mNMYWdJctnI896KUqn6PVt7jmNVepqa1bcKQtnMB1HtjsDMA== travis-after-all@1.4.5: version "1.4.5" @@ -18334,11 +18333,6 @@ unbox-primitive@^1.1.0: has-symbols "^1.1.0" which-boxed-primitive "^1.1.1" -undici-types@^7.21.0: - version "7.22.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.22.0.tgz#f1f394e65ae60c18b4d4a7681fec11361d2e5ae5" - integrity sha512-RKZvifiL60xdsIuC80UY0dq8Z7DbJUV8/l2hOVbyZAxBzEeQU4Z58+4ZzJ6WN2Lidi9KzT5EbiGX+PI/UGYuRw== - undici-types@~7.18.0: version "7.18.2" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.18.2.tgz#29357a89e7b7ca4aef3bf0fd3fd0cd73884229e9" @@ -18706,6 +18700,23 @@ webidl-conversions@^8.0.1: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-8.0.1.tgz#0657e571fe6f06fcb15ca50ed1fdbcb495cd1686" integrity sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ== +webpack-bundle-analyzer@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.2.0.tgz#9bcf0e7cc8c86632a96bf7092300287dc284c3d7" + integrity sha512-Etrauj1wYO/xjiz/Vfd6bW1lG9fEhrJpNmu10tv0X9kv+gyY3qiE09uYepqg1Xd0PxOvllRXwWYWjtQYoO/glQ== + 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" + html-escaper "^2.0.2" + opener "^1.5.2" + picocolors "^1.0.0" + sirv "^3.0.2" + ws "^8.19.0" + webpack-cli@6.0.1, webpack-cli@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-6.0.1.tgz#a1ce25da5ba077151afd73adfa12e208e5089207" @@ -18737,7 +18748,7 @@ webpack-dev-middleware@^7.4.2: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@5.2.3, webpack-dev-server@^5.2.3: +webpack-dev-server@^5.2.3: version "5.2.3" resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz#7f36a78be7ac88833fd87757edee31469a9e47d3" integrity sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ== @@ -19123,7 +19134,7 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== -ws@^8.18.0: +ws@^8.18.0, ws@^8.19.0: version "8.19.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.19.0.tgz#ddc2bdfa5b9ad860204f5a72a4863a8895fd8c8b" integrity sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg== From 25b67d883407af6153a17203f907c96cf87f9824 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Sun, 8 Mar 2026 16:50:56 +0800 Subject: [PATCH 02/29] :sparkles: feat(gui): load clipcc-block lazily Signed-off-by: SimonShiki --- packages/gui/.babelrc | 5 +-- packages/gui/.browserslistrc | 9 ++-- packages/gui/package.json | 7 +--- packages/gui/src/components/loader/loader.css | 12 ++++++ .../src/components/loader/scoped-loader.tsx | 42 +++++++++++++++++++ packages/gui/src/containers/blocks.jsx | 6 ++- .../gui/src/containers/custom-procedures.jsx | 11 +++-- .../gui/src/lib/backpack/block-to-image.js | 5 ++- packages/gui/src/lib/blocks-loader-hoc.tsx | 33 +++++++++++++++ packages/gui/src/lib/blocks-loader.ts | 21 ++++++++++ packages/gui/src/lib/blocks.js | 6 +-- packages/gui/src/lib/make-toolbox.js | 34 +++++++++++---- packages/gui/src/types.d.ts | 19 +++++++++ packages/gui/tsconfig.json | 2 +- packages/gui/webpack.config.js | 12 +++--- 15 files changed, 186 insertions(+), 38 deletions(-) create mode 100644 packages/gui/src/components/loader/scoped-loader.tsx create mode 100644 packages/gui/src/lib/blocks-loader-hoc.tsx create mode 100644 packages/gui/src/lib/blocks-loader.ts create mode 100644 packages/gui/src/types.d.ts diff --git a/packages/gui/.babelrc b/packages/gui/.babelrc index aeea6e789..7ff8a6fc4 100644 --- a/packages/gui/.babelrc +++ b/packages/gui/.babelrc @@ -1,13 +1,10 @@ { "plugins": [ - "@babel/plugin-syntax-dynamic-import", - "@babel/plugin-transform-async-to-generator", - "@babel/plugin-proposal-object-rest-spread", ["react-intl", { "messagesDir": "./translations/messages/" }]], "presets": [ - ["@babel/preset-env", {"targets": {"browsers": ["last 3 versions", "Safari >= 8", "iOS >= 8"]}}], + "@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript" ] diff --git a/packages/gui/.browserslistrc b/packages/gui/.browserslistrc index 909debc2d..d0449ca2b 100644 --- a/packages/gui/.browserslistrc +++ b/packages/gui/.browserslistrc @@ -1,3 +1,6 @@ -last 3 versions -Safari >= 8 -iOS >= 8 +Chrome >= 63 +Edge >= 15 +Firefox >= 57 +Safari >= 11 +Android >= 63 +iOS >= 11 diff --git a/packages/gui/package.json b/packages/gui/package.json index 28477560f..da739b591 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -37,7 +37,6 @@ "clipcc-paint": "3.2.0", "clipcc-render": "3.2.0", "clipcc-storage": "3.2.0", - "scratch-svg-renderer": "3.1.19", "clipcc-vm": "3.2.0", "computed-style-to-inline-style": "3.0.0", "copy-webpack-plugin": "^14.0.0", @@ -78,6 +77,7 @@ "redux": "3.7.2", "redux-throttle": "0.1.1", "scratch-render-fonts": "1.0.252", + "scratch-svg-renderer": "3.1.19", "startaudiocontext": "1.2.1", "style-loader": "^4.0.0", "to-style": "1.3.3", @@ -92,13 +92,11 @@ "@babel/cli": "7.28.6", "@babel/core": "7.29.0", "@babel/eslint-parser": "7.28.6", - "@babel/plugin-proposal-object-rest-spread": "7.14.7", - "@babel/plugin-syntax-dynamic-import": "7.2.0", - "@babel/plugin-transform-async-to-generator": "7.14.5", "@babel/preset-env": "7.29.0", "@babel/preset-react": "7.14.5", "@babel/preset-typescript": "^7.24.7", "@eslint/js": "^9.39.2", + "@types/react": "^16.1.0", "babel-core": "7.0.0-bridge.0", "babel-eslint": "10.0.3", "babel-jest": "23.6.0", @@ -127,7 +125,6 @@ "ts-loader": "^9.5.4", "typescript": "^5.9.3", "webpack": "^5.105.4", - "webpack-bundle-analyzer": "^5.2.0", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3", "yauzl": "2.10.0" diff --git a/packages/gui/src/components/loader/loader.css b/packages/gui/src/components/loader/loader.css index 8a6e47bc1..247348f6a 100644 --- a/packages/gui/src/components/loader/loader.css +++ b/packages/gui/src/components/loader/loader.css @@ -14,6 +14,18 @@ color: white; } + +.scoped-loader { + z-index: var(--clipcc-z-index-stage-wrapper-overlay); + border-radius: 0.5rem; +} + +.scoped-loader .title { + font-size: 1.5rem; + margin: 0; +} + + .fullscreen { /* Break out of the layout using position: fixed to cover the whole screen */ position: fixed; diff --git a/packages/gui/src/components/loader/scoped-loader.tsx b/packages/gui/src/components/loader/scoped-loader.tsx new file mode 100644 index 000000000..2ea645729 --- /dev/null +++ b/packages/gui/src/components/loader/scoped-loader.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import classNames from 'classnames'; +import styles from './loader.css'; + +import topBlock from './top-block.svg'; +import middleBlock from './middle-block.svg'; +import bottomBlock from './bottom-block.svg'; + +export interface ScopedLoaderProps { + /** The text to display while loading */ + text?: string; +} + +export default function ScopedLoaderComponent (props: ScopedLoaderProps) { + return ( +
+
+
+ + + +
+ {props.text ? ( +
+ {props.text} +
+ ) : null} +
+
+ ); +} diff --git a/packages/gui/src/containers/blocks.jsx b/packages/gui/src/containers/blocks.jsx index ca4f1ce56..1b527fa66 100644 --- a/packages/gui/src/containers/blocks.jsx +++ b/packages/gui/src/containers/blocks.jsx @@ -4,6 +4,7 @@ import defaultsDeep from 'lodash.defaultsdeep'; import makeToolbox from '../lib/make-toolbox'; import PropTypes from 'prop-types'; import React from 'react'; +import {injectBlock} from '../lib/blocks-loader-hoc.tsx'; import VMScratchBlocks from '../lib/blocks'; import VM from 'clipcc-vm'; @@ -51,7 +52,7 @@ const DroppableBlocks = DropAreaHOC([ class Blocks extends React.Component { constructor (props) { super(props); - this.ScratchBlocks = VMScratchBlocks(props.vm); + this.ScratchBlocks = VMScratchBlocks(props.vm, props.blocks); bindAll(this, [ 'attachVM', 'checkoutWsByProccode', @@ -660,6 +661,7 @@ class Blocks extends React.Component { Blocks.propTypes = { anyModalVisible: PropTypes.bool, + blocks: PropTypes.object, // eslint-disable-line react/forbid-prop-types hideNonVanillaBlocks: PropTypes.bool.isRequired, canUseCloud: PropTypes.bool, customProceduresVisible: PropTypes.bool, @@ -776,5 +778,5 @@ export default errorBoundaryHOC('Blocks')( connect( mapStateToProps, mapDispatchToProps - )(Blocks) + )(injectBlock(Blocks)) ); diff --git a/packages/gui/src/containers/custom-procedures.jsx b/packages/gui/src/containers/custom-procedures.jsx index 58ec5ae8f..c4e3134e5 100644 --- a/packages/gui/src/containers/custom-procedures.jsx +++ b/packages/gui/src/containers/custom-procedures.jsx @@ -3,8 +3,8 @@ import defaultsDeep from 'lodash.defaultsdeep'; import PropTypes from 'prop-types'; import React from 'react'; import CustomProceduresComponent from '../components/custom-procedures/custom-procedures.jsx'; -import * as ScratchBlocks from 'clipcc-block'; import {connect} from 'react-redux'; +import {injectBlock} from '../lib/blocks-loader-hoc.tsx'; class CustomProcedures extends React.Component { constructor (props) { @@ -28,6 +28,7 @@ class CustomProcedures extends React.Component { }; } componentWillUnmount () { + const {blocks: ScratchBlocks} = this.props; if (this.workspace) { if (ScratchBlocks.getFocusManager().getFocusedNode()) { // Focus the workspace before destroying the workspace to avoid focusing @@ -47,6 +48,7 @@ class CustomProcedures extends React.Component { {rtl: this.props.isRtl} ); + const {blocks: ScratchBlocks} = this.props; this.workspace = ScratchBlocks.inject(this.blocks, workspaceConfig); // Create the procedure declaration block for editing the mutation. @@ -184,6 +186,8 @@ class CustomProcedures extends React.Component { } CustomProcedures.propTypes = { + // eslint-disable-next-line react/forbid-prop-types + blocks: PropTypes.object, isRtl: PropTypes.bool, mutator: PropTypes.shape({ proccode: PropTypes.string, @@ -208,6 +212,7 @@ CustomProcedures.propTypes = { }) }; +/** @import * as ScratchBlocks from 'clipcc-block' */ /** @type {ScratchBlocks.BlocklyOptions} */ CustomProcedures.defaultOptions = { zoom: { @@ -232,6 +237,6 @@ const mapStateToProps = state => ({ new: state.scratchGui.customProcedures.new }); -export default connect( +export default injectBlock(connect( mapStateToProps -)(CustomProcedures); +)(CustomProcedures)); diff --git a/packages/gui/src/lib/backpack/block-to-image.js b/packages/gui/src/lib/backpack/block-to-image.js index 64e1704b9..366b225b9 100644 --- a/packages/gui/src/lib/backpack/block-to-image.js +++ b/packages/gui/src/lib/backpack/block-to-image.js @@ -1,12 +1,13 @@ import computedStyleToInlineStyle from 'computed-style-to-inline-style'; -import * as ScratchBlocks from 'clipcc-block'; +import {getScratchBlocks} from '../blocks-loader'; /** * Given a blockId, return a data-uri image that can be used to create a thumbnail. * @param {string} blockId the ID of the block to imagify * @returns {Promise} resolves to a data-url of a picture of the blocks */ -export default function (blockId) { +export default async function (blockId) { + const ScratchBlocks = await getScratchBlocks(); // Not sure any better way to access the scratch-blocks workspace than this... const block = ScratchBlocks.common.getMainWorkspace().getBlockById(blockId); const blockSvg = block.getSvgRoot().cloneNode(true /* deep */); diff --git a/packages/gui/src/lib/blocks-loader-hoc.tsx b/packages/gui/src/lib/blocks-loader-hoc.tsx new file mode 100644 index 000000000..430b040f9 --- /dev/null +++ b/packages/gui/src/lib/blocks-loader-hoc.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import {getScratchBlocks} from './blocks-loader'; +import ScopedLoaderComponent from '../components/loader/scoped-loader'; + +interface BlockLoaderProps { + blocks: typeof import('clipcc-block'); +} + +export function injectBlock> (WrappedComponent: Component) { + class BlockLoaderHOC extends React.Component { + state = { + loaded: false + }; + blocks: typeof import('clipcc-block') | null = null; + + override async componentDidMount () { + if (!this.state.loaded) { + this.blocks = await getScratchBlocks(); + this.setState({loaded: true}); + } + } + + override render () { + if (!this.state.loaded) { + return ; + } + + return ; + } + } + + return BlockLoaderHOC; +} diff --git a/packages/gui/src/lib/blocks-loader.ts b/packages/gui/src/lib/blocks-loader.ts new file mode 100644 index 000000000..9cbb90786 --- /dev/null +++ b/packages/gui/src/lib/blocks-loader.ts @@ -0,0 +1,21 @@ +let ScratchBlocksModule: typeof import('clipcc-block') | null = null; + +/** + * Check if the ScratchBlocks module is loaded. + * @returns True if the ScratchBlocks module is loaded, false otherwise. + */ +export function isScratchBlocksLoaded () { + return !!ScratchBlocksModule; +} + +/** + * Get the ScratchBlocks module, which is loaded asynchronously to reduce the initial bundle size. + * @returns A promise that resolves to the ScratchBlocks module. + */ +export async function getScratchBlocks () { + if (!ScratchBlocksModule) { + // eslint-disable-next-line require-atomic-updates + ScratchBlocksModule = await import(/* webpackChunkName: "clipcc-block" */'clipcc-block'); + } + return ScratchBlocksModule; +} diff --git a/packages/gui/src/lib/blocks.js b/packages/gui/src/lib/blocks.js index bc7f8f56e..12ddbf08e 100644 --- a/packages/gui/src/lib/blocks.js +++ b/packages/gui/src/lib/blocks.js @@ -1,15 +1,15 @@ -import * as ScratchBlocks from 'clipcc-block'; - /** * @typedef {import('clipcc-vm')} VirtualMachine + * @import * as ScratchBlocks from 'clipcc-block' */ /** * Connect scratch blocks with the vm * @param {VirtualMachine} vm - The scratch vm + * @param {ScratchBlocks} ScratchBlocks - The scratch blocks to connect * @returns {ScratchBlocks} ScratchBlocks connected with the vm */ -export default function (vm) { +export default function (vm, ScratchBlocks) { const jsonForMenuBlock = function (name, menuOptionsFn, category, start) { return { diff --git a/packages/gui/src/lib/make-toolbox.js b/packages/gui/src/lib/make-toolbox.js index 721edfae3..26d4ef2fe 100644 --- a/packages/gui/src/lib/make-toolbox.js +++ b/packages/gui/src/lib/make-toolbox.js @@ -1,6 +1,6 @@ /* eslint-disable no-unused-vars */ -import * as ScratchBlocks from 'clipcc-block'; +import {getScratchBlocks, isScratchBlocksLoaded} from './blocks-loader'; const blockSeparator = { kind: 'sep', @@ -29,8 +29,23 @@ const createShadow = (type, fields) => { }; }; +/** + * Translate a message ID into a message, using the ScratchBlocks message system if possible. + * @param {string} id - The message ID to translate + * @param {string} defaultMessage - The default message to use if the ScratchBlocks isn't available + * @returns {string} The translated message, or the default message if the ScratchBlocks isn't available + * or missing that message. + */ +const translate = (id, defaultMessage) => { + if (!isScratchBlocksLoaded()) { + return defaultMessage; + } + const ScratchBlocks = getScratchBlocks(); + return ScratchBlocks.Msg[id] ?? defaultMessage; +}; + const motion = (isInitialSetup, isStage, targetId) => { - const stageSelected = ScratchBlocks.Msg.MOTION_STAGE_SELECTED; + const stageSelected = translate('MOTION_STAGE_SELECTED', 'Stage selected: no motion blocks'); const motionContents = []; if (isStage) { @@ -158,8 +173,8 @@ const motion = (isInitialSetup, isStage, targetId) => { }; const looks = (isInitialSetup, isStage, targetId, costumeName, backdropName) => { - const hello = ScratchBlocks.Msg.LOOKS_HELLO; - const hmm = ScratchBlocks.Msg.LOOKS_HMM; + const hello = translate('LOOKS_HELLO', 'Hello!'); + const hmm = translate('LOOKS_HMM', 'Hmm...'); const looksContents = []; @@ -474,7 +489,7 @@ const control = (isInitialSetup, isStage, targetId) => { }; const sensing = (isInitialSetup, isStage, targetId, hideNonVanillaBlocks) => { - const name = ScratchBlocks.Msg.SENSING_ASK_TEXT; + const name = translate('SENSING_ASK_TEXT', `What's your name?`); const sensingContents = []; @@ -646,9 +661,9 @@ const sensing = (isInitialSetup, isStage, targetId, hideNonVanillaBlocks) => { }; const operators = (isInitialSetup, isStage, targetId, hideNonVanillaBlocks) => { - const apple = ScratchBlocks.Msg.OPERATORS_JOIN_APPLE; - const banana = ScratchBlocks.Msg.OPERATORS_JOIN_BANANA; - const letter = ScratchBlocks.Msg.OPERATORS_LETTEROF_APPLE; + const apple = translate('OPERATORS_JOIN_APPLE', 'apple'); + const banana = translate('OPERATORS_JOIN_BANANA', 'banana'); + const letter = translate('OPERATORS_LETTEROF_APPLE', 'a'); const operatorsContents = [ { @@ -980,7 +995,8 @@ const makeToolbox = function ( // Convert xml toolbox to json. for (const category of categories) { - if (category.json || !category.xml) continue; + if (category.json || !category.xml || !isScratchBlocksLoaded() ) continue; + const ScratchBlocks = getScratchBlocks(); const toolbox = ScratchBlocks.utils.toolbox.convertToolboxDefToJson( `${category.xml}` ); diff --git a/packages/gui/src/types.d.ts b/packages/gui/src/types.d.ts new file mode 100644 index 000000000..4acf4a910 --- /dev/null +++ b/packages/gui/src/types.d.ts @@ -0,0 +1,19 @@ +declare module '!!arraybuffer-loader!.*' { + declare const value: ArrayBuffer; + export default value; +} + +declare module '*?raw' { + declare const value: string; + export default value; +} + +declare module '*.svg' { + declare const value: string; + export default value; +} + +declare module '*.css' { + declare const value: { [className: string]: string }; + export default value; +} diff --git a/packages/gui/tsconfig.json b/packages/gui/tsconfig.json index 4696e5751..cf61b4da5 100644 --- a/packages/gui/tsconfig.json +++ b/packages/gui/tsconfig.json @@ -17,7 +17,7 @@ /* Language and Environment */ "target": "ES2018", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ + "jsx": "react", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index a434ab042..7441bb953 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -8,7 +8,6 @@ const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); -const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); const STATIC_PATH = process.env.STATIC_PATH || '/static'; @@ -70,9 +69,6 @@ const base = { // in much lower dependencies. babelrc: false, plugins: [ - '@babel/plugin-syntax-dynamic-import', - '@babel/plugin-transform-async-to-generator', - '@babel/plugin-proposal-object-rest-spread', ['react-intl', { messagesDir: './translations/messages/' }]], @@ -196,7 +192,12 @@ module.exports = [ }, optimization: { splitChunks: { + name: 'lib.min', chunks: 'all', + minChunks: 2, + maxInitialRequests: 5 + }, + runtimeChunk: { name: 'lib.min' } }, @@ -260,8 +261,7 @@ module.exports = [ context: '../vm/dist/web' } ] - }), - new BundleAnalyzerPlugin() + }) ]) }) ].concat( From 9e6d7ad4b25d177fd951935271e5b4180c341868 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Sun, 8 Mar 2026 17:23:32 +0800 Subject: [PATCH 03/29] :bug: fix(gui): split block chunk Signed-off-by: SimonShiki --- packages/gui/src/lib/blocks-loader.ts | 5 ++++- packages/gui/webpack.config.js | 22 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/gui/src/lib/blocks-loader.ts b/packages/gui/src/lib/blocks-loader.ts index 9cbb90786..fa40eb070 100644 --- a/packages/gui/src/lib/blocks-loader.ts +++ b/packages/gui/src/lib/blocks-loader.ts @@ -15,7 +15,10 @@ export function isScratchBlocksLoaded () { export async function getScratchBlocks () { if (!ScratchBlocksModule) { // eslint-disable-next-line require-atomic-updates - ScratchBlocksModule = await import(/* webpackChunkName: "clipcc-block" */'clipcc-block'); + ScratchBlocksModule = await import( + /* webpackChunkName: "clipcc-block" */ + 'clipcc-block' + ); } return ScratchBlocksModule; } diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index 7441bb953..9a61e5a44 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -51,7 +51,10 @@ const base = { loader: 'ts-loader', options: { transpileOnly: true, - allowTsInNodeModules: true + allowTsInNodeModules: true, + compilerOptions: { + module: 'preserve' + } } }, { @@ -192,10 +195,21 @@ module.exports = [ }, optimization: { splitChunks: { - name: 'lib.min', - chunks: 'all', + chunks: 'async', minChunks: 2, - maxInitialRequests: 5 + maxInitialRequests: 5, + cacheGroups: { + default: false, + defaultVendors: false, + lib: { + test: /[\\/]node_modules[\\/]/, + name: 'lib.min', + chunks: 'initial', + priority: 10, + reuseExistingChunk: true, + enforce: true + } + } }, runtimeChunk: { name: 'lib.min' From 02d4a42e66871294363cc16952f9722603e62fea Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Sun, 8 Mar 2026 17:23:43 +0800 Subject: [PATCH 04/29] :wrench: chore: remove outdated polyfills Signed-off-by: SimonShiki --- packages/l10n/.babelrc | 16 +++- packages/l10n/package.json | 3 - packages/l10n/webpack.config.js | 7 +- packages/paint/.babelrc | 1 - packages/paint/package.json | 1 - packages/paint/webpack.config.js | 1 - packages/storage/package.json | 1 - yarn.lock | 158 ++++--------------------------- 8 files changed, 34 insertions(+), 154 deletions(-) diff --git a/packages/l10n/.babelrc b/packages/l10n/.babelrc index 3ddfd2a4c..48765250a 100644 --- a/packages/l10n/.babelrc +++ b/packages/l10n/.babelrc @@ -1,9 +1,17 @@ { - "plugins": [ - "@babel/plugin-proposal-object-rest-spread" - ], "presets": [ - ["@babel/preset-env", {"targets": {"browsers": ["last 3 versions", "Safari >= 8", "iOS >= 8"]}}], + ["@babel/preset-env", { + "targets": { + "browsers": [ + "Chrome >= 63", + "Edge >= 15", + "Firefox >= 57", + "Safari >= 11", + "Android >= 63", + "iOS >= 8" + ] + } + }], "@babel/preset-react" ] } diff --git a/packages/l10n/package.json b/packages/l10n/package.json index 33b886a4e..52999aa6e 100644 --- a/packages/l10n/package.json +++ b/packages/l10n/package.json @@ -30,9 +30,6 @@ "devDependencies": { "@babel/eslint-parser": "7.28.6", "@babel/node": "7.2.2", - "@babel/plugin-proposal-object-rest-spread": "^7.0.0", - "@babel/plugin-syntax-dynamic-import": "^7.0.0", - "@babel/plugin-transform-async-to-generator": "^7.1.0", "@babel/preset-env": "^7.9.5", "@babel/preset-react": "^7.0.0", "async": "3.2.3", diff --git a/packages/l10n/webpack.config.js b/packages/l10n/webpack.config.js index 878b83d70..675e83807 100644 --- a/packages/l10n/webpack.config.js +++ b/packages/l10n/webpack.config.js @@ -10,12 +10,7 @@ module.exports = { use: { loader: 'babel-loader', options: { - presets: ['@babel/preset-env'], - plugins: [ - '@babel/plugin-proposal-object-rest-spread', - '@babel/plugin-syntax-dynamic-import', - '@babel/plugin-transform-async-to-generator' - ] + presets: ['@babel/preset-env'] } } }] diff --git a/packages/paint/.babelrc b/packages/paint/.babelrc index 00bc561f1..0890ca983 100644 --- a/packages/paint/.babelrc +++ b/packages/paint/.babelrc @@ -1,6 +1,5 @@ { "plugins": [ - "@babel/plugin-proposal-object-rest-spread", ["react-intl", { "messagesDir": "./translations/messages/" }] diff --git a/packages/paint/package.json b/packages/paint/package.json index a0bb158ad..4709f081a 100644 --- a/packages/paint/package.json +++ b/packages/paint/package.json @@ -50,7 +50,6 @@ "@babel/eslint-parser": "7.28.6", "@babel/preset-env": "7.29.0", "@babel/preset-react": "^7.14.5", - "@babel/plugin-proposal-object-rest-spread": "7.14.7", "autoprefixer": "9.7.4", "babel-core": "7.0.0-bridge.0", "babel-eslint": "10.1.0", diff --git a/packages/paint/webpack.config.js b/packages/paint/webpack.config.js index 62987fca8..6c8b32eb2 100644 --- a/packages/paint/webpack.config.js +++ b/packages/paint/webpack.config.js @@ -14,7 +14,6 @@ const base = { loader: 'babel-loader', include: path.resolve(__dirname, 'src'), options: { - plugins: ['@babel/plugin-proposal-object-rest-spread'], presets: ['@babel/preset-env', '@babel/preset-react'] } }, diff --git a/packages/storage/package.json b/packages/storage/package.json index e6bda140b..f928178ff 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -36,7 +36,6 @@ }, "devDependencies": { "@babel/core": "7.29.0", - "@babel/plugin-transform-runtime": "7.29.0", "@babel/polyfill": "7.12.1", "@babel/preset-env": "7.29.0", "@types/jest": "29.5.14", diff --git a/yarn.lock b/yarn.lock index 748ba0b12..41c2fc162 100644 --- a/yarn.lock +++ b/yarn.lock @@ -78,7 +78,7 @@ js-tokens "^4.0.0" picocolors "^1.1.1" -"@babel/compat-data@^7.14.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.28.6", "@babel/compat-data@^7.29.0": +"@babel/compat-data@^7.28.6", "@babel/compat-data@^7.29.0": version "7.29.0" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d" integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg== @@ -131,7 +131,7 @@ dependencies: "@babel/types" "^7.27.3" -"@babel/helper-compilation-targets@^7.14.5", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.28.6": +"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.28.6": version "7.28.6" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz#32c4a3f41f12ed1532179b108a4d746e105c2b25" integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA== @@ -164,7 +164,7 @@ regexpu-core "^6.3.1" semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.6.5", "@babel/helper-define-polyfill-provider@^0.6.6": +"@babel/helper-define-polyfill-provider@^0.6.6": version "0.6.6" resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz#714dfe33d8bd710f556df59953720f6eeb6c1a14" integrity sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA== @@ -188,7 +188,7 @@ "@babel/traverse" "^7.28.5" "@babel/types" "^7.28.5" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.14.5", "@babel/helper-module-imports@^7.28.6": +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.28.6": version "7.28.6" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c" integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== @@ -212,12 +212,12 @@ dependencies: "@babel/types" "^7.27.1" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.28.6", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.28.6", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.28.6" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8" integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== -"@babel/helper-remap-async-to-generator@^7.14.5", "@babel/helper-remap-async-to-generator@^7.27.1": +"@babel/helper-remap-async-to-generator@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6" integrity sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA== @@ -332,28 +332,6 @@ "@babel/helper-plugin-utils" "^7.28.6" "@babel/traverse" "^7.28.6" -"@babel/plugin-proposal-object-rest-spread@7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363" - integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g== - dependencies: - "@babel/compat-data" "^7.14.7" - "@babel/helper-compilation-targets" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.14.5" - -"@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" - integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== - dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.7" - "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": version "7.21.0-placeholder-for-preset-env.2" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" @@ -387,20 +365,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-dynamic-import@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" - integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-dynamic-import@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - "@babel/plugin-syntax-import-assertions@^7.28.6": version "7.28.6" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz#ae9bc1923a6ba527b70104dd2191b0cd872c8507" @@ -523,16 +487,7 @@ "@babel/helper-remap-async-to-generator" "^7.27.1" "@babel/traverse" "^7.29.0" -"@babel/plugin-transform-async-to-generator@7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz#72c789084d8f2094acb945633943ef8443d39e67" - integrity sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA== - dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.14.5" - -"@babel/plugin-transform-async-to-generator@^7.1.0", "@babel/plugin-transform-async-to-generator@^7.28.6": +"@babel/plugin-transform-async-to-generator@^7.28.6": version "7.28.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz#bd97b42237b2d1bc90d74bcb486c39be5b4d7e77" integrity sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g== @@ -793,7 +748,7 @@ "@babel/helper-plugin-utils" "^7.28.6" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-parameters@^7.14.5", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.27.7": +"@babel/plugin-transform-parameters@^7.27.7": version "7.27.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a" integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg== @@ -879,18 +834,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-runtime@7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz#a5fded13cc656700804bfd6e5ebd7fffd5266803" - integrity sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w== - dependencies: - "@babel/helper-module-imports" "^7.28.6" - "@babel/helper-plugin-utils" "^7.28.6" - 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" - "@babel/plugin-transform-shorthand-properties@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz#532abdacdec87bfee1e0ef8e2fcdee543fe32b90" @@ -1592,11 +1535,6 @@ resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz#798a33950d11226a0ebb6acafa60f5594424967f" integrity sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA== -"@discoveryjs/json-ext@0.5.7": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" - integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== - "@discoveryjs/json-ext@^0.6.1": version "0.6.3" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz#f13c7c205915eb91ae54c557f5e92bddd8be0e83" @@ -2892,11 +2830,6 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== -"@polka/url@^1.0.0-next.24": - version "1.0.0-next.29" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.29.tgz#5a40109a1ab5f84d6fd8fc928b19f367cbe7e7b1" - integrity sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww== - "@rtsao/scc@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" @@ -3856,6 +3789,11 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== +"@types/react@^16.1.0": + version "16.1.0" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.1.0.tgz#6c0e9955ce73f332b4a1948d45decaf18c764c6e" + integrity sha512-gXrB20mWBLrYGtkdf5fA6wL3FEXpY2Nz8OOgVn1qonp66JE4mqFXUigKD8CVDofQu+EsSy8G4UFRJAshFWMOvA== + "@types/retry@0.12.2": version "0.12.2" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a" @@ -4583,7 +4521,7 @@ acorn-walk@^6.0.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== -acorn-walk@^8.0.0, acorn-walk@^8.1.1: +acorn-walk@^8.1.1: version "8.3.5" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.5.tgz#8a6b8ca8fc5b34685af15dabb44118663c296496" integrity sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw== @@ -4615,7 +4553,7 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.4, acorn@^8.11.0, acorn@^8.15.0, acorn@^8.16.0, acorn@^8.4.1: +acorn@^8.11.0, acorn@^8.15.0, acorn@^8.16.0, acorn@^8.4.1: version "8.16.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a" integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== @@ -5448,7 +5386,7 @@ babel-plugin-jest-hoist@^29.6.3: "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" -babel-plugin-polyfill-corejs2@^0.4.14, babel-plugin-polyfill-corejs2@^0.4.15: +babel-plugin-polyfill-corejs2@^0.4.15: version "0.4.15" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz#808fa349686eea4741807cfaaa2aa3aa57ce120a" integrity sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw== @@ -5457,14 +5395,6 @@ babel-plugin-polyfill-corejs2@^0.4.14, babel-plugin-polyfill-corejs2@^0.4.15: "@babel/helper-define-polyfill-provider" "^0.6.6" semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz#bb7f6aeef7addff17f7602a08a6d19a128c30164" - integrity sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.5" - core-js-compat "^3.43.0" - babel-plugin-polyfill-corejs3@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.0.tgz#65b06cda48d6e447e1e926681f5a247c6ae2b9cf" @@ -5473,7 +5403,7 @@ babel-plugin-polyfill-corejs3@^0.14.0: "@babel/helper-define-polyfill-provider" "^0.6.6" core-js-compat "^3.48.0" -babel-plugin-polyfill-regenerator@^0.6.5, babel-plugin-polyfill-regenerator@^0.6.6: +babel-plugin-polyfill-regenerator@^0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz#69f5dd263cab933c42fe5ea05e83443b374bd4bf" integrity sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A== @@ -6583,11 +6513,6 @@ commander@^6.1.0, commander@^6.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== -commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - commander@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" @@ -6780,7 +6705,7 @@ copy-webpack-plugin@^14.0.0: serialize-javascript "^7.0.3" tinyglobby "^0.2.12" -core-js-compat@^3.43.0, core-js-compat@^3.48.0: +core-js-compat@^3.48.0: version "3.48.0" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.48.0.tgz#7efbe1fc1cbad44008190462217cc5558adaeaa6" integrity sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q== @@ -7173,11 +7098,6 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha512-AsElvov3LoNB7tf5k37H2jYSB+ZZPMT5sG2QjJCcdlV5chIv6htBUBUui2IKRjgtKAKtCBN7Zbwa+MtwLjSeNw== -debounce@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" - integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== - debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -9970,7 +9890,7 @@ html-entities@^2.6.0: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== -html-escaper@^2.0.0, html-escaper@^2.0.2: +html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== @@ -13761,11 +13681,6 @@ mri@^1.2.0: resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== -mrmime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.1.tgz#bc3e87f7987853a54c9850eeb1f1078cd44adddc" - integrity sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ== - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -14936,7 +14851,7 @@ picocolors@^0.2.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== -picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1: +picocolors@^1.1.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -16890,15 +16805,6 @@ sigstore@^4.0.0: "@sigstore/tuf" "^4.0.1" "@sigstore/verify" "^3.1.0" -sirv@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-3.0.2.tgz#f775fccf10e22a40832684848d636346f41cd970" - integrity sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g== - dependencies: - "@polka/url" "^1.0.0-next.24" - mrmime "^2.0.0" - totalist "^3.0.0" - sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -17969,11 +17875,6 @@ toidentifier@1.0.1, toidentifier@~1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -totalist@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" - integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== - tough-cookie@^2.3.2, tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -18700,23 +18601,6 @@ webidl-conversions@^8.0.1: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-8.0.1.tgz#0657e571fe6f06fcb15ca50ed1fdbcb495cd1686" integrity sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ== -webpack-bundle-analyzer@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.2.0.tgz#9bcf0e7cc8c86632a96bf7092300287dc284c3d7" - integrity sha512-Etrauj1wYO/xjiz/Vfd6bW1lG9fEhrJpNmu10tv0X9kv+gyY3qiE09uYepqg1Xd0PxOvllRXwWYWjtQYoO/glQ== - 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" - html-escaper "^2.0.2" - opener "^1.5.2" - picocolors "^1.0.0" - sirv "^3.0.2" - ws "^8.19.0" - webpack-cli@6.0.1, webpack-cli@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-6.0.1.tgz#a1ce25da5ba077151afd73adfa12e208e5089207" @@ -19134,7 +19018,7 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== -ws@^8.18.0, ws@^8.19.0: +ws@^8.18.0: version "8.19.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.19.0.tgz#ddc2bdfa5b9ad860204f5a72a4863a8895fd8c8b" integrity sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg== From 3211ae089a6636e44c0cdaebbabd2dea56a76138 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Sun, 8 Mar 2026 18:29:42 +0800 Subject: [PATCH 05/29] :wrench: chore: correct dependencies version Signed-off-by: SimonShiki --- packages/gui/package.json | 2 +- packages/render/package.json | 2 +- packages/vm/package.json | 6 +++--- yarn.lock | 16 ++++++++-------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/gui/package.json b/packages/gui/package.json index da739b591..07c968529 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -77,7 +77,7 @@ "redux": "3.7.2", "redux-throttle": "0.1.1", "scratch-render-fonts": "1.0.252", - "scratch-svg-renderer": "3.1.19", + "scratch-svg-renderer": "2.5.46", "startaudiocontext": "1.2.1", "style-loader": "^4.0.0", "to-style": "1.3.3", diff --git a/packages/render/package.json b/packages/render/package.json index b7456c0ad..fe84e030e 100644 --- a/packages/render/package.json +++ b/packages/render/package.json @@ -55,7 +55,7 @@ "dependencies": { "@turbowarp/nanolog": "^0.2.0", "clipcc-storage": "3.2.0", - "scratch-svg-renderer": "3.1.19", + "scratch-svg-renderer": "2.5.46", "grapheme-breaker": "0.3.2", "hull.js": "1.0.6", "ify-loader": "1.1.0", diff --git a/packages/vm/package.json b/packages/vm/package.json index 4ab50a772..54bdfbffd 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -45,11 +45,11 @@ "jszip": "^3.10.1", "@turbowarp/nanolog": "^1.0.1", "node-polyfill-webpack-plugin": "^3.0.0", - "clipcc-sb1-converter": "1.0.324", + "clipcc-sb1-converter": "1.0.325", "scratch-translate-extension-languages": "1.0.7" }, "peerDependencies": { - "scratch-svg-renderer": "3.1.19" + "scratch-svg-renderer": "2.5.46" }, "devDependencies": { "@babel/core": "7.29.0", @@ -65,7 +65,7 @@ "clipcc-l10n": "3.2.0", "clipcc-render": "3.2.0", "clipcc-storage": "3.2.0", - "scratch-svg-renderer": "3.1.19", + "scratch-svg-renderer": "2.5.46", "codingclip-worker-loader": "^3.0.10", "copy-webpack-plugin": "^14.0.0", "eslint": "^9.39.2", diff --git a/yarn.lock b/yarn.lock index 41c2fc162..ba1e7c775 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6364,10 +6364,10 @@ cli@~1.0.0: exit "0.1.2" glob "^7.1.1" -clipcc-sb1-converter@1.0.324: - version "1.0.324" - resolved "https://registry.yarnpkg.com/clipcc-sb1-converter/-/clipcc-sb1-converter-1.0.324.tgz#79a3a416ac40dabb631912bc6ff23826159f2dc0" - integrity sha512-cg8ZAjtQJngQzWD9DY3l0fG7U2+4pkgY4a1GxL1NKJA4t2vsvo4q4MtrmLr5Lmb1FNv+Pb6Ge2j/hk4tYQ3X2g== +clipcc-sb1-converter@1.0.325: + version "1.0.325" + resolved "https://registry.yarnpkg.com/clipcc-sb1-converter/-/clipcc-sb1-converter-1.0.325.tgz#165bf218fab2b09f31c1c230c954df59b5368fe5" + integrity sha512-fdiq48lVKp7MvKhBOGFGi2T9XmQW/bl7oLonpHK3Jk137niaJlbtd+/SFR0WY3zghOHry9u0CkuGpZCPVWkUZQ== dependencies: "@turbowarp/nanolog" "^1.0.1" fastestsmallesttextencoderdecoder "^1.0.22" @@ -16483,10 +16483,10 @@ scratch-render-fonts@1.0.252: dependencies: base64-loader "^1.0.0" -scratch-svg-renderer@3.1.19: - version "3.1.19" - resolved "https://registry.yarnpkg.com/scratch-svg-renderer/-/scratch-svg-renderer-3.1.19.tgz#c9259bd72560f6c8d29220a19dd82c26d624bec7" - integrity sha512-No4QMjxMb78LDfrOY+j22pMT94ypP0dGGAX9D2RDAhqx+l1uDlp4a5m5TmZJp/8lZ81bchejQhK1n4lOmfbI0A== +scratch-svg-renderer@2.5.46: + version "2.5.46" + resolved "https://registry.yarnpkg.com/scratch-svg-renderer/-/scratch-svg-renderer-2.5.46.tgz#47b6d9df4b04870a0f4b9337a289e4d20952f258" + integrity sha512-SrQgHZdqnu3DX6UuJNJPg/kpJTQT/mIVbQZvm5uTE/B47U5mSaVfgoGlNFhoNUWZlbHucqySyG4KMe+ThDUR/A== dependencies: base64-js "^1.2.1" base64-loader "^1.0.0" From acb3ab91a3b195a18b4c1b4f957348e1ec4db242 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Sun, 8 Mar 2026 19:44:41 +0800 Subject: [PATCH 06/29] :wrench: chore: replace scratch-render-fonts to our version Signed-off-by: SimonShiki --- packages/gui/package.json | 6 +- packages/gui/src/components/loader/loader.css | 2 +- .../src/containers/paint-editor-wrapper.jsx | 2 +- packages/gui/src/containers/stage.jsx | 2 +- packages/gui/src/lib/file-uploader.js | 4 +- packages/gui/src/lib/get-costume-url.js | 2 +- packages/gui/webpack.config.js | 6 + packages/paint/package.json | 4 +- packages/paint/src/playground/playground.jsx | 4 +- packages/render/package.json | 6 +- packages/render/src/SVGSkin.js | 2 +- .../render/test/integration/cpu-render.html | 2 +- packages/render/test/integration/index.html | 2 +- packages/render/webpack.config.js | 2 +- packages/vm/package.json | 8 +- packages/vm/src/import/load-costume.js | 2 +- packages/vm/src/playground/benchmark.js | 2 +- .../vm/test/fixtures/fake-bitmap-adapter.js | 2 +- yarn.lock | 126 ++++++++++++------ 19 files changed, 119 insertions(+), 67 deletions(-) diff --git a/packages/gui/package.json b/packages/gui/package.json index 07c968529..fd3bdd1b2 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -11,6 +11,7 @@ }, "main": "./dist/scratch-gui.js", "scripts": { + "analyze": "cross-env ANALYZE=1 yarn start", "build": "yarn run clean && webpack --color --bail", "clean": "rimraf ./build && mkdirp build && rimraf ./dist && mkdirp dist", "i18n:src": "rimraf ./translations/messages/src && babel src > tmp.js && rimraf tmp.js && node ./scripts/build-i18n-src.js ./translations/messages/src ./translations/", @@ -76,8 +77,8 @@ "react-virtualized": "9.20.1", "redux": "3.7.2", "redux-throttle": "0.1.1", - "scratch-render-fonts": "1.0.252", - "scratch-svg-renderer": "2.5.46", + "clipcc-render-fonts": "1.0.254", + "clipcc-svg-renderer": "2.5.47", "startaudiocontext": "1.2.1", "style-loader": "^4.0.0", "to-style": "1.3.3", @@ -125,6 +126,7 @@ "ts-loader": "^9.5.4", "typescript": "^5.9.3", "webpack": "^5.105.4", + "webpack-bundle-analyzer": "^5.2.0", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3", "yauzl": "2.10.0" diff --git a/packages/gui/src/components/loader/loader.css b/packages/gui/src/components/loader/loader.css index 247348f6a..642ca3e31 100644 --- a/packages/gui/src/components/loader/loader.css +++ b/packages/gui/src/components/loader/loader.css @@ -16,7 +16,7 @@ .scoped-loader { - z-index: var(--clipcc-z-index-stage-wrapper-overlay); + z-index: calc(var(--clipcc-z-index-loader) - 1); border-radius: 0.5rem; } diff --git a/packages/gui/src/containers/paint-editor-wrapper.jsx b/packages/gui/src/containers/paint-editor-wrapper.jsx index 2ac6d34b5..6591e52a4 100644 --- a/packages/gui/src/containers/paint-editor-wrapper.jsx +++ b/packages/gui/src/containers/paint-editor-wrapper.jsx @@ -3,7 +3,7 @@ import React from 'react'; import bindAll from 'lodash.bindall'; import VM from 'clipcc-vm'; import PaintEditor from 'clipcc-paint'; -import {inlineSvgFonts} from 'scratch-svg-renderer'; +import {inlineSvgFonts} from 'clipcc-svg-renderer'; import {connect} from 'react-redux'; diff --git a/packages/gui/src/containers/stage.jsx b/packages/gui/src/containers/stage.jsx index f744b30d6..00d0b00cd 100644 --- a/packages/gui/src/containers/stage.jsx +++ b/packages/gui/src/containers/stage.jsx @@ -8,7 +8,7 @@ import {connect} from 'react-redux'; import {STAGE_DISPLAY_SIZES} from '../lib/layout-constants'; import {getEventXY} from '../lib/touch-utils'; import VideoProvider from '../lib/video/video-provider'; -import {BitmapAdapter as V2BitmapAdapter} from 'scratch-svg-renderer'; +import {BitmapAdapter as V2BitmapAdapter} from 'clipcc-svg-renderer'; import StageComponent from '../components/stage/stage.jsx'; diff --git a/packages/gui/src/lib/file-uploader.js b/packages/gui/src/lib/file-uploader.js index 3a93d6bd0..ce6f3c160 100644 --- a/packages/gui/src/lib/file-uploader.js +++ b/packages/gui/src/lib/file-uploader.js @@ -1,4 +1,4 @@ -import {BitmapAdapter, sanitizeSvg} from 'scratch-svg-renderer'; +import {BitmapAdapter, sanitizeSvg} from 'clipcc-svg-renderer'; import randomizeSpritePosition from './randomize-sprite-position.js'; import bmpConverter from './bmp-converter'; import gifDecoder from './gif-decoder'; @@ -107,7 +107,7 @@ const costumeUpload = async function (fileData, fileType, storage, handleCostume let assetType = null; switch (fileType) { case 'image/svg+xml': { - // run svg bytes through scratch-svg-renderer's sanitization code + // run svg bytes through clipcc-svg-renderer's sanitization code fileData = sanitizeSvg.sanitizeByteStream(fileData); costumeFormat = storage.DataFormat.SVG; diff --git a/packages/gui/src/lib/get-costume-url.js b/packages/gui/src/lib/get-costume-url.js index 7c4b66572..e8941c83e 100644 --- a/packages/gui/src/lib/get-costume-url.js +++ b/packages/gui/src/lib/get-costume-url.js @@ -1,5 +1,5 @@ import storage from './storage'; -import {inlineSvgFonts} from 'scratch-svg-renderer'; +import {inlineSvgFonts} from 'clipcc-svg-renderer'; // Contains 'font-family', but doesn't only contain 'font-family="none"' const HAS_FONT_REGEXP = 'font-family(?!="none")'; diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index 9a61e5a44..00b902ac3 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -155,6 +155,12 @@ if (!process.env.CI) { base.plugins.push(new webpack.ProgressPlugin()); } +if (process.env.ANALYZE === '1') { + // eslint-disable-next-line global-require + const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); + base.plugins.push(new BundleAnalyzerPlugin()); +} + if (base.mode === 'development') { base.module.rules.push({ test: /blocks-msgs\.js$/, diff --git a/packages/paint/package.json b/packages/paint/package.json index 4709f081a..d1675deb2 100644 --- a/packages/paint/package.json +++ b/packages/paint/package.json @@ -42,7 +42,7 @@ "react-style-proptype": "^3", "react-tooltip": "^3", "redux": "^3", - "scratch-render-fonts": "^1.0.252" + "clipcc-render-fonts": "^1.0.254" }, "devDependencies": { "@babel/cli": "7.28.6", @@ -89,7 +89,7 @@ "regenerator-runtime": "0.14.1", "rimraf": "2.7.1", "clipcc-l10n": "3.2.0", - "scratch-render-fonts": "1.0.252", + "clipcc-render-fonts": "1.0.254", "style-loader": "^4.0.0", "svg-url-loader": "^8.0.0", "terser-webpack-plugin": "^5.3.17", diff --git a/packages/paint/src/playground/playground.jsx b/packages/paint/src/playground/playground.jsx index befcf4572..12a267d30 100644 --- a/packages/paint/src/playground/playground.jsx +++ b/packages/paint/src/playground/playground.jsx @@ -9,9 +9,9 @@ import {createStore} from 'redux'; import reducer from './reducers/combine-reducers'; import {intlInitialState, IntlProvider} from './reducers/intl.js'; import styles from './playground.css'; -// scratch-render-fonts is a playground-only dep. Fonts are expected to be imported +// clipcc-render-fonts is a playground-only dep. Fonts are expected to be imported // as a peer dependency, otherwise there will be two copies of them. -import 'scratch-render-fonts'; +import 'clipcc-render-fonts'; const appTarget = document.createElement('div'); appTarget.setAttribute('class', styles.playgroundContainer); diff --git a/packages/render/package.json b/packages/render/package.json index fe84e030e..f43ccd6c5 100644 --- a/packages/render/package.json +++ b/packages/render/package.json @@ -39,7 +39,7 @@ "json": "9.0.6", "node-polyfill-webpack-plugin": "^3.0.0", "playwright-chromium": "1.13.0", - "scratch-render-fonts": "1.0.252", + "clipcc-render-fonts": "1.0.254", "tap": "21.0.1", "terser-webpack-plugin": "^5.3.17", "travis-after-all": "1.4.5", @@ -50,12 +50,12 @@ "webpack-dev-server": "^5.2.3" }, "peerDependencies": { - "scratch-render-fonts": "^1.0.252" + "clipcc-render-fonts": "^1.0.254" }, "dependencies": { "@turbowarp/nanolog": "^0.2.0", "clipcc-storage": "3.2.0", - "scratch-svg-renderer": "2.5.46", + "clipcc-svg-renderer": "2.5.47", "grapheme-breaker": "0.3.2", "hull.js": "1.0.6", "ify-loader": "1.1.0", diff --git a/packages/render/src/SVGSkin.js b/packages/render/src/SVGSkin.js index 52317fb8f..c5bd76c50 100644 --- a/packages/render/src/SVGSkin.js +++ b/packages/render/src/SVGSkin.js @@ -1,7 +1,7 @@ const twgl = require('twgl.js'); const Skin = require('./Skin'); -const {loadSvgString, serializeSvgToString} = require('scratch-svg-renderer'); +const {loadSvgString, serializeSvgToString} = require('clipcc-svg-renderer'); const ShaderManager = require('./ShaderManager'); const MAX_TEXTURE_DIMENSION = 2048; diff --git a/packages/render/test/integration/cpu-render.html b/packages/render/test/integration/cpu-render.html index f83517fe4..0dca33224 100644 --- a/packages/render/test/integration/cpu-render.html +++ b/packages/render/test/integration/cpu-render.html @@ -1,7 +1,7 @@ - + diff --git a/packages/render/test/integration/index.html b/packages/render/test/integration/index.html index 51313b9d1..c75e0ebd9 100644 --- a/packages/render/test/integration/index.html +++ b/packages/render/test/integration/index.html @@ -1,7 +1,7 @@ - + diff --git a/packages/render/webpack.config.js b/packages/render/webpack.config.js index 59a188a93..762d2cb5c 100644 --- a/packages/render/webpack.config.js +++ b/packages/render/webpack.config.js @@ -110,7 +110,7 @@ module.exports = [ '!ify-loader!grapheme-breaker': 'grapheme-breaker', '!ify-loader!linebreak': 'linebreak', 'hull.js': true, - 'scratch-svg-renderer': true, + 'clipcc-svg-renderer': true, 'twgl.js': true, 'xml-escape': true } diff --git a/packages/vm/package.json b/packages/vm/package.json index 54bdfbffd..55c5c3628 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -45,11 +45,11 @@ "jszip": "^3.10.1", "@turbowarp/nanolog": "^1.0.1", "node-polyfill-webpack-plugin": "^3.0.0", - "clipcc-sb1-converter": "1.0.325", + "clipcc-sb1-converter": "1.0.326", "scratch-translate-extension-languages": "1.0.7" }, "peerDependencies": { - "scratch-svg-renderer": "2.5.46" + "clipcc-svg-renderer": "2.5.47" }, "devDependencies": { "@babel/core": "7.29.0", @@ -65,7 +65,7 @@ "clipcc-l10n": "3.2.0", "clipcc-render": "3.2.0", "clipcc-storage": "3.2.0", - "scratch-svg-renderer": "2.5.46", + "clipcc-svg-renderer": "2.5.47", "codingclip-worker-loader": "^3.0.10", "copy-webpack-plugin": "^14.0.0", "eslint": "^9.39.2", @@ -77,7 +77,7 @@ "json": "^9.0.6", "lodash.defaultsdeep": "4.6.1", "pngjs": "7.0.0", - "scratch-render-fonts": "1.0.252", + "clipcc-render-fonts": "1.0.254", "script-loader": "0.7.2", "stats.js": "0.17.0", "tap": "21.0.1", diff --git a/packages/vm/src/import/load-costume.js b/packages/vm/src/import/load-costume.js index 8351d4e4c..3ffcb2f27 100644 --- a/packages/vm/src/import/load-costume.js +++ b/packages/vm/src/import/load-costume.js @@ -1,6 +1,6 @@ const StringUtil = require('../util/string-util'); const log = require('../util/log'); -const {loadSvgString, serializeSvgToString} = require('scratch-svg-renderer'); +const {loadSvgString, serializeSvgToString} = require('clipcc-svg-renderer'); const loadVector_ = function (costume, runtime, rotationCenter, optVersion) { return new Promise(resolve => { diff --git a/packages/vm/src/playground/benchmark.js b/packages/vm/src/playground/benchmark.js index 417407293..2861c2185 100644 --- a/packages/vm/src/playground/benchmark.js +++ b/packages/vm/src/playground/benchmark.js @@ -49,7 +49,7 @@ const Runtime = require('../engine/runtime'); const ScratchRender = require('clipcc-render'); const AudioEngine = require('clipcc-audio'); -const ScratchSVGRenderer = require('scratch-svg-renderer'); +const ScratchSVGRenderer = require('clipcc-svg-renderer'); const Scratch = window.Scratch = window.Scratch || {}; diff --git a/packages/vm/test/fixtures/fake-bitmap-adapter.js b/packages/vm/test/fixtures/fake-bitmap-adapter.js index a7e5c8aa7..ff2a860fc 100644 --- a/packages/vm/test/fixtures/fake-bitmap-adapter.js +++ b/packages/vm/test/fixtures/fake-bitmap-adapter.js @@ -1,4 +1,4 @@ -const FakeBitmapAdapter = require('scratch-svg-renderer').BitmapAdapter; +const FakeBitmapAdapter = require('clipcc-svg-renderer').BitmapAdapter; FakeBitmapAdapter.prototype.resize = function (canvas) { return canvas; diff --git a/yarn.lock b/yarn.lock index ba1e7c775..8177e6c30 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1535,6 +1535,11 @@ resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz#798a33950d11226a0ebb6acafa60f5594424967f" integrity sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA== +"@discoveryjs/json-ext@0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + "@discoveryjs/json-ext@^0.6.1": version "0.6.3" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz#f13c7c205915eb91ae54c557f5e92bddd8be0e83" @@ -2830,6 +2835,11 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== +"@polka/url@^1.0.0-next.24": + version "1.0.0-next.29" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.29.tgz#5a40109a1ab5f84d6fd8fc928b19f367cbe7e7b1" + integrity sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww== + "@rtsao/scc@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" @@ -4521,7 +4531,7 @@ acorn-walk@^6.0.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== -acorn-walk@^8.1.1: +acorn-walk@^8.0.0, acorn-walk@^8.1.1: version "8.3.5" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.5.tgz#8a6b8ca8fc5b34685af15dabb44118663c296496" integrity sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw== @@ -4553,7 +4563,7 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.11.0, acorn@^8.15.0, acorn@^8.16.0, acorn@^8.4.1: +acorn@^8.0.4, acorn@^8.11.0, acorn@^8.15.0, acorn@^8.16.0, acorn@^8.4.1: version "8.16.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a" integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== @@ -6364,15 +6374,35 @@ cli@~1.0.0: exit "0.1.2" glob "^7.1.1" -clipcc-sb1-converter@1.0.325: - version "1.0.325" - resolved "https://registry.yarnpkg.com/clipcc-sb1-converter/-/clipcc-sb1-converter-1.0.325.tgz#165bf218fab2b09f31c1c230c954df59b5368fe5" - integrity sha512-fdiq48lVKp7MvKhBOGFGi2T9XmQW/bl7oLonpHK3Jk137niaJlbtd+/SFR0WY3zghOHry9u0CkuGpZCPVWkUZQ== +clipcc-render-fonts@1.0.254: + version "1.0.254" + resolved "https://registry.yarnpkg.com/clipcc-render-fonts/-/clipcc-render-fonts-1.0.254.tgz#a4be42f96d6816a65c1a9377c50f12495b244245" + integrity sha512-InyRDUNkZ5NIZXjBXR42zezu9ZgBpKAzl0HvaRTajIGp/C5v40f7JdkvJiHT/P82M/s7qEi0ayi96mBNnVlm9Q== + dependencies: + base64-loader "^1.0.0" + +clipcc-sb1-converter@1.0.326: + version "1.0.326" + resolved "https://registry.yarnpkg.com/clipcc-sb1-converter/-/clipcc-sb1-converter-1.0.326.tgz#b370eed171fc5c7644e4a1a40e48a6bd6463d5f6" + integrity sha512-t7qPJhHXtGw8+Z82msjNqfM7tzO/u9sdqgI8EQ7nVpqS+/q66tbbni8ff4EM6VFHlH6Yc3FfpM5FyH1chdu1Iw== dependencies: "@turbowarp/nanolog" "^1.0.1" fastestsmallesttextencoderdecoder "^1.0.22" js-md5 "^0.8.3" +clipcc-svg-renderer@2.5.47: + version "2.5.47" + resolved "https://registry.yarnpkg.com/clipcc-svg-renderer/-/clipcc-svg-renderer-2.5.47.tgz#0c3d688bcf3440ce03ce5097e9abd0ffb5b7692c" + integrity sha512-uRoadqG/oia8+1Xz5FurN0OTZOPbHEsXY8G6K5ZAn98E21mKqOK98AtSTk9NU38BCsGjTbbF80x4AVJOYZQM2w== + dependencies: + "@turbowarp/nanolog" "^1.0.1" + base64-js "^1.2.1" + base64-loader "^1.0.0" + css-tree "^1.1.3" + fastestsmallesttextencoderdecoder "^1.0.22" + isomorphic-dompurify "^2.4.0" + transformation-matrix "^1.15.0" + cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -6513,6 +6543,11 @@ commander@^6.1.0, commander@^6.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + commander@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" @@ -7098,6 +7133,11 @@ date-now@^0.1.4: resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha512-AsElvov3LoNB7tf5k37H2jYSB+ZZPMT5sG2QjJCcdlV5chIv6htBUBUui2IKRjgtKAKtCBN7Zbwa+MtwLjSeNw== +debounce@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -9890,7 +9930,7 @@ html-entities@^2.6.0: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== -html-escaper@^2.0.0: +html-escaper@^2.0.0, html-escaper@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== @@ -13383,11 +13423,6 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== -microee@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/microee/-/microee-0.0.6.tgz#a12bdb0103681e8b126a9b071eba4c467c78fffe" - integrity sha512-/LdL3jiBWDJ3oQIRLgRhfeCZNE3patM1LiwCC124+/HHn10sI/G2OAyiMfTNzH5oYWoZBk0tRZADAUOv+0Wt0A== - micromatch@^2.3.11: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" @@ -13493,13 +13528,6 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -minilog@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/minilog/-/minilog-3.1.0.tgz#d2d0f1887ca363d1acf0ea86d5c4df293b3fb675" - integrity sha512-Xfm4jWjWzSAduvEWtuZX/8TMkxfJlCfH7XvikCZe3ptojYTBq1eoEs3rh9/3LNLOckUP86m+8l8+Iw5NU/pBww== - dependencies: - microee "0.0.6" - minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -13681,6 +13709,11 @@ mri@^1.2.0: resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== +mrmime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.1.tgz#bc3e87f7987853a54c9850eeb1f1078cd44adddc" + integrity sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -14851,7 +14884,7 @@ picocolors@^0.2.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== -picocolors@^1.1.0, picocolors@^1.1.1: +picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -16476,26 +16509,6 @@ schema-utils@^3.0.0, schema-utils@^3.1.0: ajv "^6.12.5" ajv-keywords "^3.5.2" -scratch-render-fonts@1.0.252: - version "1.0.252" - resolved "https://registry.yarnpkg.com/scratch-render-fonts/-/scratch-render-fonts-1.0.252.tgz#1122cc8416fe43ecb7d3f47a3bf8c137e7e7923e" - integrity sha512-leYCgtHMIqy36KqjraAiwaPYc9Bjy2L8J+vZ/CEnUE2PVP3z0dDoA4akz42/hk44kpVDzD574Th3SANt+PlLVA== - dependencies: - base64-loader "^1.0.0" - -scratch-svg-renderer@2.5.46: - version "2.5.46" - resolved "https://registry.yarnpkg.com/scratch-svg-renderer/-/scratch-svg-renderer-2.5.46.tgz#47b6d9df4b04870a0f4b9337a289e4d20952f258" - integrity sha512-SrQgHZdqnu3DX6UuJNJPg/kpJTQT/mIVbQZvm5uTE/B47U5mSaVfgoGlNFhoNUWZlbHucqySyG4KMe+ThDUR/A== - dependencies: - base64-js "^1.2.1" - base64-loader "^1.0.0" - css-tree "^1.1.3" - fastestsmallesttextencoderdecoder "^1.0.22" - isomorphic-dompurify "^2.4.0" - minilog "^3.1.0" - transformation-matrix "^1.15.0" - scratch-translate-extension-languages@1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/scratch-translate-extension-languages/-/scratch-translate-extension-languages-1.0.7.tgz#aa78912c0a12db83d755045fd4c450a3bc3849cc" @@ -16805,6 +16818,15 @@ sigstore@^4.0.0: "@sigstore/tuf" "^4.0.1" "@sigstore/verify" "^3.1.0" +sirv@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-3.0.2.tgz#f775fccf10e22a40832684848d636346f41cd970" + integrity sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g== + dependencies: + "@polka/url" "^1.0.0-next.24" + mrmime "^2.0.0" + totalist "^3.0.0" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -17875,6 +17897,11 @@ toidentifier@1.0.1, toidentifier@~1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +totalist@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" + integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== + tough-cookie@^2.3.2, tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -18601,6 +18628,23 @@ webidl-conversions@^8.0.1: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-8.0.1.tgz#0657e571fe6f06fcb15ca50ed1fdbcb495cd1686" integrity sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ== +webpack-bundle-analyzer@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.2.0.tgz#9bcf0e7cc8c86632a96bf7092300287dc284c3d7" + integrity sha512-Etrauj1wYO/xjiz/Vfd6bW1lG9fEhrJpNmu10tv0X9kv+gyY3qiE09uYepqg1Xd0PxOvllRXwWYWjtQYoO/glQ== + 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" + html-escaper "^2.0.2" + opener "^1.5.2" + picocolors "^1.0.0" + sirv "^3.0.2" + ws "^8.19.0" + webpack-cli@6.0.1, webpack-cli@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-6.0.1.tgz#a1ce25da5ba077151afd73adfa12e208e5089207" @@ -19018,7 +19062,7 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== -ws@^8.18.0: +ws@^8.18.0, ws@^8.19.0: version "8.19.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.19.0.tgz#ddc2bdfa5b9ad860204f5a72a4863a8895fd8c8b" integrity sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg== From 68a62ffca595aa49bc27de7757718a2b435eb0a3 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Sun, 8 Mar 2026 19:49:55 +0800 Subject: [PATCH 07/29] :bug: fix: lazy block related errors Signed-off-by: SimonShiki --- packages/block/src/utils.ts | 13 +++++++++---- packages/gui/src/containers/blocks.jsx | 3 ++- packages/gui/src/lib/blocks-loader.ts | 3 ++- packages/gui/src/lib/blocks.js | 11 ----------- packages/gui/src/lib/make-toolbox.js | 3 +-- 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/packages/block/src/utils.ts b/packages/block/src/utils.ts index 2c1c31ceb..d2e41e8d7 100644 --- a/packages/block/src/utils.ts +++ b/packages/block/src/utils.ts @@ -26,6 +26,14 @@ import type {AnchoredComment} from './anchored_comment'; * @author fenichel@google.com (Rachel Fenichel) */ + +// Use a collator's compare instead of localeCompare which internally +// creates a collator. Using this is a lot faster in browsers that create a +// collator for every localeCompare call. +const collator = new Intl.Collator([], { + sensitivity: 'base', + numeric: true +}); /** * Compare strings with natural number sorting. * @param str1 First input. @@ -33,10 +41,7 @@ import type {AnchoredComment} from './anchored_comment'; * @returns -1, 0, or 1 to signify greater than, equality, or less than. */ export function compareStrings(str1: string, str2: string): number { - return str1.localeCompare(str2, [], { - sensitivity: 'base', - numeric: true - }); + return collator.compare(str1, str2); } /** diff --git a/packages/gui/src/containers/blocks.jsx b/packages/gui/src/containers/blocks.jsx index 1b527fa66..6c7ff3595 100644 --- a/packages/gui/src/containers/blocks.jsx +++ b/packages/gui/src/containers/blocks.jsx @@ -404,7 +404,8 @@ class Blocks extends React.Component { targetSounds.length > 0 ? targetSounds[targetSounds.length - 1].name : '', this.props.hideNonVanillaBlocks ); - } catch { + } catch (e) { + console.error(`Error making toolbox:`, e); return null; } } diff --git a/packages/gui/src/lib/blocks-loader.ts b/packages/gui/src/lib/blocks-loader.ts index fa40eb070..15896eb8f 100644 --- a/packages/gui/src/lib/blocks-loader.ts +++ b/packages/gui/src/lib/blocks-loader.ts @@ -1,4 +1,5 @@ -let ScratchBlocksModule: typeof import('clipcc-block') | null = null; +// eslint-disable-next-line import/no-mutable-exports +export let ScratchBlocksModule: typeof import('clipcc-block') | null = null; /** * Check if the ScratchBlocks module is loaded. diff --git a/packages/gui/src/lib/blocks.js b/packages/gui/src/lib/blocks.js index 12ddbf08e..670e4e0cc 100644 --- a/packages/gui/src/lib/blocks.js +++ b/packages/gui/src/lib/blocks.js @@ -323,16 +323,5 @@ export default function (vm, ScratchBlocks) { vm.runtime.emit('PLAY_NOTE', noteNum, extensionId); }; - // Use a collator's compare instead of localeCompare which internally - // creates a collator. Using this is a lot faster in browsers that create a - // collator for every localeCompare call. - const collator = new Intl.Collator([], { - sensitivity: 'base', - numeric: true - }); - ScratchBlocks.scratchBlocksUtils.compareStrings = function (str1, str2) { - return collator.compare(str1, str2); - }; - return ScratchBlocks; } diff --git a/packages/gui/src/lib/make-toolbox.js b/packages/gui/src/lib/make-toolbox.js index 26d4ef2fe..efb8ca3b2 100644 --- a/packages/gui/src/lib/make-toolbox.js +++ b/packages/gui/src/lib/make-toolbox.js @@ -1,6 +1,6 @@ /* eslint-disable no-unused-vars */ -import {getScratchBlocks, isScratchBlocksLoaded} from './blocks-loader'; +import {ScratchBlocksModule as ScratchBlocks, isScratchBlocksLoaded} from './blocks-loader'; const blockSeparator = { kind: 'sep', @@ -40,7 +40,6 @@ const translate = (id, defaultMessage) => { if (!isScratchBlocksLoaded()) { return defaultMessage; } - const ScratchBlocks = getScratchBlocks(); return ScratchBlocks.Msg[id] ?? defaultMessage; }; From 087a073af3b4f8e819a1beb3ce30994b33347b3a Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Sun, 8 Mar 2026 23:30:27 +0800 Subject: [PATCH 08/29] :wrench: chore(gui): load paint lazily Signed-off-by: SimonShiki --- packages/gui/package.json | 5 ++- .../src/containers/paint-editor-wrapper.jsx | 12 +++-- packages/gui/src/index.js | 4 +- packages/gui/src/lib/app-state-hoc.jsx | 8 ++-- packages/gui/src/lib/paint-loader-hoc.tsx | 45 +++++++++++++++++++ packages/gui/src/lib/paint-loader.ts | 25 +++++++++++ packages/gui/src/reducers/utils.ts | 32 +++++++++++++ packages/gui/tsconfig.json | 2 +- packages/gui/webpack.config.js | 5 +-- yarn.lock | 5 +++ 10 files changed, 124 insertions(+), 19 deletions(-) create mode 100644 packages/gui/src/lib/paint-loader-hoc.tsx create mode 100644 packages/gui/src/lib/paint-loader.ts create mode 100644 packages/gui/src/reducers/utils.ts diff --git a/packages/gui/package.json b/packages/gui/package.json index fd3bdd1b2..27727dbfc 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -37,7 +37,9 @@ "clipcc-l10n": "3.2.0", "clipcc-paint": "3.2.0", "clipcc-render": "3.2.0", + "clipcc-render-fonts": "1.0.254", "clipcc-storage": "3.2.0", + "clipcc-svg-renderer": "2.5.47", "clipcc-vm": "3.2.0", "computed-style-to-inline-style": "3.0.0", "copy-webpack-plugin": "^14.0.0", @@ -77,8 +79,6 @@ "react-virtualized": "9.20.1", "redux": "3.7.2", "redux-throttle": "0.1.1", - "clipcc-render-fonts": "1.0.254", - "clipcc-svg-renderer": "2.5.47", "startaudiocontext": "1.2.1", "style-loader": "^4.0.0", "to-style": "1.3.3", @@ -97,6 +97,7 @@ "@babel/preset-react": "7.14.5", "@babel/preset-typescript": "^7.24.7", "@eslint/js": "^9.39.2", + "@types/prop-types": "15.5.9", "@types/react": "^16.1.0", "babel-core": "7.0.0-bridge.0", "babel-eslint": "10.0.3", diff --git a/packages/gui/src/containers/paint-editor-wrapper.jsx b/packages/gui/src/containers/paint-editor-wrapper.jsx index 6591e52a4..5273b3db5 100644 --- a/packages/gui/src/containers/paint-editor-wrapper.jsx +++ b/packages/gui/src/containers/paint-editor-wrapper.jsx @@ -2,8 +2,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import bindAll from 'lodash.bindall'; import VM from 'clipcc-vm'; -import PaintEditor from 'clipcc-paint'; import {inlineSvgFonts} from 'clipcc-svg-renderer'; +import {injectPaint} from '../lib/paint-loader-hoc'; import {connect} from 'react-redux'; @@ -44,8 +44,10 @@ class PaintEditorWrapper extends React.Component { const { selectedCostumeIndex, vm, + paint, ...componentProps } = this.props; + const PaintEditor = paint.default; return ( { @@ -90,6 +94,6 @@ const mapStateToProps = (state, {selectedCostumeIndex}) => { }; }; -export default connect( +export default injectPaint(connect( mapStateToProps -)(PaintEditorWrapper); +)(PaintEditorWrapper)); diff --git a/packages/gui/src/index.js b/packages/gui/src/index.js index 27b97392b..542e637c9 100644 --- a/packages/gui/src/index.js +++ b/packages/gui/src/index.js @@ -2,7 +2,6 @@ import GUI from './containers/gui.jsx'; import AppStateHOC from './lib/app-state-hoc.jsx'; import GuiReducer, {guiInitialState, guiMiddleware, initEmbedded, initFullScreen, initPlayer} from './reducers/gui'; import LocalesReducer, {localesInitialState, initLocale} from './reducers/locales'; -import {ScratchPaintReducer} from 'clipcc-paint'; import {setFullScreen, setPlayer} from './reducers/mode'; import {remixProject} from './reducers/project-state'; import {setAppElement} from 'react-modal'; @@ -10,8 +9,7 @@ import totallyNormalStrings from './lib/l10n.js'; const guiReducers = { locales: LocalesReducer, - scratchGui: GuiReducer, - scratchPaint: ScratchPaintReducer + scratchGui: GuiReducer }; export { diff --git a/packages/gui/src/lib/app-state-hoc.jsx b/packages/gui/src/lib/app-state-hoc.jsx index c24b0ed09..b7c7af58a 100644 --- a/packages/gui/src/lib/app-state-hoc.jsx +++ b/packages/gui/src/lib/app-state-hoc.jsx @@ -10,6 +10,7 @@ import {setPlayer, setFullScreen} from '../reducers/mode.js'; import locales from 'clipcc-l10n'; import {detectLocale} from './detect-locale'; +import {setInitialReducers} from '../reducers/utils'; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; @@ -54,9 +55,6 @@ const AppStateHOC = function (WrappedComponent, localesOnly) { initPlayer, initTelemetryModal } = guiRedux; - // eslint-disable-next-line global-require - const {ScratchPaintReducer} = require('clipcc-paint'); - let initializedGui = guiInitialState; if (props.isFullScreen || props.isPlayerOnly) { if (props.isFullScreen) { @@ -70,8 +68,7 @@ const AppStateHOC = function (WrappedComponent, localesOnly) { } reducers = { locales: localesReducer, - scratchGui: guiReducer, - scratchPaint: ScratchPaintReducer + scratchGui: guiReducer }; initialState = { locales: initializedLocales, @@ -79,6 +76,7 @@ const AppStateHOC = function (WrappedComponent, localesOnly) { }; enhancer = composeEnhancers(guiMiddleware); } + setInitialReducers(reducers); const reducer = combineReducers(reducers); this.store = createStore( reducer, diff --git a/packages/gui/src/lib/paint-loader-hoc.tsx b/packages/gui/src/lib/paint-loader-hoc.tsx new file mode 100644 index 000000000..02920de6b --- /dev/null +++ b/packages/gui/src/lib/paint-loader-hoc.tsx @@ -0,0 +1,45 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import {getScratchPaint} from './paint-loader'; +import ScopedLoaderComponent from '../components/loader/scoped-loader'; +import {injectReducer} from '../reducers/utils'; + +interface PaintLoaderProps { + paint: typeof import('clipcc-paint'); +} + +export function injectPaint> (WrappedComponent: Component) { + class PaintLoaderHOC extends React.Component { + static contextTypes = { + store: PropTypes.shape({ + subscribe: PropTypes.func.isRequired, + dispatch: PropTypes.func.isRequired, + getState: PropTypes.func.isRequired + }) + }; + + state = { + loaded: false + }; + paint: typeof import('clipcc-paint') | null = null; + + override async componentDidMount () { + if (!this.state.loaded) { + this.paint = await getScratchPaint(); + // @ts-expect-error paint lack types + injectReducer(this.context.store, 'scratchPaint', this.paint.ScratchPaintReducer); + this.setState({loaded: true}); + } + } + + override render () { + if (!this.state.loaded) { + return ; + } + + return ; + } + } + + return PaintLoaderHOC; +} diff --git a/packages/gui/src/lib/paint-loader.ts b/packages/gui/src/lib/paint-loader.ts new file mode 100644 index 000000000..85a149e60 --- /dev/null +++ b/packages/gui/src/lib/paint-loader.ts @@ -0,0 +1,25 @@ +// eslint-disable-next-line import/no-mutable-exports +export let ScratchPaintModule: typeof import('clipcc-paint') | null = null; + +/** + * Check if the ScratchPaint module is loaded. + * @returns True if the ScratchPaint module is loaded, false otherwise. + */ +export function isScratchPaintLoaded () { + return !!ScratchPaintModule; +} + +/** + * Get the ScratchPaint module, which is loaded asynchronously to reduce the initial bundle size. + * @returns A promise that resolves to the ScratchPaint module. + */ +export async function getScratchPaint () { + if (!ScratchPaintModule) { + // eslint-disable-next-line require-atomic-updates + ScratchPaintModule = await import( + /* webpackChunkName: "clipcc-paint" */ + 'clipcc-paint' + ); + } + return ScratchPaintModule; +} diff --git a/packages/gui/src/reducers/utils.ts b/packages/gui/src/reducers/utils.ts new file mode 100644 index 000000000..6719bcb9d --- /dev/null +++ b/packages/gui/src/reducers/utils.ts @@ -0,0 +1,32 @@ +import {combineReducers, type Reducer, type Store} from 'redux'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +let initialReducers: Record> | null = null; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const dynamicReducers: Record> = {}; + +/** + * Set the initial reducers for the store. This should be called before creating the store, + * and the reducers passed here will be combined with any dynamically injected reducers. + * @param reducers The initial reducers to set for the store. + */ +export function setInitialReducers (reducers: Record>) { + initialReducers = reducers; +} + +/** + * Dynamically inject a reducer into the store. This is useful for code-splitting and loading reducers on demand. + * @param store The Redux store to inject the reducer into. + * @param key The key under which to store the reducer's state in the Redux store. + * @param reducer The reducer function to inject. + */ +export function injectReducer ( + store: Store, + key: string, + reducer: Reducer) { + dynamicReducers[key] = reducer; + store.replaceReducer(combineReducers({ + ...initialReducers, + ...dynamicReducers + })); +} diff --git a/packages/gui/tsconfig.json b/packages/gui/tsconfig.json index cf61b4da5..97b8ee35f 100644 --- a/packages/gui/tsconfig.json +++ b/packages/gui/tsconfig.json @@ -29,7 +29,7 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ + "module": "preserve", /* Specify what module code is generated. */ // "rootDir": "./src/", /* Specify the root folder within your source files. */ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index 00b902ac3..8e5335a5f 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -51,10 +51,7 @@ const base = { loader: 'ts-loader', options: { transpileOnly: true, - allowTsInNodeModules: true, - compilerOptions: { - module: 'preserve' - } + allowTsInNodeModules: true } }, { diff --git a/yarn.lock b/yarn.lock index 8177e6c30..e84057570 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3789,6 +3789,11 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== +"@types/prop-types@15.5.9": + version "15.5.9" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.9.tgz#f2d14df87b0739041bc53a7d75e3d77d726a3ec0" + integrity sha512-Nha5b+jmBI271jdTMwrHiNXM+DvThjHOfyZtMX9kj/c/LUj2xiLHsG/1L3tJ8DjAoQN48cHwUwtqBotjyXaSdQ== + "@types/qs@*": version "6.15.0" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.15.0.tgz#963ab61779843fe910639a50661b48f162bc7f79" From 87c56d253e39564a47cc300312eefb602696438e Mon Sep 17 00:00:00 2001 From: Simon Shiki Date: Sun, 8 Mar 2026 23:37:38 +0800 Subject: [PATCH 09/29] :wrench: chore(gui): remove useless context typecheck --- packages/gui/src/lib/paint-loader-hoc.tsx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/gui/src/lib/paint-loader-hoc.tsx b/packages/gui/src/lib/paint-loader-hoc.tsx index 02920de6b..e150a6390 100644 --- a/packages/gui/src/lib/paint-loader-hoc.tsx +++ b/packages/gui/src/lib/paint-loader-hoc.tsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {getScratchPaint} from './paint-loader'; import ScopedLoaderComponent from '../components/loader/scoped-loader'; @@ -10,14 +9,6 @@ interface PaintLoaderProps { export function injectPaint> (WrappedComponent: Component) { class PaintLoaderHOC extends React.Component { - static contextTypes = { - store: PropTypes.shape({ - subscribe: PropTypes.func.isRequired, - dispatch: PropTypes.func.isRequired, - getState: PropTypes.func.isRequired - }) - }; - state = { loaded: false }; From ef964651382a04917915e2a31a80bb0277826473 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Mon, 9 Mar 2026 09:09:38 +0800 Subject: [PATCH 10/29] :wrench: chore: load builtin extensions lazily Signed-off-by: SimonShiki --- packages/gui/package.json | 2 +- packages/gui/src/lib/make-toolbox.js | 3 +- packages/gui/webpack.config.js | 1 + packages/vm/package.json | 1 - .../extension-support/extension-manager.js | 50 +++++++++++-------- packages/vm/src/virtual-machine.js | 20 -------- packages/vm/webpack.config.js | 1 + yarn.lock | 5 -- 8 files changed, 33 insertions(+), 50 deletions(-) diff --git a/packages/gui/package.json b/packages/gui/package.json index 27727dbfc..896c72f8f 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -11,7 +11,7 @@ }, "main": "./dist/scratch-gui.js", "scripts": { - "analyze": "cross-env ANALYZE=1 yarn start", + "analyze": "cross-env ANALYZE=1 yarn build", "build": "yarn run clean && webpack --color --bail", "clean": "rimraf ./build && mkdirp build && rimraf ./dist && mkdirp dist", "i18n:src": "rimraf ./translations/messages/src && babel src > tmp.js && rimraf tmp.js && node ./scripts/build-i18n-src.js ./translations/messages/src ./translations/", diff --git a/packages/gui/src/lib/make-toolbox.js b/packages/gui/src/lib/make-toolbox.js index efb8ca3b2..920960753 100644 --- a/packages/gui/src/lib/make-toolbox.js +++ b/packages/gui/src/lib/make-toolbox.js @@ -994,8 +994,7 @@ const makeToolbox = function ( // Convert xml toolbox to json. for (const category of categories) { - if (category.json || !category.xml || !isScratchBlocksLoaded() ) continue; - const ScratchBlocks = getScratchBlocks(); + if (category.json || !category.xml || !isScratchBlocksLoaded()) continue; const toolbox = ScratchBlocks.utils.toolbox.convertToolboxDefToJson( `${category.xml}` ); diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index 8e5335a5f..4170b68bb 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -27,6 +27,7 @@ const base = { resolve: { extensions: ['.ts', '.js', '.tsx', '.jsx'], alias: { + 'text-encoding': 'fastestsmallesttextencoderdecoder', 'clipcc-vm': path.resolve(__dirname, '../vm/src/index.js'), 'clipcc-block': path.resolve(__dirname, '../block/src/index.ts'), 'clipcc-render': path.resolve(__dirname, '../render/src/index.js'), diff --git a/packages/vm/package.json b/packages/vm/package.json index 55c5c3628..7393d9f49 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -39,7 +39,6 @@ "diff-match-patch": "1.0.4", "fastestsmallesttextencoderdecoder": "^1.0.22", "format-message": "6.2.1", - "text-encoding": "0.7.0", "htmlparser2": "10.1.0", "immutable": "5.1.5", "jszip": "^3.10.1", diff --git a/packages/vm/src/extension-support/extension-manager.js b/packages/vm/src/extension-support/extension-manager.js index dfc92c0f2..184c92fcc 100644 --- a/packages/vm/src/extension-support/extension-manager.js +++ b/packages/vm/src/extension-support/extension-manager.js @@ -8,25 +8,33 @@ const BlockType = require('./block-type'); // TODO: move these out into a separate repository? // TODO: change extension spec so that library info, including extension ID, can be collected through static methods -/* eslint-disable global-require */ +/** + * List of core extensions that should load at startup. + */ +const coreExtensions = { + // eslint-disable-next-line global-require + coreExample: () => require('../blocks/scratch3_core_example') +}; + +/** + * List of built-in extensions that are available to load by ID or URL but do not load at startup. + */ const builtinExtensions = { // This is an example that isn't loaded with the other core blocks, // but serves as a reference for loading core blocks as extensions. - coreExample: () => require('../blocks/scratch3_core_example'), // These are the non-core built-in extensions. - pen: () => require('../extensions/scratch3_pen'), - wedo2: () => require('../extensions/scratch3_wedo2'), - music: () => require('../extensions/scratch3_music'), - microbit: () => require('../extensions/scratch3_microbit'), - text2speech: () => require('../extensions/scratch3_text2speech'), - translate: () => require('../extensions/scratch3_translate'), - videoSensing: () => require('../extensions/scratch3_video_sensing'), - ev3: () => require('../extensions/scratch3_ev3'), - makeymakey: () => require('../extensions/scratch3_makeymakey'), - boost: () => require('../extensions/scratch3_boost'), - gdxfor: () => require('../extensions/scratch3_gdx_for') + pen: () => import(/* webpackChunkName: "ext_pen" */ '../extensions/scratch3_pen'), + wedo2: () => import(/* webpackChunkName: "ext_wedo2" */ '../extensions/scratch3_wedo2'), + music: () => import(/* webpackChunkName: "ext_music" */ '../extensions/scratch3_music'), + microbit: () => import(/* webpackChunkName: "ext_microbit" */ '../extensions/scratch3_microbit'), + text2speech: () => import(/* webpackChunkName: "ext_text2speech" */ '../extensions/scratch3_text2speech'), + translate: () => import(/* webpackChunkName: "ext_translate" */ '../extensions/scratch3_translate'), + videoSensing: () => import(/* webpackChunkName: "ext_videoSensing" */ '../extensions/scratch3_video_sensing'), + ev3: () => import(/* webpackChunkName: "ext_ev3" */ '../extensions/scratch3_ev3'), + makeymakey: () => import(/* webpackChunkName: "ext_makeymakey" */ '../extensions/scratch3_makeymakey'), + boost: () => import(/* webpackChunkName: "ext_boost" */ '../extensions/scratch3_boost'), + gdxfor: () => import(/* webpackChunkName: "ext_gdxfor" */ '../extensions/scratch3_gdx_for') }; -/* eslint-enable global-require */ /** * @typedef {object} ArgumentInfo - Information about an extension block argument @@ -118,8 +126,8 @@ class ExtensionManager { * @param {string} extensionId - the ID of an internal extension */ loadExtensionIdSync (extensionId) { - if (!Object.prototype.hasOwnProperty.call(builtinExtensions, extensionId)) { - log.warn(`Could not find extension ${extensionId} in the built in extensions.`); + if (!Object.prototype.hasOwnProperty.call(coreExtensions, extensionId)) { + log.warn(`Could not find extension ${extensionId} in core extensions.`); return; } @@ -130,7 +138,7 @@ class ExtensionManager { return; } - const extension = builtinExtensions[extensionId](); + const extension = coreExtensions[extensionId](); const extensionInstance = new extension(this.runtime); const serviceName = this._registerInternalExtension(extensionInstance); this._loadedExtensions.set(extensionId, serviceName); @@ -141,20 +149,20 @@ class ExtensionManager { * @param {string} extensionURL - the URL for the extension to load OR the ID of an internal extension * @returns {Promise} resolved once the extension is loaded and initialized or rejected on failure */ - loadExtensionURL (extensionURL) { + async loadExtensionURL (extensionURL) { if (Object.prototype.hasOwnProperty.call(builtinExtensions, extensionURL)) { /** @todo dupe handling for non-builtin extensions. See commit 670e51d33580e8a2e852b3b038bb3afc282f81b9 */ if (this.isExtensionLoaded(extensionURL)) { const message = `Rejecting attempt to load a second extension with ID ${extensionURL}`; log.warn(message); - return Promise.resolve(); + return; } - const extension = builtinExtensions[extensionURL](); + const {default: extension} = await builtinExtensions[extensionURL](); const extensionInstance = new extension(this.runtime); const serviceName = this._registerInternalExtension(extensionInstance); this._loadedExtensions.set(extensionURL, serviceName); - return Promise.resolve(); + return; } return new Promise((resolve, reject) => { diff --git a/packages/vm/src/virtual-machine.js b/packages/vm/src/virtual-machine.js index 813f92e52..56895d965 100644 --- a/packages/vm/src/virtual-machine.js +++ b/packages/vm/src/virtual-machine.js @@ -28,21 +28,6 @@ require('canvas-toBlob'); const RESERVED_NAMES = ['_mouse_', '_stage_', '_edge_', '_myself_', '_random_']; -/** - * @type {string[]} - */ -const CORE_EXTENSIONS = [ - // 'motion', - // 'looks', - // 'sound', - // 'events', - // 'control', - // 'sensing', - // 'operators', - // 'variables', - // 'myBlocks' -]; - /** * @typedef {number} int * @typedef {import('./engine/target')} Target @@ -189,11 +174,6 @@ class VirtualMachine extends EventEmitter { this.extensionManager = new ExtensionManager(this.runtime); - // Load core extensions - for (const id of CORE_EXTENSIONS) { - this.extensionManager.loadExtensionIdSync(id); - } - this.blockListener = this.blockListener.bind(this); this.flyoutBlockListener = this.flyoutBlockListener.bind(this); this.monitorBlockListener = this.monitorBlockListener.bind(this); diff --git a/packages/vm/webpack.config.js b/packages/vm/webpack.config.js index b2215eda4..45440f5cf 100644 --- a/packages/vm/webpack.config.js +++ b/packages/vm/webpack.config.js @@ -16,6 +16,7 @@ const base = { }, resolve: { alias: { + 'text-encoding': 'fastestsmallesttextencoderdecoder', 'clipcc-render': path.resolve(__dirname, '../render/src/index.js'), 'clipcc-audio': path.resolve(__dirname, '../audio/src/index.js') }, diff --git a/yarn.lock b/yarn.lock index e84057570..a8ce6f2e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17732,11 +17732,6 @@ test-exclude@^7.0.1: glob "^10.4.1" minimatch "^10.2.2" -text-encoding@0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.7.0.tgz#f895e836e45990624086601798ea98e8f36ee643" - integrity sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA== - text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" From 51af9abb824c3af5dcfc7ac4ff500b733f4b6ef9 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Mon, 9 Mar 2026 11:26:33 +0800 Subject: [PATCH 11/29] :wrench: chore(gui): refine reducer injection logic Signed-off-by: SimonShiki --- packages/gui/src/lib/app-state-hoc.jsx | 3 ++- packages/gui/src/lib/paint-loader-hoc.tsx | 2 +- packages/gui/src/reducers/utils.ts | 18 ++++++++++++++---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/gui/src/lib/app-state-hoc.jsx b/packages/gui/src/lib/app-state-hoc.jsx index b7c7af58a..5885937c3 100644 --- a/packages/gui/src/lib/app-state-hoc.jsx +++ b/packages/gui/src/lib/app-state-hoc.jsx @@ -10,7 +10,7 @@ import {setPlayer, setFullScreen} from '../reducers/mode.js'; import locales from 'clipcc-l10n'; import {detectLocale} from './detect-locale'; -import {setInitialReducers} from '../reducers/utils'; +import {setInitialReducers, setStore} from '../reducers/utils'; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; @@ -83,6 +83,7 @@ const AppStateHOC = function (WrappedComponent, localesOnly) { initialState, enhancer ); + setStore(this.store); } componentDidUpdate (prevProps) { if (localesOnly) return; diff --git a/packages/gui/src/lib/paint-loader-hoc.tsx b/packages/gui/src/lib/paint-loader-hoc.tsx index e150a6390..ec0d2bdb8 100644 --- a/packages/gui/src/lib/paint-loader-hoc.tsx +++ b/packages/gui/src/lib/paint-loader-hoc.tsx @@ -18,7 +18,7 @@ export function injectPaint> | null = null; // eslint-disable-next-line @typescript-eslint/no-explicit-any +let storeInstance: Store | null = null; +// eslint-disable-next-line @typescript-eslint/no-explicit-any const dynamicReducers: Record> = {}; /** @@ -14,18 +16,26 @@ export function setInitialReducers (reducers: Record (store: Store) { + storeInstance = store; +} + /** * Dynamically inject a reducer into the store. This is useful for code-splitting and loading reducers on demand. - * @param store The Redux store to inject the reducer into. * @param key The key under which to store the reducer's state in the Redux store. * @param reducer The reducer function to inject. */ -export function injectReducer ( - store: Store, +export function injectReducer ( key: string, reducer: Reducer) { dynamicReducers[key] = reducer; - store.replaceReducer(combineReducers({ + if (!storeInstance) return; + storeInstance.replaceReducer(combineReducers({ ...initialReducers, ...dynamicReducers })); From 0a1d55010685a9d7ca3aa4058dde4bf3d6a57eaa Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Mon, 9 Mar 2026 11:26:54 +0800 Subject: [PATCH 12/29] :bug: fix: inline svg fonts Signed-off-by: SimonShiki --- packages/gui/package.json | 4 ++-- packages/paint/package.json | 4 ++-- packages/render/package.json | 6 +++--- packages/render/src/SVGSkin.js | 3 ++- packages/vm/package.json | 6 +++--- yarn.lock | 16 ++++++++-------- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/packages/gui/package.json b/packages/gui/package.json index 896c72f8f..6ad90f0ab 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -37,9 +37,9 @@ "clipcc-l10n": "3.2.0", "clipcc-paint": "3.2.0", "clipcc-render": "3.2.0", - "clipcc-render-fonts": "1.0.254", + "clipcc-render-fonts": "1.0.256", "clipcc-storage": "3.2.0", - "clipcc-svg-renderer": "2.5.47", + "clipcc-svg-renderer": "2.5.48", "clipcc-vm": "3.2.0", "computed-style-to-inline-style": "3.0.0", "copy-webpack-plugin": "^14.0.0", diff --git a/packages/paint/package.json b/packages/paint/package.json index d1675deb2..53ac02aa2 100644 --- a/packages/paint/package.json +++ b/packages/paint/package.json @@ -42,7 +42,7 @@ "react-style-proptype": "^3", "react-tooltip": "^3", "redux": "^3", - "clipcc-render-fonts": "^1.0.254" + "clipcc-render-fonts": "^1.0.256" }, "devDependencies": { "@babel/cli": "7.28.6", @@ -89,7 +89,7 @@ "regenerator-runtime": "0.14.1", "rimraf": "2.7.1", "clipcc-l10n": "3.2.0", - "clipcc-render-fonts": "1.0.254", + "clipcc-render-fonts": "1.0.256", "style-loader": "^4.0.0", "svg-url-loader": "^8.0.0", "terser-webpack-plugin": "^5.3.17", diff --git a/packages/render/package.json b/packages/render/package.json index f43ccd6c5..de2e2cdf6 100644 --- a/packages/render/package.json +++ b/packages/render/package.json @@ -39,7 +39,7 @@ "json": "9.0.6", "node-polyfill-webpack-plugin": "^3.0.0", "playwright-chromium": "1.13.0", - "clipcc-render-fonts": "1.0.254", + "clipcc-render-fonts": "1.0.256", "tap": "21.0.1", "terser-webpack-plugin": "^5.3.17", "travis-after-all": "1.4.5", @@ -50,12 +50,12 @@ "webpack-dev-server": "^5.2.3" }, "peerDependencies": { - "clipcc-render-fonts": "^1.0.254" + "clipcc-render-fonts": "^1.0.256" }, "dependencies": { "@turbowarp/nanolog": "^0.2.0", "clipcc-storage": "3.2.0", - "clipcc-svg-renderer": "2.5.47", + "clipcc-svg-renderer": "2.5.48", "grapheme-breaker": "0.3.2", "hull.js": "1.0.6", "ify-loader": "1.1.0", diff --git a/packages/render/src/SVGSkin.js b/packages/render/src/SVGSkin.js index c5bd76c50..0011dff11 100644 --- a/packages/render/src/SVGSkin.js +++ b/packages/render/src/SVGSkin.js @@ -193,7 +193,8 @@ class SVGSkin extends Skin { */ setSVG (svgData, rotationCenter) { const svgTag = loadSvgString(svgData); - const svgText = serializeSvgToString(svgTag, true /* shouldInjectFonts */); + let svgText = serializeSvgToString(svgTag, true /* shouldInjectFonts */); + svgText = svgText.replace(/"/g, "'"); this._svgImageLoaded = false; const {x, y, width, height} = svgTag.viewBox.baseVal; diff --git a/packages/vm/package.json b/packages/vm/package.json index 7393d9f49..49bc5170c 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -48,7 +48,7 @@ "scratch-translate-extension-languages": "1.0.7" }, "peerDependencies": { - "clipcc-svg-renderer": "2.5.47" + "clipcc-svg-renderer": "2.5.48" }, "devDependencies": { "@babel/core": "7.29.0", @@ -64,7 +64,7 @@ "clipcc-l10n": "3.2.0", "clipcc-render": "3.2.0", "clipcc-storage": "3.2.0", - "clipcc-svg-renderer": "2.5.47", + "clipcc-svg-renderer": "2.5.48", "codingclip-worker-loader": "^3.0.10", "copy-webpack-plugin": "^14.0.0", "eslint": "^9.39.2", @@ -76,7 +76,7 @@ "json": "^9.0.6", "lodash.defaultsdeep": "4.6.1", "pngjs": "7.0.0", - "clipcc-render-fonts": "1.0.254", + "clipcc-render-fonts": "1.0.256", "script-loader": "0.7.2", "stats.js": "0.17.0", "tap": "21.0.1", diff --git a/yarn.lock b/yarn.lock index a8ce6f2e8..8f7503f81 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6379,10 +6379,10 @@ cli@~1.0.0: exit "0.1.2" glob "^7.1.1" -clipcc-render-fonts@1.0.254: - version "1.0.254" - resolved "https://registry.yarnpkg.com/clipcc-render-fonts/-/clipcc-render-fonts-1.0.254.tgz#a4be42f96d6816a65c1a9377c50f12495b244245" - integrity sha512-InyRDUNkZ5NIZXjBXR42zezu9ZgBpKAzl0HvaRTajIGp/C5v40f7JdkvJiHT/P82M/s7qEi0ayi96mBNnVlm9Q== +clipcc-render-fonts@1.0.256: + version "1.0.256" + resolved "https://registry.yarnpkg.com/clipcc-render-fonts/-/clipcc-render-fonts-1.0.256.tgz#c7c789aefbab202c5a597e0bc8686d8f9dd5f36e" + integrity sha512-BUkYYtOs7Qo5biLgsFugxr0rzhDquC4q2wuraGCp7vl/6m6Vx9fg9gY5raKJz/+XSeBgj3Q7czV5FsrF8Z3mGg== dependencies: base64-loader "^1.0.0" @@ -6395,10 +6395,10 @@ clipcc-sb1-converter@1.0.326: fastestsmallesttextencoderdecoder "^1.0.22" js-md5 "^0.8.3" -clipcc-svg-renderer@2.5.47: - version "2.5.47" - resolved "https://registry.yarnpkg.com/clipcc-svg-renderer/-/clipcc-svg-renderer-2.5.47.tgz#0c3d688bcf3440ce03ce5097e9abd0ffb5b7692c" - integrity sha512-uRoadqG/oia8+1Xz5FurN0OTZOPbHEsXY8G6K5ZAn98E21mKqOK98AtSTk9NU38BCsGjTbbF80x4AVJOYZQM2w== +clipcc-svg-renderer@2.5.48: + version "2.5.48" + resolved "https://registry.yarnpkg.com/clipcc-svg-renderer/-/clipcc-svg-renderer-2.5.48.tgz#799fe871623ded51cd33aea2e075219277e4dde1" + integrity sha512-0B/bo7c2vTnlXGfawyUz1GbnKAFf9ubzeU9PIzhFO9zA4X4SWqWYAMY7sQmoyBx4iQh0rgyIBtXXUP31Jlwd0g== dependencies: "@turbowarp/nanolog" "^1.0.1" base64-js "^1.2.1" From 12590dd405b34e228eed8d8e408557c976f21bf3 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Mon, 9 Mar 2026 11:47:11 +0800 Subject: [PATCH 13/29] :wrench: chore(vm): load builtin extension esm-ify to make tap happy Signed-off-by: SimonShiki --- .../extension-support/extension-manager.js | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/vm/src/extension-support/extension-manager.js b/packages/vm/src/extension-support/extension-manager.js index 184c92fcc..deeb3610f 100644 --- a/packages/vm/src/extension-support/extension-manager.js +++ b/packages/vm/src/extension-support/extension-manager.js @@ -23,17 +23,20 @@ const builtinExtensions = { // This is an example that isn't loaded with the other core blocks, // but serves as a reference for loading core blocks as extensions. // These are the non-core built-in extensions. - pen: () => import(/* webpackChunkName: "ext_pen" */ '../extensions/scratch3_pen'), - wedo2: () => import(/* webpackChunkName: "ext_wedo2" */ '../extensions/scratch3_wedo2'), - music: () => import(/* webpackChunkName: "ext_music" */ '../extensions/scratch3_music'), - microbit: () => import(/* webpackChunkName: "ext_microbit" */ '../extensions/scratch3_microbit'), - text2speech: () => import(/* webpackChunkName: "ext_text2speech" */ '../extensions/scratch3_text2speech'), - translate: () => import(/* webpackChunkName: "ext_translate" */ '../extensions/scratch3_translate'), - videoSensing: () => import(/* webpackChunkName: "ext_videoSensing" */ '../extensions/scratch3_video_sensing'), - ev3: () => import(/* webpackChunkName: "ext_ev3" */ '../extensions/scratch3_ev3'), - makeymakey: () => import(/* webpackChunkName: "ext_makeymakey" */ '../extensions/scratch3_makeymakey'), - boost: () => import(/* webpackChunkName: "ext_boost" */ '../extensions/scratch3_boost'), - gdxfor: () => import(/* webpackChunkName: "ext_gdxfor" */ '../extensions/scratch3_gdx_for') + pen: () => import(/* webpackChunkName: "ext_pen" */ '../extensions/scratch3_pen/index.js'), + wedo2: () => import(/* webpackChunkName: "ext_wedo2" */ '../extensions/scratch3_wedo2/index.js'), + music: () => import(/* webpackChunkName: "ext_music" */ '../extensions/scratch3_music/index.js'), + microbit: () => import(/* webpackChunkName: "ext_microbit" */ '../extensions/scratch3_microbit/index.js'), + text2speech: () => import(/* webpackChunkName: "ext_text2speech" */ '../extensions/scratch3_text2speech/index.js'), + translate: () => import(/* webpackChunkName: "ext_translate" */ '../extensions/scratch3_translate/index.js'), + videoSensing: () => import( + /* webpackChunkName: "ext_videoSensing" */ + '../extensions/scratch3_video_sensing/index.js' + ), + ev3: () => import(/* webpackChunkName: "ext_ev3" */ '../extensions/scratch3_ev3/index.js'), + makeymakey: () => import(/* webpackChunkName: "ext_makeymakey" */ '../extensions/scratch3_makeymakey/index.js'), + boost: () => import(/* webpackChunkName: "ext_boost" */ '../extensions/scratch3_boost/index.js'), + gdxfor: () => import(/* webpackChunkName: "ext_gdxfor" */ '../extensions/scratch3_gdx_for/index.js') }; /** From fa80f5b9494909a979bc7d4ad1a4e44114c50df9 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Mon, 9 Mar 2026 12:10:45 +0800 Subject: [PATCH 14/29] :sparkles: feat(gui): optimize images on production mode Signed-off-by: SimonShiki --- packages/gui/package.json | 6 + packages/gui/webpack.config.js | 13 + yarn.lock | 1224 +++++++++++++++++++++++++++++++- 3 files changed, 1221 insertions(+), 22 deletions(-) diff --git a/packages/gui/package.json b/packages/gui/package.json index 6ad90f0ab..0f5241122 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -113,6 +113,12 @@ "eslint-plugin-react": "7.37.5", "globals": "^16.5.0", "html-webpack-plugin": "^5.6.6", + "image-minimizer-webpack-plugin": "^5.0.0", + "imagemin": "^9.0.1", + "imagemin-gifsicle": "^7.0.0", + "imagemin-jpegtran": "^8.0.0", + "imagemin-optipng": "^8.0.0", + "imagemin-svgo": "^12.0.0", "jest": "21.2.1", "jest-junit": "7.0.0", "jest-localstorage-mock": "^2.4.26", diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index 4170b68bb..fcab9b78a 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -8,6 +8,7 @@ const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); +const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin'); const STATIC_PATH = process.env.STATIC_PATH || '/static'; @@ -124,6 +125,18 @@ const base = { minimizer: [ new TerserPlugin({ include: /\.min\.js$/ + }), + new ImageMinimizerPlugin({ + minimizer: { + implementation: ImageMinimizerPlugin.imageminMinify, + options: { + plugins: [ + ['gifsicle', {interlaced: true}], + ['jpegtran', {progressive: true}], + ['optipng', {optimizationLevel: 5}] + ] + } + } }) ] }, diff --git a/yarn.lock b/yarn.lock index 8f7503f81..bd4cb9055 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1101,6 +1101,11 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz#bbe12dca5b4ef983a0d0af4b07b9bc90ea0ababa" integrity sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA== +"@borewit/text-codec@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@borewit/text-codec/-/text-codec-0.2.1.tgz#5d171538907a8cb395fdc2eb5e8f7947d96c7f2f" + integrity sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw== + "@bramus/specificity@^2.4.2": version "2.4.2" resolved "https://registry.yarnpkg.com/@bramus/specificity/-/specificity-2.4.2.tgz#aa8db8eb173fdee7324f82284833106adeecc648" @@ -1677,6 +1682,14 @@ resolved "https://registry.yarnpkg.com/@exodus/bytes/-/bytes-1.15.0.tgz#54479e0f406cbad024d6fe1c3190ecca4468df3b" integrity sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ== +"@file-type/xml@^0.4.3": + version "0.4.4" + resolved "https://registry.yarnpkg.com/@file-type/xml/-/xml-0.4.4.tgz#3b3efda7f12cbcfca26dcf5aebcf37a8ff882ade" + integrity sha512-NhCyXoHlVZ8TqM476hyzwGJ24+D5IPSaZhmrPj7qXnEVb3q6jrFzA3mM9TBpknKSI9EuQeGTKRg2DXGUwvBBoQ== + dependencies: + sax "^1.4.1" + strtok3 "^10.3.4" + "@formatjs/ecma402-abstract@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.5.0.tgz#759c8f11ff45e96f8fb58741e7fbdb41096d5ddd" @@ -2850,6 +2863,11 @@ resolved "https://registry.yarnpkg.com/@scratch/paper/-/paper-0.11.20221201200345.tgz#a7ebdd5083308c3bb9245b82e60ff6d5d6b86104" integrity sha512-I3BZNrHeaQJt2H6TD7HGsuBKJPDDF/BIDOaRvnN7Gj/QBRvpSaRK8JAmzcrRHZ+AqNtKrG50eOkS/acMjTw3rw== +"@sec-ant/readable-stream@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz#60de891bb126abfdc5410fdc6166aca065f10a0c" + integrity sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg== + "@sigstore/bundle@^2.3.2": version "2.3.2" resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-2.3.2.tgz#ad4dbb95d665405fd4a7a02c8a073dbd01e4e95e" @@ -2962,6 +2980,26 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/base62/-/base62-1.0.0.tgz#c47c42410e5212e4fa4657670e118ddfba39acd6" integrity sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA== +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + +"@sindresorhus/is@^6.3.0": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-6.3.1.tgz#43bbe2a94de0d7a11b95b7fc8100fa0e4694bbe0" + integrity sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ== + +"@sindresorhus/merge-streams@^2.1.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958" + integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg== + +"@sindresorhus/merge-streams@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz#abb11d99aeb6d27f1b563c38147a72d50058e339" + integrity sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ== + "@sinonjs/commons@^3.0.0", "@sinonjs/commons@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" @@ -3486,6 +3524,11 @@ resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.1.4.tgz#86e04e677cd6c05fa230dd15ac223fa72d1d7090" integrity sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g== +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + "@tootallnate/quickjs-emscripten@^0.23.0": version "0.23.0" resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c" @@ -4785,6 +4828,18 @@ append-transform@^0.4.0: dependencies: default-require-extensions "^1.0.0" +arch@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + +archive-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" + integrity sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA== + dependencies: + file-type "^4.2.0" + are-docs-informative@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/are-docs-informative/-/are-docs-informative-0.0.2.tgz#387f0e93f5d45280373d387a59d34c96db321963" @@ -5689,6 +5744,54 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +bin-build@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bin-build/-/bin-build-3.0.0.tgz#c5780a25a8a9f966d8244217e6c1f5082a143861" + integrity sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA== + dependencies: + decompress "^4.0.0" + download "^6.2.2" + execa "^0.7.0" + p-map-series "^1.0.0" + tempfile "^2.0.0" + +bin-check@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bin-check/-/bin-check-4.1.0.tgz#fc495970bdc88bb1d5a35fc17e65c4a149fc4a49" + integrity sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA== + dependencies: + execa "^0.7.0" + executable "^4.1.0" + +bin-version-check@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-4.0.0.tgz#7d819c62496991f80d893e6e02a3032361608f71" + integrity sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ== + dependencies: + bin-version "^3.0.0" + semver "^5.6.0" + semver-truncate "^1.1.2" + +bin-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-3.1.0.tgz#5b09eb280752b1bd28f0c9db3f96f2f43b6c0839" + integrity sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ== + dependencies: + execa "^1.0.0" + find-versions "^3.0.0" + +bin-wrapper@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bin-wrapper/-/bin-wrapper-4.1.0.tgz#99348f2cf85031e3ef7efce7e5300aeaae960605" + integrity sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q== + dependencies: + bin-check "^4.1.0" + bin-version-check "^4.0.0" + download "^7.1.0" + import-lazy "^3.1.0" + os-filter-obj "^2.0.0" + pify "^4.0.1" + binary-extensions@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" @@ -5935,6 +6038,19 @@ btoa@1.2.1: resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -5945,6 +6061,11 @@ buffer-equal@0.0.1: resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" integrity sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA== +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -5963,6 +6084,14 @@ buffer@6.0.3, buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" +buffer@^5.2.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -6057,6 +6186,19 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ== + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" @@ -6110,6 +6252,11 @@ callsites@^3.0.0, callsites@^3.1.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +callsites@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-4.2.0.tgz#98761d5be3ce092e4b9c92f7fb8c8eb9b83cadc8" + integrity sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ== + camel-case@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" @@ -6155,6 +6302,16 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== +caw@^2.0.0, caw@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" + integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== + dependencies: + get-proxy "^2.0.0" + isurl "^1.0.0-alpha5" + tunnel-agent "^0.6.0" + url-to-options "^1.0.1" + chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -6188,6 +6345,11 @@ chalk@^5.2.0, chalk@^5.3.0, chalk@^5.6.2: resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== +change-file-extension@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/change-file-extension/-/change-file-extension-0.1.1.tgz#46a342c4f327cdc0578ac7fc8412c364561da677" + integrity sha512-lB0j9teu8JtDPDHRfU8pNH33w4wMu5bOaKoT4PxH+AKugBrIfpiJMTTKIm0TErNeJPkeQEgvH31YpccTwOKPRg== + char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -6444,6 +6606,13 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q== + dependencies: + mimic-response "^1.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -6533,6 +6702,11 @@ command-exists-promise@^2.0.2: resolved "https://registry.yarnpkg.com/command-exists-promise/-/command-exists-promise-2.0.2.tgz#7beecc4b218299f3c61fa69a4047aa0b36a64a99" integrity sha512-T6PB6vdFrwnHXg/I0kivM3DqaCGZLjjYSOe0a5WgFKcz1sOnmOeIjnhQPXVXX3QjVbLyTJ85lJkX6lUpukTzaA== +commander@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" + integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== + commander@^12.1.0: version "12.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" @@ -6650,6 +6824,14 @@ concat-stream@^1.5.2, concat-stream@~1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + connect-history-api-fallback@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" @@ -6672,7 +6854,7 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== -content-disposition@~0.5.4: +content-disposition@^0.5.2, content-disposition@~0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== @@ -6704,6 +6886,11 @@ conventional-commits-parser@^6.3.0: "@simple-libs/stream-utils" "^1.2.0" meow "^13.0.0" +convert-hrtime@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/convert-hrtime/-/convert-hrtime-5.0.0.tgz#f2131236d4598b95de856926a67100a0a97e9fa3" + integrity sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg== + convert-source-map@^1.4.0, convert-source-map@^1.5.1: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" @@ -6890,6 +7077,17 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.0: + version "6.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57" + integrity sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + cross-spawn@^7.0.3, cross-spawn@^7.0.5, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" @@ -6980,7 +7178,7 @@ css-tree@^1.1.3: mdn-data "2.0.14" source-map "^0.6.1" -css-tree@^3.0.0, css-tree@^3.1.0: +css-tree@^3.0.0, css-tree@^3.0.1, css-tree@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-3.2.1.tgz#86cac7011561272b30e6b1e042ba6ce047aa7518" integrity sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA== @@ -6988,6 +7186,14 @@ css-tree@^3.0.0, css-tree@^3.1.0: mdn-data "2.27.1" source-map-js "^1.2.1" +css-tree@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" + integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== + dependencies: + mdn-data "2.0.28" + source-map-js "^1.0.1" + css-vendor@^0.3.1: version "0.3.8" resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-0.3.8.tgz#6421cfd3034ce664fe7673972fd0119fc28941fa" @@ -7010,6 +7216,13 @@ cssfontparser@^1.2.1: resolved "https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3" integrity sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg== +csso@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" + integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== + dependencies: + css-tree "~2.2.0" + cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" @@ -7191,6 +7404,66 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== +decompress-response@^3.2.0, decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw== + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^4.0.0, decompress@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + dedent@^1.0.0, dedent@^1.6.0: version "1.7.2" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.2.tgz#34e2264ab538301e27cf7b07bf2369c19baa8dd9" @@ -7551,6 +7824,48 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" +dot-prop@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-8.0.2.tgz#afda6866610684dd155a96538f8efcdf78a27f18" + integrity sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ== + dependencies: + type-fest "^3.8.0" + +download@^6.2.2: + version "6.2.5" + resolved "https://registry.yarnpkg.com/download/-/download-6.2.5.tgz#acd6a542e4cd0bb42ca70cfc98c9e43b07039714" + integrity sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA== + dependencies: + caw "^2.0.0" + content-disposition "^0.5.2" + decompress "^4.0.0" + ext-name "^5.0.0" + file-type "5.2.0" + filenamify "^2.0.0" + get-stream "^3.0.0" + got "^7.0.0" + make-dir "^1.0.0" + p-event "^1.0.0" + pify "^3.0.0" + +download@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/download/-/download-7.1.0.tgz#9059aa9d70b503ee76a132897be6dec8e5587233" + integrity sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ== + dependencies: + archive-type "^4.0.0" + caw "^2.0.1" + content-disposition "^0.5.2" + decompress "^4.2.0" + ext-name "^5.0.0" + file-type "^8.1.0" + filenamify "^2.0.0" + get-stream "^3.0.0" + got "^8.3.1" + make-dir "^1.2.0" + p-event "^2.1.0" + pify "^3.0.0" + dunder-proto@^1.0.0, dunder-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" @@ -7567,6 +7882,11 @@ duplexer2@^0.1.2, duplexer2@~0.1.4: dependencies: readable-stream "^2.0.2" +duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -7647,7 +7967,7 @@ encoding@^0.1.11, encoding@^0.1.13: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.1.0: +end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.5" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== @@ -8558,6 +8878,17 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" +exec-buffer@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/exec-buffer/-/exec-buffer-3.2.0.tgz#b1686dbd904c7cf982e652c1f5a79b1e5573082b" + integrity sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA== + dependencies: + execa "^0.7.0" + p-finally "^1.0.0" + pify "^3.0.0" + rimraf "^2.5.4" + tempfile "^2.0.0" + exec-sh@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" @@ -8578,6 +8909,19 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -8593,6 +8937,31 @@ execa@^5.0.0, execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +execa@^9.4.0: + version "9.6.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-9.6.1.tgz#5b90acedc6bdc0fa9b9a6ddf8f9cbb0c75a7c471" + integrity sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA== + dependencies: + "@sindresorhus/merge-streams" "^4.0.0" + cross-spawn "^7.0.6" + figures "^6.1.0" + get-stream "^9.0.0" + human-signals "^8.0.1" + is-plain-obj "^4.1.0" + is-stream "^4.0.1" + npm-run-path "^6.0.0" + pretty-ms "^9.2.0" + signal-exit "^4.1.0" + strip-final-newline "^4.0.0" + yoctocolors "^2.1.1" + +executable@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + exenv@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" @@ -8729,6 +9098,21 @@ express@^4.22.1: utils-merge "1.0.1" vary "~1.1.2" +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + ext@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" @@ -8821,7 +9205,12 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.9, fast-glob@^3.3.2: +fast-equals@^5.0.1: + version "5.4.0" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.4.0.tgz#b60073b8764f27029598447f05773c7534ba7f1e" + integrity sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw== + +fast-glob@^3.2.9, fast-glob@^3.3.2, fast-glob@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== @@ -8911,6 +9300,13 @@ figures@^1.3.5: escape-string-regexp "^1.0.5" object-assign "^4.1.0" +figures@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-6.1.0.tgz#935479f51865fa7479f6fa94fc6fc7ac14e62c4a" + integrity sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg== + dependencies: + is-unicode-supported "^2.0.0" + file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" @@ -8934,6 +9330,46 @@ file-loader@6.2.0, file-loader@~6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" +file-type@5.2.0, file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ== + +file-type@^10.4.0: + version "10.11.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.11.0.tgz#2961d09e4675b9fb9a3ee6b69e9cd23f43fd1890" + integrity sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw== + +file-type@^19.0.0, file-type@^19.5.0: + version "19.6.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-19.6.0.tgz#b43d8870453363891884cf5e79bb3e4464f2efd3" + integrity sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ== + dependencies: + get-stream "^9.0.1" + strtok3 "^9.0.1" + token-types "^6.0.0" + uint8array-extras "^1.3.0" + +file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== + +file-type@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" + integrity sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ== + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + +file-type@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-8.1.0.tgz#244f3b7ef641bbe0cca196c7276e4b332399f68c" + integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ== + file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" @@ -8951,6 +9387,20 @@ filename-regex@^2.0.0: resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" integrity sha512-BTCqyBaWBTsauvnHiE8i562+EdJj+oUpkqWp2R1iCoR8f6oo8STRu3of7WJJ0TqWtxN50a5YFpzYK4Jj9esYfQ== +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ== + +filenamify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9" + integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + fileset@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" @@ -9052,6 +9502,13 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-versions@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" + integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== + dependencies: + semver-regex "^2.0.0" + findup@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/findup/-/findup-0.1.5.tgz#8ad929a3393bac627957a7e5de4623b06b0e2ceb" @@ -9272,7 +9729,7 @@ from2-array@0.0.4: dependencies: from2 "^2.0.3" -from2@^2.0.3: +from2@^2.0.3, from2@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== @@ -9285,6 +9742,11 @@ fromentries@^1.2.0: resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -9350,6 +9812,11 @@ function-loop@^4.0.0: resolved "https://registry.yarnpkg.com/function-loop/-/function-loop-4.0.0.tgz#12c57cfb9fe08f77532e8b1357242aca2a02c858" integrity sha512-f34iQBedYF3XcI93uewZZOnyscDragxgTK/eTvVB74k3fCD0ZorOi5BV9GS4M8rz/JoNi0Kl3qX5Y9MH3S/CLQ== +function-timeout@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/function-timeout/-/function-timeout-1.0.2.tgz#e5a7b6ffa523756ff20e1231bbe37b5f373aadd5" + integrity sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA== + function.prototype.name@^1.1.2, function.prototype.name@^1.1.6, function.prototype.name@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.8.tgz#e68e1df7b259a5c949eeef95cdbde53edffabb78" @@ -9440,11 +9907,33 @@ get-proto@^1.0.0, get-proto@^1.0.1: dunder-proto "^1.0.1" es-object-atoms "^1.0.0" -get-stream@^3.0.0: +get-proxy@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" + integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== + dependencies: + npm-conf "^1.1.0" + +get-stream@3.0.0, get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA== + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -9457,6 +9946,14 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-stream@^9.0.0, get-stream@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-9.0.1.tgz#95157d21df8eb90d1647102b63039b1df60ebd27" + integrity sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA== + dependencies: + "@sec-ant/readable-stream" "^0.4.1" + is-stream "^4.0.1" + get-symbol-description@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz#7bdd54e0befe8ffc9f3b4e203220d9f1e881b6ee" @@ -9492,6 +9989,15 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +gifsicle@^5.0.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/gifsicle/-/gifsicle-5.3.0.tgz#499713c6f1e89ebbc3630da3a74fdb4697913b4e" + integrity sha512-FJTpgdj1Ow/FITB7SVza5HlzXa+/lqEY0tHQazAJbuAdvyJtkH4wIdsR2K414oaTwRXHFLLF+tYbipj+OpYg+Q== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + execa "^5.0.0" + git-raw-commits@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-4.0.0.tgz#b212fd2bff9726d27c1283a1157e829490593285" @@ -9651,12 +10157,67 @@ globby@^11.0.0, globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +globby@^14.0.1: + version "14.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-14.1.0.tgz#138b78e77cf5a8d794e327b15dce80bf1fb0a73e" + integrity sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA== + dependencies: + "@sindresorhus/merge-streams" "^2.1.0" + fast-glob "^3.3.3" + ignore "^7.0.3" + path-type "^6.0.0" + slash "^5.1.0" + unicorn-magic "^0.3.0" + gopd@^1.0.1, gopd@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +got@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -9750,11 +10311,23 @@ has-proto@^1.2.0: dependencies: dunder-proto "^1.0.0" +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + has-symbols@^1.0.3, has-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + has-tostringtag@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" @@ -10017,6 +10590,11 @@ htmlparser2@^8.0.1: domutils "^3.0.1" entities "^4.4.0" +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + http-cache-semantics@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" @@ -10127,6 +10705,11 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +human-signals@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-8.0.1.tgz#f08bb593b6d1db353933d06156cedec90abe51fb" + integrity sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ== + husky@^9.1.7: version "9.1.7" resolved "https://registry.yarnpkg.com/husky/-/husky-9.1.7.tgz#d46a38035d101b46a70456a850ff4201344c0b2d" @@ -10168,7 +10751,14 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.2.1: +identifier-regex@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/identifier-regex/-/identifier-regex-1.0.1.tgz#65fc1c16eebad54adcbec7eb9c99e8a926adfd29" + integrity sha512-ZrYyM0sozNPZlvBvE7Oq9Bn44n0qKGrYu5sQ0JzMUnjIhpgWYE2JB6aBoFwEYdPjqj7jPyxXTMJiHDOxDfd8yw== + dependencies: + reserved-identifiers "^1.0.0" + +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -10210,11 +10800,77 @@ ignore@^5.2.0, ignore@^5.3.1: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== -ignore@^7.0.5: +ignore@^7.0.3, ignore@^7.0.5: version "7.0.5" resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9" integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== +image-dimensions@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/image-dimensions/-/image-dimensions-2.5.0.tgz#57476c343228fb73beccdfd2686d2633f35f382b" + integrity sha512-CKZPHjAEtSg9lBV9eER0bhNn/yrY7cFEQEhkwjLhqLY+Na8lcP1pEyWsaGMGc8t2qbKWA/tuqbhFQpOKGN72Yw== + +image-minimizer-webpack-plugin@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/image-minimizer-webpack-plugin/-/image-minimizer-webpack-plugin-5.0.0.tgz#4f040534d61457db268ad301cae198c891c2280a" + integrity sha512-TSeES2mTBY1smDnQRIaTGR9EdS1xGvWsaMu+XJRlh6z7VAWHmyYR6P5AynvVHMcmK4NdvmSlRJTNWgvpeNSPuA== + dependencies: + schema-utils "^4.2.0" + serialize-javascript "^7.0.3" + +imagemin-gifsicle@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/imagemin-gifsicle/-/imagemin-gifsicle-7.0.0.tgz#1a7ab136a144c4678657ba3b6c412f80805d26b0" + integrity sha512-LaP38xhxAwS3W8PFh4y5iQ6feoTSF+dTAXFRUEYQWYst6Xd+9L/iPk34QGgK/VO/objmIlmq9TStGfVY2IcHIA== + dependencies: + execa "^1.0.0" + gifsicle "^5.0.0" + is-gif "^3.0.0" + +imagemin-jpegtran@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/imagemin-jpegtran/-/imagemin-jpegtran-8.0.0.tgz#16462e11d5ff3b5839d34b982ec9e42975e09d27" + integrity sha512-iGaaImltX4oJ1lmS9jb7Qw3NRusQnVBr7hYJuhyL0CHRV42pDMkIGBVCHKA9j9mcWHnO5Ryu3LV7t4fU4sC4xg== + dependencies: + execa "^9.4.0" + file-type "^19.5.0" + image-dimensions "^2.3.0" + jpegtran-bin "^7.0.0" + uint8array-extras "^1.4.0" + +imagemin-optipng@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/imagemin-optipng/-/imagemin-optipng-8.0.0.tgz#b88e5cf6da25cc8479e07cdf38c3ae0479df7ef2" + integrity sha512-CUGfhfwqlPjAC0rm8Fy+R2DJDBGjzy2SkfyT09L8rasnF9jSoHFqJ1xxSZWK6HVPZBMhGPMxCTL70OgTHlLF5A== + dependencies: + exec-buffer "^3.0.0" + is-png "^2.0.0" + optipng-bin "^7.0.0" + +imagemin-svgo@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/imagemin-svgo/-/imagemin-svgo-12.0.0.tgz#47dbafdad96c2cafbca8a4d798a08cec616b0a65" + integrity sha512-6f2bS/QTBsGafHCvG3FPxe3efHWq7EryznpDPg1PnfhnD4JO90sKrzW4W4AcN2HoWBsZl4yqiBWw/qxIWiPHJA== + dependencies: + is-svg "^6.1.0" + svgo "^4.0.0" + +imagemin@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/imagemin/-/imagemin-9.0.1.tgz#637214985aeb365e8f80e57b15ddeaa91e78ef8b" + integrity sha512-UoHOfynN8QeqRoUGunn6ilMnLpJ+utbmleP2ufcFqaGal8mY/PeOpV43N31uqtb+CBMFqQ7hxgKzIaAAnmcrdA== + dependencies: + change-file-extension "^0.1.1" + environment "^1.0.0" + file-type "^19.0.0" + globby "^14.0.1" + image-dimensions "^2.3.0" + junk "^4.0.1" + ow "^2.0.0" + p-pipe "^4.0.0" + slash "^5.1.0" + uint8array-extras "^1.1.0" + immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -10233,6 +10889,11 @@ import-fresh@^3.2.1, import-fresh@^3.3.0: parent-module "^1.0.0" resolve-from "^4.0.0" +import-lazy@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-3.1.0.tgz#891279202c8a2280fdbd6674dbd8da1a1dfc67cc" + integrity sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ== + import-local@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" @@ -10292,6 +10953,11 @@ ini@4.1.1: resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1" integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g== +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + ini@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.3.tgz#4c359675a6071a46985eb39b14e4a2c0ec98a795" @@ -10407,6 +11073,14 @@ intl-relativeformat@^2.1.0: dependencies: intl-messageformat "^2.0.0" +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ== + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + invariant@^2.0.0, invariant@^2.1.1, invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -10683,6 +11357,13 @@ is-generator-function@^1.0.10, is-generator-function@^1.0.7: has-tostringtag "^1.0.2" safe-regex-test "^1.1.0" +is-gif@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-gif/-/is-gif-3.0.0.tgz#c4be60b26a301d695bb833b20d9b5d66c6cf83b1" + integrity sha512-IqJ/jlbw5WJSNfwQ/lHEDXF8rxhRgF6ythk2oiEvhpG29F704eX9NO6TvPfMiq9DrbwgcEDnETYNcZDPewQoVw== + dependencies: + file-type "^10.4.0" + is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -10697,6 +11378,14 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-identifier@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-identifier/-/is-identifier-1.0.1.tgz#76d66e7813e37cc85cc8263f04eaa558d1a5d2dc" + integrity sha512-HQ5v4rEJ7REUV54bCd2l5FaD299SGDEn2UPoVXaTHAyGviLq2menVUD2udi3trQ32uvB6LdAh/0ck2EuizrtpA== + dependencies: + identifier-regex "^1.0.0" + super-regex "^1.0.0" + is-in-browser@^1.0.2: version "1.1.3" resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" @@ -10748,6 +11437,11 @@ is-nan@^1.3.2: call-bind "^1.0.0" define-properties "^1.1.3" +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== + is-negative-zero@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" @@ -10795,6 +11489,16 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== +is-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + is-plain-obj@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" @@ -10817,6 +11521,11 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-png@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d" + integrity sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g== + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -10852,6 +11561,11 @@ is-resolvable@^1.0.0: resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + is-set@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" @@ -10864,7 +11578,7 @@ is-shared-array-buffer@^1.0.4: dependencies: call-bound "^1.0.3" -is-stream@^1.0.1, is-stream@^1.1.0: +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== @@ -10874,6 +11588,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-stream@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-4.0.1.tgz#375cf891e16d2e4baec250b85926cffc14720d9b" + integrity sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A== + is-string@^1.0.5, is-string@^1.0.7, is-string@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.1.1.tgz#92ea3f3d5c5b6e039ca8677e5ac8d07ea773cbb9" @@ -10894,6 +11613,13 @@ is-subset@^0.1.1: resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" integrity sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw== +is-svg@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-6.1.0.tgz#b75936327dcbd3fa3af1f1098d5390245fbdd8b1" + integrity sha512-i7YPdvYuSCYcaLQrKwt8cvKTlwHcdA6Hp8N9SO3Q5jIzo8x6kH3N47W0BvPP7NdxVBmIHx7X9DK36czYYW7lHg== + dependencies: + "@file-type/xml" "^0.4.3" + is-symbol@^1.0.4, is-symbol@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.1.1.tgz#f47761279f532e2b05a7024a7506dbbedacd0634" @@ -10915,6 +11641,11 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== +is-unicode-supported@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz#09f0ab0de6d3744d48d265ebb98f65d11f2a9b3a" + integrity sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ== + is-url@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" @@ -11166,6 +11897,14 @@ istanbul-reports@^3.1.3, istanbul-reports@^3.1.6: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + iterator.prototype@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.5.tgz#12c959a29de32de0aa3bbbb801f4d777066dae39" @@ -12525,6 +13264,14 @@ jpeg-js@^0.4.2: resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.4.tgz#a9f1c6f1f9f0fa80cdb3484ed9635054d28936aa" integrity sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg== +jpegtran-bin@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/jpegtran-bin/-/jpegtran-bin-7.0.0.tgz#9da72fc9e59b3cd45f2bafc5324c56c341141ae7" + integrity sha512-8ecI4vXIV7eI2+nzRQsHAVaQVBGDotUY76CJZhlYaBAljBnK/509+sGGCs8eJyiS5N4tOcYZS+8Q4KgzorqlBA== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + js-base64@2.4.9: version "2.4.9" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03" @@ -12714,6 +13461,11 @@ jshint@2.9.7: shelljs "0.3.x" strip-json-comments "1.0.x" +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -12856,11 +13608,23 @@ jszip@3.10.1, jszip@^3.1.3, jszip@^3.10.1: readable-stream "~2.3.6" setimmediate "^1.0.5" +junk@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/junk/-/junk-4.0.1.tgz#7ee31f876388c05177fe36529ee714b07b50fbed" + integrity sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ== + keymirror@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/keymirror/-/keymirror-0.1.1.tgz#918889ea13f8d0a42e7c557250eee713adc95c35" integrity sha512-vIkZAFWoDijgQT/Nvl2AHCMmnegN2ehgTPYuyy2hWQkQSntI0S7ESYqdLkoSe1HyEBFHHkCgSIvVdSEiWwKvCg== +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -13183,6 +13947,16 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A== + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + lru-cache@^10.0.1, lru-cache@^10.2.0, lru-cache@^10.4.3: version "10.4.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" @@ -13225,6 +13999,22 @@ magic-string@^0.22.4: dependencies: vlq "^0.2.2" +make-asynchronous@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/make-asynchronous/-/make-asynchronous-1.1.0.tgz#6225f7f1ccaab9acaac5e2fcd0b075afefff19aa" + integrity sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg== + dependencies: + p-event "^6.0.0" + type-fest "^4.6.0" + web-worker "^1.5.0" + +make-dir@^1.0.0, make-dir@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -13337,6 +14127,11 @@ mdn-data@2.0.14: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== +mdn-data@2.0.28: + version "2.0.28" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" + integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== + mdn-data@2.27.1: version "2.27.1" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.27.1.tgz#e37b9c50880b75366c4d40ac63d9bbcacdb61f0e" @@ -13487,7 +14282,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -"mime-db@>= 1.43.0 < 2", mime-db@^1.54.0: +"mime-db@>= 1.43.0 < 2", mime-db@^1.28.0, mime-db@^1.54.0: version "1.54.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== @@ -13526,6 +14321,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + min-document@^2.19.0: version "2.19.2" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.2.tgz#f95db44639eaae3ac8ea85ae6809ae85ff7e3b81" @@ -13831,6 +14631,11 @@ next-tick@^1.1.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + no-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" @@ -14002,6 +14807,15 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + npm-bundled@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.1.tgz#cca73e15560237696254b10170d8f86dad62da25" @@ -14016,6 +14830,14 @@ npm-bundled@^5.0.0: dependencies: npm-normalize-package-bin "^5.0.0" +npm-conf@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + npm-install-checks@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" @@ -14142,6 +14964,14 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-run-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-6.0.0.tgz#25cfdc4eae04976f3349c0b1afc089052c362537" + integrity sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA== + dependencies: + path-key "^4.0.0" + unicorn-magic "^0.3.0" + nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" @@ -14389,11 +15219,26 @@ optionator@^0.9.3: type-check "^0.4.0" word-wrap "^1.2.5" +optipng-bin@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/optipng-bin/-/optipng-bin-7.0.1.tgz#beb8e55a52f8a26f885ee57ab44fcf62397d6972" + integrity sha512-W99mpdW7Nt2PpFiaO+74pkht7KEqkXkeRomdWXfEz3SALZ6hns81y/pm1dsGZ6ItUIfchiNIP6ORDr1zETU1jA== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== +os-filter-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/os-filter-obj/-/os-filter-obj-2.0.0.tgz#1c0b62d5f3a2442749a2d139e6dddee6e81d8d16" + integrity sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg== + dependencies: + arch "^2.1.0" + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -14418,6 +15263,18 @@ outdent@^0.5.0: resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.5.0.tgz#9e10982fdc41492bb473ad13840d22f9655be2ff" integrity sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q== +ow@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ow/-/ow-2.0.0.tgz#07690490ac9783b37241c4ebee32dfcab1b20ee1" + integrity sha512-ESUigmGrdhUZ2nQSFNkeKSl6ZRPupXzprMs3yF9DYlNVpJ8XAjM/fI9RUZxA7PI1K9HQDCCvBo1jr/GEIo9joQ== + dependencies: + "@sindresorhus/is" "^6.3.0" + callsites "^4.1.0" + dot-prop "^8.0.2" + environment "^1.0.0" + fast-equals "^5.0.1" + is-identifier "^1.0.0" + own-keys@^1.0.0, own-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.1.tgz#e4006910a2bf913585289676eebd6f390cf51358" @@ -14432,6 +15289,32 @@ p-cancelable@^0.3.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + +p-event@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-1.3.0.tgz#8e6b4f4f65c72bc5b6fe28b75eda874f96a4a085" + integrity sha512-hV1zbA7gwqPVFcapfeATaNjQ3J0NuzorHPyG8GPL9g/Y/TplWVBVoCKCXL6Ej2zscrCEv195QNWJXuBH6XZuzA== + dependencies: + p-timeout "^1.1.1" + +p-event@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" + integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== + dependencies: + p-timeout "^2.0.1" + +p-event@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-6.0.1.tgz#8f62a1e3616d4bc01fce3abda127e0383ef4715b" + integrity sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w== + dependencies: + p-timeout "^6.1.2" + p-filter@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" @@ -14444,6 +15327,11 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg== + p-limit@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68" @@ -14500,6 +15388,13 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-map-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-1.0.0.tgz#bf98fe575705658a9e1351befb85ae4c1f07bdca" + integrity sha512-4k9LlvY6Bo/1FcIdV33wqZQES0Py+iKISU9Uc8p8AjWoZPnFKMpVIVD3s0EYn4jzLh1I+WeUZkJ0Yoa4Qfw3Kg== + dependencies: + p-reduce "^1.0.0" + p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -14517,11 +15412,21 @@ p-map@^7.0.2: resolved "https://registry.yarnpkg.com/p-map/-/p-map-7.0.4.tgz#b81814255f542e252d5729dca4d66e5ec14935b8" integrity sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ== +p-pipe@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-4.0.0.tgz#7e5424569351b2ab452a47826acb93ce09ad6a2c" + integrity sha512-HkPfFklpZQPUKBFXzKFB6ihLriIHxnmuQdK9WmLDwe4hf2PdhhfWT/FJa+pc3bA1ywvKXtedxIRmd4Y7BTXE4w== + p-queue@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-3.0.0.tgz#0ef247082f0dd5a21b66e2cfe8fb7b06db13fb52" integrity sha512-2tv/MRmPXfmfnjLLJAHl+DdU8p2DhZafAnlpm/C/T5BpF5L9wKz5tMin4A4N2zVpJL2YMhPlRmtO7s5EtNrjfA== +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha512-3Tx1T3oM1xO/Y8Gj0sWyE78EIJZ+t+aEmXUdvQgvGmSMri7aPTHoovbXEreWKkL5j21Er60XAWLTzKbAKYOujQ== + p-retry@^6.2.0: version "6.2.1" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-6.2.1.tgz#81828f8dc61c6ef5a800585491572cc9892703af" @@ -14531,6 +15436,25 @@ p-retry@^6.2.0: is-network-error "^1.0.0" retry "^0.13.1" +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + integrity sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA== + dependencies: + p-finally "^1.0.0" + +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + +p-timeout@^6.1.2: + version "6.1.4" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-6.1.4.tgz#418e1f4dd833fa96a2e3f532547dd2abdb08dbc2" + integrity sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg== + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -14708,6 +15632,11 @@ parse-json@^5.0.0, parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-ms@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-4.0.0.tgz#c0c058edd47c2a590151a718990533fd62803df4" + integrity sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw== + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -14805,7 +15734,7 @@ path-is-inside@^1.0.1: resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== -path-key@^2.0.0: +path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== @@ -14815,6 +15744,11 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.5, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -14862,6 +15796,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +path-type@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-6.0.0.tgz#2f1bb6791a91ce99194caede5d6c5920ed81eb51" + integrity sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ== + pbkdf2@^3.1.2, pbkdf2@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.5.tgz#444a59d7a259a95536c56e80c89de31cc01ed366" @@ -14874,6 +15813,11 @@ pbkdf2@^3.1.2, pbkdf2@^3.1.5: sha.js "^2.4.12" to-buffer "^1.2.1" +peek-readable@^5.3.1: + version "5.4.2" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.4.2.tgz#aff1e1ba27a7d6911ddb103f35252ffc1787af49" + integrity sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg== + pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" @@ -14909,7 +15853,7 @@ pify@4.0.1, pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pify@^2.0.0, pify@^2.3.0: +pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== @@ -15130,6 +16074,16 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg== + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" @@ -15192,6 +16146,13 @@ pretty-format@^29.0.0, pretty-format@^29.7.0: ansi-styles "^5.0.0" react-is "^18.0.0" +pretty-ms@^9.2.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-9.3.0.tgz#dd2524fcb3c326b4931b2272dfd1e1a8ed9a9f5a" + integrity sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ== + dependencies: + parse-ms "^4.0.0" + prismjs-terminal@^1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/prismjs-terminal/-/prismjs-terminal-1.2.4.tgz#e79747acdf428bda8ea56efb81d75f699bdb0657" @@ -15311,6 +16272,11 @@ proper-lockfile@^4.1.1: retry "^0.12.0" signal-exit "^3.0.2" +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -15436,7 +16402,7 @@ quansync@^0.2.7: resolved "https://registry.yarnpkg.com/quansync/-/quansync-0.2.11.tgz#f9c3adda2e1272e4f8cf3f1457b04cbdb4ee692a" integrity sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA== -query-string@^5.1.1: +query-string@^5.0.1, query-string@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== @@ -15859,7 +16825,7 @@ readable-stream@1.1: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@^2.3.8, readable-stream@~2.3.3, readable-stream@~2.3.6: +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@^2.3.8, readable-stream@~2.3.3, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -16263,6 +17229,13 @@ resolve@^2.0.0-next.5: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + restore-cursor@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" @@ -16461,7 +17434,7 @@ sanitize-html-react@^1.13.0: regexp-quote "0.0.0" xtend "^4.0.0" -sax@>=0.6.0, sax@^1.2.1, sax@^1.2.4: +sax@>=0.6.0, sax@^1.2.1, sax@^1.2.4, sax@^1.4.1, sax@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/sax/-/sax-1.5.0.tgz#b5549b671069b7aa392df55ec7574cf411179eb8" integrity sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA== @@ -16526,6 +17499,13 @@ script-loader@0.7.2: dependencies: raw-loader "~0.5.1" +seek-bzip@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" + integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== + dependencies: + commander "^2.8.1" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -16549,6 +17529,18 @@ selfsigned@^5.5.0: "@peculiar/x509" "^1.14.2" pkijs "^3.3.3" +semver-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" + integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== + +semver-truncate@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-1.1.2.tgz#57f41de69707a62709a7e0104ba2117109ea47e8" + integrity sha512-V1fGg9i4CL3qesB6U0L6XAm4xOJiHmt4QAacazumuasc03BvtFGIMCduv01JWQ69Nv+JST9TqhSCiJoxoY031w== + dependencies: + semver "^5.3.0" + "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0, semver@^5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" @@ -16852,6 +17844,11 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slash@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce" + integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg== + slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" @@ -16934,7 +17931,28 @@ socks@^2.8.3: ip-address "^10.0.1" smart-buffer "^4.2.0" -source-map-js@^1.0.2, source-map-js@^1.2.1: +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw== + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg== + dependencies: + is-plain-obj "^1.0.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== + dependencies: + is-plain-obj "^1.0.0" + +source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== @@ -17423,6 +18441,13 @@ strip-bom@^4.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -17433,6 +18458,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-final-newline@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz#35a369ec2ac43df356e3edd5dcebb6429aa1fa5c" + integrity sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw== + strip-json-comments@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" @@ -17448,11 +18478,42 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== +strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + +strtok3@^10.3.4: + version "10.3.4" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-10.3.4.tgz#793ebd0d59df276a085586134b73a406e60be9c1" + integrity sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg== + dependencies: + "@tokenizer/token" "^0.3.0" + +strtok3@^9.0.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-9.1.1.tgz#f8feb188b3fcdbf9b8819cc9211a824c3731df38" + integrity sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^5.3.1" + style-loader@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-4.0.0.tgz#0ea96e468f43c69600011e0589cb05c44f3b17a5" integrity sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA== +super-regex@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/super-regex/-/super-regex-1.1.0.tgz#14b69b6374f7b3338db52ecd511dae97c27acf75" + integrity sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ== + dependencies: + function-timeout "^1.0.1" + make-asynchronous "^1.0.1" + time-span "^5.1.0" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -17498,6 +18559,19 @@ svg-url-loader@^8.0.0: dependencies: file-loader "~6.2.0" +svgo@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-4.0.1.tgz#c82dacd04ee9f1d55cd4e0b7f9a214c86670e3ee" + integrity sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w== + dependencies: + commander "^11.1.0" + css-select "^5.1.0" + css-tree "^3.0.1" + css-what "^6.1.0" + csso "^5.0.5" + picocolors "^1.1.1" + sax "^1.5.0" + symbol-observable@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" @@ -17631,6 +18705,19 @@ tapable@^2.0.0, tapable@^2.3.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== +tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + tar@^6.1.11, tar@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" @@ -17678,6 +18765,19 @@ tcp-port-used@^1.0.2: debug "4.3.1" is2 "^2.0.6" +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ== + +tempfile@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" + integrity sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA== + dependencies: + temp-dir "^1.0.0" + uuid "^3.0.1" + term-size@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" @@ -17755,7 +18855,7 @@ through2@^2.0.0, through2@~2.0.3: readable-stream "~2.3.6" xtend "~4.0.1" -through@^2.3.6: +through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== @@ -17765,6 +18865,18 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== +time-span@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/time-span/-/time-span-5.1.0.tgz#80c76cf5a0ca28e0842d3f10a4e99034ce94b90d" + integrity sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA== + dependencies: + convert-hrtime "^5.0.0" + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== + timers-browserify@^2.0.12: version "2.0.12" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" @@ -17833,7 +18945,7 @@ tmpl@1.0.5: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== -to-buffer@^1.2.0, to-buffer@^1.2.1, to-buffer@^1.2.2: +to-buffer@^1.1.1, to-buffer@^1.2.0, to-buffer@^1.2.1, to-buffer@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.2.tgz#ffe59ef7522ada0a2d1cb5dfe03bb8abc3cdc133" integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw== @@ -17897,6 +19009,15 @@ toidentifier@1.0.1, toidentifier@~1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +token-types@^6.0.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.1.2.tgz#18d0fd59b996d421f9f83914d6101c201bd08129" + integrity sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww== + dependencies: + "@borewit/text-codec" "^0.2.1" + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + totalist@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" @@ -17965,6 +19086,13 @@ tree-dump@^1.0.3, tree-dump@^1.1.0: resolved "https://registry.yarnpkg.com/tree-dump/-/tree-dump-1.1.0.tgz#ab29129169dc46004414f5a9d4a3c6e89f13e8a4" integrity sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA== +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg== + dependencies: + escape-string-regexp "^1.0.2" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -18148,7 +19276,12 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@^4.27.0, type-fest@^4.4.0, type-fest@^4.41.0: +type-fest@^3.8.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" + integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== + +type-fest@^4.27.0, type-fest@^4.4.0, type-fest@^4.41.0, type-fest@^4.6.0: version "4.41.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== @@ -18251,6 +19384,11 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== +uint8array-extras@^1.1.0, uint8array-extras@^1.3.0, uint8array-extras@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/uint8array-extras/-/uint8array-extras-1.5.0.tgz#10d2a85213de3ada304fea1c454f635c73839e86" + integrity sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A== + unbox-primitive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz#8d9d2c9edeea8460c7f35033a88867944934d1e2" @@ -18261,6 +19399,14 @@ unbox-primitive@^1.1.0: has-symbols "^1.1.0" which-boxed-primitive "^1.1.1" +unbzip2-stream@^1.0.9: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + undici-types@~7.18.0: version "7.18.2" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.18.2.tgz#29357a89e7b7ca4aef3bf0fd3fd0cd73884229e9" @@ -18302,6 +19448,11 @@ unicode-trie@^0.3.0, unicode-trie@^0.3.1: pako "^0.2.5" tiny-inflate "^1.0.0" +unicorn-magic@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz#4efd45c85a69e0dd576d25532fbfa22aa5c8a104" + integrity sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA== + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -18405,6 +19556,25 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA== + dependencies: + prepend-http "^1.0.1" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A== + url@^0.11.3: version "0.11.4" resolved "https://registry.yarnpkg.com/url/-/url-0.11.4.tgz#adca77b3562d56b72746e76b330b7f27b6721f3c" @@ -18469,7 +19639,7 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^3.3.2: +uuid@^3.0.1, uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== @@ -18608,6 +19778,11 @@ web-audio-test-api@0.5.2: resolved "https://registry.yarnpkg.com/web-audio-test-api/-/web-audio-test-api-0.5.2.tgz#c1e24d21ced0603f1a495272a1eb669db28873fa" integrity sha512-RevLfVjp+wwe/dBPe361IpmNpeXXW6JVmlp8dk0YIxLwAh7evn6JpEQQalVgX4PH/jA8tpLpjD/8tFNUYTf88w== +web-worker@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.5.0.tgz#71b2b0fbcc4293e8f0aa4f6b8a3ffebff733dcc5" + integrity sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -19241,7 +20416,7 @@ yargs@^9.0.0: y18n "^3.2.1" yargs-parser "^7.0.0" -yauzl@2.10.0, yauzl@^2.10.0: +yauzl@2.10.0, yauzl@^2.10.0, yauzl@^2.4.2: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== @@ -19269,6 +20444,11 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yoctocolors@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yoctocolors/-/yoctocolors-2.1.2.tgz#d795f54d173494e7d8db93150cec0ed7f678c83a" + integrity sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug== + yoga-layout@~3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/yoga-layout/-/yoga-layout-3.2.1.tgz#d2d1ba06f0e81c2eb650c3e5ad8b0b4adde1e843" From 5e3247672cb90b428c788e1ad4a3de0257bcf8c2 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Mon, 9 Mar 2026 14:40:22 +0800 Subject: [PATCH 15/29] :bug: fix(gui): broken sound thumbnail Signed-off-by: SimonShiki --- .../gui/src/lib/backpack/sound-thumbnail.jpg | Bin 1278 -> 1721 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/packages/gui/src/lib/backpack/sound-thumbnail.jpg b/packages/gui/src/lib/backpack/sound-thumbnail.jpg index f709aaa137f42fba5368fb432fb4af7cadb9b7b4..1d5e58a85dea20dc855cf3638c0449f0ea6ca49d 100644 GIT binary patch literal 1721 zcmbW0eKgcr7{~9tkC{;oh9W7Ew^j05v823aC4@~|Ry0C(nhK*@v)R1NIPI)5?WPwS zCXur89;FaVt4XtBSTstTyo~WOelp{?ziB(|Is4b{exG~Kx#!;Jx##;i&%JOD`~oc7 z;oi9A!U7F zJ3ymQs_{V>97ZKP7K_0V@C1Tt64l6RL?VeuAdu8aBr*jNL2b!Wb;=UeT6Kx4Tvde( z3XwomW&Ah64*-=2wt}q~lp#P=GgK0ghW=-iEq!Orln_a zxaZDi^Dq4H06yKWb_HrLFy$=(n!t-96%7$|8%GxAn8H9a#cpM&P#skl%8^B2}fvVU+<5iT^+11v$sg+eDH6GO$~)@;OUxcU>q znVN>yr-@qIvaXdqR9kBkFiAUbw3DQ5WGgY2snFh&{X4Lf|3&r@>~F4KK*6Ap=3%J7 z1t=AHTvL$8o#Js_su~(|Q&u@tPPTFti9a0*oqZ9!*N5}-8@-8&0(2Q32G>)gTP*90 z)(J!M^0`4*?GDDZ4_X}@2?$v3@2&+x_=*H&d9qG&N9bj3XM5T0tZOkk%=t2L`?zHr z?>Y?3t)A#8OAg!%Xvh^p=D~%`qQ${ME#0@#>ms|H`1JWR%mSu)sR9>Uj!O%A{n8|k za?|(GzO@s6eIbkFA_;pbD?sW7+0N+>W-xRf>(0pIXcw-u4tTxZHPxo<@0@2#mA#5$ znF+^k>59?0ocp(ujupj(W_K{-=5-+Y_HNUspvEnWZ2 zJ>ocx6~w5Uws($!qT~}$dr|`7h>$H8I`>1<=ls??r84;U_gm)< zlokrxYgVH@jb=)l!=QDqs@dfm6toM%#v&)4dR1jHYv&{kgz7IZ_`xXVA5GI7ay< znZGjYR`cQS>i9LQXAJYnoa0d)vHakbvNFX3|FHUos%nKMLDD@QFR^IC^9xyfTTBJx zc8|$HoPHS89pUh{*erH;C`F@CxvX1Gmz9o5Wx)(QE7!fY`gx~(Z;5|JSy$7sc?^RpehUm9Hn2%XlL;J|!O)YcL2)nEK35z(7pR{xV(`xW_uPr=J@*-N zqf((bSJEb8M;fH>r^!6{NxV6=Ww%}JJO+6O(r6e&`#~0Q zJnrf=x9a-tN$_0XAd#R->-No@R9R|0f!$JdEo~L>*T(Tq;uCQ$6n%=hA_5PEWSLoyWTt(s4 i)oGg|Qqdsun~l85Te?LBSMnw}nQ<{%{_ftMu=r0(@&Gdc literal 1278 zcmex=@azt76w5@M*+jYLLn9fgT#eOMoz*GjT1K> zObQl4wiBcwL6{L}2OH3Mm<-UNiUJCTj)92|jRu7i7jFFU{}uxeP?|}QSrF);s~~NP zk!Ar5t?9Na4}F<+UAA`7cJDP8rYJ(})#@AJm4vnK1Jm}Z@M zysp$Q>Z|CixMvL@{S5U$LpgwcWn^XgI4vj8UifSm>+Bkp>^aY^r2Z<;UBp^CTdg=_ z)ixP_>HD4z@nvCe#O_3Q^vpf-Y3G#r^Tk(%=Y0Efc6GmMdryLx!B?J-w<5l7?c`qy zHkAov>dS1Cg9Sd~vJdx72MaQT1b?tY6fm*bGciJh5llu#py;c=J5{-!>rGucLDMoY zF8s*z>l1!mOfy%HT*3J-``fbF5rH+D?flH^mwi9H+voc2WkSnYB2M!zx@xZTW9d4! zKfE0O8Pa-QPS|kp?3I@-jL$=Y>cUs4w=ZGZvaCZXwXCOK zX$sf{z1reDAwGVs`udM|qkY#s%ropt^qcRH%z3U$_{-*)Pm{al%U179-q>lsuzRn? zRN-_<`_hZ@x0L4HTw=BR)m0X;m#p_+Ptv)yCw}2d|A4}n2cOm!xe6C_OcC5aCGXYM zn$~%Lz*^H|ujl!Vo0?VY&5$6Hkned3@Lp z6hx#Kfk~b!lO$E9bRB7PJ~Gew$mGROKq8(hV6BWmtpYzDf8;EY663UA%F$$GF02{R z$)1|VUg#5Xp+1M5t9Dj!oAN8p(9$RshE)ys!#c|<*e)G-SzaX`e{_>YbK0Ha?k*+O zJq&U^Q77^iCT(0J@8wYZis6r2SnXw@dGnlSyiZQJBrNlXcTPxw<)updrzS0LTGSsa zmf!UWywg(r!q8DrC8t+MLPg|5r+N9KHthr!y#+c||1PmDUctrWt*V&V$aaXs;jQ14 z1lL^&TD!zwfPKgT%w{0BA9*IcwCLf=1=Eajd1Akqul}f=l)rRq^n_MMwW%)>=kq~g klNqe`wbA8GK1%S%(Ez4iZ102be|@Bjb+ From 3496755f7977815ead1e100d37997f6b78d208f8 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Mon, 9 Mar 2026 15:48:17 +0800 Subject: [PATCH 16/29] :wrench: chore(gui): preload paint Signed-off-by: SimonShiki --- packages/gui/src/containers/gui.jsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/gui/src/containers/gui.jsx b/packages/gui/src/containers/gui.jsx index 6f565e80d..33b1a5010 100644 --- a/packages/gui/src/containers/gui.jsx +++ b/packages/gui/src/containers/gui.jsx @@ -40,12 +40,17 @@ import themeManagerHOC from '../lib/theme-manager-hoc.jsx'; import GUIComponent from '../components/gui/gui.jsx'; import {setIsScratchDesktop} from '../lib/isScratchDesktop.js'; +import {isScratchPaintLoaded, getScratchPaint} from '../lib/paint-loader.ts'; class GUI extends React.Component { componentDidMount () { setIsScratchDesktop(this.props.isScratchDesktop); this.props.onStorageInit(storage); this.props.onVmInit(this.props.vm); + // Preload paint editor when main editor get ready + if (!isScratchPaintLoaded()) { + getScratchPaint(); + } } componentDidUpdate (prevProps) { if (this.props.projectId !== prevProps.projectId && this.props.projectId !== null) { From 1cba99139bc6b62f303720535ede64dc7fdcfde2 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Mon, 9 Mar 2026 21:23:28 +0800 Subject: [PATCH 17/29] :wrench: chore(gui): keep env var consistency Signed-off-by: SimonShiki --- packages/gui/webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index fcab9b78a..5bb52a692 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -166,7 +166,7 @@ if (!process.env.CI) { base.plugins.push(new webpack.ProgressPlugin()); } -if (process.env.ANALYZE === '1') { +if (process.env.ANALYZE) { // eslint-disable-next-line global-require const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); base.plugins.push(new BundleAnalyzerPlugin()); From 3d1a82b7af9c60dfe536f452bbb308b68ba8c8d8 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Tue, 10 Mar 2026 12:00:34 +0800 Subject: [PATCH 18/29] :wrench: chore(gui): refine paint editor preload logic Signed-off-by: SimonShiki --- packages/gui/src/containers/gui.jsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/gui/src/containers/gui.jsx b/packages/gui/src/containers/gui.jsx index 33b1a5010..9f406c009 100644 --- a/packages/gui/src/containers/gui.jsx +++ b/packages/gui/src/containers/gui.jsx @@ -47,10 +47,10 @@ class GUI extends React.Component { setIsScratchDesktop(this.props.isScratchDesktop); this.props.onStorageInit(storage); this.props.onVmInit(this.props.vm); - // Preload paint editor when main editor get ready - if (!isScratchPaintLoaded()) { - getScratchPaint(); + if (!this.props.isPlayerOnly) { + this.preloadPaint(); } + } componentDidUpdate (prevProps) { if (this.props.projectId !== prevProps.projectId && this.props.projectId !== null) { @@ -61,6 +61,15 @@ class GUI extends React.Component { // At this time the project view in www doesn't need to know when a project is unloaded this.props.onProjectLoaded(); } + if (!this.props.isPlayerOnly && prevProps.isPlayerOnly) { + this.preloadPaint(); + } + } + preloadPaint () { + // Preload paint editor when main editor get ready + if (!isScratchPaintLoaded()) { + getScratchPaint(); + } } render () { if (this.props.isError) { @@ -109,6 +118,7 @@ GUI.propTypes = { intl: intlShape, isError: PropTypes.bool, isLoading: PropTypes.bool, + isPlayerOnly: PropTypes.bool, isScratchDesktop: PropTypes.bool, isShowingProject: PropTypes.bool, loadingStateVisible: PropTypes.bool, From cd0ac38f349606b3b1d4230e32d9185997c24adc Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Tue, 10 Mar 2026 15:35:20 +0800 Subject: [PATCH 19/29] :wrench: chore(vm): load clipcc-sb1-convertor lazily Signed-off-by: SimonShiki --- packages/vm/src/virtual-machine.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/vm/src/virtual-machine.js b/packages/vm/src/virtual-machine.js index 56895d965..977680ef8 100644 --- a/packages/vm/src/virtual-machine.js +++ b/packages/vm/src/virtual-machine.js @@ -418,9 +418,11 @@ class VirtualMachine extends EventEmitter { resolve(res); }); }) - .catch(error => { - // eslint-disable-next-line global-require - const {SB1File, ValidationError} = require('clipcc-sb1-converter'); + .catch(async error => { + const {SB1File, ValidationError} = await import( + /* webpackChunkName: "clipcc-sb1-convertor" */ + 'clipcc-sb1-converter' + ); try { const sb1 = new SB1File(input); From 7b718e66e5ee48418d078c692b7febb1aa3c69ce Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Fri, 13 Mar 2026 13:38:12 +0800 Subject: [PATCH 20/29] :wrench: chore: make hex and large json external Signed-off-by: SimonShiki --- packages/gui/src/reducers/utils.ts | 2 +- packages/gui/webpack.config.js | 73 +++--- packages/storage/package.json | 1 + packages/vm/package.json | 9 +- pnpm-lock.yaml | 379 ++++++++++++++++++----------- pnpm-workspace.yaml | 3 + 6 files changed, 289 insertions(+), 178 deletions(-) diff --git a/packages/gui/src/reducers/utils.ts b/packages/gui/src/reducers/utils.ts index 1f9f47891..86f2c0a0c 100644 --- a/packages/gui/src/reducers/utils.ts +++ b/packages/gui/src/reducers/utils.ts @@ -1,7 +1,7 @@ import {combineReducers, type Reducer, type Store} from 'redux'; // eslint-disable-next-line @typescript-eslint/no-explicit-any -let initialReducers: Record> | null = null; +let initialReducers: Record> = {}; // eslint-disable-next-line @typescript-eslint/no-explicit-any let storeInstance: Store | null = null; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index 7e21dbfdd..831506a7e 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -32,12 +32,13 @@ const base = { 'clipcc-vm': path.resolve(__dirname, '../vm/src/index.js'), 'clipcc-block': path.resolve(__dirname, '../block/src/index.ts'), 'clipcc-render': path.resolve(__dirname, '../render/src/index.js'), - 'clipcc-audio': path.resolve(__dirname, '../audio/src/index.js') + 'clipcc-audio': path.resolve(__dirname, '../audio/src/index.js'), + 'clipcc-storage': path.resolve(__dirname, '../storage/src/index.ts'), } }, snapshot: { managedPaths: [ - /^.+?[\\/]node_modules[\\/](?!scratch-(blocks|l10n|paint|render|storage|vm))[\\/]/ + /^.+?[\\/]node_modules[\\/](?!scratch-(blocks|l10n|paint|storage|render|storage|vm))[\\/]/ ] }, module: { @@ -46,7 +47,8 @@ const base = { path.resolve(__dirname, 'src'), path.resolve(__dirname, '../vm/src'), path.resolve(__dirname, '../block/src'), - path.resolve(__dirname, '../audio/src') + path.resolve(__dirname, '../audio/src'), + path.resolve(__dirname, '../storage/src') ], test: /\.([cm]?ts|tsx)$/, loader: 'ts-loader', @@ -106,10 +108,7 @@ const base = { type: 'asset/source' }, { test: /\.hex$/, - type: 'asset/inline', - generator: { - dataUrl: content => `data:text/plain;base64,${content.toString('base64')}` - } + type: 'asset' }, { resourceQuery: '?arrayBuffer', type: 'javascript/auto', @@ -120,6 +119,34 @@ const base = { }] }, optimization: { + splitChunks: { + chunks: 'async', + minChunks: 2, + maxInitialRequests: 5, + cacheGroups: { + default: false, + defaultVendors: false, + metadata: { + test: module => module.type === 'json' && module.size() > 128 * 1024, + name: 'metadata', + chunks: 'all', + priority: 20, + reuseExistingChunk: true, + enforce: true + }, + lib: { + test: /[\\/]node_modules[\\/]/, + name: 'runtime', + chunks: 'initial', + priority: 10, + reuseExistingChunk: true, + enforce: true + } + } + }, + runtimeChunk: { + name: 'runtime' + }, minimizer: [ new TerserPlugin({ include: /\.min\.js$/ @@ -208,28 +235,6 @@ module.exports = [ } ]) }, - optimization: { - splitChunks: { - chunks: 'async', - minChunks: 2, - maxInitialRequests: 5, - cacheGroups: { - default: false, - defaultVendors: false, - lib: { - test: /[\\/]node_modules[\\/]/, - name: 'lib.min', - chunks: 'initial', - priority: 10, - reuseExistingChunk: true, - enforce: true - } - } - }, - runtimeChunk: { - name: 'lib.min' - } - }, plugins: base.plugins.concat([ new webpack.DefinePlugin({ 'process.env.DEBUG': Boolean(process.env.DEBUG), @@ -238,30 +243,30 @@ module.exports = [ 'clipcc.BUILD_TIME': Date.now() }), new HtmlWebpackPlugin({ - chunks: ['lib.min', 'gui'], + chunks: ['runtime.min', 'lib.min', 'gui'], template: 'src/playground/index.ejs', title: 'ClipCC GUI' }), new HtmlWebpackPlugin({ - chunks: ['lib.min', 'blocksonly'], + chunks: ['runtime.min', 'lib.min', 'blocksonly'], template: 'src/playground/index.ejs', filename: 'blocks-only.html', title: 'ClipCC GUI: Blocks Only Example' }), new HtmlWebpackPlugin({ - chunks: ['lib.min', 'compatibilitytesting'], + chunks: ['runtime.min', 'lib.min', 'compatibilitytesting'], template: 'src/playground/index.ejs', filename: 'compatibility-testing.html', title: 'ClipCC GUI: Compatibility Testing' }), new HtmlWebpackPlugin({ - chunks: ['lib.min', 'player'], + chunks: ['runtime.min', 'lib.min', 'player'], template: 'src/playground/index.ejs', filename: 'player.html', title: 'ClipCC GUI: Player Example' }), new HtmlWebpackPlugin({ - chunks: ['lib.min', 'lifecycle'], + chunks: ['runtime.min', 'lib.min', 'lifecycle'], template: 'src/playground/index.ejs', filename: 'lifecycle.html', title: 'ClipCC GUI: Lifecycle Test' diff --git a/packages/storage/package.json b/packages/storage/package.json index 2c133df98..21b262e90 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -51,6 +51,7 @@ "json": "^9.0.6", "node-fetch": "^3.3.2", "rimraf": "6.0.1", + "terser-webpack-plugin": "^5.3.17", "ts-jest": "^29.4.5", "ts-jest-mock-import-meta": "1.2.1", "ts-loader": "9.5.4", diff --git a/packages/vm/package.json b/packages/vm/package.json index 798f387ff..18c85e9a9 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -29,12 +29,14 @@ "version": "json -f package.json -I -e \"this.repository.sha = '$(git log -n1 --pretty=format:%H)'\"" }, "dependencies": { + "@turbowarp/nanolog": "^1.0.1", "@vernier/godirect": "1.8.3", "arraybuffer-loader": "1.0.8", "atob": "2.1.2", "btoa": "1.2.1", "canvas-toBlob": "1.0.0", "clipcc-parser": "workspace:~", + "clipcc-sb1-converter": "1.0.326", "decode-html": "2.0.0", "diff-match-patch": "1.0.4", "fastestsmallesttextencoderdecoder": "^1.0.22", @@ -42,19 +44,18 @@ "htmlparser2": "10.1.0", "immutable": "5.1.5", "jszip": "^3.10.1", - "@turbowarp/nanolog": "^1.0.1", "node-polyfill-webpack-plugin": "^3.0.0", - "clipcc-sb1-converter": "1.0.326", "scratch-translate-extension-languages": "1.0.7" }, "peerDependencies": { - "clipcc-svg-renderer": "2.5.48" + "clipcc-svg-renderer": "2.5.49" }, "devDependencies": { "@babel/core": "7.29.0", "@babel/eslint-parser": "7.28.6", "@babel/preset-env": "7.29.0", "@types/fastestsmallesttextencoderdecoder": "^1.0.2", + "@types/node": "^25.4.0", "adm-zip": "0.4.11", "babel-eslint": "10.1.0", "babel-loader": "^10.1.0", @@ -63,6 +64,7 @@ "clipcc-block": "workspace:~", "clipcc-l10n": "workspace:~", "clipcc-render": "workspace:~", + "clipcc-render-fonts": "1.0.256", "clipcc-storage": "workspace:~", "clipcc-svg-renderer": "2.5.49", "codingclip-worker-loader": "^3.0.10", @@ -76,7 +78,6 @@ "json": "^9.0.6", "lodash.defaultsdeep": "4.6.1", "pngjs": "7.0.0", - "clipcc-render-fonts": "1.0.256", "script-loader": "0.7.2", "stats.js": "0.17.0", "tap": "21.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 661afc33a..58c81b701 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,10 +21,10 @@ importers: version: 0.2.1 '@changesets/cli': specifier: ^2.30.0 - version: 2.30.0(@types/node@12.20.55) + version: 2.30.0(@types/node@25.4.0) '@commitlint/cli': specifier: ^20.4.3 - version: 20.4.3(@types/node@12.20.55)(typescript@5.9.3) + version: 20.4.3(@types/node@25.4.0)(typescript@5.9.3) '@crowdin/cli': specifier: ^4.12.0 version: 4.14.0(encoding@0.1.13) @@ -79,7 +79,7 @@ importers: version: link:../lint-config tap: specifier: 21.0.1 - version: 21.0.1(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + version: 21.0.1(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -128,7 +128,7 @@ importers: version: 16.5.0 jest: specifier: ^30.3.0 - version: 30.3.0(@types/node@12.20.55) + version: 30.3.0(@types/node@25.4.0) jest-canvas-mock: specifier: ^2.5.2 version: 2.5.2 @@ -146,7 +146,7 @@ importers: version: 5.0.0(webpack@5.105.4) ts-jest: specifier: ^29.4.5 - version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@12.20.55))(typescript@5.9.3) + version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@25.4.0))(typescript@5.9.3) ts-loader: specifier: ^9.5.4 version: 9.5.4(typescript@5.9.3)(webpack@5.105.4) @@ -441,7 +441,7 @@ importers: version: 12.0.0 jest: specifier: ^30.3.0 - version: 30.3.0(@types/node@12.20.55) + version: 30.3.0(@types/node@25.4.0) jest-environment-jsdom: specifier: ^30.3.0 version: 30.3.0 @@ -702,7 +702,7 @@ importers: version: 5.6.6(webpack@5.105.4) jest: specifier: ^30.3.0 - version: 30.3.0(@types/node@12.20.55) + version: 30.3.0(@types/node@25.4.0) jest-canvas-mock: specifier: 2.3.1 version: 2.3.1 @@ -823,7 +823,7 @@ importers: version: 13.0.6 tap: specifier: ^21.0.1 - version: 21.0.1(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + version: 21.0.1(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3) packages/render: dependencies: @@ -899,7 +899,7 @@ importers: version: 1.13.0 tap: specifier: 21.0.1 - version: 21.0.1(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + version: 21.0.1(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3) terser-webpack-plugin: specifier: ^5.3.17 version: 5.3.17(webpack@5.105.4) @@ -991,6 +991,9 @@ importers: rimraf: specifier: 6.0.1 version: 6.0.1 + terser-webpack-plugin: + specifier: ^5.3.17 + version: 5.3.17(webpack@5.105.4) ts-jest: specifier: ^29.4.5 version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@12.20.55))(typescript@5.9.3) @@ -1076,6 +1079,9 @@ importers: '@types/fastestsmallesttextencoderdecoder': specifier: ^1.0.2 version: 1.0.2 + '@types/node': + specifier: ^25.4.0 + version: 25.4.0 adm-zip: specifier: 0.4.11 version: 0.4.11 @@ -1150,7 +1156,7 @@ importers: version: 0.17.0 tap: specifier: 21.0.1 - version: 21.0.1(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + version: 21.0.1(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3) terser-webpack-plugin: specifier: ^5.3.17 version: 5.3.17(webpack@5.105.4) @@ -2929,6 +2935,9 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@25.4.0': + resolution: {integrity: sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==} + '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -9598,6 +9607,9 @@ packages: unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + undici@7.22.0: resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} engines: {node: '>=20.18.1'} @@ -10960,7 +10972,7 @@ snapshots: dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.30.0(@types/node@12.20.55)': + '@changesets/cli@2.30.0(@types/node@25.4.0)': dependencies: '@changesets/apply-release-plan': 7.1.0 '@changesets/assemble-release-plan': 6.0.9 @@ -10976,7 +10988,7 @@ snapshots: '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@12.20.55) + '@inquirer/external-editor': 1.0.3(@types/node@25.4.0) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 enquirer: 2.4.1 @@ -11074,11 +11086,11 @@ snapshots: human-id: 4.1.3 prettier: 2.8.8 - '@commitlint/cli@20.4.3(@types/node@12.20.55)(typescript@5.9.3)': + '@commitlint/cli@20.4.3(@types/node@25.4.0)(typescript@5.9.3)': dependencies: '@commitlint/format': 20.4.3 '@commitlint/lint': 20.4.3 - '@commitlint/load': 20.4.3(@types/node@12.20.55)(typescript@5.9.3) + '@commitlint/load': 20.4.3(@types/node@25.4.0)(typescript@5.9.3) '@commitlint/read': 20.4.3 '@commitlint/types': 20.4.3 tinyexec: 1.0.2 @@ -11120,14 +11132,14 @@ snapshots: '@commitlint/rules': 20.4.3 '@commitlint/types': 20.4.3 - '@commitlint/load@20.4.3(@types/node@12.20.55)(typescript@5.9.3)': + '@commitlint/load@20.4.3(@types/node@25.4.0)(typescript@5.9.3)': dependencies: '@commitlint/config-validator': 20.4.3 '@commitlint/execute-rule': 20.0.0 '@commitlint/resolve-extends': 20.4.3 '@commitlint/types': 20.4.3 cosmiconfig: 9.0.1(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.2.0(@types/node@12.20.55)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.2.0(@types/node@25.4.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) is-plain-obj: 4.1.0 lodash.mergewith: 4.6.2 picocolors: 1.1.1 @@ -11365,12 +11377,12 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inquirer/external-editor@1.0.3(@types/node@12.20.55)': + '@inquirer/external-editor@1.0.3(@types/node@25.4.0)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@isaacs/cliui@8.0.2': dependencies: @@ -11387,14 +11399,14 @@ snapshots: dependencies: minipass: 7.1.3 - '@isaacs/ts-node-temp-fork-for-pr-2009@10.9.7(@types/node@12.20.55)(typescript@5.5.4)': + '@isaacs/ts-node-temp-fork-for-pr-2009@10.9.7(@types/node@25.4.0)(typescript@5.5.4)': dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node14': 14.1.8 '@tsconfig/node16': 16.1.8 '@tsconfig/node18': 18.2.6 '@tsconfig/node20': 20.1.9 - '@types/node': 12.20.55 + '@types/node': 25.4.0 acorn: 8.16.0 acorn-walk: 8.3.5 arg: 4.1.3 @@ -11403,14 +11415,14 @@ snapshots: typescript: 5.5.4 v8-compile-cache-lib: 3.0.1 - '@isaacs/ts-node-temp-fork-for-pr-2009@10.9.7(@types/node@12.20.55)(typescript@5.9.3)': + '@isaacs/ts-node-temp-fork-for-pr-2009@10.9.7(@types/node@25.4.0)(typescript@5.9.3)': dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node14': 14.1.8 '@tsconfig/node16': 16.1.8 '@tsconfig/node18': 18.2.6 '@tsconfig/node20': 20.1.9 - '@types/node': 12.20.55 + '@types/node': 25.4.0 acorn: 8.16.0 acorn-walk: 8.3.5 arg: 4.1.3 @@ -12081,19 +12093,19 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@tapjs/after-each@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/after-each@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) function-loop: 4.0.0 - '@tapjs/after@3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/after@3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) is-actual-promise: 1.0.2 - '@tapjs/asserts@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': + '@tapjs/asserts@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) '@tapjs/stack': 4.0.0 is-actual-promise: 1.0.2 tcompare: 9.0.0(react-dom@16.4.0(react@18.3.1))(react@18.3.1) @@ -12102,35 +12114,35 @@ snapshots: - react - react-dom - '@tapjs/before-each@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/before-each@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) function-loop: 4.0.0 - '@tapjs/before@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/before@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) is-actual-promise: 1.0.2 - '@tapjs/chdir@3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/chdir@3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/config@5.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/config@5.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/test': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/test': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) chalk: 5.6.2 jackspeak: 4.2.3 polite-json: 5.0.0 tap-yaml: 4.0.0 walk-up-path: 4.0.0 - '@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': + '@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': dependencies: '@tapjs/processinfo': 3.1.9 '@tapjs/stack': 4.0.0 - '@tapjs/test': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/test': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) async-hook-domain: 4.0.1 diff: 5.2.2 is-actual-promise: 1.0.2 @@ -12151,33 +12163,33 @@ snapshots: dependencies: minipass: 7.1.3 - '@tapjs/filter@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/filter@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/fixture@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/fixture@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) mkdirp: 3.0.1 rimraf: 6.0.1 - '@tapjs/intercept@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/intercept@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) '@tapjs/stack': 4.0.0 - '@tapjs/mock@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/mock@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) '@tapjs/stack': 4.0.0 resolve-import: 2.4.0 walk-up-path: 4.0.0 - '@tapjs/node-serialize@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/node-serialize@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) '@tapjs/error-serdes': 4.0.0 '@tapjs/stack': 4.0.0 tap-parser: 18.0.0 @@ -12190,10 +12202,10 @@ snapshots: signal-exit: 4.1.0 uuid: 8.3.2 - '@tapjs/reporter@4.0.1(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))': + '@tapjs/reporter@4.0.1(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))': dependencies: - '@tapjs/config': 5.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/config': 5.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) '@tapjs/stack': 4.0.0 chalk: 5.6.2 ink: 5.2.1(react@18.3.1) @@ -12214,17 +12226,17 @@ snapshots: - react-dom - utf-8-validate - '@tapjs/run@4.0.1(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': + '@tapjs/run@4.0.1(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': dependencies: - '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/before': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/config': 5.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/before': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/config': 5.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) '@tapjs/processinfo': 3.1.9 - '@tapjs/reporter': 4.0.1(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1)) - '@tapjs/spawn': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/stdin': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/test': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/reporter': 4.0.1(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1)) + '@tapjs/spawn': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/stdin': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/test': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) c8: 10.1.3 chalk: 5.6.2 chokidar: 3.6.0 @@ -12258,9 +12270,9 @@ snapshots: - supports-color - utf-8-validate - '@tapjs/snapshot@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': + '@tapjs/snapshot@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) is-actual-promise: 1.0.2 tcompare: 9.0.0(react-dom@16.4.0(react@18.3.1))(react@18.3.1) trivial-deferred: 2.0.0 @@ -12268,36 +12280,36 @@ snapshots: - react - react-dom - '@tapjs/spawn@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/spawn@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) '@tapjs/stack@4.0.0': {} - '@tapjs/stdin@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': - dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - - '@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': - dependencies: - '@isaacs/ts-node-temp-fork-for-pr-2009': 10.9.7(@types/node@12.20.55)(typescript@5.5.4) - '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/after-each': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/asserts': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/before': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/before-each': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/chdir': 3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/filter': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/fixture': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/intercept': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/mock': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/node-serialize': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/snapshot': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/spawn': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/stdin': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/typescript': 3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(typescript@5.5.4) - '@tapjs/worker': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/stdin@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + dependencies: + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + + '@tapjs/test@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)': + dependencies: + '@isaacs/ts-node-temp-fork-for-pr-2009': 10.9.7(@types/node@25.4.0)(typescript@5.5.4) + '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/after-each': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/asserts': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/before': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/before-each': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/chdir': 3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/filter': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/fixture': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/intercept': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/mock': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/node-serialize': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/snapshot': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/spawn': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/stdin': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/typescript': 3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(typescript@5.5.4) + '@tapjs/worker': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) glob: 11.1.0 jackspeak: 4.2.3 mkdirp: 3.0.1 @@ -12316,29 +12328,29 @@ snapshots: - react - react-dom - '@tapjs/typescript@3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(typescript@5.5.4)': + '@tapjs/typescript@3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(typescript@5.5.4)': dependencies: - '@isaacs/ts-node-temp-fork-for-pr-2009': 10.9.7(@types/node@12.20.55)(typescript@5.5.4) - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@isaacs/ts-node-temp-fork-for-pr-2009': 10.9.7(@types/node@25.4.0)(typescript@5.5.4) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@swc/core' - '@swc/wasm' - '@types/node' - typescript - '@tapjs/typescript@3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(typescript@5.9.3)': + '@tapjs/typescript@3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(typescript@5.9.3)': dependencies: - '@isaacs/ts-node-temp-fork-for-pr-2009': 10.9.7(@types/node@12.20.55)(typescript@5.9.3) - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@isaacs/ts-node-temp-fork-for-pr-2009': 10.9.7(@types/node@25.4.0)(typescript@5.9.3) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@swc/core' - '@swc/wasm' - '@types/node' - typescript - '@tapjs/worker@4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': + '@tapjs/worker@4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))': dependencies: - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) '@testim/chrome-version@1.1.4': {} @@ -12394,20 +12406,20 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/bonjour@3.5.13': dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 4.19.8 - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/connect@3.4.38': dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/eslint-scope@3.7.7': dependencies: @@ -12423,7 +12435,7 @@ snapshots: '@types/express-serve-static-core@4.19.8': dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/qs': 6.15.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -12443,7 +12455,7 @@ snapshots: '@types/http-proxy@1.17.17': dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/hull.js@1.0.4': {} @@ -12479,7 +12491,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/mime@1.3.5': {} @@ -12489,6 +12501,10 @@ snapshots: '@types/node@12.20.55': {} + '@types/node@25.4.0': + dependencies: + undici-types: 7.18.2 + '@types/parse-json@4.0.2': {} '@types/prop-types@15.5.9': {} @@ -12505,7 +12521,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/retry@0.12.2': {} @@ -12520,11 +12536,11 @@ snapshots: '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/send@1.2.1': dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/serve-index@1.9.4': dependencies: @@ -12533,12 +12549,12 @@ snapshots: '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/send': 0.17.6 '@types/sockjs@0.3.36': dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/stack-utils@2.0.3': {} @@ -12555,7 +12571,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/yargs-parser@21.0.3': {} @@ -14205,9 +14221,9 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@6.2.0(@types/node@12.20.55)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig-typescript-loader@6.2.0(@types/node@25.4.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 cosmiconfig: 9.0.1(typescript@5.9.3) jiti: 2.6.1 typescript: 5.9.3 @@ -16919,7 +16935,7 @@ snapshots: '@jest/expect': 30.3.0 '@jest/test-result': 30.3.0 '@jest/types': 30.3.0 - '@types/node': 12.20.55 + '@types/node': 25.4.0 chalk: 4.1.2 co: 4.6.0 dedent: 1.7.2 @@ -16958,6 +16974,25 @@ snapshots: - supports-color - ts-node + jest-cli@30.3.0(@types/node@25.4.0): + dependencies: + '@jest/core': 30.3.0 + '@jest/test-result': 30.3.0 + '@jest/types': 30.3.0 + chalk: 4.1.2 + exit-x: 0.2.2 + import-local: 3.2.0 + jest-config: 30.3.0(@types/node@25.4.0) + jest-util: 30.3.0 + jest-validate: 30.3.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + jest-config@30.3.0(@types/node@12.20.55): dependencies: '@babel/core': 7.29.0 @@ -16989,6 +17024,37 @@ snapshots: - babel-plugin-macros - supports-color + jest-config@30.3.0(@types/node@25.4.0): + dependencies: + '@babel/core': 7.29.0 + '@jest/get-type': 30.1.0 + '@jest/pattern': 30.0.1 + '@jest/test-sequencer': 30.3.0 + '@jest/types': 30.3.0 + babel-jest: 30.3.0(@babel/core@7.29.0) + chalk: 4.1.2 + ci-info: 4.4.0 + deepmerge: 4.3.1 + glob: 10.5.0 + graceful-fs: 4.2.11 + jest-circus: 30.3.0 + jest-docblock: 30.2.0 + jest-environment-node: 30.3.0 + jest-regex-util: 30.0.1 + jest-resolve: 30.3.0 + jest-runner: 30.3.0 + jest-util: 30.3.0 + jest-validate: 30.3.0 + parse-json: 5.2.0 + pretty-format: 30.3.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 25.4.0 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -17030,7 +17096,7 @@ snapshots: '@jest/environment': 30.3.0 '@jest/fake-timers': 30.3.0 '@jest/types': 30.3.0 - '@types/node': 12.20.55 + '@types/node': 25.4.0 jest-mock: 30.3.0 jest-util: 30.3.0 jest-validate: 30.3.0 @@ -17272,13 +17338,13 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@30.3.0: dependencies: - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@ungap/structured-clone': 1.3.0 jest-util: 30.3.0 merge-stream: 2.0.0 @@ -17297,6 +17363,19 @@ snapshots: - supports-color - ts-node + jest@30.3.0(@types/node@25.4.0): + dependencies: + '@jest/core': 30.3.0 + '@jest/types': 30.3.0 + import-local: 3.2.0 + jest-cli: 30.3.0(@types/node@25.4.0) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + jiti@2.6.1: {} jpeg-js@0.4.4: {} @@ -19937,27 +20016,27 @@ snapshots: yaml: 2.8.2 yaml-types: 0.4.0(yaml@2.8.2) - tap@21.0.1(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3): - dependencies: - '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/after-each': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/asserts': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/before': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/before-each': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/chdir': 3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/core': 4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/filter': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/fixture': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/intercept': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/mock': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/node-serialize': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/run': 4.0.1(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/snapshot': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/spawn': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/stdin': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) - '@tapjs/test': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) - '@tapjs/typescript': 3.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@12.20.55)(typescript@5.9.3) - '@tapjs/worker': 4.0.0(@tapjs/core@4.0.0(@types/node@12.20.55)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + tap@21.0.1(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)(typescript@5.9.3): + dependencies: + '@tapjs/after': 3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/after-each': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/asserts': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/before': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/before-each': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/chdir': 3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/core': 4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/filter': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/fixture': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/intercept': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/mock': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/node-serialize': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/run': 4.0.1(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/snapshot': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/spawn': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/stdin': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) + '@tapjs/test': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1) + '@tapjs/typescript': 3.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1))(@types/node@25.4.0)(typescript@5.9.3) + '@tapjs/worker': 4.0.0(@tapjs/core@4.0.0(@types/node@25.4.0)(react-dom@16.4.0(react@18.3.1))(react@18.3.1)) resolve-import: 2.4.0 transitivePeerDependencies: - '@swc/core' @@ -20217,6 +20296,26 @@ snapshots: babel-jest: 30.3.0(@babel/core@7.29.0) jest-util: 30.3.0 + ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@25.4.0))(typescript@5.9.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.8 + jest: 30.3.0(@types/node@25.4.0) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.4 + type-fest: 4.41.0 + typescript: 5.9.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.29.0 + '@jest/transform': 30.3.0 + '@jest/types': 30.3.0 + babel-jest: 30.3.0(@babel/core@7.29.0) + jest-util: 30.3.0 + ts-loader@9.5.4(typescript@5.9.3)(webpack@5.105.4): dependencies: chalk: 4.1.2 @@ -20373,6 +20472,8 @@ snapshots: buffer: 5.7.1 through: 2.3.8 + undici-types@7.18.2: {} + undici@7.22.0: {} unicode-canonical-property-names-ecmascript@2.0.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 9787a7d2c..798e1f099 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,6 +4,9 @@ packages: onlyBuiltDependencies: - chromedriver - core-js + - gifsicle + - jpegtran-bin + - optipng-bin - playwright-chromium - unrs-resolver From 7173e16f7f0585ababa25abad1d249cc73d51d24 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Fri, 13 Mar 2026 15:46:22 +0800 Subject: [PATCH 21/29] :wrench: chore: externalize assets Signed-off-by: SimonShiki --- packages/audio/.gitignore | 1 + packages/gui/webpack.config.js | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/audio/.gitignore b/packages/audio/.gitignore index 285b88956..04c9161df 100644 --- a/packages/audio/.gitignore +++ b/packages/audio/.gitignore @@ -10,4 +10,5 @@ npm-* /dist /dist.js +/dist.js.LICENSE.txt /dist.js.map diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index 831506a7e..b7570c47c 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -23,7 +23,8 @@ const base = { output: { library: 'GUI', filename: '[name].js', - chunkFilename: 'chunks/[name].js' + chunkFilename: 'chunks/[name].js', + assetModuleFilename: 'assets/[hash][ext][query]', }, resolve: { extensions: ['.ts', '.js', '.tsx', '.jsx'], @@ -231,7 +232,7 @@ module.exports = [ { test: /\.(svg|png|wav|gif|jpg)$/, resourceQuery: {not: [/raw/]}, - type: 'asset/inline' + type: 'asset' } ]) }, @@ -320,7 +321,7 @@ module.exports = [ { test: /\.(svg|png|wav|gif|jpg)$/, resourceQuery: {not: [/raw/]}, - type: 'asset/inline' + type: 'asset' } ]) }, From 7d13e6202a3907727de10aea24af8c52a67efb17 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Fri, 13 Mar 2026 15:49:05 +0800 Subject: [PATCH 22/29] :wrench: chore(vm): bump sb1 convertor to fix tests Signed-off-by: SimonShiki --- packages/vm/package.json | 2 +- pnpm-lock.yaml | 48 ++++++++++++---------------------------- 2 files changed, 15 insertions(+), 35 deletions(-) diff --git a/packages/vm/package.json b/packages/vm/package.json index 18c85e9a9..0d6d0acb3 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -36,7 +36,7 @@ "btoa": "1.2.1", "canvas-toBlob": "1.0.0", "clipcc-parser": "workspace:~", - "clipcc-sb1-converter": "1.0.326", + "clipcc-sb1-converter": "1.0.327", "decode-html": "2.0.0", "diff-match-patch": "1.0.4", "fastestsmallesttextencoderdecoder": "^1.0.22", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 58c81b701..5f2e98618 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -441,7 +441,7 @@ importers: version: 12.0.0 jest: specifier: ^30.3.0 - version: 30.3.0(@types/node@25.4.0) + version: 30.3.0(@types/node@12.20.55) jest-environment-jsdom: specifier: ^30.3.0 version: 30.3.0 @@ -972,7 +972,7 @@ importers: version: link:../lint-config eslint-plugin-jest: specifier: 27.9.0 - version: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@8.57.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(jest@30.3.0(@types/node@12.20.55))(typescript@5.9.3) + version: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@8.57.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(jest@30.3.0(@types/node@25.4.0))(typescript@5.9.3) eslint-plugin-react: specifier: 7.37.5 version: 7.37.5(eslint@9.39.2(jiti@2.6.1)) @@ -981,7 +981,7 @@ importers: version: 6.2.0(webpack@5.105.4) jest: specifier: ^30.3.0 - version: 30.3.0(@types/node@12.20.55) + version: 30.3.0(@types/node@25.4.0) json: specifier: ^9.0.6 version: 9.0.6 @@ -996,10 +996,10 @@ importers: version: 5.3.17(webpack@5.105.4) ts-jest: specifier: ^29.4.5 - version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@12.20.55))(typescript@5.9.3) + version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@25.4.0))(typescript@5.9.3) ts-jest-mock-import-meta: specifier: 1.2.1 - version: 1.2.1(ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@12.20.55))(typescript@5.9.3)) + version: 1.2.1(ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@25.4.0))(typescript@5.9.3)) ts-loader: specifier: 9.5.4 version: 9.5.4(typescript@5.9.3)(webpack@5.105.4) @@ -1037,8 +1037,8 @@ importers: specifier: workspace:~ version: link:../parser clipcc-sb1-converter: - specifier: 1.0.326 - version: 1.0.326 + specifier: 1.0.327 + version: 1.0.327 decode-html: specifier: 2.0.0 version: 2.0.0 @@ -4185,8 +4185,8 @@ packages: clipcc-render-fonts@1.0.256: resolution: {integrity: sha512-BUkYYtOs7Qo5biLgsFugxr0rzhDquC4q2wuraGCp7vl/6m6Vx9fg9gY5raKJz/+XSeBgj3Q7czV5FsrF8Z3mGg==} - clipcc-sb1-converter@1.0.326: - resolution: {integrity: sha512-t7qPJhHXtGw8+Z82msjNqfM7tzO/u9sdqgI8EQ7nVpqS+/q66tbbni8ff4EM6VFHlH6Yc3FfpM5FyH1chdu1Iw==} + clipcc-sb1-converter@1.0.327: + resolution: {integrity: sha512-OnmnpRWKImSKTA28gfxkdFVkZnGECFxGOJIFS0u3GJngG+QWTGYajA8J9eeRie9uXghj7QjRRdW818pNczofmg==} clipcc-svg-renderer@2.5.49: resolution: {integrity: sha512-O9tBPOcuk3B6Srgrpr0G2UmHNhexxtLlprDC1DmT1542kqtZvLYJDNtf3HrTR2OwmaiWo/t3qCvYlJXrGiVvtg==} @@ -14018,7 +14018,7 @@ snapshots: dependencies: base64-loader: 1.0.0 - clipcc-sb1-converter@1.0.326: + clipcc-sb1-converter@1.0.327: dependencies: '@turbowarp/nanolog': 1.0.1 fastestsmallesttextencoderdecoder: 1.0.22 @@ -15105,13 +15105,13 @@ snapshots: '@typescript-eslint/experimental-utils': 1.13.0(eslint@9.39.2(jiti@2.6.1)) eslint: 9.39.2(jiti@2.6.1) - eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@8.57.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(jest@30.3.0(@types/node@12.20.55))(typescript@5.9.3): + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@8.57.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(jest@30.3.0(@types/node@25.4.0))(typescript@5.9.3): dependencies: '@typescript-eslint/utils': 5.62.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) optionalDependencies: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@8.57.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - jest: 30.3.0(@types/node@12.20.55) + jest: 30.3.0(@types/node@25.4.0) transitivePeerDependencies: - supports-color - typescript @@ -20272,29 +20272,9 @@ snapshots: dependencies: typescript: 5.9.3 - ts-jest-mock-import-meta@1.2.1(ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@12.20.55))(typescript@5.9.3)): + ts-jest-mock-import-meta@1.2.1(ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@25.4.0))(typescript@5.9.3)): dependencies: - ts-jest: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@12.20.55))(typescript@5.9.3) - - ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@12.20.55))(typescript@5.9.3): - dependencies: - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - handlebars: 4.7.8 - jest: 30.3.0(@types/node@12.20.55) - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.7.4 - type-fest: 4.41.0 - typescript: 5.9.3 - yargs-parser: 21.1.1 - optionalDependencies: - '@babel/core': 7.29.0 - '@jest/transform': 30.3.0 - '@jest/types': 30.3.0 - babel-jest: 30.3.0(@babel/core@7.29.0) - jest-util: 30.3.0 + ts-jest: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@25.4.0))(typescript@5.9.3) ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@25.4.0))(typescript@5.9.3): dependencies: From d17f266a5e82c5a569e0794170d8c5fb2243b657 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Fri, 13 Mar 2026 17:04:27 +0800 Subject: [PATCH 23/29] :wrench: chore: minify css Signed-off-by: SimonShiki --- packages/gui/package.json | 2 +- .../update-peripheral-step.jsx | 1 - packages/gui/webpack.config.js | 12 +- packages/paint/package.json | 1 - pnpm-lock.yaml | 478 +++++++++++++++++- 5 files changed, 471 insertions(+), 23 deletions(-) diff --git a/packages/gui/package.json b/packages/gui/package.json index dbf1c3e18..9d565dadd 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -105,6 +105,7 @@ "babel-loader": "^10.1.0", "chromedriver": "146.0.1", "cross-fetch": "^3.1.8", + "css-minimizer-webpack-plugin": "^8.0.0", "enzyme": "3.11.0", "enzyme-adapter-react-16": "1.15.7", "eslint": "^9.39.2", @@ -129,7 +130,6 @@ "raf": "3.4.1", "react-test-renderer": "16.2.0", "redux-mock-store": "1.5.3", - "regenerator-runtime": "0.14.1", "rimraf": "2.7.1", "selenium-webdriver": "3.6.0", "terser-webpack-plugin": "^5.3.17", diff --git a/packages/gui/src/components/connection-modal/update-peripheral-step.jsx b/packages/gui/src/components/connection-modal/update-peripheral-step.jsx index 3ba9f92ae..4c61be731 100644 --- a/packages/gui/src/components/connection-modal/update-peripheral-step.jsx +++ b/packages/gui/src/components/connection-modal/update-peripheral-step.jsx @@ -1,4 +1,3 @@ -import 'regenerator-runtime/runtime'; import {FormattedMessage} from 'react-intl'; import PropTypes from 'prop-types'; import classNames from 'classnames'; diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index b7570c47c..059bdb219 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -9,6 +9,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin'); +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const STATIC_PATH = process.env.STATIC_PATH || '/static'; @@ -137,7 +138,7 @@ const base = { }, lib: { test: /[\\/]node_modules[\\/]/, - name: 'runtime', + name: 'lib.min', chunks: 'initial', priority: 10, reuseExistingChunk: true, @@ -145,9 +146,6 @@ const base = { } } }, - runtimeChunk: { - name: 'runtime' - }, minimizer: [ new TerserPlugin({ include: /\.min\.js$/ @@ -159,10 +157,14 @@ const base = { plugins: [ ['gifsicle', {interlaced: true}], ['jpegtran', {progressive: true}], - ['optipng', {optimizationLevel: 5}] + ['optipng', {optimizationLevel: 5}], + ['svgo'] ] } } + }), + new CssMinimizerPlugin({ + minify: CssMinimizerPlugin.lightningCssMinify }) ] }, diff --git a/packages/paint/package.json b/packages/paint/package.json index b485ad140..728021570 100644 --- a/packages/paint/package.json +++ b/packages/paint/package.json @@ -87,7 +87,6 @@ "redux": "3.7.2", "redux-mock-store": "1.5.4", "redux-throttle": "0.1.1", - "regenerator-runtime": "0.14.1", "rimraf": "2.7.1", "clipcc-l10n": "workspace:~", "clipcc-render-fonts": "1.0.256", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f2e98618..89fb376ce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -394,6 +394,9 @@ importers: cross-fetch: specifier: ^3.1.8 version: 3.2.0(encoding@0.1.13) + css-minimizer-webpack-plugin: + specifier: ^8.0.0 + version: 8.0.0(webpack@5.105.4) enzyme: specifier: 3.11.0 version: 3.11.0 @@ -441,7 +444,7 @@ importers: version: 12.0.0 jest: specifier: ^30.3.0 - version: 30.3.0(@types/node@12.20.55) + version: 30.3.0(@types/node@25.4.0) jest-environment-jsdom: specifier: ^30.3.0 version: 30.3.0 @@ -466,9 +469,6 @@ importers: redux-mock-store: specifier: 1.5.3 version: 1.5.3 - regenerator-runtime: - specifier: 0.14.1 - version: 0.14.1 rimraf: specifier: 2.7.1 version: 2.7.1 @@ -702,7 +702,7 @@ importers: version: 5.6.6(webpack@5.105.4) jest: specifier: ^30.3.0 - version: 30.3.0(@types/node@25.4.0) + version: 30.3.0(@types/node@12.20.55) jest-canvas-mock: specifier: 2.3.1 version: 2.3.1 @@ -769,9 +769,6 @@ importers: redux-throttle: specifier: 0.1.1 version: 0.1.1 - regenerator-runtime: - specifier: 0.14.1 - version: 0.14.1 rimraf: specifier: 2.7.1 version: 2.7.1 @@ -4060,6 +4057,9 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + caniuse-lite@1.0.30001777: resolution: {integrity: sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==} @@ -4237,6 +4237,9 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -4455,6 +4458,12 @@ packages: resolution: {integrity: sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==} engines: {node: '>= 0.10'} + css-declaration-sorter@7.3.1: + resolution: {integrity: sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + css-loader@6.7.3: resolution: {integrity: sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==} engines: {node: '>= 12.13.0'} @@ -4464,6 +4473,31 @@ packages: css-mediaquery@0.1.2: resolution: {integrity: sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==} + css-minimizer-webpack-plugin@8.0.0: + resolution: {integrity: sha512-9bEpzHs8gEq6/cbEj418jXL/YWjBUD2YTLLk905Npt2JODqnRITin0+So5Vx4Dp5vyi2Lpt9pp2QHzQ7fdxNrw==} + engines: {node: '>= 20.9.0'} + peerDependencies: + '@parcel/css': '*' + '@swc/css': '*' + clean-css: '*' + csso: '*' + esbuild: '*' + lightningcss: '*' + 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 + css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} @@ -4497,6 +4531,24 @@ packages: cssfontparser@1.2.1: resolution: {integrity: sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==} + cssnano-preset-default@7.0.11: + resolution: {integrity: sha512-waWlAMuCakP7//UCY+JPrQS1z0OSLeOXk2sKWJximKWGupVxre50bzPlvpbUwZIDylhf/ptf0Pk+Yf7C+hoa3g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + cssnano-utils@5.0.1: + resolution: {integrity: sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + cssnano@7.1.3: + resolution: {integrity: sha512-mLFHQAzyapMVFLiJIn7Ef4C2UCEvtlTlbyILR6B5ZsUAV3D/Pa761R5uC1YPhyBkRd3eqaDm2ncaNrD7R4mTRg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + csso@5.0.5: resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} @@ -6996,6 +7048,10 @@ packages: lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + linebreak@0.3.0: resolution: {integrity: sha512-zt8pzlM3oq4moDN8U5mP1SbZ44yKV6dXCu44Ez6iTXmxUl8/jRFWeho2SDqL5YDBv0TBKPgU/XGovZwnXAKlOQ==} @@ -7099,6 +7155,9 @@ packages: lodash.unescape@4.0.1: resolution: {integrity: sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==} + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + lodash.upperfirst@4.3.1: resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} @@ -8021,6 +8080,48 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} + postcss-calc@10.1.1: + resolution: {integrity: sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-colormin@7.0.6: + resolution: {integrity: sha512-oXM2mdx6IBTRm39797QguYzVEWzbdlFiMNfq88fCCN1Wepw3CYmJ/1/Ifa/KjWo+j5ZURDl2NTldLJIw51IeNQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-convert-values@7.0.9: + resolution: {integrity: sha512-l6uATQATZaCa0bckHV+r6dLXfWtUBKXxO3jK+AtxxJJtgMPD+VhhPCCx51I4/5w8U5uHV67g3w7PXj+V3wlMlg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-comments@7.0.6: + resolution: {integrity: sha512-Sq+Fzj1Eg5/CPf1ERb0wS1Im5cvE2gDXCE+si4HCn1sf+jpQZxDI4DXEp8t77B/ImzDceWE2ebJQFXdqZ6GRJw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-duplicates@7.0.2: + resolution: {integrity: sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-empty@7.0.1: + resolution: {integrity: sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-overridden@7.0.1: + resolution: {integrity: sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + postcss-import@12.0.1: resolution: {integrity: sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==} engines: {node: '>=6.0.0'} @@ -8032,6 +8133,42 @@ packages: postcss: ^7.0.0 || ^8.0.1 webpack: ^5.0.0 + postcss-merge-longhand@7.0.5: + resolution: {integrity: sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-merge-rules@7.0.8: + resolution: {integrity: sha512-BOR1iAM8jnr7zoQSlpeBmCsWV5Uudi/+5j7k05D0O/WP3+OFMPD86c1j/20xiuRtyt45bhxw/7hnhZNhW2mNFA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-font-values@7.0.1: + resolution: {integrity: sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-gradients@7.0.1: + resolution: {integrity: sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-params@7.0.6: + resolution: {integrity: sha512-YOn02gC68JijlaXVuKvFSCvQOhTpblkcfDre2hb/Aaa58r2BIaK4AtE/cyZf2wV7YKAG+UlP9DT+By0ry1E4VQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-selectors@7.0.6: + resolution: {integrity: sha512-lIbC0jy3AAwDxEgciZlBullDiMBeBCT+fz5G8RcA9MWqh/hfUkpOI3vNDUNEZHgokaoiv0juB9Y8fGcON7rU/A==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + postcss-modules-extract-imports@3.1.0: resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} engines: {node: ^10 || ^12 || >= 14} @@ -8056,10 +8193,94 @@ packages: peerDependencies: postcss: ^8.1.0 + postcss-normalize-charset@7.0.1: + resolution: {integrity: sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-display-values@7.0.1: + resolution: {integrity: sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-positions@7.0.1: + resolution: {integrity: sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-repeat-style@7.0.1: + resolution: {integrity: sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-string@7.0.1: + resolution: {integrity: sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-timing-functions@7.0.1: + resolution: {integrity: sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-unicode@7.0.6: + resolution: {integrity: sha512-z6bwTV84YW6ZvvNoaNLuzRW4/uWxDKYI1iIDrzk6D2YTL7hICApy+Q1LP6vBEsljX8FM7YSuV9qI79XESd4ddQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-url@7.0.1: + resolution: {integrity: sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-whitespace@7.0.1: + resolution: {integrity: sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-ordered-values@7.0.2: + resolution: {integrity: sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-reduce-initial@7.0.6: + resolution: {integrity: sha512-G6ZyK68AmrPdMB6wyeA37ejnnRG2S8xinJrZJnOv+IaRKf6koPAVbQsiC7MfkmXaGmF1UO+QCijb27wfpxuRNg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-reduce-transforms@7.0.1: + resolution: {integrity: sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + postcss-selector-parser@7.1.1: resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} engines: {node: '>=4'} + postcss-svgo@7.1.1: + resolution: {integrity: sha512-zU9H9oEDrUFKa0JB7w+IYL7Qs9ey1mZyjhbf0KLxwJDdDRtoPvCmaEfknzqfHj44QS9VD6c5sJnBAVYTLRg/Sg==} + engines: {node: ^18.12.0 || ^20.9.0 || >= 18} + peerDependencies: + postcss: ^8.4.32 + + postcss-unique-selectors@7.0.5: + resolution: {integrity: sha512-3QoYmEt4qg/rUWDn6Tc8+ZVPmbp4G1hXDtCNWDx0st8SjtCbRcxRXDDM1QrEiXGG3A45zscSJFb4QH90LViyxg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + postcss-value-parser@3.3.1: resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==} @@ -8493,9 +8714,6 @@ packages: regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regex-cache@0.4.4: resolution: {integrity: sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==} engines: {node: '>=0.10.0'} @@ -9145,6 +9363,12 @@ packages: peerDependencies: webpack: ^5.27.0 + stylehacks@7.0.8: + resolution: {integrity: sha512-I3f053GBLIiS5Fg6OMFhq/c+yW+5Hc2+1fgq7gElDMMSqwlRb3tBf2ef6ucLStYRpId4q//bQO1FjcyNyy4yDQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + super-regex@1.1.0: resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} engines: {node: '>=18'} @@ -11649,7 +11873,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 12.20.55 + '@types/node': 25.4.0 '@types/yargs': 17.0.35 chalk: 4.1.2 @@ -13878,6 +14102,13 @@ snapshots: camelcase@6.3.0: {} + caniuse-api@3.0.0: + dependencies: + browserslist: 4.28.1 + caniuse-lite: 1.0.30001777 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + caniuse-lite@1.0.30001777: {} canvas-toBlob@1.0.0: {} @@ -14083,6 +14314,8 @@ snapshots: color-name@1.1.4: {} + colord@2.9.3: {} + colorette@2.0.20: {} colors@0.6.2: {} @@ -14321,6 +14554,10 @@ snapshots: randombytes: 2.1.0 randomfill: 1.0.4 + css-declaration-sorter@7.3.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + css-loader@6.7.3(webpack@5.105.4): dependencies: icss-utils: 5.1.0(postcss@8.5.8) @@ -14335,6 +14572,16 @@ snapshots: css-mediaquery@0.1.2: {} + css-minimizer-webpack-plugin@8.0.0(webpack@5.105.4): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + cssnano: 7.1.3(postcss@8.5.8) + jest-worker: 30.3.0 + postcss: 8.5.8 + schema-utils: 4.3.3 + serialize-javascript: 7.0.4 + webpack: 5.105.4(webpack-cli@6.0.1) + css-select@4.3.0: dependencies: boolbase: 1.0.0 @@ -14376,6 +14623,50 @@ snapshots: cssfontparser@1.2.1: {} + cssnano-preset-default@7.0.11(postcss@8.5.8): + dependencies: + browserslist: 4.28.1 + css-declaration-sorter: 7.3.1(postcss@8.5.8) + cssnano-utils: 5.0.1(postcss@8.5.8) + postcss: 8.5.8 + postcss-calc: 10.1.1(postcss@8.5.8) + postcss-colormin: 7.0.6(postcss@8.5.8) + postcss-convert-values: 7.0.9(postcss@8.5.8) + postcss-discard-comments: 7.0.6(postcss@8.5.8) + postcss-discard-duplicates: 7.0.2(postcss@8.5.8) + postcss-discard-empty: 7.0.1(postcss@8.5.8) + postcss-discard-overridden: 7.0.1(postcss@8.5.8) + postcss-merge-longhand: 7.0.5(postcss@8.5.8) + postcss-merge-rules: 7.0.8(postcss@8.5.8) + postcss-minify-font-values: 7.0.1(postcss@8.5.8) + postcss-minify-gradients: 7.0.1(postcss@8.5.8) + postcss-minify-params: 7.0.6(postcss@8.5.8) + postcss-minify-selectors: 7.0.6(postcss@8.5.8) + postcss-normalize-charset: 7.0.1(postcss@8.5.8) + postcss-normalize-display-values: 7.0.1(postcss@8.5.8) + postcss-normalize-positions: 7.0.1(postcss@8.5.8) + postcss-normalize-repeat-style: 7.0.1(postcss@8.5.8) + postcss-normalize-string: 7.0.1(postcss@8.5.8) + postcss-normalize-timing-functions: 7.0.1(postcss@8.5.8) + postcss-normalize-unicode: 7.0.6(postcss@8.5.8) + postcss-normalize-url: 7.0.1(postcss@8.5.8) + postcss-normalize-whitespace: 7.0.1(postcss@8.5.8) + postcss-ordered-values: 7.0.2(postcss@8.5.8) + postcss-reduce-initial: 7.0.6(postcss@8.5.8) + postcss-reduce-transforms: 7.0.1(postcss@8.5.8) + postcss-svgo: 7.1.1(postcss@8.5.8) + postcss-unique-selectors: 7.0.5(postcss@8.5.8) + + cssnano-utils@5.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + cssnano@7.1.3(postcss@8.5.8): + dependencies: + cssnano-preset-default: 7.0.11(postcss@8.5.8) + lilconfig: 3.1.3 + postcss: 8.5.8 + csso@5.0.5: dependencies: css-tree: 2.2.1 @@ -17292,7 +17583,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 12.20.55 + '@types/node': 25.4.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -17566,6 +17857,8 @@ snapshots: dependencies: immediate: 3.0.6 + lilconfig@3.1.3: {} + linebreak@0.3.0: dependencies: base64-js: 0.0.8 @@ -17662,6 +17955,8 @@ snapshots: lodash.unescape@4.0.1: {} + lodash.uniq@4.5.0: {} + lodash.upperfirst@4.3.1: {} lodash@4.17.23: {} @@ -18635,6 +18930,43 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-calc@10.1.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + postcss-colormin@7.0.6(postcss@8.5.8): + dependencies: + browserslist: 4.28.1 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-convert-values@7.0.9(postcss@8.5.8): + dependencies: + browserslist: 4.28.1 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@7.0.6(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + + postcss-discard-duplicates@7.0.2(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-discard-empty@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-discard-overridden@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-import@12.0.1: dependencies: postcss: 7.0.39 @@ -18650,6 +18982,45 @@ snapshots: semver: 7.7.4 webpack: 5.105.4(webpack-cli@6.0.1) + postcss-merge-longhand@7.0.5(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + stylehacks: 7.0.8(postcss@8.5.8) + + postcss-merge-rules@7.0.8(postcss@8.5.8): + dependencies: + browserslist: 4.28.1 + caniuse-api: 3.0.0 + cssnano-utils: 5.0.1(postcss@8.5.8) + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + + postcss-minify-font-values@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@7.0.1(postcss@8.5.8): + dependencies: + colord: 2.9.3 + cssnano-utils: 5.0.1(postcss@8.5.8) + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-minify-params@7.0.6(postcss@8.5.8): + dependencies: + browserslist: 4.28.1 + cssnano-utils: 5.0.1(postcss@8.5.8) + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@7.0.6(postcss@8.5.8): + dependencies: + cssesc: 3.0.0 + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + postcss-modules-extract-imports@3.1.0(postcss@8.5.8): dependencies: postcss: 8.5.8 @@ -18671,11 +19042,84 @@ snapshots: icss-utils: 5.1.0(postcss@8.5.8) postcss: 8.5.8 + postcss-normalize-charset@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-normalize-display-values@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@7.0.6(postcss@8.5.8): + dependencies: + browserslist: 4.28.1 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@7.0.2(postcss@8.5.8): + dependencies: + cssnano-utils: 5.0.1(postcss@8.5.8) + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@7.0.6(postcss@8.5.8): + dependencies: + browserslist: 4.28.1 + caniuse-api: 3.0.0 + postcss: 8.5.8 + + postcss-reduce-transforms@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + postcss-selector-parser@7.1.1: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-svgo@7.1.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + svgo: 4.0.1 + + postcss-unique-selectors@7.0.5(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + postcss-value-parser@3.3.1: {} postcss-value-parser@4.2.0: {} @@ -19210,8 +19654,6 @@ snapshots: regenerator-runtime@0.13.11: {} - regenerator-runtime@0.14.1: {} - regex-cache@0.4.4: dependencies: is-equal-shallow: 0.1.3 @@ -19947,6 +20389,12 @@ snapshots: dependencies: webpack: 5.105.4(webpack-cli@6.0.1) + stylehacks@7.0.8(postcss@8.5.8): + dependencies: + browserslist: 4.28.1 + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + super-regex@1.1.0: dependencies: function-timeout: 1.0.2 From edbf78e7b19c4a35f9020e71fa9c68930efa45c8 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Fri, 13 Mar 2026 17:33:31 +0800 Subject: [PATCH 24/29] :wrench: chore(vm): make loadExtensionURL can load core extensions Signed-off-by: SimonShiki --- packages/vm/src/extension-support/extension-manager.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/vm/src/extension-support/extension-manager.js b/packages/vm/src/extension-support/extension-manager.js index deeb3610f..7d5258580 100644 --- a/packages/vm/src/extension-support/extension-manager.js +++ b/packages/vm/src/extension-support/extension-manager.js @@ -153,6 +153,10 @@ class ExtensionManager { * @returns {Promise} resolved once the extension is loaded and initialized or rejected on failure */ async loadExtensionURL (extensionURL) { + if (Object.prototype.hasOwnProperty.call(coreExtensions, extensionURL)) { + this.loadExtensionIdSync(extensionURL); + return; + } if (Object.prototype.hasOwnProperty.call(builtinExtensions, extensionURL)) { /** @todo dupe handling for non-builtin extensions. See commit 670e51d33580e8a2e852b3b038bb3afc282f81b9 */ if (this.isExtensionLoaded(extensionURL)) { From 8ca7f6198b26d61b41dba3b74dc5090bc46fe840 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Fri, 13 Mar 2026 17:49:21 +0800 Subject: [PATCH 25/29] :bug: fix(storage): export type individually Signed-off-by: SimonShiki --- packages/storage/src/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/storage/src/index.ts b/packages/storage/src/index.ts index 37a8830b1..0f64aa772 100644 --- a/packages/storage/src/index.ts +++ b/packages/storage/src/index.ts @@ -1,19 +1,19 @@ import {ScratchStorage} from './ScratchStorage'; -import Asset, {AssetId} from './Asset'; +import Asset from './Asset'; +import type {AssetId} from './Asset'; import {AssetType} from './AssetType'; import {DataFormat} from './DataFormat'; import Helper from './Helper'; export { - /** - * Export for use with NPM & Node.js. - * @type {ScratchStorage} - */ ScratchStorage, Asset, - AssetId, AssetType, DataFormat, Helper }; + +export type { + AssetId +}; From 682881685ce3cca9d0fdf3dcf4f3af6570f4b1a9 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Thu, 16 Apr 2026 11:04:48 +0800 Subject: [PATCH 26/29] :rewind: chore: revert chunk split related changes Signed-off-by: SimonShiki --- packages/gui/src/components/loader/loader.css | 12 ---- .../src/components/loader/scoped-loader.tsx | 42 -------------- packages/gui/src/containers/blocks.jsx | 11 ++-- .../gui/src/containers/custom-procedures.jsx | 11 +--- packages/gui/src/containers/gui.tsx | 13 ----- .../src/containers/paint-editor-wrapper.jsx | 12 ++-- packages/gui/src/lib/app-state-hoc.tsx | 21 ++++--- .../gui/src/lib/backpack/block-to-image.js | 5 +- packages/gui/src/lib/blocks-loader-hoc.tsx | 33 ----------- packages/gui/src/lib/blocks-loader.ts | 25 -------- packages/gui/src/lib/blocks.js | 6 +- packages/gui/src/lib/make-toolbox.ts | 41 +++++-------- packages/gui/src/lib/paint-loader-hoc.tsx | 35 ------------ packages/gui/src/lib/paint-loader.js | 28 --------- packages/gui/src/reducers/utils.ts | 43 -------------- .../extension-support/extension-manager.js | 57 +++++++------------ packages/vm/src/virtual-machine.js | 28 +++++++-- 17 files changed, 83 insertions(+), 340 deletions(-) delete mode 100644 packages/gui/src/components/loader/scoped-loader.tsx delete mode 100644 packages/gui/src/lib/blocks-loader-hoc.tsx delete mode 100644 packages/gui/src/lib/blocks-loader.ts delete mode 100644 packages/gui/src/lib/paint-loader-hoc.tsx delete mode 100644 packages/gui/src/lib/paint-loader.js delete mode 100644 packages/gui/src/reducers/utils.ts diff --git a/packages/gui/src/components/loader/loader.css b/packages/gui/src/components/loader/loader.css index 642ca3e31..8a6e47bc1 100644 --- a/packages/gui/src/components/loader/loader.css +++ b/packages/gui/src/components/loader/loader.css @@ -14,18 +14,6 @@ color: white; } - -.scoped-loader { - z-index: calc(var(--clipcc-z-index-loader) - 1); - border-radius: 0.5rem; -} - -.scoped-loader .title { - font-size: 1.5rem; - margin: 0; -} - - .fullscreen { /* Break out of the layout using position: fixed to cover the whole screen */ position: fixed; diff --git a/packages/gui/src/components/loader/scoped-loader.tsx b/packages/gui/src/components/loader/scoped-loader.tsx deleted file mode 100644 index 2ea645729..000000000 --- a/packages/gui/src/components/loader/scoped-loader.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import styles from './loader.css'; - -import topBlock from './top-block.svg'; -import middleBlock from './middle-block.svg'; -import bottomBlock from './bottom-block.svg'; - -export interface ScopedLoaderProps { - /** The text to display while loading */ - text?: string; -} - -export default function ScopedLoaderComponent (props: ScopedLoaderProps) { - return ( -
-
-
- - - -
- {props.text ? ( -
- {props.text} -
- ) : null} -
-
- ); -} diff --git a/packages/gui/src/containers/blocks.jsx b/packages/gui/src/containers/blocks.jsx index 8ea288e08..a578d6b7b 100644 --- a/packages/gui/src/containers/blocks.jsx +++ b/packages/gui/src/containers/blocks.jsx @@ -4,7 +4,6 @@ import defaultsDeep from 'lodash.defaultsdeep'; import makeToolbox from '../lib/make-toolbox'; import PropTypes from 'prop-types'; import React from 'react'; -import {injectBlock} from '../lib/blocks-loader-hoc.tsx'; import VMScratchBlocks, {setRecordSoundCallback} from '../lib/blocks'; import VM from 'clipcc-vm'; @@ -52,7 +51,7 @@ const DroppableBlocks = DropAreaHOC([ class Blocks extends React.Component { constructor (props) { super(props); - this.ScratchBlocks = VMScratchBlocks(props.vm, props.blocks); + this.ScratchBlocks = VMScratchBlocks(props.vm); bindAll(this, [ 'attachVM', 'checkoutWsByProccode', @@ -196,7 +195,7 @@ class Blocks extends React.Component { // call setLocale if the locale has changed, or changed while the blocks were hidden. // vm.getLocale() will be out of sync if locale was changed while not visible this.setLocale(); - // eslint-disable-next-line no-negated-condition + // eslint-disable-next-line no-negated-condition } else if (this.props.theme !== prevProps.theme) { this.ScratchBlocks.Theme.setTheme(this.themeMapName[this.props.theme] || 'scratch', this.workspace); } else { @@ -404,8 +403,7 @@ class Blocks extends React.Component { targetSounds.length > 0 ? targetSounds[targetSounds.length - 1].name : '', this.props.hideNonVanillaBlocks ); - } catch (e) { - console.error(`Error making toolbox:`, e); + } catch { return null; } } @@ -662,7 +660,6 @@ class Blocks extends React.Component { Blocks.propTypes = { anyModalVisible: PropTypes.bool, - blocks: PropTypes.object, // eslint-disable-line react/forbid-prop-types hideNonVanillaBlocks: PropTypes.bool.isRequired, canUseCloud: PropTypes.bool, customProceduresVisible: PropTypes.bool, @@ -779,5 +776,5 @@ export default errorBoundaryHOC('Blocks')( connect( mapStateToProps, mapDispatchToProps - )(injectBlock(Blocks)) + )(Blocks) ); diff --git a/packages/gui/src/containers/custom-procedures.jsx b/packages/gui/src/containers/custom-procedures.jsx index c4e3134e5..58ec5ae8f 100644 --- a/packages/gui/src/containers/custom-procedures.jsx +++ b/packages/gui/src/containers/custom-procedures.jsx @@ -3,8 +3,8 @@ import defaultsDeep from 'lodash.defaultsdeep'; import PropTypes from 'prop-types'; import React from 'react'; import CustomProceduresComponent from '../components/custom-procedures/custom-procedures.jsx'; +import * as ScratchBlocks from 'clipcc-block'; import {connect} from 'react-redux'; -import {injectBlock} from '../lib/blocks-loader-hoc.tsx'; class CustomProcedures extends React.Component { constructor (props) { @@ -28,7 +28,6 @@ class CustomProcedures extends React.Component { }; } componentWillUnmount () { - const {blocks: ScratchBlocks} = this.props; if (this.workspace) { if (ScratchBlocks.getFocusManager().getFocusedNode()) { // Focus the workspace before destroying the workspace to avoid focusing @@ -48,7 +47,6 @@ class CustomProcedures extends React.Component { {rtl: this.props.isRtl} ); - const {blocks: ScratchBlocks} = this.props; this.workspace = ScratchBlocks.inject(this.blocks, workspaceConfig); // Create the procedure declaration block for editing the mutation. @@ -186,8 +184,6 @@ class CustomProcedures extends React.Component { } CustomProcedures.propTypes = { - // eslint-disable-next-line react/forbid-prop-types - blocks: PropTypes.object, isRtl: PropTypes.bool, mutator: PropTypes.shape({ proccode: PropTypes.string, @@ -212,7 +208,6 @@ CustomProcedures.propTypes = { }) }; -/** @import * as ScratchBlocks from 'clipcc-block' */ /** @type {ScratchBlocks.BlocklyOptions} */ CustomProcedures.defaultOptions = { zoom: { @@ -237,6 +232,6 @@ const mapStateToProps = state => ({ new: state.scratchGui.customProcedures.new }); -export default injectBlock(connect( +export default connect( mapStateToProps -)(CustomProcedures)); +)(CustomProcedures); diff --git a/packages/gui/src/containers/gui.tsx b/packages/gui/src/containers/gui.tsx index 7fdb7bb76..1a9395a60 100644 --- a/packages/gui/src/containers/gui.tsx +++ b/packages/gui/src/containers/gui.tsx @@ -38,7 +38,6 @@ import themeManagerHOC from '../lib/theme-manager-hoc.jsx'; import GUIComponent from '../components/gui/gui'; import {setIsScratchDesktop} from '../lib/isScratchDesktop'; -import {isScratchPaintLoaded, getScratchPaint} from '../lib/paint-loader'; import type {RootState} from '../lib/app-state-hoc'; import type {PropsOf} from '../lib/type-traits'; @@ -119,9 +118,6 @@ class GUI extends React.Component { setIsScratchDesktop(!!this.props.isScratchDesktop); this.props.onStorageInit!(storage); this.props.onVmInit!(this.props.vm); - if (!this.props.isPlayerOnly) { - this.preloadPaint(); - } } override componentDidUpdate (prevProps: GUIProps) { if (this.props.projectId !== prevProps.projectId && this.props.projectId !== null) { @@ -132,15 +128,6 @@ class GUI extends React.Component { // At this time the project view in www doesn't need to know when a project is unloaded this.props.onProjectLoaded!(); } - if (!this.props.isPlayerOnly && prevProps.isPlayerOnly) { - this.preloadPaint(); - } - } - preloadPaint () { - // Preload paint editor when main editor get ready - if (!isScratchPaintLoaded()) { - getScratchPaint(); - } } override render () { if (this.props.isError) { diff --git a/packages/gui/src/containers/paint-editor-wrapper.jsx b/packages/gui/src/containers/paint-editor-wrapper.jsx index 786a35338..e9f83a005 100644 --- a/packages/gui/src/containers/paint-editor-wrapper.jsx +++ b/packages/gui/src/containers/paint-editor-wrapper.jsx @@ -2,8 +2,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import bindAll from 'lodash.bindall'; import VM from 'clipcc-vm'; +import PaintEditor from 'clipcc-paint'; import {inlineSvgFonts} from 'clipcc-svg-renderer'; -import {injectPaint} from '../lib/paint-loader-hoc'; import {connect} from 'react-redux'; @@ -56,10 +56,8 @@ class PaintEditorWrapper extends React.Component { const { selectedCostumeIndex, vm, - paint, ...componentProps } = this.props; - const PaintEditor = paint.default; return ( { @@ -111,6 +107,6 @@ const mapStateToProps = (state, {selectedCostumeIndex}) => { }; }; -export default injectPaint(connect( +export default connect( mapStateToProps -)(PaintEditorWrapper)); +)(PaintEditorWrapper); diff --git a/packages/gui/src/lib/app-state-hoc.tsx b/packages/gui/src/lib/app-state-hoc.tsx index 4f0a3245e..2d174900b 100644 --- a/packages/gui/src/lib/app-state-hoc.tsx +++ b/packages/gui/src/lib/app-state-hoc.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {Provider} from 'react-redux'; import {createStore, combineReducers, compose} from 'redux'; -import type {Store} from 'redux'; +import type {Reducer, Store, StoreEnhancer} from 'redux'; import ConnectedIntlProvider from './connected-intl-provider.jsx'; import localesReducer, {initLocale, localesInitialState} from '../reducers/locales'; @@ -11,7 +11,6 @@ import {setPlayer, setFullScreen} from '../reducers/mode'; import locales from 'clipcc-l10n'; import {detectLocale} from './detect-locale'; -import {setInitialReducers, setStore} from '../reducers/utils'; import type {GuiState} from '../reducers/gui'; type ComposeEnhancers = typeof compose; @@ -49,7 +48,7 @@ const AppStateHOC = function

( localesOnly?: boolean ): React.ComponentType

{ class AppStateWrapper extends React.Component

{ - private store!: Store>; + private store!: Store; constructor (props: P) { super(props); @@ -63,9 +62,8 @@ const AppStateHOC = function

( // browser modal const reducers = {locales: localesReducer}; const initialState = {locales: initializedLocales}; - const enhancer = composeEnhancers(); - setInitialReducers(reducers); - const reducer = combineReducers<{locales: LocalesState}>(reducers); + const enhancer: StoreEnhancer = composeEnhancers(); + const reducer = combineReducers(reducers); this.store = createStore( reducer, initialState, @@ -84,6 +82,8 @@ const AppStateHOC = function

( initPlayer, initTelemetryModal } = guiRedux; + // eslint-disable-next-line global-require, @typescript-eslint/no-require-imports + const {ScratchPaintReducer}: { ScratchPaintReducer: Reducer } = require('clipcc-paint'); let initializedGui: GuiState = guiInitialState; if (props.isFullScreen || props.isPlayerOnly) { @@ -98,22 +98,21 @@ const AppStateHOC = function

( } const reducers = { locales: localesReducer, - scratchGui: guiReducer + scratchGui: guiReducer, + scratchPaint: ScratchPaintReducer }; const initialState = { locales: initializedLocales, scratchGui: initializedGui }; - const enhancer = composeEnhancers(guiMiddleware); - setInitialReducers(reducers); - const reducer = combineReducers(reducers); + const enhancer: StoreEnhancer = composeEnhancers(guiMiddleware); + const reducer = combineReducers(reducers); this.store = createStore( reducer, initialState, enhancer ); } - setStore(this.store); } override componentDidUpdate (prevProps: Readonly

) { if (localesOnly) return; diff --git a/packages/gui/src/lib/backpack/block-to-image.js b/packages/gui/src/lib/backpack/block-to-image.js index 366b225b9..64e1704b9 100644 --- a/packages/gui/src/lib/backpack/block-to-image.js +++ b/packages/gui/src/lib/backpack/block-to-image.js @@ -1,13 +1,12 @@ import computedStyleToInlineStyle from 'computed-style-to-inline-style'; -import {getScratchBlocks} from '../blocks-loader'; +import * as ScratchBlocks from 'clipcc-block'; /** * Given a blockId, return a data-uri image that can be used to create a thumbnail. * @param {string} blockId the ID of the block to imagify * @returns {Promise} resolves to a data-url of a picture of the blocks */ -export default async function (blockId) { - const ScratchBlocks = await getScratchBlocks(); +export default function (blockId) { // Not sure any better way to access the scratch-blocks workspace than this... const block = ScratchBlocks.common.getMainWorkspace().getBlockById(blockId); const blockSvg = block.getSvgRoot().cloneNode(true /* deep */); diff --git a/packages/gui/src/lib/blocks-loader-hoc.tsx b/packages/gui/src/lib/blocks-loader-hoc.tsx deleted file mode 100644 index 430b040f9..000000000 --- a/packages/gui/src/lib/blocks-loader-hoc.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import {getScratchBlocks} from './blocks-loader'; -import ScopedLoaderComponent from '../components/loader/scoped-loader'; - -interface BlockLoaderProps { - blocks: typeof import('clipcc-block'); -} - -export function injectBlock> (WrappedComponent: Component) { - class BlockLoaderHOC extends React.Component { - state = { - loaded: false - }; - blocks: typeof import('clipcc-block') | null = null; - - override async componentDidMount () { - if (!this.state.loaded) { - this.blocks = await getScratchBlocks(); - this.setState({loaded: true}); - } - } - - override render () { - if (!this.state.loaded) { - return ; - } - - return ; - } - } - - return BlockLoaderHOC; -} diff --git a/packages/gui/src/lib/blocks-loader.ts b/packages/gui/src/lib/blocks-loader.ts deleted file mode 100644 index 15896eb8f..000000000 --- a/packages/gui/src/lib/blocks-loader.ts +++ /dev/null @@ -1,25 +0,0 @@ -// eslint-disable-next-line import/no-mutable-exports -export let ScratchBlocksModule: typeof import('clipcc-block') | null = null; - -/** - * Check if the ScratchBlocks module is loaded. - * @returns True if the ScratchBlocks module is loaded, false otherwise. - */ -export function isScratchBlocksLoaded () { - return !!ScratchBlocksModule; -} - -/** - * Get the ScratchBlocks module, which is loaded asynchronously to reduce the initial bundle size. - * @returns A promise that resolves to the ScratchBlocks module. - */ -export async function getScratchBlocks () { - if (!ScratchBlocksModule) { - // eslint-disable-next-line require-atomic-updates - ScratchBlocksModule = await import( - /* webpackChunkName: "clipcc-block" */ - 'clipcc-block' - ); - } - return ScratchBlocksModule; -} diff --git a/packages/gui/src/lib/blocks.js b/packages/gui/src/lib/blocks.js index 7d86bde9a..bff950212 100644 --- a/packages/gui/src/lib/blocks.js +++ b/packages/gui/src/lib/blocks.js @@ -1,6 +1,7 @@ +import * as ScratchBlocks from 'clipcc-block'; + /** * @typedef {import('clipcc-vm')} VirtualMachine - * @import * as ScratchBlocks from 'clipcc-block' */ /** @@ -19,10 +20,9 @@ export const setRecordSoundCallback = callback => { /** * Connect scratch blocks with the vm * @param {VirtualMachine} vm - The scratch vm - * @param {ScratchBlocks} ScratchBlocks - The scratch blocks to connect * @returns {ScratchBlocks} ScratchBlocks connected with the vm */ -export default function (vm, ScratchBlocks) { +export default function (vm) { const jsonForMenuBlock = function (name, menuOptionsFn, category, start) { return { diff --git a/packages/gui/src/lib/make-toolbox.ts b/packages/gui/src/lib/make-toolbox.ts index 03cb9d31b..4d4be19fc 100644 --- a/packages/gui/src/lib/make-toolbox.ts +++ b/packages/gui/src/lib/make-toolbox.ts @@ -1,13 +1,12 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import {ScratchBlocksModule as ClipCCBlocks, isScratchBlocksLoaded} from './blocks-loader'; -import type * as ClipCCBlockType from 'clipcc-block'; +import * as ClipCCBlocks from 'clipcc-block'; type ShadowFields = Record; -type ShadowInput = ClipCCBlockType.serialization.blocks.ConnectionState; -type ToolboxInfo = ClipCCBlockType.utils.toolbox.ToolboxInfo; -type ToolboxItem = ClipCCBlockType.utils.toolbox.ToolboxItemInfo; +type ShadowInput = ClipCCBlocks.serialization.blocks.ConnectionState; +type ToolboxInfo = ClipCCBlocks.utils.toolbox.ToolboxInfo; +type ToolboxItem = ClipCCBlocks.utils.toolbox.ToolboxItemInfo; interface ExtensionCategory { id: string; @@ -42,22 +41,8 @@ const createShadow = (type: string, fields?: ShadowFields): ShadowInput => { }; }; -/** - * Translate a message ID into a message, using the ScratchBlocks message system if possible. - * @param id - The message ID to translate - * @param defaultMessage - The default message to use if the ScratchBlocks isn't available - * @returns The translated message, or the default message if the ScratchBlocks isn't available - * or missing that message. - */ -const translate = (id: string, defaultMessage: string) => { - if (!isScratchBlocksLoaded()) { - return defaultMessage; - } - return ClipCCBlocks!.Msg[id] ?? defaultMessage; -}; - const motion = (isInitialSetup: boolean, isStage: boolean, targetId?: string | null): ToolboxItem => { - const stageSelected = translate('MOTION_STAGE_SELECTED', 'Stage selected: no motion blocks'); + const stageSelected = ClipCCBlocks.Msg.MOTION_STAGE_SELECTED; const motionContents: ToolboxItem[] = []; if (isStage) { @@ -191,8 +176,8 @@ const looks = ( costumeName: string, backdropName: string ): ToolboxItem => { - const hello = translate('LOOKS_HELLO', 'Hello!'); - const hmm = translate('LOOKS_HMM', 'Hmm...'); + const hello = ClipCCBlocks.Msg.LOOKS_HELLO; + const hmm = ClipCCBlocks.Msg.LOOKS_HMM; const looksContents: ToolboxItem[] = []; @@ -517,7 +502,7 @@ const sensing = ( targetId: string | null | undefined, hideNonVanillaBlocks: boolean ): ToolboxItem => { - const name = translate('SENSING_ASK_TEXT', `What's your name?`); + const name = ClipCCBlocks.Msg.SENSING_ASK_TEXT; const sensingContents: ToolboxItem[] = []; @@ -694,9 +679,9 @@ const operators = ( targetId: string | null | undefined, hideNonVanillaBlocks: boolean ): ToolboxItem => { - const apple = translate('OPERATORS_JOIN_APPLE', 'apple'); - const banana = translate('OPERATORS_JOIN_BANANA', 'banana'); - const letter = translate('OPERATORS_LETTEROF_APPLE', 'a'); + const apple = ClipCCBlocks.Msg.OPERATORS_JOIN_APPLE; + const banana = ClipCCBlocks.Msg.OPERATORS_JOIN_BANANA; + const letter = ClipCCBlocks.Msg.OPERATORS_LETTEROF_APPLE; const operatorsContents: ToolboxItem[] = [ { @@ -1026,8 +1011,8 @@ const makeToolbox = function ( // Convert xml toolbox to json. for (const category of categories) { - if (category.json || !category.xml || !isScratchBlocksLoaded()) continue; - const toolbox = ClipCCBlocks!.utils.toolbox.convertToolboxDefToJson( + if (category.json || !category.xml) continue; + const toolbox = ClipCCBlocks.utils.toolbox.convertToolboxDefToJson( `${category.xml}` ); if (!toolbox || toolbox.contents.length === 0) { diff --git a/packages/gui/src/lib/paint-loader-hoc.tsx b/packages/gui/src/lib/paint-loader-hoc.tsx deleted file mode 100644 index b54633136..000000000 --- a/packages/gui/src/lib/paint-loader-hoc.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import {getScratchPaint} from './paint-loader'; -import ScopedLoaderComponent from '../components/loader/scoped-loader'; -import {injectReducer} from '../reducers/utils'; - -interface PaintLoaderProps { - paint: typeof import('clipcc-paint'); -} - -export function injectPaint> (WrappedComponent: Component) { - class PaintLoaderHOC extends React.Component { - state = { - loaded: false - }; - paint: typeof import('clipcc-paint') | null = null; - - override async componentDidMount () { - if (!this.state.loaded) { - this.paint = await getScratchPaint(); - injectReducer('scratchPaint', this.paint.ScratchPaintReducer); - this.setState({loaded: true}); - } - } - - override render () { - if (!this.state.loaded) { - return ; - } - - return ; - } - } - - return PaintLoaderHOC; -} diff --git a/packages/gui/src/lib/paint-loader.js b/packages/gui/src/lib/paint-loader.js deleted file mode 100644 index 5e11e2828..000000000 --- a/packages/gui/src/lib/paint-loader.js +++ /dev/null @@ -1,28 +0,0 @@ -// eslint-disable-next-line import/no-mutable-exports -export let ScratchPaintModule = null; -let loadingPromise = null; - -/** - * Check if the ScratchPaint module is loaded. - * @returns {boolean} True if the ScratchPaint module is loaded, false otherwise. - */ -export const isScratchPaintLoaded = function () { - return !!ScratchPaintModule; -}; - -/** - * Get the ScratchPaint module, which is loaded asynchronously to reduce the initial bundle size. - * @returns {Promise} A promise that resolves to the ScratchPaint module. - */ -export const getScratchPaint = function () { - if (!loadingPromise) { - loadingPromise = import( - /* webpackChunkName: "clipcc-paint" */ - 'clipcc-paint' - ).then(module => { - ScratchPaintModule = module; - return module; - }); - } - return loadingPromise; -}; diff --git a/packages/gui/src/reducers/utils.ts b/packages/gui/src/reducers/utils.ts deleted file mode 100644 index 56c6b6e2b..000000000 --- a/packages/gui/src/reducers/utils.ts +++ /dev/null @@ -1,43 +0,0 @@ -import {combineReducers, type Reducer, type Store} from 'redux'; -import type {ReducerMap} from '../lib/type-traits'; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -let initialReducers: Record> = {}; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -let storeInstance: Store | null = null; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const dynamicReducers: Record> = {}; - -/** - * Set the initial reducers for the store. This should be called before creating the store, - * and the reducers passed here will be combined with any dynamically injected reducers. - * @param reducers The initial reducers to set for the store. - */ -export function setInitialReducers (reducers: ReducerMap) { - initialReducers = reducers; -} - -/** - * Set the Redux store instance. This is necessary for the injectReducer function to work, - * as it needs access to the store to replace the reducer. - * @param store The Redux store instance to set for dynamic reducer injection. - */ -export function setStore (store: Store) { - storeInstance = store; -} - -/** - * Dynamically inject a reducer into the store. This is useful for code-splitting and loading reducers on demand. - * @param key The key under which to store the reducer's state in the Redux store. - * @param reducer The reducer function to inject. - */ -export function injectReducer ( - key: string, - reducer: Reducer) { - dynamicReducers[key] = reducer; - if (!storeInstance) return; - storeInstance.replaceReducer(combineReducers({ - ...initialReducers, - ...dynamicReducers - })); -} diff --git a/packages/vm/src/extension-support/extension-manager.js b/packages/vm/src/extension-support/extension-manager.js index 7d5258580..dfc92c0f2 100644 --- a/packages/vm/src/extension-support/extension-manager.js +++ b/packages/vm/src/extension-support/extension-manager.js @@ -8,36 +8,25 @@ const BlockType = require('./block-type'); // TODO: move these out into a separate repository? // TODO: change extension spec so that library info, including extension ID, can be collected through static methods -/** - * List of core extensions that should load at startup. - */ -const coreExtensions = { - // eslint-disable-next-line global-require - coreExample: () => require('../blocks/scratch3_core_example') -}; - -/** - * List of built-in extensions that are available to load by ID or URL but do not load at startup. - */ +/* eslint-disable global-require */ const builtinExtensions = { // This is an example that isn't loaded with the other core blocks, // but serves as a reference for loading core blocks as extensions. + coreExample: () => require('../blocks/scratch3_core_example'), // These are the non-core built-in extensions. - pen: () => import(/* webpackChunkName: "ext_pen" */ '../extensions/scratch3_pen/index.js'), - wedo2: () => import(/* webpackChunkName: "ext_wedo2" */ '../extensions/scratch3_wedo2/index.js'), - music: () => import(/* webpackChunkName: "ext_music" */ '../extensions/scratch3_music/index.js'), - microbit: () => import(/* webpackChunkName: "ext_microbit" */ '../extensions/scratch3_microbit/index.js'), - text2speech: () => import(/* webpackChunkName: "ext_text2speech" */ '../extensions/scratch3_text2speech/index.js'), - translate: () => import(/* webpackChunkName: "ext_translate" */ '../extensions/scratch3_translate/index.js'), - videoSensing: () => import( - /* webpackChunkName: "ext_videoSensing" */ - '../extensions/scratch3_video_sensing/index.js' - ), - ev3: () => import(/* webpackChunkName: "ext_ev3" */ '../extensions/scratch3_ev3/index.js'), - makeymakey: () => import(/* webpackChunkName: "ext_makeymakey" */ '../extensions/scratch3_makeymakey/index.js'), - boost: () => import(/* webpackChunkName: "ext_boost" */ '../extensions/scratch3_boost/index.js'), - gdxfor: () => import(/* webpackChunkName: "ext_gdxfor" */ '../extensions/scratch3_gdx_for/index.js') + pen: () => require('../extensions/scratch3_pen'), + wedo2: () => require('../extensions/scratch3_wedo2'), + music: () => require('../extensions/scratch3_music'), + microbit: () => require('../extensions/scratch3_microbit'), + text2speech: () => require('../extensions/scratch3_text2speech'), + translate: () => require('../extensions/scratch3_translate'), + videoSensing: () => require('../extensions/scratch3_video_sensing'), + ev3: () => require('../extensions/scratch3_ev3'), + makeymakey: () => require('../extensions/scratch3_makeymakey'), + boost: () => require('../extensions/scratch3_boost'), + gdxfor: () => require('../extensions/scratch3_gdx_for') }; +/* eslint-enable global-require */ /** * @typedef {object} ArgumentInfo - Information about an extension block argument @@ -129,8 +118,8 @@ class ExtensionManager { * @param {string} extensionId - the ID of an internal extension */ loadExtensionIdSync (extensionId) { - if (!Object.prototype.hasOwnProperty.call(coreExtensions, extensionId)) { - log.warn(`Could not find extension ${extensionId} in core extensions.`); + if (!Object.prototype.hasOwnProperty.call(builtinExtensions, extensionId)) { + log.warn(`Could not find extension ${extensionId} in the built in extensions.`); return; } @@ -141,7 +130,7 @@ class ExtensionManager { return; } - const extension = coreExtensions[extensionId](); + const extension = builtinExtensions[extensionId](); const extensionInstance = new extension(this.runtime); const serviceName = this._registerInternalExtension(extensionInstance); this._loadedExtensions.set(extensionId, serviceName); @@ -152,24 +141,20 @@ class ExtensionManager { * @param {string} extensionURL - the URL for the extension to load OR the ID of an internal extension * @returns {Promise} resolved once the extension is loaded and initialized or rejected on failure */ - async loadExtensionURL (extensionURL) { - if (Object.prototype.hasOwnProperty.call(coreExtensions, extensionURL)) { - this.loadExtensionIdSync(extensionURL); - return; - } + loadExtensionURL (extensionURL) { if (Object.prototype.hasOwnProperty.call(builtinExtensions, extensionURL)) { /** @todo dupe handling for non-builtin extensions. See commit 670e51d33580e8a2e852b3b038bb3afc282f81b9 */ if (this.isExtensionLoaded(extensionURL)) { const message = `Rejecting attempt to load a second extension with ID ${extensionURL}`; log.warn(message); - return; + return Promise.resolve(); } - const {default: extension} = await builtinExtensions[extensionURL](); + const extension = builtinExtensions[extensionURL](); const extensionInstance = new extension(this.runtime); const serviceName = this._registerInternalExtension(extensionInstance); this._loadedExtensions.set(extensionURL, serviceName); - return; + return Promise.resolve(); } return new Promise((resolve, reject) => { diff --git a/packages/vm/src/virtual-machine.js b/packages/vm/src/virtual-machine.js index fa335685e..83ad0e1fb 100644 --- a/packages/vm/src/virtual-machine.js +++ b/packages/vm/src/virtual-machine.js @@ -28,6 +28,21 @@ require('canvas-toBlob'); const RESERVED_NAMES = ['_mouse_', '_stage_', '_edge_', '_myself_', '_random_']; +/** + * @type {string[]} + */ +const CORE_EXTENSIONS = [ + // 'motion', + // 'looks', + // 'sound', + // 'events', + // 'control', + // 'sensing', + // 'operators', + // 'variables', + // 'myBlocks' +]; + /** * @typedef {number} int * @typedef {import('./engine/target')} Target @@ -174,6 +189,11 @@ class VirtualMachine extends EventEmitter { this.extensionManager = new ExtensionManager(this.runtime); + // Load core extensions + for (const id of CORE_EXTENSIONS) { + this.extensionManager.loadExtensionIdSync(id); + } + this.blockListener = this.blockListener.bind(this); this.flyoutBlockListener = this.flyoutBlockListener.bind(this); this.monitorBlockListener = this.monitorBlockListener.bind(this); @@ -421,11 +441,9 @@ class VirtualMachine extends EventEmitter { resolve(res); }); }) - .catch(async error => { - const {SB1File, ValidationError} = await import( - /* webpackChunkName: "clipcc-sb1-convertor" */ - 'clipcc-sb1-converter' - ); + .catch(error => { + // eslint-disable-next-line global-require + const {SB1File, ValidationError} = require('clipcc-sb1-converter'); try { const sb1 = new SB1File(input); From 6efc582d7ad2bf695f135620c33d8745f006c04e Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Thu, 16 Apr 2026 11:15:39 +0800 Subject: [PATCH 27/29] :art: fix(gui): extra spaces Signed-off-by: SimonShiki --- packages/gui/src/lib/app-state-hoc.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gui/src/lib/app-state-hoc.tsx b/packages/gui/src/lib/app-state-hoc.tsx index 2d174900b..5bbf4ed49 100644 --- a/packages/gui/src/lib/app-state-hoc.tsx +++ b/packages/gui/src/lib/app-state-hoc.tsx @@ -83,7 +83,7 @@ const AppStateHOC = function

( initTelemetryModal } = guiRedux; // eslint-disable-next-line global-require, @typescript-eslint/no-require-imports - const {ScratchPaintReducer}: { ScratchPaintReducer: Reducer } = require('clipcc-paint'); + const {ScratchPaintReducer}: {ScratchPaintReducer: Reducer} = require('clipcc-paint'); let initializedGui: GuiState = guiInitialState; if (props.isFullScreen || props.isPlayerOnly) { From b3d2052a0c7a415e510f5794407a3dfb6be3fd2f Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Thu, 16 Apr 2026 18:16:07 +0800 Subject: [PATCH 28/29] :art: fix(gui): remove extra spaces [skip ci] Signed-off-by: SimonShiki --- packages/gui/src/containers/blocks.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gui/src/containers/blocks.jsx b/packages/gui/src/containers/blocks.jsx index a578d6b7b..f82f9a682 100644 --- a/packages/gui/src/containers/blocks.jsx +++ b/packages/gui/src/containers/blocks.jsx @@ -195,7 +195,7 @@ class Blocks extends React.Component { // call setLocale if the locale has changed, or changed while the blocks were hidden. // vm.getLocale() will be out of sync if locale was changed while not visible this.setLocale(); - // eslint-disable-next-line no-negated-condition + // eslint-disable-next-line no-negated-condition } else if (this.props.theme !== prevProps.theme) { this.ScratchBlocks.Theme.setTheme(this.themeMapName[this.props.theme] || 'scratch', this.workspace); } else { From fc3374e32ee36260905070fea990f4277a319841 Mon Sep 17 00:00:00 2001 From: SimonShiki Date: Sat, 18 Apr 2026 10:54:19 +0800 Subject: [PATCH 29/29] :wrench: chore: only include needed node polyfills Signed-off-by: SimonShiki --- packages/audio/webpack.config.js | 4 +++- packages/gui/webpack.config.js | 4 +++- packages/render/webpack.config.js | 4 +++- packages/vm/webpack.config.js | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/audio/webpack.config.js b/packages/audio/webpack.config.js index a8b1defa6..23820490f 100644 --- a/packages/audio/webpack.config.js +++ b/packages/audio/webpack.config.js @@ -30,6 +30,8 @@ module.exports = { 'startaudiocontext': true }, plugins: [ - new NodePolyfillPlugin() + new NodePolyfillPlugin({ + includeAliases: ['events'] + }) ] }; diff --git a/packages/gui/webpack.config.js b/packages/gui/webpack.config.js index a1aea4f68..0ef65c8ec 100644 --- a/packages/gui/webpack.config.js +++ b/packages/gui/webpack.config.js @@ -151,7 +151,9 @@ const base = { path.resolve(__dirname, '../vm') ] }), - new NodePolyfillPlugin(), + new NodePolyfillPlugin({ + includeAliases: ['buffer', 'events'] + }), new CopyWebpackPlugin({ patterns: [ { diff --git a/packages/render/webpack.config.js b/packages/render/webpack.config.js index 46b679666..eb1a270eb 100644 --- a/packages/render/webpack.config.js +++ b/packages/render/webpack.config.js @@ -38,7 +38,9 @@ const base = { ] }, plugins: [ - new NodePolyfillPlugin() + new NodePolyfillPlugin({ + includeAliases: ['events'] + }) ] }; diff --git a/packages/vm/webpack.config.js b/packages/vm/webpack.config.js index eb27c7762..50d4f7ead 100644 --- a/packages/vm/webpack.config.js +++ b/packages/vm/webpack.config.js @@ -53,7 +53,9 @@ const base = { ] }, plugins: [ - new NodePolyfillPlugin(), + new NodePolyfillPlugin({ + includeAliases: ['events', 'buffer'] + }), new webpack.DefinePlugin({ 'clipcc.VERSION': version, 'clipcc.BUILD_TIME': Date.now()