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"