diff --git a/.babelrc b/.babelrc index c6e484601..33ba270f0 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,10 @@ { - "presets": ["react-app"], + "presets": [ + "react-app", + "@babel/preset-env", + "@babel/preset-react", + "@babel/preset-typescript" + ], "plugins": [ [ "prismjs", diff --git a/.yarnrc.yml b/.yarnrc.yml index 6ff085359..d3770d784 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -3,3 +3,11 @@ nodeLinker: node-modules yarnPath: .yarn/releases/yarn-3.4.1.cjs checksumBehavior: "update" + +npmScopes: + RaspberryPiFoundation: + npmRegistryServer: "https://npm.pkg.github.com" + +npmRegistries: + "https://npm.pkg.github.com": + npmAuthToken: "${GITHUB_TOKEN}" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index d1ecbd1ff..f3d3a602c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,9 +3,12 @@ x-app: &x-app context: . volumes: - .:/app + - ../scratch-editor:/scratch-editor - node_modules:/app/node_modules - /var/run/docker.sock:/var/run/docker.sock stdin_open: true + environment: + - GITHUB_TOKEN=${GITHUB_TOKEN} services: app: <<: *x-app diff --git a/package.json b/package.json index 8a8573118..eadec16a9 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.34.2", "private": true, "dependencies": { + "@RaspberryPiFoundation/scratch-gui": "link:../scratch-editor/packages/scratch-gui", "@apollo/client": "^3.7.8", "@babel/core": "^7.17.10", "@codemirror/commands": "^6.1.1", @@ -27,6 +28,7 @@ "apollo-link-sentry": "^3.2.3", "assert": "^2.1.0", "axios": "^0.24.0", + "buffer": "^6.0.3", "classnames": "^2.3.2", "codemirror": "^6.0.1", "container-query-polyfill": "^1.0.2", @@ -43,8 +45,10 @@ "jest-axe": "^7.0.0", "jest-canvas-mock": "^2.5.2", "js-convert-case": "^4.2.0", + "js-file-download": "^0.4.12", "jszip": "^3.10.1", "jszip-utils": "^0.1.0", + "lodash.bindall": "^4.4.0", "marked": "^15.0.6", "material-symbols": "^0.27.0", "mime-types": "^2.1.35", @@ -111,6 +115,7 @@ }, "devDependencies": { "@babel/preset-env": "^7.17.10", + "@babel/preset-typescript": "^7.28.5", "@pmmmwh/react-refresh-webpack-plugin": "0.4.3", "@react-three/test-renderer": "8.2.1", "@svgr/webpack": "5.5.0", @@ -165,10 +170,13 @@ "path-browserify": "^1.0.1", "pnp-webpack-plugin": "1.6.4", "postcss-flexbugs-fixes": "4.2.1", + "postcss-import": "12.0.1", "postcss-loader": "3.0.0", "postcss-normalize": "8.0.1", "postcss-preset-env": "6.7.0", "postcss-safe-parser": "5.0.2", + "postcss-scss": "4.0.9", + "postcss-simple-vars": "5.0.2", "prettier": "^2.8.8", "react-dev-utils": "^11.0.3", "react-test-renderer": "^17.0.2", @@ -187,6 +195,7 @@ "stylelint-scss": "3.12.0", "stylelint-use-logical": "^2.1.0", "terser-webpack-plugin": "4.2.3", + "to-string-loader": "^1.2.0", "url-loader": "4.1.1", "webgl-mock-threejs": "^0.0.1", "webpack": "5.95.0", diff --git a/src/components/Editor/Project/Project.jsx b/src/components/Editor/Project/Project.jsx index 727277326..c7461b7ff 100644 --- a/src/components/Editor/Project/Project.jsx +++ b/src/components/Editor/Project/Project.jsx @@ -5,6 +5,8 @@ import "react-tabs/style/react-tabs.css"; import "react-toastify/dist/ReactToastify.css"; import { useContainerQuery } from "react-container-query"; import classnames from "classnames"; +import { compose } from "redux"; +import { setAppElement } from "react-modal"; import "../../../assets/stylesheets/Project.scss"; import Output from "../Output/Output"; @@ -15,8 +17,26 @@ import EditorInput from "../EditorInput/EditorInput"; import ResizableWithHandle from "../../../utils/ResizableWithHandle"; import { projContainer } from "../../../utils/containerQueries"; +import GUI, { AppStateHOC } from "@RaspberryPiFoundation/scratch-gui"; +import ScratchIntegrationHOC from "./ScratchIntegrationHOC"; +import Button from "../../Button/Button"; + +const WrappedGui = compose(AppStateHOC, ScratchIntegrationHOC)(GUI); +// const WrappedGUI = AppStateHOC(GUI); + const Project = (props) => { const webComponent = useSelector((state) => state.editor.webComponent); + const reactAppApiEndpoint = useSelector( + (state) => state.editor.reactAppApiEndpoint, + ); + const [isReady, setIsReady] = useState(false); + + useEffect(() => { + // Set app element to document body to avoid shadow DOM issues + setAppElement(document.body); + setIsReady(true); + }, []); + const { nameEditable = true, withProjectbar = true, @@ -33,26 +53,55 @@ const Project = (props) => { } }, [saving, autosave]); - const [params, containerRef] = useContainerQuery(projContainer); - const [defaultWidth, setDefaultWidth] = useState("auto"); - const [defaultHeight, setDefaultHeight] = useState("auto"); - const [maxWidth, setMaxWidth] = useState("100%"); - const [handleDirection, setHandleDirection] = useState("right"); + // const [params, containerRef] = useContainerQuery(projContainer); + // const [defaultWidth, setDefaultWidth] = useState("auto"); + // const [defaultHeight, setDefaultHeight] = useState("auto"); + // const [maxWidth, setMaxWidth] = useState("100%"); + // const [handleDirection, setHandleDirection] = useState("right"); const [loading, setLoading] = useState(true); + const [containerReady, setContainerReady] = useState(false); - useMemo(() => { - const isDesktop = params["width-larger-than-720"]; + // useMemo(() => { + // const isDesktop = params["width-larger-than-720"]; - setDefaultWidth(isDesktop ? "50%" : "100%"); - setDefaultHeight(isDesktop ? "100%" : "50%"); - setMaxWidth(isDesktop ? "75%" : "100%"); - setHandleDirection(isDesktop ? "right" : "bottom"); - }, [params["width-larger-than-720"]]); + // setDefaultWidth(isDesktop ? "50%" : "100%"); + // setDefaultHeight(isDesktop ? "100%" : "50%"); + // setMaxWidth(isDesktop ? "75%" : "100%"); + // setHandleDirection(isDesktop ? "right" : "bottom"); + // }, [params["width-larger-than-720"]]); useEffect(() => { setLoading(false); }, []); + useEffect(() => { + // Set the app element for React Modal to the root of your web component + const appRoot = + document.querySelector("editor-wc")?.shadowRoot?.querySelector("#root") || + document.getElementById("root"); + if (appRoot) { + setAppElement(appRoot); + } + }, []); + + if (!isReady) { + return
Loading Scratch Editor...
; + } + + const scratchProjectHost = reactAppApiEndpoint + ? `${reactAppApiEndpoint}/api/projects` + : null; + const scratchProjectId = "blank-scratch-starter"; + const scratchBasePath = process.env.PUBLIC_URL || "/"; + const scratchGuiProps = { + locale: "en", + menuBarHidden: true, + // assetHost: "https://editor-scratch.raspberrypi.org/api/assets", + // basePath: scratchBasePath, + // projectId: scratchProjectId, + // projectHost: scratchProjectHost, + }; + return (
{ {withSidebar && ( )} -
+
*/}
); diff --git a/src/components/Editor/Project/ScratchIntegrationHOC.jsx b/src/components/Editor/Project/ScratchIntegrationHOC.jsx new file mode 100644 index 000000000..fb3d15b54 --- /dev/null +++ b/src/components/Editor/Project/ScratchIntegrationHOC.jsx @@ -0,0 +1,238 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; +import bindAll from "lodash.bindall"; +import { + remixProject, + manualUpdateProject, + setStageSize, +} from "@RaspberryPiFoundation/scratch-gui"; + +import fileDownload from "js-file-download"; + +const ScratchIntegrationHOC = function (WrappedComponent) { + class ScratchIntegrationComponent extends React.Component { + constructor(props) { + super(props); + bindAll(this, [ + "handleMessage", + "handleDownload", + "handleUpload", + "handleRemix", + "handleSave", + "handleBlocksChanged", + ]); + } + componentDidMount() { + window.addEventListener("message", this.handleMessage); + this.props.setStageSize(); + if (this.props.vm) { + console.log("Setting up VM listeners in componentDidMount..."); + this.setupVMListeners(); + } else { + console.log("VM not available yet in componentDidMount."); + } + } + + componentDidUpdate(prevProps) { + // Set up listeners when VM becomes available + if (!prevProps.vm && this.props.vm) { + console.log("Setting up VM listeners in componentDidUpdate..."); + this.setupVMListeners(); + } + } + + componentWillUnmount() { + window.removeEventListener("message", this.handleMessage); + this.removeVMListeners(); + } + + setupVMListeners() { + const vm = this.props.vm; + if (!vm) return; + + console.log("=== Looking for Blockly workspace ==="); + + // Method 1: Check for global Blockly + if (window.Blockly) { + console.log("Found global Blockly:", window.Blockly); + const workspace = window.Blockly.getMainWorkspace?.(); + console.log("Blockly main workspace:", workspace); + + if (workspace) { + workspace.addChangeListener((event) => { + console.log("Blockly workspace change event:", event); + console.log("Event type:", event.type); + if (event.type === "endDrag") { + this.handleBlocksChanged(); + } + }); + console.log("✓ Added Blockly workspace change listener"); + return; // Success! + } + } + // const vm = this.props.vm; + // if (!vm) return; + + // // if (vm.runtime.getEditingTarget()) { + // // const workspace = vm.runtime.getEditingTarget().blocks; + // console.log(vm); + // console.log(vm.runtime); + // console.log(vm.runtime.constructor.PROJECT_CHANGED); + // vm.runtime.on('BLOCK_DRAG_UPDATE', this.handleBlocksChanged); + // // workspace.on('BLOCK_CREATE', this.handleBlocksChanged); + // // workspace.on('BLOCK_DELETE', this.handleBlocksChanged); + // // } + // console.log("Blocks changed listener set up...") + // // this.startPolling(); + } + + removeVMListeners() { + // Clean up any listeners set up in setupVMListeners + const vm = this.props.vm; + if (!vm) return; + + // const workspace = vm.runtime.getEditingTarget()?.blocks; + vm.runtime.removeListener('BLOCK_DRAG_UPDATE', this.handleBlocksChanged); + } + handleBlocksChanged() { + console.log("Blocks have changed"); + + // Debounce to avoid saving on every tiny change + if (this.saveTimeout) { + clearTimeout(this.saveTimeout); + } + + this.saveTimeout = setTimeout(() => { + if (this.props.saveProjectSb3) { + this.props.saveProjectSb3().then((sb3Content) => { + console.log("Autosaving project...", sb3Content); + + // Convert Blob/ArrayBuffer to base64 for localStorage + const reader = new FileReader(); + reader.onloadend = () => { + const base64String = reader.result.split(',')[1]; // Remove data:application/octet-stream;base64, prefix + localStorage.setItem("autosavedProject", base64String); + console.log("Project saved to localStorage (base64)"); + }; + reader.readAsDataURL(sb3Content); + + // This sb3Content is what you'd send to your save API + // It's the complete .sb3 file content + }); + } + }, 2000); // Wait 2 seconds after last change + }; + + handleMessage(event) { + // These are events sent from the page telling Scratch GUI to do certain things. + // Here we are telling Scratch GUI how to do those things. + // We want this the other way around in some of these cases. + if (event.origin !== window.location.origin) return; + + switch (event.data.type) { + case "scratch-gui-download": + this.handleDownload(event); + break; + case "scratch-gui-upload": + console.log("trying to upload..."); + this.handleUpload(event); + break; + case "scratch-gui-remix": + this.handleRemix(event); + break; + case "scratch-gui-save": + this.handleSave(event); + break; + } + } + handleDownload(event) { + if (!this.props.vmReady || !this.props.saveProjectSb3) { + console.error("Cannot download: Scratch VM not ready"); + return; + } + + const filename = event.data.filename; + this.props.saveProjectSb3().then((content) => { + fileDownload(content, filename); + }); + } + handleUpload(event) { + if (!this.props.vmReady || !this.props.loadProject) { + console.error("Cannot upload: Scratch VM not ready"); + return; + } + + console.log("it's uploading..."); + const file = event.data.file; + file.arrayBuffer().then((blob) => { + this.props.loadProject(blob).then(() => { + console.log("upload complete!"); + }); + }); + } + handleRemix() { + this.props.onClickRemix(); + } + handleSave() { + this.props.onClickSave(); + } + render() { + const { + vmReady, + saveProjectSb3, + loadProject, + onClickRemix, + onClickSave, + setStageSize, + ...componentProps + } = this.props; + return ; + } + } + + const mapStateToProps = (state) => { + // Check if scratchGui and vm exist before trying to access them + const vm = state.scratchGui?.vm; + + if (!vm) { + console.warn("Scratch VM not initialized yet"); + return { + saveProjectSb3: null, + loadProject: null, + vmReady: false, + vm: null, + }; + } else { + console.log("Scratch VM is initialized"); + } + + return { + saveProjectSb3: vm.saveProjectSb3?.bind(vm), + loadProject: vm.loadProject?.bind(vm), + vmReady: true, + vm: vm, + }; + }; + + const mapDispatchToProps = (dispatch) => ({ + onClickRemix: () => dispatch(remixProject()), + onClickSave: () => dispatch(manualUpdateProject()), + setStageSize: () => dispatch(setStageSize("small")), + }); + + ScratchIntegrationComponent.propTypes = { + saveProjectSb3: PropTypes.func, + loadProject: PropTypes.func, + onClickRemix: PropTypes.func, + onClickSave: PropTypes.func, + setStageSize: PropTypes.func, + vmReady: PropTypes.bool, + }; + return connect( + mapStateToProps, + mapDispatchToProps, + )(ScratchIntegrationComponent); +}; + +export { ScratchIntegrationHOC as default }; diff --git a/src/web-component.js b/src/web-component.js index 345502510..f65a78f6b 100644 --- a/src/web-component.js +++ b/src/web-component.js @@ -30,10 +30,6 @@ class WebComponent extends HTMLElement { sidebarPlugins = []; connectedCallback() { - if (!this.shadowRoot) { - this.mountPoint = this.shadowRoot; - } - console.log("Mounted web-component..."); this.mountReactApp(); @@ -43,7 +39,9 @@ class WebComponent extends HTMLElement { if (this.root) { console.log("Unmounted web-component..."); this.root.unmount(); + this.root = null; } + this.mountPoint = null; store.dispatch(resetStore()); } @@ -171,11 +169,13 @@ class WebComponent extends HTMLElement { } mountReactApp() { + if (!this.isConnected) { + return; + } if (!this.mountPoint) { this.mountPoint = document.createElement("div"); - this.mountPoint.setAttribute("id", "root"); - this.mountPoint.setAttribute("part", "editor-root"); - this.attachShadow({ mode: "open" }).appendChild(this.mountPoint); + this.mountPoint.setAttribute("data-web-component-root", "editor-root"); + this.appendChild(this.mountPoint); this.root = ReactDOMClient.createRoot(this.mountPoint); } diff --git a/webpack.config.js b/webpack.config.js index df68e746c..e99bec70a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,14 +1,25 @@ const path = require("path"); +const webpack = require("webpack"); const Dotenv = require("dotenv-webpack"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const WorkerPlugin = require("worker-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); +const postcssImport = require("postcss-import"); +const postcssSimpleVars = require("postcss-simple-vars"); +const postcssScss = require("postcss-scss"); let publicUrl = process.env.PUBLIC_URL || "/"; if (!publicUrl.endsWith("/")) { publicUrl += "/"; } +// scratch-gui uses postcss, so we need to match that here +const scratchGuiInclude = [ + /node_modules\/scratch-gui/, + /node_modules\/@RaspberryPiFoundation\/scratch-gui/, + /scratch-editor\/packages\/scratch-gui/, +]; + module.exports = { entry: { "web-component": path.resolve(__dirname, "./src/web-component.js"), @@ -16,21 +27,123 @@ module.exports = { }, module: { rules: [ + { + test: /\.(ts|tsx)$/, + include: [ + ...scratchGuiInclude, + /node_modules\/@scratch/, // Include @scratch packages + /node_modules\/scratch-paint/, // Include scratch-paint + ], + use: [ + { + loader: "babel-loader", + options: { + presets: [ + "@babel/preset-env", + "@babel/preset-react", + "@babel/preset-typescript", + ], + plugins: [ + [ + "prismjs", + { + languages: ["javascript", "css", "python", "html"], + plugins: [ + "line-numbers", + "line-highlight", + "highlight-keywords", + "normalize-whitespace", + ], + theme: "twilight", + css: true, + }, + ], + ], + }, + }, + ], + }, { test: /\.(js|jsx)$/, - exclude: /node_modules/, - use: ["babel-loader"], + exclude: + /node_modules\/(?!scratch-gui|@RaspberryPiFoundation\/scratch-gui|@scratch|scratch-paint)/, + use: [ + { + loader: "babel-loader", + options: { + presets: ["@babel/preset-env", "@babel/preset-react"], + plugins: [ + [ + "prismjs", + { + languages: ["javascript", "css", "python", "html"], + plugins: [ + "line-numbers", + "line-highlight", + "highlight-keywords", + "normalize-whitespace", + ], + theme: "twilight", + css: true, + }, + ], + ], + }, + }, + ], }, { test: /\.css$/, - use: ["css-loader"], + oneOf: [ + { + include: scratchGuiInclude, + use: [ + "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 1, + modules: { + auto: (resourcePath) => !resourcePath.endsWith(".raw.css"), + localIdentName: "[name]_[local]_[hash:base64:5]", // Match scratch-gui module naming + exportLocalsConvention: "camelCase", + }, + }, + }, + { + loader: "postcss-loader", + options: { + parser: postcssScss, + plugins: [postcssImport(), postcssSimpleVars()], + }, + }, + ], + }, + { + use: [ + "to-string-loader", + { + loader: "css-loader", + options: { + modules: false, + }, + }, + ], + }, + ], }, { test: /\.s[ac]ss$/i, exclude: [/node_modules/], use: [ + { + loader: "to-string-loader", + }, { loader: "css-loader", + // options: { + // modules: false, // Add this to disable CSS Modules + // }, }, { loader: "resolve-url-loader", @@ -79,15 +192,64 @@ module.exports = { }, ], }, + { + test: /\.mp3$/, + type: "asset/resource", + generator: { + filename: "static/media/[name].[hash][ext]", + }, + }, + { + test: /\.wav$/, + type: "asset/resource", + generator: { + filename: "static/media/[name].[hash][ext]", + }, + }, + { + test: /\.(png|jpg|jpeg|gif)$/, + include: scratchGuiInclude, + type: "asset/resource", + generator: { + filename: "static/media/[name].[hash][ext]", + }, + }, + // Handle arrayBuffer imports specifically + { + test: /\.(mp3|wav)$/, + resourceQuery: /arrayBuffer/, + type: "asset/resource", + generator: { + filename: "static/media/[name].[hash][ext]", + }, + }, + { + test: /\.hex$/, + include: scratchGuiInclude, + type: "asset/resource", + generator: { + filename: "static/firmware/[name].[hash][ext]", + }, + }, ], }, resolve: { - extensions: [".*", ".js", ".jsx", ".css"], + extensions: [".*", ".js", ".jsx", ".css", ".ts", ".tsx"], // Add .ts and .tsx + alias: { + "@RaspberryPiFoundation/scratch-gui": path.resolve( + __dirname, + "../scratch-editor/packages/scratch-gui/src", + ), + react: path.resolve(__dirname, "node_modules/react"), + "react-dom": path.resolve(__dirname, "node_modules/react-dom"), + "react-redux": path.resolve(__dirname, "node_modules/react-redux"), + }, fallback: { stream: require.resolve("stream-browserify"), assert: require.resolve("assert"), path: require.resolve("path-browserify"), url: require.resolve("url/"), + buffer: require.resolve("buffer"), }, }, output: { @@ -102,6 +264,9 @@ module.exports = { port: 3011, liveReload: true, hot: false, + client: { + overlay: false, + }, static: { directory: path.join(__dirname, "public"), }, @@ -137,6 +302,9 @@ module.exports = { path: "./.env", systemvars: true, }), + new webpack.ProvidePlugin({ + Buffer: ["buffer", "Buffer"], + }), new HtmlWebpackPlugin({ inject: "body", template: "src/web-component.html", diff --git a/yarn.lock b/yarn.lock index 296305fca..dd5df6233 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,12 @@ __metadata: version: 6 cacheKey: 8 +"@RaspberryPiFoundation/scratch-gui@link:../scratch-editor/packages/scratch-gui::locator=%40raspberrypifoundation%2Feditor-ui%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@RaspberryPiFoundation/scratch-gui@link:../scratch-editor/packages/scratch-gui::locator=%40raspberrypifoundation%2Feditor-ui%40workspace%3A." + languageName: node + linkType: soft + "@actions/core@npm:^1.2.0": version: 1.11.1 resolution: "@actions/core@npm:1.11.1" @@ -134,6 +140,17 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" + dependencies: + "@babel/helper-validator-identifier": ^7.27.1 + js-tokens: ^4.0.0 + picocolors: ^1.1.1 + checksum: 5874edc5d37406c4a0bb14cf79c8e51ad412fb0423d176775ac14fc0259831be1bf95bdda9c2aa651126990505e09a9f0ed85deaa99893bc316d2682c5115bdc + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.7, @babel/compat-data@npm:^7.25.8": version: 7.25.8 resolution: "@babel/compat-data@npm:7.25.8" @@ -176,6 +193,19 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/generator@npm:7.28.5" + dependencies: + "@babel/parser": ^7.28.5 + "@babel/types": ^7.28.5 + "@jridgewell/gen-mapping": ^0.3.12 + "@jridgewell/trace-mapping": ^0.3.28 + jsesc: ^3.0.2 + checksum: 3e86fa0197bb33394a85a73dbbca92bb1b3f250a30294c7e327359c0978ad90f36f3d71c7f2965a3fc349cfa82becc8f87e7421c75796c8bc48dd9010dd866d1 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.18.6, @babel/helper-annotate-as-pure@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-annotate-as-pure@npm:7.25.7" @@ -185,6 +215,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-annotate-as-pure@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" + dependencies: + "@babel/types": ^7.27.3 + checksum: 63863a5c936ef82b546ca289c9d1b18fabfc24da5c4ee382830b124e2e79b68d626207febc8d4bffc720f50b2ee65691d7d12cc0308679dee2cd6bdc926b7190 + languageName: node + linkType: hard + "@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.25.7" @@ -225,6 +264,23 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-create-class-features-plugin@npm:7.28.5" + dependencies: + "@babel/helper-annotate-as-pure": ^7.27.3 + "@babel/helper-member-expression-to-functions": ^7.28.5 + "@babel/helper-optimise-call-expression": ^7.27.1 + "@babel/helper-replace-supers": ^7.27.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 + "@babel/traverse": ^7.28.5 + semver: ^6.3.1 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 98f94a27bcde0cf0b847c41e1307057a1caddd131fb5fa0b1566e0c15ccc20b0ebab9667d782bffcd3eac9262226b18e86dcf30ab0f4dc5d14b1e1bf243aba49 + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.7" @@ -253,6 +309,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-globals@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/helper-globals@npm:7.28.0" + checksum: d8d7b91c12dad1ee747968af0cb73baf91053b2bcf78634da2c2c4991fb45ede9bd0c8f9b5f3254881242bc0921218fcb7c28ae885477c25177147e978ce4397 + languageName: node + linkType: hard + "@babel/helper-member-expression-to-functions@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-member-expression-to-functions@npm:7.25.7" @@ -263,6 +326,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^7.27.1, @babel/helper-member-expression-to-functions@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-member-expression-to-functions@npm:7.28.5" + dependencies: + "@babel/traverse": ^7.28.5 + "@babel/types": ^7.28.5 + checksum: 447d385233bae2eea713df1785f819b5a5ca272950740da123c42d23f491045120f0fbbb5609c091f7a9bbd40f289a442846dde0cb1bf0c59440fa093690cf7c + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-module-imports@npm:7.25.7" @@ -273,6 +346,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-module-imports@npm:7.27.1" + dependencies: + "@babel/traverse": ^7.27.1 + "@babel/types": ^7.27.1 + checksum: 92d01c71c0e4aacdc2babce418a9a1a27a8f7d770a210ffa0f3933f321befab18b655bc1241bebc40767516731de0b85639140c42e45a8210abe1e792f115b28 + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-module-transforms@npm:7.25.7" @@ -287,6 +370,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.27.1": + version: 7.28.3 + resolution: "@babel/helper-module-transforms@npm:7.28.3" + dependencies: + "@babel/helper-module-imports": ^7.27.1 + "@babel/helper-validator-identifier": ^7.27.1 + "@babel/traverse": ^7.28.3 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 7cf7b79da0fa626d6c84bfc7b35c079a2559caecaa2ff645b0f1db0d741507aa4df6b5b98a3283e8ac4e89094af271d805bf5701e5c4f916e622797b7c8cbb18 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-optimise-call-expression@npm:7.25.7" @@ -296,6 +392,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-optimise-call-expression@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" + dependencies: + "@babel/types": ^7.27.1 + checksum: 0fb7ee824a384529d6b74f8a58279f9b56bfe3cce332168067dddeab2552d8eeb56dc8eaf86c04a3a09166a316cb92dfc79c4c623cd034ad4c563952c98b464f + languageName: node + linkType: hard + "@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.25.7, @babel/helper-plugin-utils@npm:^7.8.0": version: 7.25.7 resolution: "@babel/helper-plugin-utils@npm:7.25.7" @@ -303,6 +408,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-plugin-utils@npm:7.27.1" + checksum: 5d715055301badab62bdb2336075a77f8dc8bd290cad2bc1b37ea3bf1b3efc40594d308082229f239deb4d6b5b80b0a73bce000e595ea74416e0339c11037047 + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-remap-async-to-generator@npm:7.25.7" @@ -329,6 +441,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-replace-supers@npm:7.27.1" + dependencies: + "@babel/helper-member-expression-to-functions": ^7.27.1 + "@babel/helper-optimise-call-expression": ^7.27.1 + "@babel/traverse": ^7.27.1 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 3690266c304f21008690ba68062f889a363583cabc13c3d033b94513953147af3e0a3fdb48fa1bb9fa3734b64e221fc65e5222ab70837f02321b7225f487c6ef + languageName: node + linkType: hard + "@babel/helper-simple-access@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-simple-access@npm:7.25.7" @@ -349,6 +474,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" + dependencies: + "@babel/traverse": ^7.27.1 + "@babel/types": ^7.27.1 + checksum: 4f380c5d0e0769fa6942a468b0c2d7c8f0c438f941aaa88f785f8752c103631d0904c7b4e76207a3b0e6588b2dec376595370d92ca8f8f1b422c14a69aa146d4 + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-string-parser@npm:7.25.7" @@ -356,6 +491,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-string-parser@npm:7.27.1" + checksum: 0a8464adc4b39b138aedcb443b09f4005d86207d7126e5e079177e05c3116107d856ec08282b365e9a79a9872f40f4092a6127f8d74c8a01c1ef789dacfc25d6 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-validator-identifier@npm:7.25.7" @@ -370,6 +512,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.27.1, @babel/helper-validator-identifier@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-validator-identifier@npm:7.28.5" + checksum: 5a251a6848e9712aea0338f659a1a3bd334d26219d5511164544ca8ec20774f098c3a6661e9da65a0d085c745c00bb62c8fada38a62f08fa1f8053bc0aeb57e4 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-validator-option@npm:7.25.7" @@ -377,6 +526,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-option@npm:7.27.1" + checksum: db73e6a308092531c629ee5de7f0d04390835b21a263be2644276cb27da2384b64676cab9f22cd8d8dbd854c92b1d7d56fc8517cf0070c35d1c14a8c828b0903 + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-wrap-function@npm:7.25.7" @@ -421,6 +577,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/parser@npm:7.28.5" + dependencies: + "@babel/types": ^7.28.5 + bin: + parser: ./bin/babel-parser.js + checksum: 5c2456e3f26c70d4a3ce1a220b529a91a2df26c54a2894fd0dea2342699ea1067ffdda9f0715eeab61da46ff546fd5661bc70be6d8d11977cbe21f5f0478819a + languageName: node + linkType: hard + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.7": version: 7.25.7 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.7" @@ -698,6 +865,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-jsx@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-jsx@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": ^7.27.1 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: c6d1324cff286a369aa95d99b8abd21dd07821b5d3affd5fe7d6058c84cff9190743287826463ee57a7beecd10fa1e4bc99061df532ee14e188c1c8937b13e3a + languageName: node + linkType: hard + "@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" @@ -797,6 +975,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-typescript@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-typescript@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": ^7.27.1 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 87836f7e32af624c2914c73cd6b9803cf324e07d43f61dbb973c6a86f75df725e12540d91fac7141c14b697aa9268fd064220998daced156e96ac3062d7afb41 + languageName: node + linkType: hard + "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -1106,6 +1295,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-commonjs@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.27.1" + dependencies: + "@babel/helper-module-transforms": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: bc45c1beff9b145c982bd6a614af338893d38bce18a9df7d658c9084e0d8114b286dcd0e015132ae7b15dd966153cb13321e4800df9766d0ddd892d22bf09d2a + languageName: node + linkType: hard + "@babel/plugin-transform-modules-systemjs@npm:^7.25.7": version: 7.25.7 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.7" @@ -1442,6 +1643,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/plugin-transform-typescript@npm:7.28.5" + dependencies: + "@babel/helper-annotate-as-pure": ^7.27.3 + "@babel/helper-create-class-features-plugin": ^7.28.5 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 + "@babel/plugin-syntax-typescript": ^7.27.1 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 202785e9cc6fb04efba091b3d5560cc8089cdc54df12fafa3d32ed7089e8d7a95b92b2fb1b53ec3e4db3bbafe56e8b32a3530cac004b3e493e902def8666001d + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-escapes@npm:^7.25.7": version: 7.25.7 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.25.7" @@ -1611,6 +1827,21 @@ __metadata: languageName: node linkType: hard +"@babel/preset-typescript@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/preset-typescript@npm:7.28.5" + dependencies: + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-validator-option": ^7.27.1 + "@babel/plugin-syntax-jsx": ^7.27.1 + "@babel/plugin-transform-modules-commonjs": ^7.27.1 + "@babel/plugin-transform-typescript": ^7.28.5 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 22f889835d9db1e627846e71ca2f02e2d24e2eb9ebcf9845b3b1d37bd3a53787967bafabbbcb342f06aaf7627399a7102ba6ca18f9a0e17066c865d680d2ceb9 + languageName: node + linkType: hard + "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.24.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2": version: 7.25.7 resolution: "@babel/runtime@npm:7.25.7" @@ -1631,6 +1862,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/template@npm:7.27.2" + dependencies: + "@babel/code-frame": ^7.27.1 + "@babel/parser": ^7.27.2 + "@babel/types": ^7.27.1 + checksum: ff5628bc066060624afd970616090e5bba91c6240c2e4b458d13267a523572cbfcbf549391eec8217b94b064cf96571c6273f0c04b28a8567b96edc675c28e27 + languageName: node + linkType: hard + "@babel/traverse@npm:^7.25.7, @babel/traverse@npm:^7.7.0": version: 7.25.7 resolution: "@babel/traverse@npm:7.25.7" @@ -1646,6 +1888,21 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/traverse@npm:7.28.5" + dependencies: + "@babel/code-frame": ^7.27.1 + "@babel/generator": ^7.28.5 + "@babel/helper-globals": ^7.28.0 + "@babel/parser": ^7.28.5 + "@babel/template": ^7.27.2 + "@babel/types": ^7.28.5 + debug: ^4.3.1 + checksum: e028ee9654f44be7c2a2df268455cee72d5c424c9ae536785f8f7c8680356f7b977c77ad76909d07eeed09ff1e125ce01cf783011f66b56c838791a85fa6af04 + languageName: node + linkType: hard + "@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.8, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.0": version: 7.25.8 resolution: "@babel/types@npm:7.25.8" @@ -1657,6 +1914,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/types@npm:7.28.5" + dependencies: + "@babel/helper-string-parser": ^7.27.1 + "@babel/helper-validator-identifier": ^7.28.5 + checksum: 5bc266af9e55ff92f9ddf33d83a42c9de1a87f9579d0ed62ef94a741a081692dd410a4fbbab18d514b83e135083ff05bc0e37003834801c9514b9d8ad748070d + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -2295,6 +2562,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:^0.3.12": + version: 0.3.13 + resolution: "@jridgewell/gen-mapping@npm:0.3.13" + dependencies: + "@jridgewell/sourcemap-codec": ^1.5.0 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: f2105acefc433337145caa3c84bba286de954f61c0bc46279bbd85a9e6a02871089717fa060413cfb6a9d44189fe8313b2d1cabf3a2eb3284d208fd5f75c54ff + languageName: node + linkType: hard + "@jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.5 resolution: "@jridgewell/gen-mapping@npm:0.3.5" @@ -2337,6 +2614,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: c2e36e67971f719a8a3a85ef5a5f580622437cc723c35d03ebd0c9c0b06418700ef006f58af742791f71f6a4fc68fcfaf1f6a74ec2f9a3332860e9373459dae7 + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": version: 0.3.25 resolution: "@jridgewell/trace-mapping@npm:0.3.25" @@ -2347,6 +2631,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.28": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: af8fda2431348ad507fbddf8e25f5d08c79ecc94594061ce402cf41bc5aba1a7b3e59bf0fd70a619b35f33983a3f488ceeba8faf56bff784f98bb5394a8b7d47 + languageName: node + linkType: hard + "@jsonjoy.com/base64@npm:^1.1.1": version: 1.1.2 resolution: "@jsonjoy.com/base64@npm:1.1.2" @@ -2948,9 +3242,11 @@ __metadata: version: 0.0.0-use.local resolution: "@raspberrypifoundation/editor-ui@workspace:." dependencies: + "@RaspberryPiFoundation/scratch-gui": "link:../scratch-editor/packages/scratch-gui" "@apollo/client": ^3.7.8 "@babel/core": ^7.17.10 "@babel/preset-env": ^7.17.10 + "@babel/preset-typescript": ^7.28.5 "@codemirror/commands": ^6.1.1 "@codemirror/lang-css": ^6.0.0 "@codemirror/lang-html": ^6.1.2 @@ -2988,6 +3284,7 @@ __metadata: babel-plugin-prismjs: ^2.1.0 babel-preset-react-app: ^10.0.1 bfj: ^7.0.2 + buffer: ^6.0.3 camelcase: ^6.1.0 case-sensitive-paths-webpack-plugin: 2.3.0 classnames: ^2.3.2 @@ -3037,8 +3334,10 @@ __metadata: jest-transformer-svg: ^2.0.0 jest-watch-typeahead: ^2.2.0 js-convert-case: ^4.2.0 + js-file-download: ^0.4.12 jszip: ^3.10.1 jszip-utils: ^0.1.0 + lodash.bindall: ^4.4.0 marked: ^15.0.6 material-symbols: ^0.27.0 mime-types: ^2.1.35 @@ -3052,10 +3351,13 @@ __metadata: plotly.js: ^3.0.2 pnp-webpack-plugin: 1.6.4 postcss-flexbugs-fixes: 4.2.1 + postcss-import: 12.0.1 postcss-loader: 3.0.0 postcss-normalize: 8.0.1 postcss-preset-env: 6.7.0 postcss-safe-parser: 5.0.2 + postcss-scss: 4.0.9 + postcss-simple-vars: 5.0.2 prettier: ^2.8.8 prismjs: ^1.29.0 prompts: 2.4.0 @@ -3101,6 +3403,7 @@ __metadata: stylelint-use-logical: ^2.1.0 terser-webpack-plugin: 4.2.3 three: 0.169.0 + to-string-loader: ^1.2.0 ts-pnp: 1.2.0 url: ^0.11.4 url-loader: 4.1.1 @@ -11857,7 +12160,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.16.0": +"is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1": version: 2.16.1 resolution: "is-core-module@npm:2.16.1" dependencies: @@ -13178,6 +13481,13 @@ __metadata: languageName: node linkType: hard +"js-file-download@npm:^0.4.12": + version: 0.4.12 + resolution: "js-file-download@npm:0.4.12" + checksum: a03847eef0184fbf34a7b7fd365ea6aa1a6cc142efeac52c4baa0cdde845dc93718eb66808dfcffd6c91b37ddc9d058d352ac9698b4280744bad3587240c93b6 + languageName: node + linkType: hard + "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -13654,7 +13964,7 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3": +"loader-utils@npm:^1.0.0, loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3": version: 1.4.2 resolution: "loader-utils@npm:1.4.2" dependencies: @@ -13720,6 +14030,13 @@ __metadata: languageName: node linkType: hard +"lodash.bindall@npm:^4.4.0": + version: 4.4.0 + resolution: "lodash.bindall@npm:4.4.0" + checksum: 6b4a6a8b00777ca4dac33ee9d7b16400db09c141d2761eaba032599e101e2e378f6f63d91abfaf71945aba2bff3e934b2c4f2d0e9988b6d90f639a68894862a2 + languageName: node + linkType: hard + "lodash.debounce@npm:^4.0.8": version: 4.0.8 resolution: "lodash.debounce@npm:4.0.8" @@ -15432,7 +15749,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 @@ -15446,7 +15763,7 @@ __metadata: languageName: node linkType: hard -"pify@npm:^2.2.0": +"pify@npm:^2.2.0, pify@npm:^2.3.0": version: 2.3.0 resolution: "pify@npm:2.3.0" checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba @@ -15837,6 +16154,18 @@ __metadata: languageName: node linkType: hard +"postcss-import@npm:12.0.1": + version: 12.0.1 + resolution: "postcss-import@npm:12.0.1" + dependencies: + postcss: ^7.0.1 + postcss-value-parser: ^3.2.3 + read-cache: ^1.0.0 + resolve: ^1.1.7 + checksum: f891e16ace33337627d64a2b37a1c285f06aef6aa9d780768db96b7c509a649e8fa7f686768f9b96d42ff364f8a4c0d06c9e850d83bd00cbe625abdbf9fa046f + languageName: node + linkType: hard + "postcss-initial@npm:^3.0.0": version: 3.0.4 resolution: "postcss-initial@npm:3.0.4" @@ -16303,6 +16632,15 @@ __metadata: languageName: node linkType: hard +"postcss-scss@npm:4.0.9": + version: 4.0.9 + resolution: "postcss-scss@npm:4.0.9" + peerDependencies: + postcss: ^8.4.29 + checksum: dc358bafc23d52ed3a9a29333808825deba213042be74ece6eae7a61c692f67d0e6691fa7005367b013c01c79562fbb9ef2fe4c0485075233931bd90715f5132 + languageName: node + linkType: hard + "postcss-selector-matches@npm:^4.0.0": version: 4.0.0 resolution: "postcss-selector-matches@npm:4.0.0" @@ -16355,6 +16693,15 @@ __metadata: languageName: node linkType: hard +"postcss-simple-vars@npm:5.0.2": + version: 5.0.2 + resolution: "postcss-simple-vars@npm:5.0.2" + dependencies: + postcss: ^7.0.14 + checksum: 6d9e72bd9646b4080393f1819e47158df72bbdcbfa9d3a949c247ee8756a3f3d72a36f18a9033f2d67723a05f914f921e22fadcf821556c3598a65d7752e12e6 + languageName: node + linkType: hard + "postcss-sorting@npm:^4.1.0": version: 4.1.0 resolution: "postcss-sorting@npm:4.1.0" @@ -16387,7 +16734,7 @@ __metadata: languageName: node linkType: hard -"postcss-value-parser@npm:^3.0.0": +"postcss-value-parser@npm:^3.0.0, postcss-value-parser@npm:^3.2.3": version: 3.3.1 resolution: "postcss-value-parser@npm:3.3.1" checksum: 62cd26e1cdbcf2dcc6bcedf3d9b409c9027bc57a367ae20d31dd99da4e206f730689471fd70a2abe866332af83f54dc1fa444c589e2381bf7f8054c46209ce16 @@ -17289,6 +17636,15 @@ __metadata: languageName: node linkType: hard +"read-cache@npm:^1.0.0": + version: 1.0.0 + resolution: "read-cache@npm:1.0.0" + dependencies: + pify: ^2.3.0 + checksum: cffc728b9ede1e0667399903f9ecaf3789888b041c46ca53382fa3a06303e5132774dc0a96d0c16aa702dbac1ea0833d5a868d414f5ab2af1e1438e19e6657c6 + languageName: node + linkType: hard + "read-pkg-up@npm:^8.0.0": version: 8.0.0 resolution: "read-pkg-up@npm:8.0.0" @@ -17882,6 +18238,19 @@ __metadata: languageName: node linkType: hard +"resolve@npm:^1.1.7": + version: 1.22.11 + resolution: "resolve@npm:1.22.11" + dependencies: + is-core-module: ^2.16.1 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: 6d5baa2156b95a65ac431e7642e21106584e9f4194da50871cae8bc1bbd2b53bb7cee573c92543d83bb999620b224a087f62379d800ed1ccb189da6df5d78d50 + languageName: node + linkType: hard + "resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.4": version: 1.22.8 resolution: "resolve@npm:1.22.8" @@ -17938,6 +18307,19 @@ __metadata: languageName: node linkType: hard +"resolve@patch:resolve@^1.1.7#~builtin": + version: 1.22.11 + resolution: "resolve@patch:resolve@npm%3A1.22.11#~builtin::version=1.22.11&hash=c3c19d" + dependencies: + is-core-module: ^2.16.1 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: 1462da84ac3410d7c2e12e4f5f25c1423d8a174c3b4245c43eafea85e7bbe6af3eb7ec10a4850b5e518e8531608604742b8cbd761e1acd7ad1035108b7c98013 + languageName: node + linkType: hard + "resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.4#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" @@ -20076,6 +20458,15 @@ __metadata: languageName: node linkType: hard +"to-string-loader@npm:^1.2.0": + version: 1.2.0 + resolution: "to-string-loader@npm:1.2.0" + dependencies: + loader-utils: ^1.0.0 + checksum: 738d51379aab962c843b0764335b0a1f89f42402b18c1a75d1e2653ef938702a7a6f132cfe7fb888cd14ca2e9a76ed779f9be34ea0a257c500d3f8edde8a1140 + languageName: node + linkType: hard + "toidentifier@npm:1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1"