diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 2f2199028..de3b9fe93 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -125,9 +125,10 @@ jobs:
- name: Build WC bundle
run: |
- if [[ "${{ inputs.environment }}" != "production" ]]; then
- yarn build:dev
- fi
+ # TODO: Reinitialise when storybook build is fixed
+ # if [[ "${{ inputs.environment }}" != "production" ]]; then
+ # yarn build:dev
+ # fi
yarn build
env:
PUBLIC_URL: ${{ needs.setup-environment.outputs.public_url }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3c293f456..d1166906a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Fixed
- Bug causing py-enigma code to disable stop button
+- Crashing caused by excessive file sizes (#1138)
### Changed
diff --git a/cypress/e2e/spec-wc-skulpt.cy.js b/cypress/e2e/spec-wc-skulpt.cy.js
index 6f5e05b9f..5b733ca8a 100644
--- a/cypress/e2e/spec-wc-skulpt.cy.js
+++ b/cypress/e2e/spec-wc-skulpt.cy.js
@@ -121,25 +121,31 @@ describe("Running the code with skulpt", () => {
runCode("import sense_hat");
cy.get("editor-wc")
.shadow()
- .find("#root")
+ .find(".skulptrunner")
.should("contain", "Visual output");
});
it("does not render astro pi component on page load", () => {
- cy.get("editor-wc").shadow().find("#root").should("not.contain", "yaw");
+ cy.get("editor-wc")
+ .shadow()
+ .find(".skulptrunner")
+ .should("not.contain", "yaw");
});
it("renders astro pi component if sense hat imported", () => {
runCode("import sense_hat");
cy.get("editor-wc").shadow().contains("Visual output").click();
- cy.get("editor-wc").shadow().find("#root").should("contain", "yaw");
+ cy.get("editor-wc").shadow().find(".skulptrunner").should("contain", "yaw");
});
it("does not render astro pi component if sense hat unimported", () => {
runCode("import sense_hat");
runCode("import p5");
cy.get("editor-wc").shadow().contains("Visual output").click();
- cy.get("editor-wc").shadow().find("#root").should("not.contain", "yaw");
+ cy.get("editor-wc")
+ .shadow()
+ .find(".skulptrunner")
+ .should("not.contain", "yaw");
});
it("runs a simple turtle program", () => {
diff --git a/package.json b/package.json
index c10bbb230..762751131 100644
--- a/package.json
+++ b/package.json
@@ -15,8 +15,8 @@
"@hello-pangea/dnd": "^16.2.0",
"@juggle/resize-observer": "^3.3.1",
"@lezer/highlight": "^1.0.0",
- "@raspberrypifoundation/design-system-core": "^0.1.9",
- "@raspberrypifoundation/design-system-react": "^0.1.5",
+ "@raspberrypifoundation/design-system-core": "^1.6.0",
+ "@raspberrypifoundation/design-system-react": "^1.6.0",
"@react-three/drei": "9.114.3",
"@react-three/fiber": "^8.0.13",
"@reduxjs/toolkit": "^1.6.2",
@@ -45,6 +45,7 @@
"js-convert-case": "^4.2.0",
"jszip": "^3.10.1",
"jszip-utils": "^0.1.0",
+ "material-symbols": "^0.27.0",
"mime-types": "^2.1.35",
"node-html-parser": "^6.1.5",
"oidc-client": "^1.11.5",
diff --git a/src/assets/stylesheets/EditorPanel.scss b/src/assets/stylesheets/EditorPanel.scss
index d7452bbc3..5b52b3747 100644
--- a/src/assets/stylesheets/EditorPanel.scss
+++ b/src/assets/stylesheets/EditorPanel.scss
@@ -39,3 +39,7 @@
@include font-size-2(regular);
}
}
+
+.rpf-alert {
+ margin: 0;
+}
diff --git a/src/assets/stylesheets/ExternalStyles.scss b/src/assets/stylesheets/ExternalStyles.scss
index b9f63b27e..83acc15eb 100644
--- a/src/assets/stylesheets/ExternalStyles.scss
+++ b/src/assets/stylesheets/ExternalStyles.scss
@@ -2,3 +2,5 @@
@use "../../../node_modules/react-toggle/style.css";
@use "../../../node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css";
@use "../../../node_modules/prismjs/plugins/line-highlight/prism-line-highlight.css";
+@use "../../../node_modules/@raspberrypifoundation/design-system-core/scss/components/alert.scss";
+@use "../../../node_modules/material-symbols/sharp.scss";
diff --git a/src/assets/stylesheets/Tabs.scss b/src/assets/stylesheets/Tabs.scss
index 2a6c42bd8..beb3856e3 100644
--- a/src/assets/stylesheets/Tabs.scss
+++ b/src/assets/stylesheets/Tabs.scss
@@ -72,6 +72,7 @@
padding-inline-end: 0;
}
}
+
&__tab-close-btn {
block-size: 100%;
padding: $space-0-25;
@@ -112,6 +113,7 @@
&__tab-panel--selected {
flex: 1;
display: flex;
+ flex-direction: column;
overflow-y: auto;
}
}
diff --git a/src/components/Editor/EditorPanel/EditorPanel.jsx b/src/components/Editor/EditorPanel/EditorPanel.jsx
index 29b148e56..951cfb70b 100644
--- a/src/components/Editor/EditorPanel/EditorPanel.jsx
+++ b/src/components/Editor/EditorPanel/EditorPanel.jsx
@@ -1,6 +1,6 @@
/* eslint-disable react-hooks/exhaustive-deps */
import "../../../assets/stylesheets/EditorPanel.scss";
-import React, { useRef, useEffect, useContext } from "react";
+import React, { useRef, useEffect, useContext, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { updateProjectComponent } from "../../../redux/EditorSlice";
import { useCookies } from "react-cookie";
@@ -11,16 +11,20 @@ import { EditorState } from "@codemirror/state";
import { defaultKeymap, indentWithTab } from "@codemirror/commands";
import { indentationMarkers } from "@replit/codemirror-indentation-markers";
import { indentUnit } from "@codemirror/language";
+import "material-symbols";
import { html } from "@codemirror/lang-html";
import { css } from "@codemirror/lang-css";
import { python } from "@codemirror/lang-python";
import { javascript } from "@codemirror/lang-javascript";
+import { Alert } from "@raspberrypifoundation/design-system-react";
import { editorLightTheme } from "../../../assets/themes/editorLightTheme";
import { editorDarkTheme } from "../../../assets/themes/editorDarkTheme";
import { SettingsContext } from "../../../utils/settings";
+const MAX_CHARACTERS = 8500000;
+
const EditorPanel = ({ extension = "html", fileName = "index" }) => {
const editor = useRef();
const project = useSelector((state) => state.editor.project);
@@ -29,6 +33,7 @@ const EditorPanel = ({ extension = "html", fileName = "index" }) => {
const dispatch = useDispatch();
const { t } = useTranslation();
const settings = useContext(SettingsContext);
+ const [characterLimitExceeded, setCharacterLimitExceeded] = useState(false);
const updateStoredProject = (content) => {
dispatch(
@@ -86,6 +91,16 @@ const EditorPanel = ({ extension = "html", fileName = "index" }) => {
customIndentUnit = " ";
}
+ const limitCharacters = EditorState.transactionFilter.of((transaction) => {
+ const newDoc = transaction.newDoc;
+ if (newDoc.length > MAX_CHARACTERS) {
+ setCharacterLimitExceeded(true);
+ return [];
+ }
+ setCharacterLimitExceeded(false);
+ return transaction;
+ });
+
const startState = EditorState.create({
doc: code,
extensions: [
@@ -98,6 +113,7 @@ const EditorPanel = ({ extension = "html", fileName = "index" }) => {
indentationMarkers(),
indentUnit.of(customIndentUnit),
EditorView.editable.of(!readOnly),
+ limitCharacters,
],
});
@@ -123,7 +139,18 @@ const EditorPanel = ({ extension = "html", fileName = "index" }) => {
}, [cookies]);
return (
-
+ <>
+
+ {characterLimitExceeded && (
+
+ )}
+ >
);
};
diff --git a/src/components/Editor/EditorPanel/EditorPanel.test.js b/src/components/Editor/EditorPanel/EditorPanel.test.js
index 872a2916a..5c5c9783a 100644
--- a/src/components/Editor/EditorPanel/EditorPanel.test.js
+++ b/src/components/Editor/EditorPanel/EditorPanel.test.js
@@ -1,7 +1,7 @@
import configureStore from "redux-mock-store";
import { Provider } from "react-redux";
import { SettingsContext } from "../../../utils/settings";
-import { render, screen } from "@testing-library/react";
+import { fireEvent, render, screen } from "@testing-library/react";
import { axe, toHaveNoViolations } from "jest-axe";
import EditorPanel from "./EditorPanel";
@@ -88,3 +88,48 @@ describe("When read only", () => {
expect(editorInputArea).toHaveAttribute("contenteditable", "false");
});
});
+
+describe("When excessive file content is pasted into the editor", () => {
+ beforeEach(() => {
+ renderEditorPanel({ readOnly: false });
+ const editorInputArea = screen.getByLabelText("editorPanel.ariaLabel");
+ const massiveFileContent = "mango".repeat(2000000);
+ fireEvent.paste(editorInputArea, {
+ clipboardData: {
+ getData: () => massiveFileContent,
+ },
+ });
+ });
+
+ test("It does not display the file content", () => {
+ expect(screen.queryByText(/mango/)).not.toBeInTheDocument();
+ });
+
+ test("Character limit exceeded message is displayed", () => {
+ expect(
+ screen.getByText("editorPanel.characterLimitError"),
+ ).toBeInTheDocument();
+ });
+
+ test("It allows the user to input text below the limit", () => {
+ const editorInputArea = screen.getByLabelText("editorPanel.ariaLabel");
+ fireEvent.paste(editorInputArea, {
+ clipboardData: {
+ getData: () => "mango",
+ },
+ });
+ expect(screen.getByText("mango")).toBeInTheDocument();
+ });
+
+ test("It removes the character limit exceeded message when the user inputs text below the limit", () => {
+ const editorInputArea = screen.getByLabelText("editorPanel.ariaLabel");
+ fireEvent.paste(editorInputArea, {
+ clipboardData: {
+ getData: () => "mango",
+ },
+ });
+ expect(
+ screen.queryByText("editorPanel.characterLimitError"),
+ ).not.toBeInTheDocument();
+ });
+});
diff --git a/src/hooks/useProjectPersistence.js b/src/hooks/useProjectPersistence.js
index 749f9ec28..5c8bc03f6 100644
--- a/src/hooks/useProjectPersistence.js
+++ b/src/hooks/useProjectPersistence.js
@@ -8,6 +8,8 @@ import {
} from "../redux/EditorSlice";
import { showLoginPrompt, showSavePrompt } from "../utils/Notifications";
+const COMBINED_FILE_SIZE_SOFT_LIMIT = 1000000;
+
export const useProjectPersistence = ({
user,
project = {},
@@ -18,6 +20,13 @@ export const useProjectPersistence = ({
}) => {
const dispatch = useDispatch();
+ const combinedFileSize = project.components?.reduce(
+ (sum, component) => sum + component.content.length,
+ 0,
+ );
+ const autoSaveInterval =
+ combinedFileSize > COMBINED_FILE_SIZE_SOFT_LIMIT ? 10000 : 2000;
+
const saveToLocalStorage = (project) => {
localStorage.setItem(
project.identifier || "project",
@@ -90,7 +99,7 @@ export const useProjectPersistence = ({
}
}
}
- }, 2000);
+ }, autoSaveInterval);
return () => clearTimeout(debouncer);
}, [dispatch, project, user, hasShownSavePrompt]); // eslint-disable-line react-hooks/exhaustive-deps
diff --git a/src/hooks/useProjectPersistence.test.js b/src/hooks/useProjectPersistence.test.js
index b1b69efac..0ccf4fc91 100644
--- a/src/hooks/useProjectPersistence.test.js
+++ b/src/hooks/useProjectPersistence.test.js
@@ -314,6 +314,34 @@ describe("When logged in", () => {
});
});
+ test("Increases save interval for large projects", async () => {
+ const largeProject = {
+ ...project,
+ components: [
+ {
+ name: "main",
+ extension: "py",
+ content: "mango".repeat(200001),
+ },
+ ],
+ };
+ renderHook(() =>
+ useProjectPersistence({
+ user: user1,
+ project: largeProject,
+ saveTriggered: false,
+ }),
+ );
+ jest.advanceTimersByTime(2500);
+ expect(saveProject).not.toHaveBeenCalled();
+ jest.runAllTimers();
+ expect(saveProject).toHaveBeenCalledWith({
+ project: largeProject,
+ accessToken: user1.access_token,
+ autosave: true,
+ });
+ });
+
test("Saves project to database if save triggered", async () => {
renderHook(() =>
useProjectPersistence({
diff --git a/src/utils/i18n.js b/src/utils/i18n.js
index c044d0f05..b61ab4d92 100644
--- a/src/utils/i18n.js
+++ b/src/utils/i18n.js
@@ -123,6 +123,9 @@ i18n
},
editorPanel: {
ariaLabel: "editor text input",
+ characterLimitError: "Error: Character limit reached",
+ characterLimitExplanation:
+ "Files in the editor are limited to {{maxCharacters}} characters",
viewOnly: "View only",
},
filePanel: {
diff --git a/storybook/package.json b/storybook/package.json
index c5c064b00..3045f9826 100644
--- a/storybook/package.json
+++ b/storybook/package.json
@@ -7,6 +7,8 @@
"build-storybook": "build-storybook"
},
"dependencies": {
+ "@raspberrypifoundation/design-system-core": "^1.6.0",
+ "@raspberrypifoundation/design-system-react": "^1.6.0",
"@reduxjs/toolkit": "^1.8.3",
"@storybook/addon-actions": "6.5.10",
"@storybook/addon-essentials": "6.5.10",
diff --git a/storybook/yarn.lock b/storybook/yarn.lock
index 8c82e4e70..2fe3ab6b2 100644
--- a/storybook/yarn.lock
+++ b/storybook/yarn.lock
@@ -2835,6 +2835,31 @@ __metadata:
languageName: node
linkType: hard
+"@raspberrypifoundation/design-system-core@npm:^1.6.0":
+ version: 1.6.1
+ resolution: "@raspberrypifoundation/design-system-core@npm:1.6.1"
+ dependencies:
+ classnames: ^2.3.2
+ checksum: a204d21a373e89b08a2cda763591f7be22c5d72c2974f1cd6f4331fe5c29f3816979e0a1224e7f15cfd03190f28e171329e5e729e2ffec8ea00ca8910406a1a9
+ languageName: node
+ linkType: hard
+
+"@raspberrypifoundation/design-system-react@npm:^1.6.0":
+ version: 1.6.0
+ resolution: "@raspberrypifoundation/design-system-react@npm:1.6.0"
+ dependencies:
+ classnames: ^2.3.2
+ material-symbols: ^0.14.5
+ prop-types: ^15.8.1
+ react: ^18.2.0
+ react-dom: ^18.2.0
+ react-router-dom: ^6.24.0
+ peerDependencies:
+ react-router-dom: ^6.24.0
+ checksum: 6bb6341f90d3c4fa569817813de7a1a9e69a23c12ca2cf0f20d47b9d0954771e237bda27eedba93b91a0d1d81fca32e155415ddc902947630711b38583f97ac5
+ languageName: node
+ linkType: hard
+
"@reduxjs/toolkit@npm:^1.8.3":
version: 1.9.5
resolution: "@reduxjs/toolkit@npm:1.9.5"
@@ -2862,6 +2887,13 @@ __metadata:
languageName: node
linkType: hard
+"@remix-run/router@npm:1.21.0":
+ version: 1.21.0
+ resolution: "@remix-run/router@npm:1.21.0"
+ checksum: d9477a7772053ad0ffcf03385cfb1a54e56f8a56d1f9f5062de3b1dfcbd019dd73282a00a5a72aa55c120771110982448c165c1405d64540aaef13051a8e45cc
+ languageName: node
+ linkType: hard
+
"@storybook/addon-actions@npm:6.5.10":
version: 6.5.10
resolution: "@storybook/addon-actions@npm:6.5.10"
@@ -6654,6 +6686,13 @@ __metadata:
languageName: node
linkType: hard
+"classnames@npm:^2.3.2":
+ version: 2.5.1
+ resolution: "classnames@npm:2.5.1"
+ checksum: da424a8a6f3a96a2e87d01a432ba19315503294ac7e025f9fece656db6b6a0f7b5003bb1fbb51cbb0d9624d964f1b9bb35a51c73af9b2434c7b292c42231c1e5
+ languageName: node
+ linkType: hard
+
"clean-css@npm:^4.2.3":
version: 4.2.4
resolution: "clean-css@npm:4.2.4"
@@ -11007,6 +11046,13 @@ __metadata:
languageName: node
linkType: hard
+"material-symbols@npm:^0.14.5":
+ version: 0.14.7
+ resolution: "material-symbols@npm:0.14.7"
+ checksum: 191dea0145eadabd3122b891b965d8568793c3f53a540186a30b459948a8a0c00938642dcca3c4fcca483b08d7480d02722c6de10caeeeae30437306a79f64b6
+ languageName: node
+ linkType: hard
+
"md5.js@npm:^1.3.4":
version: 1.3.5
resolution: "md5.js@npm:1.3.5"
@@ -13204,7 +13250,7 @@ __metadata:
languageName: node
linkType: hard
-"prop-types@npm:^15.0.0, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2":
+"prop-types@npm:^15.0.0, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
version: 15.8.1
resolution: "prop-types@npm:15.8.1"
dependencies:
@@ -13470,6 +13516,18 @@ __metadata:
languageName: node
linkType: hard
+"react-dom@npm:^18.2.0":
+ version: 18.3.1
+ resolution: "react-dom@npm:18.3.1"
+ dependencies:
+ loose-envify: ^1.1.0
+ scheduler: ^0.23.2
+ peerDependencies:
+ react: ^18.3.1
+ checksum: 298954ecd8f78288dcaece05e88b570014d8f6dce5db6f66e6ee91448debeb59dcd31561dddb354eee47e6c1bb234669459060deb238ed0213497146e555a0b9
+ languageName: node
+ linkType: hard
+
"react-element-to-jsx-string@npm:^14.3.4":
version: 14.3.4
resolution: "react-element-to-jsx-string@npm:14.3.4"
@@ -13591,6 +13649,19 @@ __metadata:
languageName: node
linkType: hard
+"react-router-dom@npm:^6.24.0":
+ version: 6.28.0
+ resolution: "react-router-dom@npm:6.28.0"
+ dependencies:
+ "@remix-run/router": 1.21.0
+ react-router: 6.28.0
+ peerDependencies:
+ react: ">=16.8"
+ react-dom: ">=16.8"
+ checksum: 0cf4658a92bc66f50ec9d8518c36aa5a402bcadce71fb624ed6f900d73a29ea87ff904a4f2c42279107e75e80cc08c6192563fadcc5d4e642e6d476e38e83b21
+ languageName: node
+ linkType: hard
+
"react-router@npm:6.18.0":
version: 6.18.0
resolution: "react-router@npm:6.18.0"
@@ -13602,6 +13673,17 @@ __metadata:
languageName: node
linkType: hard
+"react-router@npm:6.28.0":
+ version: 6.28.0
+ resolution: "react-router@npm:6.28.0"
+ dependencies:
+ "@remix-run/router": 1.21.0
+ peerDependencies:
+ react: ">=16.8"
+ checksum: 23246ca957b5c2bc8d6f9a81fee2df2ce4fc3feca3ec27c2fd85999568fc1299a4e8273e4ab70b6f3acd43a1fb45e0c93cb01ef77e68c9f9e1f7e4f42a1419ea
+ languageName: node
+ linkType: hard
+
"react-style-singleton@npm:^2.2.1":
version: 2.2.1
resolution: "react-style-singleton@npm:2.2.1"
@@ -13630,6 +13712,15 @@ __metadata:
languageName: node
linkType: hard
+"react@npm:^18.2.0":
+ version: 18.3.1
+ resolution: "react@npm:18.3.1"
+ dependencies:
+ loose-envify: ^1.1.0
+ checksum: a27bcfa8ff7c15a1e50244ad0d0c1cb2ad4375eeffefd266a64889beea6f6b64c4966c9b37d14ee32d6c9fcd5aa6ba183b6988167ab4d127d13e7cb5b386a376
+ languageName: node
+ linkType: hard
+
"read-pkg-up@npm:^1.0.1":
version: 1.0.1
resolution: "read-pkg-up@npm:1.0.1"
@@ -14246,6 +14337,15 @@ __metadata:
languageName: node
linkType: hard
+"scheduler@npm:^0.23.2":
+ version: 0.23.2
+ resolution: "scheduler@npm:0.23.2"
+ dependencies:
+ loose-envify: ^1.1.0
+ checksum: 3e82d1f419e240ef6219d794ff29c7ee415fbdc19e038f680a10c067108e06284f1847450a210b29bbaf97b9d8a97ced5f624c31c681248ac84c80d56ad5a2c4
+ languageName: node
+ linkType: hard
+
"schema-utils@npm:2.7.0":
version: 2.7.0
resolution: "schema-utils@npm:2.7.0"
@@ -14862,6 +14962,8 @@ __metadata:
version: 0.0.0-use.local
resolution: "storybook@workspace:."
dependencies:
+ "@raspberrypifoundation/design-system-core": ^1.6.0
+ "@raspberrypifoundation/design-system-react": ^1.6.0
"@reduxjs/toolkit": ^1.8.3
"@storybook/addon-actions": 6.5.10
"@storybook/addon-essentials": 6.5.10
diff --git a/webpack.config.js b/webpack.config.js
index 4a0fc9f70..0666b78f8 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -67,6 +67,14 @@ module.exports = {
},
],
},
+ {
+ test: /\.(woff|woff2|eot|ttf|otf)$/,
+ use: [
+ {
+ loader: "url-loader",
+ },
+ ],
+ },
],
},
resolve: {
diff --git a/yarn.lock b/yarn.lock
index eb1234465..ab941ab3b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2697,24 +2697,28 @@ __metadata:
languageName: node
linkType: hard
-"@raspberrypifoundation/design-system-core@npm:^0.1.9":
- version: 0.1.16
- resolution: "@raspberrypifoundation/design-system-core@npm:0.1.16"
+"@raspberrypifoundation/design-system-core@npm:^1.6.0":
+ version: 1.6.0
+ resolution: "@raspberrypifoundation/design-system-core@npm:1.6.0"
dependencies:
classnames: ^2.3.2
- checksum: 015534a27d500ff56f7f425584676bae4a7bb818372f2a5b3c587c6e350a2d8949bc053268ecf03420c301a72157cb7b316c9a4dbf73fc525e797b9141c4f2a7
+ checksum: 3eda17c4068e752daf070b6cbce9630b1b51997b911a4753b73f2c3726a40ec6bfba1b751380a4ad6f51e3e2e8e9cac66a7709343a7de9c5c8b074b409742a26
languageName: node
linkType: hard
-"@raspberrypifoundation/design-system-react@npm:^0.1.5":
- version: 0.1.5
- resolution: "@raspberrypifoundation/design-system-react@npm:0.1.5"
+"@raspberrypifoundation/design-system-react@npm:^1.6.0":
+ version: 1.6.0
+ resolution: "@raspberrypifoundation/design-system-react@npm:1.6.0"
dependencies:
classnames: ^2.3.2
+ material-symbols: ^0.14.5
prop-types: ^15.8.1
react: ^18.2.0
react-dom: ^18.2.0
- checksum: 7dc02f8d68a8dc5899dbb9e671eb062b0278fcdda195755d935e2fd4f1c692166790df94d13adf083d8b7ee8bf399bcb05077e301296cc1b4dc0763b44ab9651
+ react-router-dom: ^6.24.0
+ peerDependencies:
+ react-router-dom: ^6.24.0
+ checksum: 6bb6341f90d3c4fa569817813de7a1a9e69a23c12ca2cf0f20d47b9d0954771e237bda27eedba93b91a0d1d81fca32e155415ddc902947630711b38583f97ac5
languageName: node
linkType: hard
@@ -2736,8 +2740,8 @@ __metadata:
"@juggle/resize-observer": ^3.3.1
"@lezer/highlight": ^1.0.0
"@pmmmwh/react-refresh-webpack-plugin": 0.4.3
- "@raspberrypifoundation/design-system-core": ^0.1.9
- "@raspberrypifoundation/design-system-react": ^0.1.5
+ "@raspberrypifoundation/design-system-core": ^1.6.0
+ "@raspberrypifoundation/design-system-react": ^1.6.0
"@react-three/drei": 9.114.3
"@react-three/fiber": ^8.0.13
"@react-three/test-renderer": 8.2.1
@@ -2812,6 +2816,7 @@ __metadata:
js-convert-case: ^4.2.0
jszip: ^3.10.1
jszip-utils: ^0.1.0
+ material-symbols: ^0.27.0
mime-types: ^2.1.35
mini-css-extract-plugin: 0.11.3
mock-match-media: ^0.4.3
@@ -3071,6 +3076,13 @@ __metadata:
languageName: node
linkType: hard
+"@remix-run/router@npm:1.21.0":
+ version: 1.21.0
+ resolution: "@remix-run/router@npm:1.21.0"
+ checksum: d9477a7772053ad0ffcf03385cfb1a54e56f8a56d1f9f5062de3b1dfcbd019dd73282a00a5a72aa55c120771110982448c165c1405d64540aaef13051a8e45cc
+ languageName: node
+ linkType: hard
+
"@replit/codemirror-indentation-markers@npm:^6.1.0":
version: 6.5.3
resolution: "@replit/codemirror-indentation-markers@npm:6.5.3"
@@ -12498,6 +12510,20 @@ __metadata:
languageName: node
linkType: hard
+"material-symbols@npm:^0.14.5":
+ version: 0.14.7
+ resolution: "material-symbols@npm:0.14.7"
+ checksum: 191dea0145eadabd3122b891b965d8568793c3f53a540186a30b459948a8a0c00938642dcca3c4fcca483b08d7480d02722c6de10caeeeae30437306a79f64b6
+ languageName: node
+ linkType: hard
+
+"material-symbols@npm:^0.27.0":
+ version: 0.27.0
+ resolution: "material-symbols@npm:0.27.0"
+ checksum: 6a585863e75c291aab6104e4ebb38e344dd0e3d39e14653bcb529d558f2b55a3f00d2fc58e59b2ee2d08dc0b7e209fb7ac88ed49cf7158c7fbaf9697edd514ff
+ languageName: node
+ linkType: hard
+
"mathml-tag-names@npm:^2.1.3":
version: 2.1.3
resolution: "mathml-tag-names@npm:2.1.3"
@@ -15342,6 +15368,19 @@ __metadata:
languageName: node
linkType: hard
+"react-router-dom@npm:^6.24.0":
+ version: 6.28.0
+ resolution: "react-router-dom@npm:6.28.0"
+ dependencies:
+ "@remix-run/router": 1.21.0
+ react-router: 6.28.0
+ peerDependencies:
+ react: ">=16.8"
+ react-dom: ">=16.8"
+ checksum: 0cf4658a92bc66f50ec9d8518c36aa5a402bcadce71fb624ed6f900d73a29ea87ff904a4f2c42279107e75e80cc08c6192563fadcc5d4e642e6d476e38e83b21
+ languageName: node
+ linkType: hard
+
"react-router-dom@npm:^6.7.0":
version: 6.27.0
resolution: "react-router-dom@npm:6.27.0"
@@ -15366,6 +15405,17 @@ __metadata:
languageName: node
linkType: hard
+"react-router@npm:6.28.0":
+ version: 6.28.0
+ resolution: "react-router@npm:6.28.0"
+ dependencies:
+ "@remix-run/router": 1.21.0
+ peerDependencies:
+ react: ">=16.8"
+ checksum: 23246ca957b5c2bc8d6f9a81fee2df2ce4fc3feca3ec27c2fd85999568fc1299a4e8273e4ab70b6f3acd43a1fb45e0c93cb01ef77e68c9f9e1f7e4f42a1419ea
+ languageName: node
+ linkType: hard
+
"react-shallow-renderer@npm:^16.13.1":
version: 16.15.0
resolution: "react-shallow-renderer@npm:16.15.0"