From 98012d17bf04dbd6487611ff140baed87f33d194 Mon Sep 17 00:00:00 2001 From: Joacim Breiler Date: Sun, 3 Mar 2024 07:47:51 +0100 Subject: [PATCH 1/4] New pendant made in react --- .../pendantui/v1/model/FileStatus.java | 5 + .../pendantui/v1/resources/FilesResource.java | 22 +- .../pendantui/v1/ws/EventsSocket.java | 25 +- ugs-pendant/src/main/webapp2/.eslintrc.cjs | 18 + ugs-pendant/src/main/webapp2/.gitignore | 24 + ugs-pendant/src/main/webapp2/README.md | 30 + ugs-pendant/src/main/webapp2/index.html | 13 + .../src/main/webapp2/package-lock.json | 3762 +++++++++++++++++ ugs-pendant/src/main/webapp2/package.json | 37 + ugs-pendant/src/main/webapp2/public/vite.svg | 1 + ugs-pendant/src/main/webapp2/src/App.scss | 11 + ugs-pendant/src/main/webapp2/src/App.tsx | 34 + .../src/main/webapp2/src/assets/LCD.ttf | Bin 0 -> 29780 bytes .../src/main/webapp2/src/assets/icon.svg | 365 ++ .../src/main/webapp2/src/bootstrap.scss | 23 + .../webapp2/src/components/AlarmModal.tsx | 37 + .../webapp2/src/components/AxisPanel.scss | 41 + .../main/webapp2/src/components/AxisPanel.tsx | 81 + .../src/components/ControllerState.scss | 46 + .../src/components/ControllerState.tsx | 17 + .../webapp2/src/components/DropdownInput.tsx | 35 + .../main/webapp2/src/components/Footer.tsx | 34 + .../main/webapp2/src/components/Header.tsx | 54 + .../main/webapp2/src/components/JogPanel.scss | 29 + .../main/webapp2/src/components/JogPanel.tsx | 202 + .../webapp2/src/components/RangeSlider.tsx | 38 + .../main/webapp2/src/components/RunFooter.tsx | 11 + .../main/webapp2/src/hooks/useAppDispatch.ts | 5 + .../main/webapp2/src/hooks/useAppSelector.ts | 4 + .../src/main/webapp2/src/hooks/useDebounce.ts | 14 + ugs-pendant/src/main/webapp2/src/index.css | 68 + ugs-pendant/src/main/webapp2/src/main.tsx | 12 + .../webapp2/src/model/ConnectionParameters.ts | 3 + .../webapp2/src/model/ControllerStateEvent.ts | 5 + .../src/model/ControllerStatusEvent.ts | 6 + .../src/main/webapp2/src/model/Coordinate.ts | 9 + .../src/main/webapp2/src/model/Settings.ts | 6 + .../src/main/webapp2/src/model/Status.ts | 28 + .../src/main/webapp2/src/model/UGSEvent.ts | 7 + .../main/webapp2/src/pages/ConnectPage.tsx | 93 + .../src/main/webapp2/src/pages/MainPage.tsx | 63 + .../main/webapp2/src/pages/WaitingPage.tsx | 29 + .../src/main/webapp2/src/services/machine.ts | 85 + .../src/main/webapp2/src/services/settings.ts | 20 + .../src/main/webapp2/src/services/status.ts | 16 + .../src/store/connectionParametersSlice.ts | 32 + .../main/webapp2/src/store/counterSlice.ts | 29 + .../main/webapp2/src/store/settingsSlice.ts | 56 + .../webapp2/src/store/socketMiddleware.ts | 111 + .../src/main/webapp2/src/store/socketSlice.ts | 33 + .../src/main/webapp2/src/store/statusSlice.ts | 96 + .../src/main/webapp2/src/store/store.ts | 22 + .../src/main/webapp2/src/utils/Socket.ts | 44 + .../src/main/webapp2/src/vite-env.d.ts | 1 + ugs-pendant/src/main/webapp2/tsconfig.json | 25 + .../src/main/webapp2/tsconfig.node.json | 10 + ugs-pendant/src/main/webapp2/vite.config.ts | 21 + 57 files changed, 5943 insertions(+), 5 deletions(-) create mode 100644 ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/model/FileStatus.java create mode 100644 ugs-pendant/src/main/webapp2/.eslintrc.cjs create mode 100644 ugs-pendant/src/main/webapp2/.gitignore create mode 100644 ugs-pendant/src/main/webapp2/README.md create mode 100644 ugs-pendant/src/main/webapp2/index.html create mode 100644 ugs-pendant/src/main/webapp2/package-lock.json create mode 100644 ugs-pendant/src/main/webapp2/package.json create mode 100644 ugs-pendant/src/main/webapp2/public/vite.svg create mode 100644 ugs-pendant/src/main/webapp2/src/App.scss create mode 100644 ugs-pendant/src/main/webapp2/src/App.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/assets/LCD.ttf create mode 100644 ugs-pendant/src/main/webapp2/src/assets/icon.svg create mode 100644 ugs-pendant/src/main/webapp2/src/bootstrap.scss create mode 100644 ugs-pendant/src/main/webapp2/src/components/AlarmModal.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/AxisPanel.scss create mode 100644 ugs-pendant/src/main/webapp2/src/components/AxisPanel.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/ControllerState.scss create mode 100644 ugs-pendant/src/main/webapp2/src/components/ControllerState.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/DropdownInput.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/Footer.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/Header.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/JogPanel.scss create mode 100644 ugs-pendant/src/main/webapp2/src/components/JogPanel.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/RangeSlider.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/RunFooter.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/hooks/useAppDispatch.ts create mode 100644 ugs-pendant/src/main/webapp2/src/hooks/useAppSelector.ts create mode 100644 ugs-pendant/src/main/webapp2/src/hooks/useDebounce.ts create mode 100644 ugs-pendant/src/main/webapp2/src/index.css create mode 100644 ugs-pendant/src/main/webapp2/src/main.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/model/ConnectionParameters.ts create mode 100644 ugs-pendant/src/main/webapp2/src/model/ControllerStateEvent.ts create mode 100644 ugs-pendant/src/main/webapp2/src/model/ControllerStatusEvent.ts create mode 100644 ugs-pendant/src/main/webapp2/src/model/Coordinate.ts create mode 100644 ugs-pendant/src/main/webapp2/src/model/Settings.ts create mode 100644 ugs-pendant/src/main/webapp2/src/model/Status.ts create mode 100644 ugs-pendant/src/main/webapp2/src/model/UGSEvent.ts create mode 100644 ugs-pendant/src/main/webapp2/src/pages/ConnectPage.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/pages/MainPage.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/pages/WaitingPage.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/services/machine.ts create mode 100644 ugs-pendant/src/main/webapp2/src/services/settings.ts create mode 100644 ugs-pendant/src/main/webapp2/src/services/status.ts create mode 100644 ugs-pendant/src/main/webapp2/src/store/connectionParametersSlice.ts create mode 100644 ugs-pendant/src/main/webapp2/src/store/counterSlice.ts create mode 100644 ugs-pendant/src/main/webapp2/src/store/settingsSlice.ts create mode 100644 ugs-pendant/src/main/webapp2/src/store/socketMiddleware.ts create mode 100644 ugs-pendant/src/main/webapp2/src/store/socketSlice.ts create mode 100644 ugs-pendant/src/main/webapp2/src/store/statusSlice.ts create mode 100644 ugs-pendant/src/main/webapp2/src/store/store.ts create mode 100644 ugs-pendant/src/main/webapp2/src/utils/Socket.ts create mode 100644 ugs-pendant/src/main/webapp2/src/vite-env.d.ts create mode 100644 ugs-pendant/src/main/webapp2/tsconfig.json create mode 100644 ugs-pendant/src/main/webapp2/tsconfig.node.json create mode 100644 ugs-pendant/src/main/webapp2/vite.config.ts diff --git a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/model/FileStatus.java b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/model/FileStatus.java new file mode 100644 index 0000000000..6e8b1472c4 --- /dev/null +++ b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/model/FileStatus.java @@ -0,0 +1,5 @@ +package com.willwinder.universalgcodesender.pendantui.v1.model; + +public record FileStatus(String fileName, long rowCount, long completedRowCount, long remainingRowCount, + long sendDuration, long sendRemainingDuration) { +} diff --git a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/resources/FilesResource.java b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/resources/FilesResource.java index 2ebfe45775..2abc44fc0a 100644 --- a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/resources/FilesResource.java +++ b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/resources/FilesResource.java @@ -19,12 +19,9 @@ This file is part of Universal Gcode Sender (UGS). package com.willwinder.universalgcodesender.pendantui.v1.resources; import com.willwinder.universalgcodesender.model.BackendAPI; +import com.willwinder.universalgcodesender.pendantui.v1.model.FileStatus; import com.willwinder.universalgcodesender.pendantui.v1.model.WorkspaceFileList; import jakarta.inject.Inject; -import org.apache.commons.io.IOUtils; -import org.glassfish.jersey.media.multipart.FormDataBodyPart; -import org.glassfish.jersey.media.multipart.FormDataParam; - import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; @@ -32,11 +29,16 @@ This file is part of Universal Gcode Sender (UGS). import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; +import org.apache.commons.io.IOUtils; +import org.glassfish.jersey.media.multipart.FormDataBodyPart; +import org.glassfish.jersey.media.multipart.FormDataParam; + import java.io.File; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.List; +import java.util.Optional; @Path("/files") public class FilesResource { @@ -98,4 +100,16 @@ public WorkspaceFileList getWorkspaceFileList() { public void openWorkspaceFile(@QueryParam("file") String file) throws Exception { backendAPI.openWorkspaceFile(file); } + + @GET + @Path("getFileStatus") + @Produces(MediaType.APPLICATION_JSON) + public FileStatus getFileStatus() { + return new FileStatus(Optional.ofNullable(backendAPI.getGcodeFile()).map(File::getAbsolutePath).orElse(""), + backendAPI.getNumRows(), + backendAPI.getNumCompletedRows(), + backendAPI.getNumRemainingRows(), + backendAPI.getSendDuration(), + backendAPI.getSendRemainingDuration()); + } } diff --git a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/ws/EventsSocket.java b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/ws/EventsSocket.java index ff007597d3..a1caa3f497 100644 --- a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/ws/EventsSocket.java +++ b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/ws/EventsSocket.java @@ -21,10 +21,15 @@ This file is part of Universal Gcode Sender (UGS). import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.willwinder.universalgcodesender.listeners.ControllerStatus; +import com.willwinder.universalgcodesender.listeners.ControllerStatusBuilder; import com.willwinder.universalgcodesender.listeners.UGSEventListener; import com.willwinder.universalgcodesender.model.UGSEvent; +import com.willwinder.universalgcodesender.model.UnitUtils; +import com.willwinder.universalgcodesender.model.events.ControllerStatusEvent; import com.willwinder.universalgcodesender.pendantui.BackendProvider; import com.willwinder.universalgcodesender.pendantui.v1.model.Event; +import com.willwinder.universalgcodesender.utils.Settings; import jakarta.websocket.ClientEndpoint; import jakarta.websocket.OnClose; import jakarta.websocket.OnError; @@ -53,6 +58,13 @@ public EventsSocket() { } } + private static ControllerStatus convertToPreferredUnits(ControllerStatus controllerStatusEvent, UnitUtils.Units units) { + return ControllerStatusBuilder.newInstance(controllerStatusEvent) + .setMachineCoord(controllerStatusEvent.getMachineCoord().getPositionIn(units)) + .setWorkCoord(controllerStatusEvent.getWorkCoord().getPositionIn(units)) + .build(); + } + @OnOpen public void onWebSocketConnect(Session session) { sessions.put(session.getId(), session); @@ -74,7 +86,7 @@ public void onWebSocketError(Session session, Throwable cause) { @Override public void UGSEvent(UGSEvent evt) { try { - String data = gson.toJson(new Event(evt)).replaceAll(":NaN", ":null"); + String data = getEventAsString(evt); sessions.values().forEach(session -> { try { session.getBasicRemote().sendText(data); @@ -86,4 +98,15 @@ public void UGSEvent(UGSEvent evt) { e.printStackTrace(); } } + + private String getEventAsString(UGSEvent evt) { + if (evt instanceof ControllerStatusEvent controllerStatusEvent) { + Settings settings = BackendProvider.getBackendAPI().getSettings(); + ControllerStatus currentStatus = convertToPreferredUnits(controllerStatusEvent.getStatus(), settings.getPreferredUnits()); + ControllerStatus previousStatus = convertToPreferredUnits(controllerStatusEvent.getPreviousStatus(), settings.getPreferredUnits()); + return gson.toJson(new Event(new ControllerStatusEvent(currentStatus, previousStatus))).replace(":NaN", ":null"); + } + + return gson.toJson(new Event(evt)); + } } \ No newline at end of file diff --git a/ugs-pendant/src/main/webapp2/.eslintrc.cjs b/ugs-pendant/src/main/webapp2/.eslintrc.cjs new file mode 100644 index 0000000000..d6c9537953 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/.eslintrc.cjs @@ -0,0 +1,18 @@ +module.exports = { + root: true, + env: { browser: true, es2020: true }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + ], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parser: '@typescript-eslint/parser', + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, +} diff --git a/ugs-pendant/src/main/webapp2/.gitignore b/ugs-pendant/src/main/webapp2/.gitignore new file mode 100644 index 0000000000..a547bf36d8 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/ugs-pendant/src/main/webapp2/README.md b/ugs-pendant/src/main/webapp2/README.md new file mode 100644 index 0000000000..0d6babeddb --- /dev/null +++ b/ugs-pendant/src/main/webapp2/README.md @@ -0,0 +1,30 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default { + // other rules... + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + project: ['./tsconfig.json', './tsconfig.node.json'], + tsconfigRootDir: __dirname, + }, +} +``` + +- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` +- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list diff --git a/ugs-pendant/src/main/webapp2/index.html b/ugs-pendant/src/main/webapp2/index.html new file mode 100644 index 0000000000..7db1f26861 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/index.html @@ -0,0 +1,13 @@ + + + + + + + Universal Gcode Sender + + +
+ + + diff --git a/ugs-pendant/src/main/webapp2/package-lock.json b/ugs-pendant/src/main/webapp2/package-lock.json new file mode 100644 index 0000000000..baa3b93ffd --- /dev/null +++ b/ugs-pendant/src/main/webapp2/package-lock.json @@ -0,0 +1,3762 @@ +{ + "name": "webapp2", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "webapp2", + "version": "0.0.0", + "dependencies": { + "@fortawesome/fontawesome-free": "^6.5.1", + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/react-fontawesome": "^0.2.0", + "@reduxjs/toolkit": "^2.0.1", + "bootstrap": "^5.3.2", + "react": "^18.2.0", + "react-bootstrap": "^2.9.2", + "react-dom": "^18.2.0", + "react-redux": "^9.0.4" + }, + "devDependencies": { + "@types/react": "^18.2.43", + "@types/react-dom": "^18.2.17", + "@typescript-eslint/eslint-plugin": "^6.14.0", + "@typescript-eslint/parser": "^6.14.0", + "@vitejs/plugin-react": "^4.2.1", + "eslint": "^8.55.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "sass": "^1.69.6", + "typescript": "^5.2.2", + "vite": "^5.0.8" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz", + "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz", + "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz", + "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", + "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", + "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", + "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", + "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", + "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", + "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", + "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", + "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", + "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", + "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", + "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", + "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", + "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", + "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", + "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", + "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", + "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", + "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", + "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", + "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", + "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", + "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", + "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz", + "integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz", + "integrity": "sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz", + "integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz", + "integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.1.tgz", + "integrity": "sha512-NqzkLFP8ZVI4GSorS0AYljC13QW2sc8bDqJOkBvkAt3M8gbcAXJWVRGtZBCRscki9RZF+rNlnPdg0G0jYkhJcg==", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.0.1.tgz", + "integrity": "sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA==", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.0", + "redux-thunk": "^3.1.0", + "reselect": "^5.0.1" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.15.tgz", + "integrity": "sha512-cZFXYTxbpzYcieq/mBwSyXgqnGMHoBVh3J7MU0CCoIB4NRZxV9/TuwTBAaLMqpNhC3zTPMCgkQ5Ey07L02Xmcw==", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", + "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@popperjs/core": "^2.11.6", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", + "@types/warning": "^3.0.0", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "peerDependencies": { + "react": ">=16.14.0" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.1.tgz", + "integrity": "sha512-6vMdBZqtq1dVQ4CWdhFwhKZL6E4L1dV6jUjuBvsavvNJSppzi6dLBbuV+3+IyUREaj9ZFvQefnQm28v4OCXlig==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.1.tgz", + "integrity": "sha512-Jto9Fl3YQ9OLsTDWtLFPtaIMSL2kwGyGoVCmPC8Gxvym9TCZm4Sie+cVeblPO66YZsYH8MhBKDMGZ2NDxuk/XQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.1.tgz", + "integrity": "sha512-LtYcLNM+bhsaKAIGwVkh5IOWhaZhjTfNOkGzGqdHvhiCUVuJDalvDxEdSnhFzAn+g23wgsycmZk1vbnaibZwwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.1.tgz", + "integrity": "sha512-KyP/byeXu9V+etKO6Lw3E4tW4QdcnzDG/ake031mg42lob5tN+5qfr+lkcT/SGZaH2PdW4Z1NX9GHEkZ8xV7og==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.1.tgz", + "integrity": "sha512-Yqz/Doumf3QTKplwGNrCHe/B2p9xqDghBZSlAY0/hU6ikuDVQuOUIpDP/YcmoT+447tsZTmirmjgG3znvSCR0Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.1.tgz", + "integrity": "sha512-u3XkZVvxcvlAOlQJ3UsD1rFvLWqu4Ef/Ggl40WAVCuogf4S1nJPHh5RTgqYFpCOvuGJ7H5yGHabjFKEZGExk5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.1.tgz", + "integrity": "sha512-0XSYN/rfWShW+i+qjZ0phc6vZ7UWI8XWNz4E/l+6edFt+FxoEghrJHjX1EY/kcUGCnZzYYRCl31SNdfOi450Aw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.1.tgz", + "integrity": "sha512-LmYIO65oZVfFt9t6cpYkbC4d5lKHLYv5B4CSHRpnANq0VZUQXGcCPXHzbCXCz4RQnx7jvlYB1ISVNCE/omz5cw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.1.tgz", + "integrity": "sha512-kr8rEPQ6ns/Lmr/hiw8sEVj9aa07gh1/tQF2Y5HrNCCEPiCBGnBUt9tVusrcBBiJfIt1yNaXN6r1CCmpbFEDpg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.1.tgz", + "integrity": "sha512-t4QSR7gN+OEZLG0MiCgPqMWZGwmeHhsM4AkegJ0Kiy6TnJ9vZ8dEIwHw1LcZKhbHxTY32hp9eVCMdR3/I8MGRw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.1.tgz", + "integrity": "sha512-7XI4ZCBN34cb+BH557FJPmh0kmNz2c25SCQeT9OiFWEgf8+dL6ZwJ8f9RnUIit+j01u07Yvrsuu1rZGxJCc51g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.1.tgz", + "integrity": "sha512-yE5c2j1lSWOH5jp+Q0qNL3Mdhr8WuqCNVjc6BxbVfS5cAS6zRmdiw7ktb8GNpDCEUJphILY6KACoFoRtKoqNQg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.1.tgz", + "integrity": "sha512-PyJsSsafjmIhVgaI1Zdj7m8BB8mMckFah/xbpplObyHfiXzKcI5UOUXRyOdHW7nz4DpMCuzLnF7v5IWHenCwYA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@swc/helpers": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz", + "integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/react": { + "version": "18.2.46", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.46.tgz", + "integrity": "sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.18", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz", + "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, + "node_modules/@types/warning": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.16.0.tgz", + "integrity": "sha512-O5f7Kv5o4dLWQtPX4ywPPa+v9G+1q1x8mz0Kr0pXUtKsevo+gIJHLkGc8RxaZWtP8RrhwhSNIWThnW42K9/0rQ==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/type-utils": "6.16.0", + "@typescript-eslint/utils": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.16.0.tgz", + "integrity": "sha512-H2GM3eUo12HpKZU9njig3DF5zJ58ja6ahj1GoHEHOgQvYxzoFJJEvC1MQ7T2l9Ha+69ZSOn7RTxOdpC/y3ikMw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/typescript-estree": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.16.0.tgz", + "integrity": "sha512-0N7Y9DSPdaBQ3sqSCwlrm9zJwkpOuc6HYm7LpzLAPqBL7dmzAUimr4M29dMkOP/tEwvOCC/Cxo//yOfJD3HUiw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.16.0.tgz", + "integrity": "sha512-ThmrEOcARmOnoyQfYkHw/DX2SEYBalVECmoldVuH6qagKROp/jMnfXpAU/pAIWub9c4YTxga+XwgAkoA0pxfmg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.16.0", + "@typescript-eslint/utils": "6.16.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.16.0.tgz", + "integrity": "sha512-hvDFpLEvTJoHutVl87+MG/c5C8I6LOgEx05zExTSJDEVU7hhR3jhV8M5zuggbdFCw98+HhZWPHZeKS97kS3JoQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.16.0.tgz", + "integrity": "sha512-VTWZuixh/vr7nih6CfrdpmFNLEnoVBF1skfjdyGnNwXOH1SLeHItGdZDHhhAIzd3ACazyY2Fg76zuzOVTaknGA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.16.0.tgz", + "integrity": "sha512-T83QPKrBm6n//q9mv7oiSvy/Xq/7Hyw9SzSEhMHJwznEmQayfBM87+oAlkNAMEO7/MjIwKyOHgBJbxB0s7gx2A==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/typescript-estree": "6.16.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.16.0.tgz", + "integrity": "sha512-QSFQLruk7fhs91a/Ep/LqRdbJCZ1Rq03rqBdKT5Ky17Sz8zRLUksqIe9DW0pKtg/Z35/ztbLQ6qpOCN6rOC11A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz", + "integrity": "sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.5", + "@babel/plugin-transform-react-jsx-self": "^7.23.3", + "@babel/plugin-transform-react-jsx-source": "^7.23.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bootstrap": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", + "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001572", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz", + "integrity": "sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/classnames": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.0.tgz", + "integrity": "sha512-FQuRlyKinxrb5gwJlfVASbSrDlikDJ07426TrfPsdGLvtochowmkbnSFdQGJ2aoXrSetq5KqGV9emvWpy+91xA==" + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.616", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz", + "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", + "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.10", + "@esbuild/android-arm": "0.19.10", + "@esbuild/android-arm64": "0.19.10", + "@esbuild/android-x64": "0.19.10", + "@esbuild/darwin-arm64": "0.19.10", + "@esbuild/darwin-x64": "0.19.10", + "@esbuild/freebsd-arm64": "0.19.10", + "@esbuild/freebsd-x64": "0.19.10", + "@esbuild/linux-arm": "0.19.10", + "@esbuild/linux-arm64": "0.19.10", + "@esbuild/linux-ia32": "0.19.10", + "@esbuild/linux-loong64": "0.19.10", + "@esbuild/linux-mips64el": "0.19.10", + "@esbuild/linux-ppc64": "0.19.10", + "@esbuild/linux-riscv64": "0.19.10", + "@esbuild/linux-s390x": "0.19.10", + "@esbuild/linux-x64": "0.19.10", + "@esbuild/netbsd-x64": "0.19.10", + "@esbuild/openbsd-x64": "0.19.10", + "@esbuild/sunos-x64": "0.19.10", + "@esbuild/win32-arm64": "0.19.10", + "@esbuild/win32-ia32": "0.19.10", + "@esbuild/win32-x64": "0.19.10" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.5.tgz", + "integrity": "sha512-D53FYKJa+fDmZMtriODxvhwrO+IOqrxoEo21gMA0sjHdU6dPVH4OhyFip9ypl8HOF5RV5KdTo+rBQLvnY2cO8w==", + "dev": true, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.3.tgz", + "integrity": "sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-bootstrap": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.2.tgz", + "integrity": "sha512-a36B+EHsAI/aH+ZhXNILBFnqscE3zr10dWmjBmfhIb2QR7KSXJiGzYd6Faf/25G8G7/CP9TCL2B0WhUBOD2UBQ==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.6", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.8.1", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.5", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "@types/react": ">=16.14.8", + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "node_modules/react-redux": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.0.4.tgz", + "integrity": "sha512-9J1xh8sWO0vYq2sCxK2My/QO7MzUMRi3rpiILP/+tDr8krBHixC6JMM17fMK88+Oh3e4Ae6/sHIhNBgkUivwFA==", + "dependencies": { + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25", + "react": "^18.0", + "react-native": ">=0.69", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/reselect": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.0.1.tgz", + "integrity": "sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg==" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.1.tgz", + "integrity": "sha512-pgPO9DWzLoW/vIhlSoDByCzcpX92bKEorbgXuZrqxByte3JFk2xSW2JEeAcyLc9Ru9pqcNNW+Ob7ntsk2oT/Xw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.9.1", + "@rollup/rollup-android-arm64": "4.9.1", + "@rollup/rollup-darwin-arm64": "4.9.1", + "@rollup/rollup-darwin-x64": "4.9.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.9.1", + "@rollup/rollup-linux-arm64-gnu": "4.9.1", + "@rollup/rollup-linux-arm64-musl": "4.9.1", + "@rollup/rollup-linux-riscv64-gnu": "4.9.1", + "@rollup/rollup-linux-x64-gnu": "4.9.1", + "@rollup/rollup-linux-x64-musl": "4.9.1", + "@rollup/rollup-win32-arm64-msvc": "4.9.1", + "@rollup/rollup-win32-ia32-msvc": "4.9.1", + "@rollup/rollup-win32-x64-msvc": "4.9.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sass": { + "version": "1.69.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.6.tgz", + "integrity": "sha512-qbRr3k9JGHWXCvZU77SD2OTwUlC+gNT+61JOLcmLm+XqH4h/5D+p4IIsxvpkB89S9AwJOyb5+rWNpIucaFxSFQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/vite": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.1.tgz", + "integrity": "sha512-wclpAgY3F1tR7t9LL5CcHC41YPkQIpKUGeIuT8MdNwNZr6OqOTLs7JX5vIHAtzqLWXts0T+GDrh9pN2arneKqg==", + "dev": true, + "dependencies": { + "esbuild": "^0.19.3", + "postcss": "^8.4.35", + "rollup": "^4.2.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/ugs-pendant/src/main/webapp2/package.json b/ugs-pendant/src/main/webapp2/package.json new file mode 100644 index 0000000000..a896c01828 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/package.json @@ -0,0 +1,37 @@ +{ + "name": "webapp2", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/fontawesome-free": "^6.5.1", + "@fortawesome/react-fontawesome": "^0.2.0", + "@reduxjs/toolkit": "^2.0.1", + "bootstrap": "^5.3.2", + "react": "^18.2.0", + "react-bootstrap": "^2.9.2", + "react-dom": "^18.2.0", + "react-redux": "^9.0.4" + }, + "devDependencies": { + "@types/react": "^18.2.43", + "@types/react-dom": "^18.2.17", + "@typescript-eslint/eslint-plugin": "^6.14.0", + "@typescript-eslint/parser": "^6.14.0", + "@vitejs/plugin-react": "^4.2.1", + "eslint": "^8.55.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "sass": "^1.69.6", + "typescript": "^5.2.2", + "vite": "^5.0.8" + } +} diff --git a/ugs-pendant/src/main/webapp2/public/vite.svg b/ugs-pendant/src/main/webapp2/public/vite.svg new file mode 100644 index 0000000000..e7b8dfb1b2 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ugs-pendant/src/main/webapp2/src/App.scss b/ugs-pendant/src/main/webapp2/src/App.scss new file mode 100644 index 0000000000..0be52b45b3 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/App.scss @@ -0,0 +1,11 @@ +@import './bootstrap'; + +body { + background-repeat: no-repeat; + background: #f2f2f2; + background-attachment: fixed; + +} + +.app { +} \ No newline at end of file diff --git a/ugs-pendant/src/main/webapp2/src/App.tsx b/ugs-pendant/src/main/webapp2/src/App.tsx new file mode 100644 index 0000000000..28641d32cb --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/App.tsx @@ -0,0 +1,34 @@ +import { useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { useAppSelector } from "./hooks/useAppSelector"; +import "./App.scss"; +import Header from "./components/Header"; +import ConnectPage from "./pages/ConnectPage"; +import MainPage from "./pages/MainPage"; +import { socketActions } from "./store/socketSlice"; +import WaitingPage from "./pages/WaitingPage"; +import AlarmModal from "./components/AlarmModal"; +import Footer from "./components/Footer"; + +function App() { + const status = useAppSelector((state) => state.status); + const isConnected = useAppSelector((state) => state.socket.isConnected); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(socketActions.connect()); + }, [dispatch]); + + return ( +
+
+ {!isConnected && (status.state === "DISCONNECTED" || status.state === "CONNECTING") && } + {isConnected && status.state === "DISCONNECTED" && } + {isConnected && (status.state !== "DISCONNECTED" && status.state !== "CONNECTING") && } + {status.state === "ALARM" && } +
+
+ ); +} + +export default App; diff --git a/ugs-pendant/src/main/webapp2/src/assets/LCD.ttf b/ugs-pendant/src/main/webapp2/src/assets/LCD.ttf new file mode 100644 index 0000000000000000000000000000000000000000..57386786a350f10c0a809158301e9772e2ae1b49 GIT binary patch literal 29780 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%0DY`JN1v&mjy-15ox6E`wPM`*Qmkni2#z{}v) z3*;q?3|=9xVmxyQ{rzq726+?TA~DHPe6!?T@(%ozN^%$;%1%gd73Pv^1fOpO_s&O; zLL$VX zsWgqI(+tu|38KU^X%?m8nA7?jzPN&K;^3<*0lJRjWlQ+R3ckf6zMHb1ZXl1-YFa~UX&pI04wCoC$8;lk zA79h^E7?!>k&p1Lmq+lemtT`-@y(ZC!Oz`Fp24?b?k7)@r^plJpY(iMk5`d5;@!YE z;Y%?$;~Oh~hX?t6d`ISPe0k*t+C(>bn`*1ZjG0ob(h`-P>YZE@2-ertdIK``OkP(X z-W2u(MB<%XXV%q*H+TawO`RI7st-2RR8)sANDW5el&PV*#y~I_u5C;SI-qA-Fo2@* zK6jB!Lp^~;?{rlmY#OiFGhJ2~7D>u<=kAoS1A3<`G{Q3VOqV5wMUpx*ib$#%g;Qoa z1*Dh`m^PCu;($ap&2$~4&WhffS{a4)S?dDzdL?$Avl^?aLtzgb3MAgMR72cG%z{#r@k+5rCuV}0Gm%CI)Q z*3`naruS^s_&U}2vt{G!M3R1XWmBygsBfyN4m35U*SU{8izE*95{E^uYSZdn2cAU| zhkBVTmUlIXBz19=bg2zdIBkimfV4)}foF*c0Rb^vKN<~+nF=otIeksyoY3uOyFxWPV bgEVZJ*tk8^Rmv?N{`PCFL7uw5sri2ZNZH$- literal 0 HcmV?d00001 diff --git a/ugs-pendant/src/main/webapp2/src/assets/icon.svg b/ugs-pendant/src/main/webapp2/src/assets/icon.svg new file mode 100644 index 0000000000..a51e0d7d3d --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/assets/icon.svg @@ -0,0 +1,365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/ugs-pendant/src/main/webapp2/src/bootstrap.scss b/ugs-pendant/src/main/webapp2/src/bootstrap.scss new file mode 100644 index 0000000000..28ef53d7c6 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/bootstrap.scss @@ -0,0 +1,23 @@ +@import "bootstrap/scss/bootstrap"; + +.btn-secondary { + background-color: white; + color: #353a40; + border-color: #c2c2c2; +} + +.btn-secondary.btn:hover { + background-color: #f7f7f7; + color: #353a40; + border-color: #c2c2c2; +} + +.btn-secondary.btn:disabled { + background-color: #f7f7f7; + color: #353a40; + border-color: #c2c2c2; +} + +.bg-dark { + background-color: #2a2c2d !important; +} \ No newline at end of file diff --git a/ugs-pendant/src/main/webapp2/src/components/AlarmModal.tsx b/ugs-pendant/src/main/webapp2/src/components/AlarmModal.tsx new file mode 100644 index 0000000000..02afa99ac6 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/AlarmModal.tsx @@ -0,0 +1,37 @@ +import Button from "react-bootstrap/Button"; +import Modal from "react-bootstrap/Modal"; +import { homeMachine, killAlarm, softReset } from "../services/machine"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + faHome, + faLockOpen, + faRefresh, +} from "@fortawesome/free-solid-svg-icons"; + +const AlarmModal = () => { + return ( + <> + {}}> + + Alarm! + + + The controller is in an alarm state. This could mean that it has lost its position and needs to be reset or homed. + + + + + + + + + ); +}; + +export default AlarmModal; diff --git a/ugs-pendant/src/main/webapp2/src/components/AxisPanel.scss b/ugs-pendant/src/main/webapp2/src/components/AxisPanel.scss new file mode 100644 index 0000000000..5556f1552b --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/AxisPanel.scss @@ -0,0 +1,41 @@ +@font-face { + font-family: "LCD"; + src: url(../assets/LCD.ttf); +} + +.axisRow { + margin-top: 12px; + margin-left: 0px; +} + +.axisPanel { + background-color: #2a2c2d; + color: #05d4ff; + border-radius: 6px; + font-family: "LCD"; + font-size: 32px; + padding: 2px; + padding-left: 12px; + padding-right: 12px; + text-align: end; +} + +.axisChanging { + color: #00e200; +} + +.limitPin { + color: #f00000; +} + +.axisUnits { + font-size: 0.5em; +} + +.axisZeroButton { + width: 100%; + height: 100%; + padding: 0px; + font-weight: bold +} + diff --git a/ugs-pendant/src/main/webapp2/src/components/AxisPanel.tsx b/ugs-pendant/src/main/webapp2/src/components/AxisPanel.tsx new file mode 100644 index 0000000000..8e6374ce0c --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/AxisPanel.tsx @@ -0,0 +1,81 @@ +import { useEffect, useState } from "react"; +import "./AxisPanel.scss"; +import { Button, Col, Row } from "react-bootstrap"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faDeleteLeft } from "@fortawesome/free-solid-svg-icons"; +import { resetToZero } from "../services/machine"; +import { useAppSelector } from "../hooks/useAppSelector"; + +type Props = { + axisType: AxisType; +}; + +const round = (value: number) => { + return Math.round((value + Number.EPSILON) * 1000) / 1000; +}; + +export enum AxisType { + X = "X", + Y = "Y", + Z = "Z", + A = "A", + B = "B", + C = "C", +} + +const AxisPanel = ({ axisType }: Props) => { + const [active, setActive] = useState(false); + const status = useAppSelector((state) => state.status); + + const machineCoord = (status.machineCoord as any)[ + axisType.toLocaleLowerCase() + ]; + const workCoord = (status.workCoord as any)[axisType.toLocaleLowerCase()]; + const limitPin = (status.pins as any)?.[axisType.toLocaleLowerCase()]; + + useEffect(() => { + setActive(true); + const timer = setTimeout(() => setActive(false), 300); + return () => clearTimeout(timer); + }, [machineCoord, workCoord]); + + return ( + + + + + {axisType} + + + {round(workCoord).toFixed(3)} + {" "}{status.workCoord.units.toLocaleLowerCase()} + + + + + + + + ); +}; + +export default AxisPanel; diff --git a/ugs-pendant/src/main/webapp2/src/components/ControllerState.scss b/ugs-pendant/src/main/webapp2/src/components/ControllerState.scss new file mode 100644 index 0000000000..eb657dcb11 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/ControllerState.scss @@ -0,0 +1,46 @@ +.controllerState { + overflow: hidden; + margin-left: 12px; + + .card-body { + text-align: center; + padding: 5px 12px; + font-weight: bold; + } + + .hold, + .door { + background-color: #ff970b; + color: black; + } + + .run, + .jog, + .home { + background-color: #00c900; + color: black; + } + + .check { + background-color: #05D4FF; + } + + .idle, + .connecting, + .disconnected { + background-color: #808080; + color: black; + } + + .alarm { + background-color: #dc3545; + color: white; + animation: blinker 1s linear infinite; + } + + @keyframes blinker { + 50% { + background-color: #6e030e; + } + } +} diff --git a/ugs-pendant/src/main/webapp2/src/components/ControllerState.tsx b/ugs-pendant/src/main/webapp2/src/components/ControllerState.tsx new file mode 100644 index 0000000000..21853a9484 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/ControllerState.tsx @@ -0,0 +1,17 @@ +import { Card } from "react-bootstrap"; +import { useAppSelector } from "../hooks/useAppSelector"; +import "./ControllerState.scss"; + +const ControllerState = () => { + const state = useAppSelector((state) => state.status.state); + + return ( + + + {state} + + + ); +}; + +export default ControllerState; diff --git a/ugs-pendant/src/main/webapp2/src/components/DropdownInput.tsx b/ugs-pendant/src/main/webapp2/src/components/DropdownInput.tsx new file mode 100644 index 0000000000..e3345a94c3 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/DropdownInput.tsx @@ -0,0 +1,35 @@ +import React, { useEffect, useState } from "react"; +import { Dropdown, DropdownButton, Form, InputGroup } from "react-bootstrap"; + +type Props = { + value: string; + options: string[]; + label: string; + editable?: boolean; + onChange?: React.ChangeEventHandler; +}; + +const DropdownInput = ({ value, options, label, onChange, editable}: Props) => { + const [currentValue, setCurrentValue] = useState(""); + useEffect(() => setCurrentValue(value), [value]); + + return ( + + + + + + + {options.map((option, index) => { + return ( + setCurrentValue(option)}> + {option} + + ); + })} + + + ); +}; + +export default DropdownInput; diff --git a/ugs-pendant/src/main/webapp2/src/components/Footer.tsx b/ugs-pendant/src/main/webapp2/src/components/Footer.tsx new file mode 100644 index 0000000000..b081e8a568 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/Footer.tsx @@ -0,0 +1,34 @@ +import { + Button, + Dropdown, + DropdownButton, + Nav, + NavDropdown, + Navbar, +} from "react-bootstrap"; + +const Footer = () => { + return ( + + + + + + + + + ); +}; + +export default Footer; diff --git a/ugs-pendant/src/main/webapp2/src/components/Header.tsx b/ugs-pendant/src/main/webapp2/src/components/Header.tsx new file mode 100644 index 0000000000..c516ce1523 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/Header.tsx @@ -0,0 +1,54 @@ +import { + faPause, + faPlugCircleXmark, + faRefresh, + faStop, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { useState } from "react"; +import { Navbar, Nav, NavLink, Button } from "react-bootstrap"; +import { useAppSelector } from "../hooks/useAppSelector"; +import { disconnect, softReset } from "../services/machine"; +import ControllerState from "./ControllerState"; + +const Header = () => { + const [activeKey, setActiveKey] = useState("/home"); + const isConnected = useAppSelector((state) => state.socket.isConnected); + const state = useAppSelector((state) => state.status.state); + + return ( + <> + + + + + ); +}; + +export default Header; diff --git a/ugs-pendant/src/main/webapp2/src/components/JogPanel.scss b/ugs-pendant/src/main/webapp2/src/components/JogPanel.scss new file mode 100644 index 0000000000..b14769ade1 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/JogPanel.scss @@ -0,0 +1,29 @@ +.jogButton { + width: 100%; + height: 100%; + min-height: 70px; + font-weight: bold; +} + +.jogButtonSmall { + min-height: 50px; + min-width: 50px; + border-radius: 50%; +} + +.jogRow { + margin-top: 0px; + margin-bottom: 0px; +} + +.jogColumn { + padding: 0; + text-align: center; + margin-top: auto; + margin-bottom: auto; +} + +.actions { + margin-top: 12px; + margin-bottom: 12px; +} diff --git a/ugs-pendant/src/main/webapp2/src/components/JogPanel.tsx b/ugs-pendant/src/main/webapp2/src/components/JogPanel.tsx new file mode 100644 index 0000000000..9d0dada0ca --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/JogPanel.tsx @@ -0,0 +1,202 @@ +import { + faCaretDown, + faCaretLeft, + faCaretRight, + faCaretUp, + faChevronLeft, + faChevronRight, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { useMemo } from "react"; +import { Button, Col, Container, Form, Row } from "react-bootstrap"; +import { useAppSelector } from "../hooks/useAppSelector"; +import { jog } from "../services/machine"; +import "./JogPanel.scss"; +import RangeSlider from "./RangeSlider"; +import { setSettings } from "../store/settingsSlice"; +import { useDispatch } from "react-redux"; +import { useAppDispatch } from "../hooks/useAppDispatch"; + +const JogPanel = () => { + const dispatch = useAppDispatch(); + const currentState = useAppSelector((state) => state.status.state); + const settings = useAppSelector((state) => state.settings); + const isEnabled = useMemo( + () => currentState === "IDLE" || currentState === "JOG", + [currentState] + ); + + return ( + + + + + + + + + + + + + + + + + + + + + +   + + + + + + + + + + + + + + + + + + + + + + + + + + dispatch(setSettings({ ...settings, jogStepSizeXY: value })) + } + /> + + + + + + + ); +}; + +export default JogPanel; diff --git a/ugs-pendant/src/main/webapp2/src/components/RangeSlider.tsx b/ugs-pendant/src/main/webapp2/src/components/RangeSlider.tsx new file mode 100644 index 0000000000..8fad475b54 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/RangeSlider.tsx @@ -0,0 +1,38 @@ +import { Col, Form, Row } from "react-bootstrap"; +import useDebounce from "../hooks/useDebounce"; +import { useEffect, useState } from "react"; + +type Props = { + max?: number; + min?: number; + step?: number; + value?: number; + onChange: (value: number) => void; + disabled?: boolean; +}; + +const RangeSlider = ({ onChange, max, min, step, value, disabled }: Props) => { + + const debouncedValue = useDebounce(value); + useEffect(() => { + onChange(debouncedValue || 0); + }, [debouncedValue, onChange]); + + return ( + + Step size {value} + + onChange(+event.target.value)} + disabled={disabled} + /> + + + ); +}; + +export default RangeSlider; diff --git a/ugs-pendant/src/main/webapp2/src/components/RunFooter.tsx b/ugs-pendant/src/main/webapp2/src/components/RunFooter.tsx new file mode 100644 index 0000000000..699b710bfa --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/RunFooter.tsx @@ -0,0 +1,11 @@ +import { Button, Container, Navbar } from "react-bootstrap"; + +const RunFooter = () => { + return ( + + + + ); +}; + +export default RunFooter; diff --git a/ugs-pendant/src/main/webapp2/src/hooks/useAppDispatch.ts b/ugs-pendant/src/main/webapp2/src/hooks/useAppDispatch.ts new file mode 100644 index 0000000000..883dc9aeb3 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/hooks/useAppDispatch.ts @@ -0,0 +1,5 @@ +import { useDispatch } from "react-redux"; +import type { AppDispatch } from "../store/store"; + +type DispatchFunc = () => AppDispatch; +export const useAppDispatch: DispatchFunc = useDispatch; diff --git a/ugs-pendant/src/main/webapp2/src/hooks/useAppSelector.ts b/ugs-pendant/src/main/webapp2/src/hooks/useAppSelector.ts new file mode 100644 index 0000000000..673661f7c3 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/hooks/useAppSelector.ts @@ -0,0 +1,4 @@ +import { TypedUseSelectorHook, useSelector } from "react-redux"; +import type { RootState } from "../store/store"; + +export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/ugs-pendant/src/main/webapp2/src/hooks/useDebounce.ts b/ugs-pendant/src/main/webapp2/src/hooks/useDebounce.ts new file mode 100644 index 0000000000..69bb1c95c4 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/hooks/useDebounce.ts @@ -0,0 +1,14 @@ +import { useEffect, useState } from "react"; + +const useDebounce = (value: T, delay?: number): T => { + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect(() => { + const timer = setTimeout(() => setDebouncedValue(value), delay || 500); + return () => clearTimeout(timer); + }, [value, delay]); + + return debouncedValue; +}; + +export default useDebounce; \ No newline at end of file diff --git a/ugs-pendant/src/main/webapp2/src/index.css b/ugs-pendant/src/main/webapp2/src/index.css new file mode 100644 index 0000000000..b8a7f729d0 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/index.css @@ -0,0 +1,68 @@ +/*:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +}*/ diff --git a/ugs-pendant/src/main/webapp2/src/main.tsx b/ugs-pendant/src/main/webapp2/src/main.tsx new file mode 100644 index 0000000000..0a682742f8 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/main.tsx @@ -0,0 +1,12 @@ +import ReactDOM from "react-dom/client"; +import App from "./App.tsx"; +import { Provider } from "react-redux"; +import { store } from "./store/store.ts"; + +import "./index.css"; + +ReactDOM.createRoot(document.getElementById("root")!).render( + + + +); diff --git a/ugs-pendant/src/main/webapp2/src/model/ConnectionParameters.ts b/ugs-pendant/src/main/webapp2/src/model/ConnectionParameters.ts new file mode 100644 index 0000000000..da8de3b597 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/model/ConnectionParameters.ts @@ -0,0 +1,3 @@ +export type ConnectionParameters = { + baudRates: string[]; +}; diff --git a/ugs-pendant/src/main/webapp2/src/model/ControllerStateEvent.ts b/ugs-pendant/src/main/webapp2/src/model/ControllerStateEvent.ts new file mode 100644 index 0000000000..b2c3db0698 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/model/ControllerStateEvent.ts @@ -0,0 +1,5 @@ + +export type ControllerStateEvent = { + state: string; + previousState: string; +}; diff --git a/ugs-pendant/src/main/webapp2/src/model/ControllerStatusEvent.ts b/ugs-pendant/src/main/webapp2/src/model/ControllerStatusEvent.ts new file mode 100644 index 0000000000..81e583a535 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/model/ControllerStatusEvent.ts @@ -0,0 +1,6 @@ +import { Status } from "./Status"; + +export type ControllerStatusEvent = { + status: Status; + previousStatus: Status; +}; diff --git a/ugs-pendant/src/main/webapp2/src/model/Coordinate.ts b/ugs-pendant/src/main/webapp2/src/model/Coordinate.ts new file mode 100644 index 0000000000..83f333f4ec --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/model/Coordinate.ts @@ -0,0 +1,9 @@ +export type Coordinate = { + x: number; + y: number; + z: number; + a: number; + b: number; + c: number; + units: "MM" | "INCH"; +}; diff --git a/ugs-pendant/src/main/webapp2/src/model/Settings.ts b/ugs-pendant/src/main/webapp2/src/model/Settings.ts new file mode 100644 index 0000000000..d340737679 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/model/Settings.ts @@ -0,0 +1,6 @@ +export type Settings = { + jogFeedRate: number; + jogStepSizeXY: number; + preferredUnits: "mm" | "inch"; + jogStepSizeZ: number; +}; diff --git a/ugs-pendant/src/main/webapp2/src/model/Status.ts b/ugs-pendant/src/main/webapp2/src/model/Status.ts new file mode 100644 index 0000000000..ec78bb6b2b --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/model/Status.ts @@ -0,0 +1,28 @@ +import { Coordinate } from "./Coordinate"; + +export type Status = { + machineCoord: Coordinate; + workCoord: Coordinate; + feedSpeed: number; + spindleSpeed: number; + state: string; + rowCount: number; + completedRowCount: number; + remainingRowCount: number; + fileName: string; + sendDuration: number; + sendRemainingDuration: number; + pins: { + x: boolean; + y: boolean; + z: boolean; + a: boolean; + b: boolean; + c: boolean; + probe: boolean; + door: boolean; + hold: boolean; + softReset: boolean; + cycleStart: boolean; + } +}; diff --git a/ugs-pendant/src/main/webapp2/src/model/UGSEvent.ts b/ugs-pendant/src/main/webapp2/src/model/UGSEvent.ts new file mode 100644 index 0000000000..7dfcfc832d --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/model/UGSEvent.ts @@ -0,0 +1,7 @@ +import { ControllerStateEvent } from "./ControllerStateEvent"; +import { ControllerStatusEvent } from "./ControllerStatusEvent"; + +export type UGSEvent = { + eventType: "ControllerStatusEvent" | "ControllerStateEvent" | "SettingChangedEvent"; + event: ControllerStateEvent | ControllerStatusEvent; +}; diff --git a/ugs-pendant/src/main/webapp2/src/pages/ConnectPage.tsx b/ugs-pendant/src/main/webapp2/src/pages/ConnectPage.tsx new file mode 100644 index 0000000000..e17e592218 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/pages/ConnectPage.tsx @@ -0,0 +1,93 @@ +import { useEffect, useState } from "react"; +import { Button, Col, Container, Form, FormGroup, Row } from "react-bootstrap"; +import DropdownInput from "../components/DropdownInput"; +import { useAppDispatch } from "../hooks/useAppDispatch"; +import { + connect, + getBaudRateList, + getFirmwareList, + getPortList, + getSelectedBaudRate, + getSelectedFirmware, + getSelectedPort, +} from "../services/machine"; +import { fetchStatus } from "../store/statusSlice"; + +const ConnectPage = () => { + const [ports, setPorts] = useState([]); + const [firmwares, setFirmwares] = useState([]); + const [baudRates, setBaudRates] = useState([]); + + const [selectedFirmware, setSelectedFirmware] = useState(""); + const [selectedPort, setSelectedPort] = useState(""); + const [selectedBaudRate, setSelectedBaud] = useState(""); + const dispatch = useAppDispatch(); + + useEffect(() => { + dispatch(fetchStatus()) + .unwrap() + .catch((error: any) => { + console.error(error); + }); + + getPortList().then((portList) => setPorts(portList)); + getFirmwareList().then((firmwareList) => setFirmwares(firmwareList)); + getBaudRateList().then((buadRateList) => setBaudRates(buadRateList)); + getSelectedPort().then((selectedPort) => setSelectedPort(selectedPort)); + getSelectedFirmware().then((selectedFirmware) => + setSelectedFirmware(selectedFirmware) + ); + getSelectedBaudRate().then((selectedBaudRate) => + setSelectedBaud(selectedBaudRate) + ); + }, []); + + return ( + + + +
+ + + setSelectedFirmware(element.currentTarget.value) + } + /> + + + + + setSelectedPort(element.currentTarget.value) + } + editable={true} + /> + + + + + setSelectedBaud(element.currentTarget.value) + } + editable={true} + /> + + + +
+ +
+
+ ); +}; + +export default ConnectPage; diff --git a/ugs-pendant/src/main/webapp2/src/pages/MainPage.tsx b/ugs-pendant/src/main/webapp2/src/pages/MainPage.tsx new file mode 100644 index 0000000000..aeee4e5cf4 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/pages/MainPage.tsx @@ -0,0 +1,63 @@ +import { Button, Col, Container, Nav, NavDropdown, Row } from "react-bootstrap"; +import AxisPanel, { AxisType } from "../components/AxisPanel"; +import JogPanel from "../components/JogPanel"; +import { useAppSelector } from "../hooks/useAppSelector"; +import { homeMachine, resetToZero, returnToZero } from "../services/machine"; + +const isAvailable = (value: number | undefined) => { + return value !== null && !Number.isNaN(value); +}; + +const MainPage = () => { + const state = useAppSelector((state) => state.status.state); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default MainPage; diff --git a/ugs-pendant/src/main/webapp2/src/pages/WaitingPage.tsx b/ugs-pendant/src/main/webapp2/src/pages/WaitingPage.tsx new file mode 100644 index 0000000000..b38670ee7c --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/pages/WaitingPage.tsx @@ -0,0 +1,29 @@ +import { useEffect } from "react"; +import { Container, Spinner } from "react-bootstrap"; +import { useAppSelector } from "../hooks/useAppSelector"; +import { useDispatch } from "react-redux"; +import { socketActions } from "../store/socketSlice"; + +const WaitingPage = () => { + const dispatch = useDispatch(); + const { isConnected, isEstablishingConnection } = useAppSelector( + (state) => state.socket + ); + + useEffect(() => { + const timer = setTimeout(() => { + dispatch(socketActions.connect()); + }, 4000); + + return () => clearTimeout(timer); + }, [dispatch, isConnected, isEstablishingConnection]); + + return ( + + Waiting for UGS to become active{" "} + + + ); +}; + +export default WaitingPage; diff --git a/ugs-pendant/src/main/webapp2/src/services/machine.ts b/ugs-pendant/src/main/webapp2/src/services/machine.ts new file mode 100644 index 0000000000..eac083ba65 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/services/machine.ts @@ -0,0 +1,85 @@ +/** + * Retreives a list of available ports + * + * @returns a list of available ports + */ +export const getPortList = (): Promise => { + return fetch("api/v1/machine/getPortList") + .then((response) => response.json()) + .then((data) => data as string[]); +}; + +/** + * Retreives the currently selected port + * + * @returns the currently selected port + */ +export const getSelectedPort = (): Promise => { + return fetch("api/v1/machine/getSelectedPort") + .then((response) => response.json()) + .then((data) => data as any) + .then((data) => data?.selectedPort ?? ""); +}; + +export const getSelectedFirmware = (): Promise => { + return fetch("api/v1/machine/getSelectedFirmware") + .then((response) => response.json()) + .then((data) => data as any) + .then((data) => data?.selectedFirmware ?? ""); +}; + +export const getSelectedBaudRate = (): Promise => { + return fetch("api/v1/machine/getSelectedBaudRate") + .then((response) => response.json()) + .then((data) => data as any) + .then((data) => data?.selectedBaudRate ?? ""); +}; + +export const getFirmwareList = (): Promise => { + return fetch("api/v1/machine/getFirmwareList") + .then((response) => response.json()) + .then((data) => data as string[]); +}; + +export const getBaudRateList = (): Promise => { + return fetch("api/v1/machine/getBaudRateList") + .then((response) => response.json()) + .then((data) => data as string[]); +}; + +export const connect = (): Promise => { + return fetch("api/v1/machine/connect").then(); +}; + +export const disconnect = (): Promise => { + return fetch("api/v1/machine/disconnect").then(); +}; + +export const softReset = (): Promise => { + return fetch("api/v1/machine/softReset").then(); +}; + +export const killAlarm = (): Promise => { + return fetch("api/v1/machine/killAlarm").then(); +}; + +export const homeMachine = (): Promise => { + return fetch("api/v1/machine/homeMachine").then(); +}; + +export const returnToZero = (): Promise => { + return fetch("api/v1/machine/returnToZero").then(); +}; + +export const jog = (x: number, y: number, z: number): Promise => { + return fetch(`api/v1/machine/jog?x=${x}&y=${y}&z=${z}`).then(); +}; + +export const resetToZero = ( + axis?: "A" | "B" | "C" | "X" | "Y" | "Z" +): Promise => { + if (axis) { + return fetch(`api/v1/machine/resetToZero?axis=${axis}`).then(); + } + return fetch(`api/v1/machine/resetToZero`).then(); +}; diff --git a/ugs-pendant/src/main/webapp2/src/services/settings.ts b/ugs-pendant/src/main/webapp2/src/services/settings.ts new file mode 100644 index 0000000000..234cb9e3b3 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/services/settings.ts @@ -0,0 +1,20 @@ +import { Settings } from "../model/Settings"; + +export const fetchSettings = (): Promise => { + return fetch("api/v1/settings/getSettings").then((response) => + response.json() + ); +}; + +export const putSettings = (settings: Settings): Promise => { + const url = "api/v1/settings/setSettings"; + const request = { + method: "POST", + headers: { + 'Content-Type': "application/json" + }, + body: JSON.stringify(settings), + }; + + return fetch(url, request).then(() => settings); +}; diff --git a/ugs-pendant/src/main/webapp2/src/services/status.ts b/ugs-pendant/src/main/webapp2/src/services/status.ts new file mode 100644 index 0000000000..a341076564 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/services/status.ts @@ -0,0 +1,16 @@ +import { Status } from "../model/Status"; + +const getStatus = () => { + return fetch("api/v1/status/getStatus") + .then((response) => response.text()) + .then((text) => { + // Workaround for a quirk where the backend returns "NaN" if it is not a number + let convertedText = text.replaceAll('"NaN"', "null"); + return JSON.parse(convertedText) as Status; + }) + .then((response) => { + return response; + }); +}; + +export default getStatus; diff --git a/ugs-pendant/src/main/webapp2/src/store/connectionParametersSlice.ts b/ugs-pendant/src/main/webapp2/src/store/connectionParametersSlice.ts new file mode 100644 index 0000000000..72f3fd76c2 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/store/connectionParametersSlice.ts @@ -0,0 +1,32 @@ +import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; +import { ConnectionParameters } from "../model/ConnectionParameters"; + +export const fetchConnectionParameters = createAsyncThunk( + "connectionParameters/fetch", + async () => + fetch("api/v1/machine/getParameters") + .then((response) => response.json()) + .then((data) => data as ConnectionParameters) +); + +const initialState: ConnectionParameters = { + baudRates: [], +}; + +export const statusSlice = createSlice({ + name: "status", + initialState, + reducers: {}, + extraReducers(builder) { + builder.addCase(fetchConnectionParameters.pending, () => { + return initialState; + }); + builder.addCase(fetchConnectionParameters.fulfilled, (_state, action) => { + return action.payload; + }); + }, +}); + +// Action creators are generated for each case reducer function + +export default statusSlice.reducer; diff --git a/ugs-pendant/src/main/webapp2/src/store/counterSlice.ts b/ugs-pendant/src/main/webapp2/src/store/counterSlice.ts new file mode 100644 index 0000000000..04640d9bc4 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/store/counterSlice.ts @@ -0,0 +1,29 @@ +import { createSlice } from "@reduxjs/toolkit"; + +export const counterSlice = createSlice({ + name: "counter", + initialState: { + value: 0, + }, + reducers: { + increment: (state) => { + // Redux Toolkit allows us to write "mutating" logic in reducers. It + // doesn't actually mutate the state because it uses the Immer library, + // which detects changes to a "draft state" and produces a brand new + // immutable state based off those changes. + // Also, no return statement is required from these functions. + state.value += 1; + }, + decrement: (state) => { + state.value -= 1; + }, + incrementByAmount: (state, action) => { + state.value += action.payload; + }, + }, +}); + +// Action creators are generated for each case reducer function +export const { increment, decrement, incrementByAmount } = counterSlice.actions; + +export default counterSlice.reducer; diff --git a/ugs-pendant/src/main/webapp2/src/store/settingsSlice.ts b/ugs-pendant/src/main/webapp2/src/store/settingsSlice.ts new file mode 100644 index 0000000000..969b4ab785 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/store/settingsSlice.ts @@ -0,0 +1,56 @@ +import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; +import { Settings } from "../model/Settings"; +import { fetchSettings, putSettings } from "../services/settings"; +import { RootState } from "./store"; + +export const getSettings = createAsyncThunk( + "settings/get", + fetchSettings +); + +export const setSettings = createAsyncThunk< + Settings, + Settings, + { state: RootState } +>("settings/set", async (settings, thunkApi) => { + const currentState = thunkApi.getState(); + console.log(currentState.settings, settings); + if ( + currentState.settings.jogFeedRate === settings.jogFeedRate && + currentState.settings.jogStepSizeXY === settings.jogStepSizeXY && + currentState.settings.jogStepSizeZ === settings.jogStepSizeZ + ) { + return currentState.settings; + } + + return putSettings(settings); +}); + +const initialState: Settings = { + jogFeedRate: 100, + jogStepSizeXY: 1, + preferredUnits: "mm", + jogStepSizeZ: 1, +}; + +const settingsSlice = createSlice({ + name: "status", + initialState, + reducers: {}, + extraReducers(builder) { + builder.addCase(getSettings.pending, () => { + return initialState; + }); + builder.addCase(getSettings.fulfilled, (_state, action) => { + return action.payload; + }); + + builder.addCase(setSettings.fulfilled, (_state, action) => { + return action.payload; + }); + }, +}); + +// Action creators are generated for each case reducer function +export const settingsActions = settingsSlice.actions; +export default settingsSlice.reducer; diff --git a/ugs-pendant/src/main/webapp2/src/store/socketMiddleware.ts b/ugs-pendant/src/main/webapp2/src/store/socketMiddleware.ts new file mode 100644 index 0000000000..546a45aca6 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/store/socketMiddleware.ts @@ -0,0 +1,111 @@ +/*import { Middleware, MiddlewareAPI } from "@reduxjs/toolkit"; +import { RootState } from "./store"; +import { Socket } from "../utils/Socket"; +import { ControllerStateEvent } from "../model/ControllerStateEvent"; +import { UGSEvent } from "../model/UGSEvent"; +import { ControllerStatusEvent } from "../model/ControllerStatusEvent"; + +const createSocketMiddleware = (socket: Socket) => { + socket.connect("ws://" + location.host + "/ws/v1/events"); + + socket.on("open", (event) => { + console.log(event); + setInterval(() => { + socket.send("ping"); + }, 4000); + }); + + socket.onMessage((messageEvent: MessageEvent) => { + const ugsEvent = JSON.parse(messageEvent.data) as UGSEvent; + if (ugsEvent.eventType === "ControllerStateEvent") { + console.log( + ugsEvent.eventType, + (ugsEvent.event as ControllerStateEvent).state + ); + } else if (ugsEvent.eventType === "ControllerStatusEvent") { + console.log( + ugsEvent.eventType, + (ugsEvent.event as ControllerStatusEvent).status.state + ); + } else { + console.log("Unknown event", messageEvent.data); + } + }); + + socket.on("close", (event) => { + console.log("...and I say goodbye!"); + }); + + //socket.send('A message') + //socket.disconnect() +}; + +const socket = new Socket(); + +export const socketMiddleware: Middleware = + (api : MiddlewareAPI) => + (next : Dispatch) => (action: A) => { + + return next(action); + };*/ + +import { socketActions } from "./socketSlice"; +import { Socket } from "../utils/Socket"; +import { UGSEvent } from "../model/UGSEvent"; +import { ControllerStatusEvent } from "../model/ControllerStatusEvent"; +import { fetchStatus, statusActions } from "./statusSlice"; +import { Action, ThunkMiddleware } from "@reduxjs/toolkit"; +import { RootState } from "./store"; +import { getSettings } from "./settingsSlice"; + +/** + * This is a TypeScript example of a simple logging middleware for Redux. + * It will log every action that passes through the middleware pipeline. + */ +export const socketMiddleware: ThunkMiddleware = + (store) => (next) => (action) => { + // Not a socket action + if (!socketActions.connect.match(action)) { + return next(action); + } + + const socket = new Socket(); + socket.connect("ws://" + location.host + "/ws/v1/events"); + + socket.on("open", () => { + console.log("Established connection"); + store.dispatch(socketActions.connectionEstablished()); + store.dispatch(getSettings()); + + const timer = setInterval(() => { + if (!socket.isConnected()) { + clearInterval(timer); + return; + } + + socket.send("ping"); + }, 4000); + }); + + socket.on("close", () => { + console.log("Closing!!"); + store.dispatch(socketActions.connectionClosed()); + }); + + socket.onMessage((messageEvent: MessageEvent) => { + const ugsEvent = JSON.parse(messageEvent.data) as UGSEvent; + if (ugsEvent.eventType === "ControllerStatusEvent") { + store.dispatch( + statusActions.setStatus( + (ugsEvent.event as ControllerStatusEvent).status + ) + ); + } else if (ugsEvent.eventType === "SettingChangedEvent") { + store.dispatch(fetchStatus()); + } else { + console.info("Unknown event", messageEvent.data); + } + }); + + return next(action); + }; diff --git a/ugs-pendant/src/main/webapp2/src/store/socketSlice.ts b/ugs-pendant/src/main/webapp2/src/store/socketSlice.ts new file mode 100644 index 0000000000..555223aa18 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/store/socketSlice.ts @@ -0,0 +1,33 @@ +import { createSlice } from "@reduxjs/toolkit"; + +export interface SocketState { + isEstablishingConnection: boolean; + isConnected: boolean; +} + +const initialState: SocketState = { + isEstablishingConnection: false, + isConnected: false, +}; + +const socketSlice = createSlice({ + name: "socket", + initialState, + reducers: { + connect: (state) => { + state.isEstablishingConnection = true; + }, + connectionEstablished: (state) => { + state.isConnected = true; + state.isEstablishingConnection = true; + }, + connectionClosed: (state) => { + state.isConnected = false; + state.isEstablishingConnection = false; + }, + }, +}); + +export const socketActions = socketSlice.actions; + +export default socketSlice.reducer; diff --git a/ugs-pendant/src/main/webapp2/src/store/statusSlice.ts b/ugs-pendant/src/main/webapp2/src/store/statusSlice.ts new file mode 100644 index 0000000000..6f05252796 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/store/statusSlice.ts @@ -0,0 +1,96 @@ +import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; +import { Status } from "../model/Status"; +import getStatus from "../services/status"; + +export const fetchStatus = createAsyncThunk("status/fetch", getStatus); + +const initialState: Status = { + machineCoord: { + x: 0, + y: 0, + z: 0, + a: 0, + b: 0, + c: 0, + units: "MM", + }, + workCoord: { + x: 0, + y: 0, + z: 0, + a: 0, + b: 0, + c: 0, + units: "MM", + }, + feedSpeed: 0, + spindleSpeed: 0, + state: "DISCONNECTED", + rowCount: 0, + completedRowCount: 0, + remainingRowCount: 0, + fileName: "", + sendDuration: 0, + sendRemainingDuration: 0, + pins: { + x: false, + y: false, + z: false, + a: false, + b: false, + c: false, + cycleStart: false, + hold: false, + probe: false, + door: false, + softReset: false, + }, +}; + +const statusSlice = createSlice({ + name: "status", + initialState, + reducers: { + setStatus: (state, action) => { + state.machineCoord = action.payload.machineCoord; + state.workCoord = action.payload.workCoord; + state.feedSpeed = action.payload.feedSpeed; + state.spindleSpeed = action.payload.spindleSpeed; + state.state = action.payload.state; + state.rowCount = action.payload.rowCount; + state.completedRowCount = action.payload.completedRowCount; + state.remainingRowCount = action.payload.remainingRowCount; + state.fileName = action.payload.fileName; + state.sendDuration = action.payload.sendDuration; + state.sendRemainingDuration = action.payload.sendRemainingDuration; + state.pins = { + x: action.payload.pins.x, + y: action.payload.pins.y, + z: action.payload.pins.z, + a: action.payload.pins.a, + b: action.payload.pins.b, + c: action.payload.pins.c, + cycleStart: action.payload.pins.cycleStart, + hold: action.payload.pins.hold, + probe: action.payload.pins.probe, + softReset: action.payload.pins.softReset, + door: action.payload.pins.door, + }; + }, + }, + extraReducers(builder) { + builder.addCase(fetchStatus.pending, (state) => { + return state; + }); + builder.addCase(fetchStatus.fulfilled, (_state, action) => { + return action.payload; + }); + builder.addCase(fetchStatus.rejected, () => { + return initialState; + }); + }, +}); + +// Action creators are generated for each case reducer function +export const statusActions = statusSlice.actions; +export default statusSlice.reducer; diff --git a/ugs-pendant/src/main/webapp2/src/store/store.ts b/ugs-pendant/src/main/webapp2/src/store/store.ts new file mode 100644 index 0000000000..9d336173e1 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/store/store.ts @@ -0,0 +1,22 @@ +import { combineReducers, configureStore } from "@reduxjs/toolkit"; +import counterReducer from "./counterSlice"; +import statusReducer from "./statusSlice"; +import socketReducer from "./socketSlice"; +import settingsReducer from "./settingsSlice"; +import { socketMiddleware } from "./socketMiddleware"; + +const rootReducer = combineReducers({ + counter: counterReducer, + status: statusReducer, + socket: socketReducer, + settings: settingsReducer +}); + +export const store = configureStore({ + reducer: rootReducer, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware().concat(socketMiddleware), +}); + +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; diff --git a/ugs-pendant/src/main/webapp2/src/utils/Socket.ts b/ugs-pendant/src/main/webapp2/src/utils/Socket.ts new file mode 100644 index 0000000000..2ccf49bec7 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/utils/Socket.ts @@ -0,0 +1,44 @@ +class Socket { + socket: WebSocket | undefined; + + constructor() { + this.socket = undefined; + } + + connect(url: string) { + if (!this.socket) { + this.socket = new WebSocket(url); + } + } + + disconnect() { + if (this.socket) { + this.socket.close(); + this.socket = undefined; + } + } + + isConnected() { + return !!this.socket; + } + + send(message: any) { + if (this.socket) { + this.socket.send(JSON.stringify(message)); + } + } + + onMessage(messageListener : (message: MessageEvent) => void) { + if (this.socket) { + this.socket.addEventListener("message", messageListener); + } + }; + + on(eventName: string, callback: EventListenerOrEventListenerObject) { + if (this.socket) { + this.socket.addEventListener(eventName, callback); + } + } +} + +export { Socket }; diff --git a/ugs-pendant/src/main/webapp2/src/vite-env.d.ts b/ugs-pendant/src/main/webapp2/src/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/ugs-pendant/src/main/webapp2/tsconfig.json b/ugs-pendant/src/main/webapp2/tsconfig.json new file mode 100644 index 0000000000..a938959d3f --- /dev/null +++ b/ugs-pendant/src/main/webapp2/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2021", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/ugs-pendant/src/main/webapp2/tsconfig.node.json b/ugs-pendant/src/main/webapp2/tsconfig.node.json new file mode 100644 index 0000000000..42872c59f5 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/ugs-pendant/src/main/webapp2/vite.config.ts b/ugs-pendant/src/main/webapp2/vite.config.ts new file mode 100644 index 0000000000..ddf7961b83 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/vite.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + server: { + proxy: { + '/api': { + target: 'http://localhost:8080', + changeOrigin: true, + ws: false, + }, + '/ws': { + target: 'http://localhost:8080', + changeOrigin: true, + ws: true, + }, + }, + }, +}) From 95415b1aa1dddb5a5be33d480ded158211f5509f Mon Sep 17 00:00:00 2001 From: Joacim Breiler Date: Thu, 9 May 2024 16:52:55 +0200 Subject: [PATCH 2/4] Added more features to the react pendant --- ugs-pendant/pom.xml | 2 + .../pendantui/html/StaticResource.java | 4 +- .../pendantui/v1/model/Settings.java | 36 ++ .../v1/resources/SettingsResource.java | 9 +- ugs-pendant/src/main/webapp2/.gitignore | 1 + ugs-pendant/src/main/webapp2/fonts/LCD.ttf | Bin 0 -> 29780 bytes .../src/main/webapp2/package-lock.json | 404 +++++++++++------- ugs-pendant/src/main/webapp2/package.json | 5 +- ugs-pendant/src/main/webapp2/src/App.scss | 2 +- ugs-pendant/src/main/webapp2/src/App.tsx | 34 +- .../src/main/webapp2/src/bootstrap.scss | 31 +- .../src/components/AccessoryState.scss | 15 + .../webapp2/src/components/AccessoryState.tsx | 15 + .../webapp2/src/components/AxisPanel.scss | 13 +- .../main/webapp2/src/components/AxisPanel.tsx | 5 + .../webapp2/src/components/DropdownInput.tsx | 33 +- .../main/webapp2/src/components/FeedRate.scss | 12 + .../main/webapp2/src/components/FeedRate.tsx | 30 ++ .../main/webapp2/src/components/Footer.scss | 45 ++ .../main/webapp2/src/components/Footer.tsx | 70 +-- .../main/webapp2/src/components/Header.tsx | 55 ++- .../main/webapp2/src/components/JogPanel.tsx | 47 +- .../webapp2/src/components/MacrosPanel.tsx | 45 ++ .../webapp2/src/components/RangeSlider.scss | 73 ++++ .../webapp2/src/components/RangeSlider.tsx | 29 +- .../main/webapp2/src/components/RunFooter.tsx | 2 +- .../main/webapp2/src/components/RunPanel.tsx | 43 ++ .../main/webapp2/src/components/StepSize.scss | 7 + .../main/webapp2/src/components/StepSize.tsx | 30 ++ .../src/main/webapp2/src/hooks/useDebounce.ts | 11 +- .../src/main/webapp2/src/model/Macro.ts | 5 + .../src/main/webapp2/src/model/Settings.ts | 6 +- .../main/webapp2/src/pages/ConnectPage.tsx | 44 +- .../src/main/webapp2/src/pages/MainPage.tsx | 131 +++--- .../src/main/webapp2/src/services/machine.ts | 21 + .../src/main/webapp2/src/services/macros.ts | 20 + .../main/webapp2/src/store/settingsSlice.ts | 13 +- .../webapp2/src/store/socketMiddleware.ts | 77 +--- ugs-pendant/src/main/webapp2/vite.config.ts | 25 +- 39 files changed, 1042 insertions(+), 408 deletions(-) create mode 100644 ugs-pendant/src/main/webapp2/fonts/LCD.ttf create mode 100644 ugs-pendant/src/main/webapp2/src/components/AccessoryState.scss create mode 100644 ugs-pendant/src/main/webapp2/src/components/AccessoryState.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/FeedRate.scss create mode 100644 ugs-pendant/src/main/webapp2/src/components/FeedRate.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/Footer.scss create mode 100644 ugs-pendant/src/main/webapp2/src/components/MacrosPanel.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/RangeSlider.scss create mode 100644 ugs-pendant/src/main/webapp2/src/components/RunPanel.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/components/StepSize.scss create mode 100644 ugs-pendant/src/main/webapp2/src/components/StepSize.tsx create mode 100644 ugs-pendant/src/main/webapp2/src/model/Macro.ts create mode 100644 ugs-pendant/src/main/webapp2/src/services/macros.ts diff --git a/ugs-pendant/pom.xml b/ugs-pendant/pom.xml index d51de3b123..544892d205 100644 --- a/ugs-pendant/pom.xml +++ b/ugs-pendant/pom.xml @@ -141,6 +141,8 @@ v16.13.2 8.1.2 + diff --git a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/html/StaticResource.java b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/html/StaticResource.java index a633016cc6..9294bf9015 100644 --- a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/html/StaticResource.java +++ b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/html/StaticResource.java @@ -41,6 +41,8 @@ private static String getMimeType(String path) { mimeType = "text/html"; } else if (path.endsWith(".css")) { mimeType = "text/css"; + } else if (path.endsWith(".ttf")) { + mimeType = "font/ttf"; } return mimeType; } @@ -51,7 +53,7 @@ public Response getIndex() throws Exception { } @GET - @Path("{path:.*\\.(jpg|gif|html|js|css|ico)$}") + @Path("{path:.*\\.(jpg|gif|html|js|css|ico|ttf)$}") public Response getStaticResource(@PathParam("path") String path) throws Exception { if (path.equalsIgnoreCase("")) { path = "index.html"; diff --git a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/model/Settings.java b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/model/Settings.java index 21ff150e54..5baad005d9 100644 --- a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/model/Settings.java +++ b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/model/Settings.java @@ -10,6 +10,10 @@ public class Settings implements Serializable { private double jogStepSizeXY; private UnitUtils.Units preferredUnits; private double jogStepSizeZ; + private String port; + private String portRate; + private String firmwareVersion; + private boolean useZStepSize; public void setJogFeedRate(double jogFeedRate) { this.jogFeedRate = jogFeedRate; @@ -42,4 +46,36 @@ public double getJogStepSizeZ() { public void setJogStepSizeZ(double jogStepSizeZ) { this.jogStepSizeZ = jogStepSizeZ; } + + public void setPort(String port) { + this.port = port; + } + + public String getPort() { + return port; + } + + public void setPortRate(String portRate) { + this.portRate = portRate; + } + + public String getPortRate() { + return portRate; + } + + public void setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public void setUseZStepSize(boolean useZStepSize) { + this.useZStepSize = useZStepSize; + } + + public boolean isUseZStepSize() { + return useZStepSize; + } } diff --git a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/resources/SettingsResource.java b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/resources/SettingsResource.java index ef75fe226c..f4e2b78958 100644 --- a/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/resources/SettingsResource.java +++ b/ugs-pendant/src/main/java/com/willwinder/universalgcodesender/pendantui/v1/resources/SettingsResource.java @@ -42,6 +42,10 @@ public Settings getSettings() { response.setJogStepSizeXY(settings.getManualModeStepSize()); response.setJogStepSizeZ(settings.getZJogStepSize()); response.setPreferredUnits(settings.getPreferredUnits()); + response.setPort(settings.getPort()); + response.setPortRate(settings.getPortRate()); + response.setFirmwareVersion(settings.getFirmwareVersion()); + response.setUseZStepSize(settings.useZStepSize()); return response; } @@ -54,6 +58,9 @@ public void setSettings(Settings settings) throws Exception { backendSettings.setManualModeStepSize(settings.getJogStepSizeXY()); backendSettings.setZJogStepSize(settings.getJogStepSizeZ()); backendSettings.setPreferredUnits(settings.getPreferredUnits()); - backendAPI.applySettings(backendSettings); + backendSettings.setPort(settings.getPort()); + backendSettings.setPortRate(settings.getPortRate()); + backendSettings.setFirmwareVersion(settings.getFirmwareVersion()); + backendSettings.setUseZStepSize(settings.isUseZStepSize()); } } diff --git a/ugs-pendant/src/main/webapp2/.gitignore b/ugs-pendant/src/main/webapp2/.gitignore index a547bf36d8..72f4f2ee2a 100644 --- a/ugs-pendant/src/main/webapp2/.gitignore +++ b/ugs-pendant/src/main/webapp2/.gitignore @@ -22,3 +22,4 @@ dist-ssr *.njsproj *.sln *.sw? +node/* diff --git a/ugs-pendant/src/main/webapp2/fonts/LCD.ttf b/ugs-pendant/src/main/webapp2/fonts/LCD.ttf new file mode 100644 index 0000000000000000000000000000000000000000..57386786a350f10c0a809158301e9772e2ae1b49 GIT binary patch literal 29780 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%0DY`JN1v&mjy-15ox6E`wPM`*Qmkni2#z{}v) z3*;q?3|=9xVmxyQ{rzq726+?TA~DHPe6!?T@(%ozN^%$;%1%gd73Pv^1fOpO_s&O; zLL$VX zsWgqI(+tu|38KU^X%?m8nA7?jzPN&K;^3<*0lJRjWlQ+R3ckf6zMHb1ZXl1-YFa~UX&pI04wCoC$8;lk zA79h^E7?!>k&p1Lmq+lemtT`-@y(ZC!Oz`Fp24?b?k7)@r^plJpY(iMk5`d5;@!YE z;Y%?$;~Oh~hX?t6d`ISPe0k*t+C(>bn`*1ZjG0ob(h`-P>YZE@2-ertdIK``OkP(X z-W2u(MB<%XXV%q*H+TawO`RI7st-2RR8)sANDW5el&PV*#y~I_u5C;SI-qA-Fo2@* zK6jB!Lp^~;?{rlmY#OiFGhJ2~7D>u<=kAoS1A3<`G{Q3VOqV5wMUpx*ib$#%g;Qoa z1*Dh`m^PCu;($ap&2$~4&WhffS{a4)S?dDzdL?$Avl^?aLtzgb3MAgMR72cG%z{#r@k+5rCuV}0Gm%CI)Q z*3`naruS^s_&U}2vt{G!M3R1XWmBygsBfyN4m35U*SU{8izE*95{E^uYSZdn2cAU| zhkBVTmUlIXBz19=bg2zdIBkimfV4)}foF*c0Rb^vKN<~+nF=otIeksyoY3uOyFxWPV bgEVZJ*tk8^Rmv?N{`PCFL7uw5sri2ZNZH$- literal 0 HcmV?d00001 diff --git a/ugs-pendant/src/main/webapp2/package-lock.json b/ugs-pendant/src/main/webapp2/package-lock.json index baa3b93ffd..5d3e0fcda6 100644 --- a/ugs-pendant/src/main/webapp2/package-lock.json +++ b/ugs-pendant/src/main/webapp2/package-lock.json @@ -17,7 +17,8 @@ "react": "^18.2.0", "react-bootstrap": "^2.9.2", "react-dom": "^18.2.0", - "react-redux": "^9.0.4" + "react-redux": "^9.0.4", + "react-router-dom": "^6.23.0" }, "devDependencies": { "@types/react": "^18.2.43", @@ -412,9 +413,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", - "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "cpu": [ "ppc64" ], @@ -428,9 +429,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", - "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "cpu": [ "arm" ], @@ -444,9 +445,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", - "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "cpu": [ "arm64" ], @@ -460,9 +461,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", - "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "cpu": [ "x64" ], @@ -476,9 +477,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", - "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "cpu": [ "arm64" ], @@ -492,9 +493,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", - "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "cpu": [ "x64" ], @@ -508,9 +509,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", - "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "cpu": [ "arm64" ], @@ -524,9 +525,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", - "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "cpu": [ "x64" ], @@ -540,9 +541,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", - "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "cpu": [ "arm" ], @@ -556,9 +557,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", - "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "cpu": [ "arm64" ], @@ -572,9 +573,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", - "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "cpu": [ "ia32" ], @@ -588,9 +589,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", - "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "cpu": [ "loong64" ], @@ -604,9 +605,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", - "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "cpu": [ "mips64el" ], @@ -620,9 +621,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", - "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "cpu": [ "ppc64" ], @@ -636,9 +637,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", - "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "cpu": [ "riscv64" ], @@ -652,9 +653,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", - "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "cpu": [ "s390x" ], @@ -668,9 +669,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", - "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "cpu": [ "x64" ], @@ -684,9 +685,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", - "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "cpu": [ "x64" ], @@ -700,9 +701,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", - "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "cpu": [ "x64" ], @@ -716,9 +717,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", - "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "cpu": [ "x64" ], @@ -732,9 +733,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", - "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "cpu": [ "arm64" ], @@ -748,9 +749,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", - "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "cpu": [ "ia32" ], @@ -764,9 +765,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", - "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "cpu": [ "x64" ], @@ -1110,6 +1111,14 @@ } } }, + "node_modules/@remix-run/router": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", + "integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@restart/hooks": { "version": "0.4.15", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.15.tgz", @@ -1150,9 +1159,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.1.tgz", - "integrity": "sha512-6vMdBZqtq1dVQ4CWdhFwhKZL6E4L1dV6jUjuBvsavvNJSppzi6dLBbuV+3+IyUREaj9ZFvQefnQm28v4OCXlig==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz", + "integrity": "sha512-jwXtxYbRt1V+CdQSy6Z+uZti7JF5irRKF8hlKfEnF/xJpcNGuuiZMBvuoYM+x9sr9iWGnzrlM0+9hvQ1kgkf1w==", "cpu": [ "arm" ], @@ -1163,9 +1172,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.1.tgz", - "integrity": "sha512-Jto9Fl3YQ9OLsTDWtLFPtaIMSL2kwGyGoVCmPC8Gxvym9TCZm4Sie+cVeblPO66YZsYH8MhBKDMGZ2NDxuk/XQ==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.0.tgz", + "integrity": "sha512-fI9nduZhCccjzlsA/OuAwtFGWocxA4gqXGTLvOyiF8d+8o0fZUeSztixkYjcGq1fGZY3Tkq4yRvHPFxU+jdZ9Q==", "cpu": [ "arm64" ], @@ -1176,9 +1185,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.1.tgz", - "integrity": "sha512-LtYcLNM+bhsaKAIGwVkh5IOWhaZhjTfNOkGzGqdHvhiCUVuJDalvDxEdSnhFzAn+g23wgsycmZk1vbnaibZwwA==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.0.tgz", + "integrity": "sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA==", "cpu": [ "arm64" ], @@ -1189,9 +1198,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.1.tgz", - "integrity": "sha512-KyP/byeXu9V+etKO6Lw3E4tW4QdcnzDG/ake031mg42lob5tN+5qfr+lkcT/SGZaH2PdW4Z1NX9GHEkZ8xV7og==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.0.tgz", + "integrity": "sha512-LDyFB9GRolGN7XI6955aFeI3wCdCUszFWumWU0deHA8VpR3nWRrjG6GtGjBrQxQKFevnUTHKCfPR4IvrW3kCgQ==", "cpu": [ "x64" ], @@ -1202,9 +1211,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.1.tgz", - "integrity": "sha512-Yqz/Doumf3QTKplwGNrCHe/B2p9xqDghBZSlAY0/hU6ikuDVQuOUIpDP/YcmoT+447tsZTmirmjgG3znvSCR0Q==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.0.tgz", + "integrity": "sha512-ygrGVhQP47mRh0AAD0zl6QqCbNsf0eTo+vgwkY6LunBcg0f2Jv365GXlDUECIyoXp1kKwL5WW6rsO429DBY/bA==", "cpu": [ "arm" ], @@ -1215,9 +1224,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.1.tgz", - "integrity": "sha512-u3XkZVvxcvlAOlQJ3UsD1rFvLWqu4Ef/Ggl40WAVCuogf4S1nJPHh5RTgqYFpCOvuGJ7H5yGHabjFKEZGExk5Q==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.0.tgz", + "integrity": "sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A==", "cpu": [ "arm64" ], @@ -1228,9 +1237,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.1.tgz", - "integrity": "sha512-0XSYN/rfWShW+i+qjZ0phc6vZ7UWI8XWNz4E/l+6edFt+FxoEghrJHjX1EY/kcUGCnZzYYRCl31SNdfOi450Aw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.0.tgz", + "integrity": "sha512-nrRw8ZTQKg6+Lttwqo6a2VxR9tOroa2m91XbdQ2sUUzHoedXlsyvY1fN4xWdqz8PKmf4orDwejxXHjh7YBGUCA==", "cpu": [ "arm64" ], @@ -1240,10 +1249,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.0.tgz", + "integrity": "sha512-xV0d5jDb4aFu84XKr+lcUJ9y3qpIWhttO3Qev97z8DKLXR62LC3cXT/bMZXrjLF9X+P5oSmJTzAhqwUbY96PnA==", + "cpu": [ + "ppc64le" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.1.tgz", - "integrity": "sha512-LmYIO65oZVfFt9t6cpYkbC4d5lKHLYv5B4CSHRpnANq0VZUQXGcCPXHzbCXCz4RQnx7jvlYB1ISVNCE/omz5cw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.0.tgz", + "integrity": "sha512-SDDhBQwZX6LPRoPYjAZWyL27LbcBo7WdBFWJi5PI9RPCzU8ijzkQn7tt8NXiXRiFMJCVpkuMkBf4OxSxVMizAw==", "cpu": [ "riscv64" ], @@ -1253,10 +1275,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.0.tgz", + "integrity": "sha512-RxB/qez8zIDshNJDufYlTT0ZTVut5eCpAZ3bdXDU9yTxBzui3KhbGjROK2OYTTor7alM7XBhssgoO3CZ0XD3qA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.1.tgz", - "integrity": "sha512-kr8rEPQ6ns/Lmr/hiw8sEVj9aa07gh1/tQF2Y5HrNCCEPiCBGnBUt9tVusrcBBiJfIt1yNaXN6r1CCmpbFEDpg==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.0.tgz", + "integrity": "sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg==", "cpu": [ "x64" ], @@ -1267,9 +1302,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.1.tgz", - "integrity": "sha512-t4QSR7gN+OEZLG0MiCgPqMWZGwmeHhsM4AkegJ0Kiy6TnJ9vZ8dEIwHw1LcZKhbHxTY32hp9eVCMdR3/I8MGRw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.0.tgz", + "integrity": "sha512-i0QwbHYfnOMYsBEyjxcwGu5SMIi9sImDVjDg087hpzXqhBSosxkE7gyIYFHgfFl4mr7RrXksIBZ4DoLoP4FhJg==", "cpu": [ "x64" ], @@ -1280,9 +1315,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.1.tgz", - "integrity": "sha512-7XI4ZCBN34cb+BH557FJPmh0kmNz2c25SCQeT9OiFWEgf8+dL6ZwJ8f9RnUIit+j01u07Yvrsuu1rZGxJCc51g==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.0.tgz", + "integrity": "sha512-Fq52EYb0riNHLBTAcL0cun+rRwyZ10S9vKzhGKKgeD+XbwunszSY0rVMco5KbOsTlwovP2rTOkiII/fQ4ih/zQ==", "cpu": [ "arm64" ], @@ -1293,9 +1328,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.1.tgz", - "integrity": "sha512-yE5c2j1lSWOH5jp+Q0qNL3Mdhr8WuqCNVjc6BxbVfS5cAS6zRmdiw7ktb8GNpDCEUJphILY6KACoFoRtKoqNQg==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.0.tgz", + "integrity": "sha512-e/PBHxPdJ00O9p5Ui43+vixSgVf4NlLsmV6QneGERJ3lnjIua/kim6PRFe3iDueT1rQcgSkYP8ZBBXa/h4iPvw==", "cpu": [ "ia32" ], @@ -1306,9 +1341,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.1.tgz", - "integrity": "sha512-PyJsSsafjmIhVgaI1Zdj7m8BB8mMckFah/xbpplObyHfiXzKcI5UOUXRyOdHW7nz4DpMCuzLnF7v5IWHenCwYA==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.0.tgz", + "integrity": "sha512-aGg7iToJjdklmxlUlJh/PaPNa4PmqHfyRMLunbL3eaMO0gp656+q1zOKkpJ/CVe9CryJv6tAN1HDoR8cNGzkag==", "cpu": [ "x64" ], @@ -1367,6 +1402,12 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -2017,9 +2058,9 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", - "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "hasInstallScript": true, "bin": { @@ -2029,29 +2070,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.10", - "@esbuild/android-arm": "0.19.10", - "@esbuild/android-arm64": "0.19.10", - "@esbuild/android-x64": "0.19.10", - "@esbuild/darwin-arm64": "0.19.10", - "@esbuild/darwin-x64": "0.19.10", - "@esbuild/freebsd-arm64": "0.19.10", - "@esbuild/freebsd-x64": "0.19.10", - "@esbuild/linux-arm": "0.19.10", - "@esbuild/linux-arm64": "0.19.10", - "@esbuild/linux-ia32": "0.19.10", - "@esbuild/linux-loong64": "0.19.10", - "@esbuild/linux-mips64el": "0.19.10", - "@esbuild/linux-ppc64": "0.19.10", - "@esbuild/linux-riscv64": "0.19.10", - "@esbuild/linux-s390x": "0.19.10", - "@esbuild/linux-x64": "0.19.10", - "@esbuild/netbsd-x64": "0.19.10", - "@esbuild/openbsd-x64": "0.19.10", - "@esbuild/sunos-x64": "0.19.10", - "@esbuild/win32-arm64": "0.19.10", - "@esbuild/win32-ia32": "0.19.10", - "@esbuild/win32-x64": "0.19.10" + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "node_modules/escalade": { @@ -3061,9 +3102,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -3082,7 +3123,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -3245,6 +3286,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz", + "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==", + "dependencies": { + "@remix-run/router": "1.16.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz", + "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==", + "dependencies": { + "@remix-run/router": "1.16.0", + "react-router": "6.23.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -3330,10 +3401,13 @@ } }, "node_modules/rollup": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.1.tgz", - "integrity": "sha512-pgPO9DWzLoW/vIhlSoDByCzcpX92bKEorbgXuZrqxByte3JFk2xSW2JEeAcyLc9Ru9pqcNNW+Ob7ntsk2oT/Xw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.0.tgz", + "integrity": "sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ==", "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, "bin": { "rollup": "dist/bin/rollup" }, @@ -3342,19 +3416,21 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.1", - "@rollup/rollup-android-arm64": "4.9.1", - "@rollup/rollup-darwin-arm64": "4.9.1", - "@rollup/rollup-darwin-x64": "4.9.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.1", - "@rollup/rollup-linux-arm64-gnu": "4.9.1", - "@rollup/rollup-linux-arm64-musl": "4.9.1", - "@rollup/rollup-linux-riscv64-gnu": "4.9.1", - "@rollup/rollup-linux-x64-gnu": "4.9.1", - "@rollup/rollup-linux-x64-musl": "4.9.1", - "@rollup/rollup-win32-arm64-msvc": "4.9.1", - "@rollup/rollup-win32-ia32-msvc": "4.9.1", - "@rollup/rollup-win32-x64-msvc": "4.9.1", + "@rollup/rollup-android-arm-eabi": "4.14.0", + "@rollup/rollup-android-arm64": "4.14.0", + "@rollup/rollup-darwin-arm64": "4.14.0", + "@rollup/rollup-darwin-x64": "4.14.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.14.0", + "@rollup/rollup-linux-arm64-gnu": "4.14.0", + "@rollup/rollup-linux-arm64-musl": "4.14.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.14.0", + "@rollup/rollup-linux-riscv64-gnu": "4.14.0", + "@rollup/rollup-linux-s390x-gnu": "4.14.0", + "@rollup/rollup-linux-x64-gnu": "4.14.0", + "@rollup/rollup-linux-x64-musl": "4.14.0", + "@rollup/rollup-win32-arm64-msvc": "4.14.0", + "@rollup/rollup-win32-ia32-msvc": "4.14.0", + "@rollup/rollup-win32-x64-msvc": "4.14.0", "fsevents": "~2.3.2" } }, @@ -3470,9 +3546,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -3657,14 +3733,14 @@ } }, "node_modules/vite": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.1.tgz", - "integrity": "sha512-wclpAgY3F1tR7t9LL5CcHC41YPkQIpKUGeIuT8MdNwNZr6OqOTLs7JX5vIHAtzqLWXts0T+GDrh9pN2arneKqg==", + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz", + "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==", "dev": true, "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.35", - "rollup": "^4.2.0" + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" diff --git a/ugs-pendant/src/main/webapp2/package.json b/ugs-pendant/src/main/webapp2/package.json index a896c01828..6f2b84f640 100644 --- a/ugs-pendant/src/main/webapp2/package.json +++ b/ugs-pendant/src/main/webapp2/package.json @@ -10,16 +10,17 @@ "preview": "vite preview" }, "dependencies": { + "@fortawesome/fontawesome-free": "^6.5.1", "@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/free-solid-svg-icons": "^6.5.1", - "@fortawesome/fontawesome-free": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", "@reduxjs/toolkit": "^2.0.1", "bootstrap": "^5.3.2", "react": "^18.2.0", "react-bootstrap": "^2.9.2", "react-dom": "^18.2.0", - "react-redux": "^9.0.4" + "react-redux": "^9.0.4", + "react-router-dom": "^6.23.0" }, "devDependencies": { "@types/react": "^18.2.43", diff --git a/ugs-pendant/src/main/webapp2/src/App.scss b/ugs-pendant/src/main/webapp2/src/App.scss index 0be52b45b3..1d5a5163bc 100644 --- a/ugs-pendant/src/main/webapp2/src/App.scss +++ b/ugs-pendant/src/main/webapp2/src/App.scss @@ -8,4 +8,4 @@ body { } .app { -} \ No newline at end of file +} diff --git a/ugs-pendant/src/main/webapp2/src/App.tsx b/ugs-pendant/src/main/webapp2/src/App.tsx index 28641d32cb..d1599f9c48 100644 --- a/ugs-pendant/src/main/webapp2/src/App.tsx +++ b/ugs-pendant/src/main/webapp2/src/App.tsx @@ -8,25 +8,51 @@ import MainPage from "./pages/MainPage"; import { socketActions } from "./store/socketSlice"; import WaitingPage from "./pages/WaitingPage"; import AlarmModal from "./components/AlarmModal"; -import Footer from "./components/Footer"; +import { RouterProvider, createBrowserRouter } from "react-router-dom"; +import JogPanel from "./components/JogPanel"; +import MacrosPanel from "./components/MacrosPanel"; +import RunPanel from "./components/RunPanel"; function App() { const status = useAppSelector((state) => state.status); const isConnected = useAppSelector((state) => state.socket.isConnected); const dispatch = useDispatch(); - + useEffect(() => { dispatch(socketActions.connect()); }, [dispatch]); + const router = createBrowserRouter([ + { + path: "/", + element: , + children: [ + { + path: "jog", + element: , + }, + { + path: "macros", + element: , + }, + { + path: "run", + element: , + }, + ], + }, + ]); + return (
+
{!isConnected && (status.state === "DISCONNECTED" || status.state === "CONNECTING") && } {isConnected && status.state === "DISCONNECTED" && } - {isConnected && (status.state !== "DISCONNECTED" && status.state !== "CONNECTING") && } + {isConnected && (status.state !== "DISCONNECTED" && status.state !== "CONNECTING") && } {status.state === "ALARM" && } -
+ +
); } diff --git a/ugs-pendant/src/main/webapp2/src/bootstrap.scss b/ugs-pendant/src/main/webapp2/src/bootstrap.scss index 28ef53d7c6..fd72f7bf02 100644 --- a/ugs-pendant/src/main/webapp2/src/bootstrap.scss +++ b/ugs-pendant/src/main/webapp2/src/bootstrap.scss @@ -1,23 +1,30 @@ @import "bootstrap/scss/bootstrap"; .btn-secondary { - background-color: white; - color: #353a40; - border-color: #c2c2c2; + background-color: white; + color: #353a40; + border-color: #c2c2c2; } .btn-secondary.btn:hover { - background-color: #f7f7f7; - color: #353a40; - border-color: #c2c2c2; + background-color: #f7f7f7; + color: #353a40; + border-color: #c2c2c2; } .btn-secondary.btn:disabled { - background-color: #f7f7f7; - color: #353a40; - border-color: #c2c2c2; + background-color: #f7f7f7; + color: #353a40; + border-color: #c2c2c2; } -.bg-dark { - background-color: #2a2c2d !important; -} \ No newline at end of file +.bg-dark { + background-color: #2a2c2d !important; +} + +@media (min-width: 576px) { + .container-sm, + .container { + max-width: 100%; + } +} diff --git a/ugs-pendant/src/main/webapp2/src/components/AccessoryState.scss b/ugs-pendant/src/main/webapp2/src/components/AccessoryState.scss new file mode 100644 index 0000000000..f05f5cab39 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/AccessoryState.scss @@ -0,0 +1,15 @@ +.accessoryState { + overflow: hidden; + margin-left: 12px; + display: inline-flex; + + .card-body { + text-align: center; + padding: 5px 12px; + font-weight: bold; + + background-color: #dc3545; + color: white; + } + } + \ No newline at end of file diff --git a/ugs-pendant/src/main/webapp2/src/components/AccessoryState.tsx b/ugs-pendant/src/main/webapp2/src/components/AccessoryState.tsx new file mode 100644 index 0000000000..3288f5784b --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/AccessoryState.tsx @@ -0,0 +1,15 @@ +import { Card } from "react-bootstrap"; +import "./AccessoryState.scss"; + +type Props = { + children: React.ReactNode; +}; +const AccessoryState = ({ children }: Props) => { + return ( + + {children} + + ); +}; + +export default AccessoryState; diff --git a/ugs-pendant/src/main/webapp2/src/components/AxisPanel.scss b/ugs-pendant/src/main/webapp2/src/components/AxisPanel.scss index 5556f1552b..fcc14c8876 100644 --- a/ugs-pendant/src/main/webapp2/src/components/AxisPanel.scss +++ b/ugs-pendant/src/main/webapp2/src/components/AxisPanel.scss @@ -1,10 +1,10 @@ @font-face { - font-family: "LCD"; - src: url(../assets/LCD.ttf); + font-family: "lcd"; + src: url(/fonts/LCD.ttf); } .axisRow { - margin-top: 12px; + margin-bottom: 10px; margin-left: 0px; } @@ -12,11 +12,11 @@ background-color: #2a2c2d; color: #05d4ff; border-radius: 6px; - font-family: "LCD"; + font-family: "lcd"; font-size: 32px; padding: 2px; - padding-left: 12px; - padding-right: 12px; + padding-left: 10px; + padding-right: 10px; text-align: end; } @@ -36,6 +36,5 @@ width: 100%; height: 100%; padding: 0px; - font-weight: bold } diff --git a/ugs-pendant/src/main/webapp2/src/components/AxisPanel.tsx b/ugs-pendant/src/main/webapp2/src/components/AxisPanel.tsx index 8e6374ce0c..6143f88149 100644 --- a/ugs-pendant/src/main/webapp2/src/components/AxisPanel.tsx +++ b/ugs-pendant/src/main/webapp2/src/components/AxisPanel.tsx @@ -39,6 +39,11 @@ const AxisPanel = ({ axisType }: Props) => { return () => clearTimeout(timer); }, [machineCoord, workCoord]); + // Hide axis if there is no work coordinate + if(workCoord === null) { + return <>; + } + return ( ; + onChange?: (value: string) => void; }; -const DropdownInput = ({ value, options, label, onChange, editable}: Props) => { +const DropdownInput = ({ + value, + options, + label, + onChange, + editable, +}: Props) => { const [currentValue, setCurrentValue] = useState(""); - useEffect(() => setCurrentValue(value), [value]); + useEffect(() => { + setCurrentValue(value); + }, [value]); return ( - + setCurrentValue(e.currentTarget.value)} + onBlur={(e) => onChange && onChange(e.currentTarget.value)} + readOnly={!editable} + /> {options.map((option, index) => { return ( - setCurrentValue(option)}> + { + setCurrentValue(option); + onChange && onChange(option); + }} + > {option} ); diff --git a/ugs-pendant/src/main/webapp2/src/components/FeedRate.scss b/ugs-pendant/src/main/webapp2/src/components/FeedRate.scss new file mode 100644 index 0000000000..a97b84fb13 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/FeedRate.scss @@ -0,0 +1,12 @@ +.stepSize { + display: inline-block; + width: 100%; + + .btn { + min-width: 10px; + } + + button { + width: 100%; + } +} \ No newline at end of file diff --git a/ugs-pendant/src/main/webapp2/src/components/FeedRate.tsx b/ugs-pendant/src/main/webapp2/src/components/FeedRate.tsx new file mode 100644 index 0000000000..7378d93252 --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/FeedRate.tsx @@ -0,0 +1,30 @@ +import { Dropdown, DropdownButton } from "react-bootstrap"; +import { useAppSelector } from "../hooks/useAppSelector"; +import "./FeedRate.scss"; + +type Props = { + value: number; + onChange: (value: number) => void; +}; + +const options = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000]; + +const FeedRate = ({ value, onChange }: Props) => { + const units = useAppSelector((state) => state.settings.preferredUnits); + + return ( + + {options.map((option, index) => ( + onChange(option)}> + {option} {units.toLocaleLowerCase() + "/min"} + + ))} + + ); +}; + +export default FeedRate; diff --git a/ugs-pendant/src/main/webapp2/src/components/Footer.scss b/ugs-pendant/src/main/webapp2/src/components/Footer.scss new file mode 100644 index 0000000000..dba0279bae --- /dev/null +++ b/ugs-pendant/src/main/webapp2/src/components/Footer.scss @@ -0,0 +1,45 @@ +.controllerState { + overflow: hidden; + margin-left: 12px; + + .card-body { + text-align: center; + padding: 5px 12px; + font-weight: bold; + } + + .hold { + background-color: #ff970b; + color: black; + } + + .run, + .jog, + .home { + background-color: #00c900; + color: black; + } + + .check { + background-color: #05D4FF; + } + + .idle, + .connecting, + .disconnected { + background-color: #808080; + color: black; + } + + .alarm { + background-color: #dc3545; + color: white; + animation: blinker 1s linear infinite; + } + + @keyframes blinker { + 50% { + background-color: #6e030e; + } + } +} diff --git a/ugs-pendant/src/main/webapp2/src/components/Footer.tsx b/ugs-pendant/src/main/webapp2/src/components/Footer.tsx index b081e8a568..740ecc196b 100644 --- a/ugs-pendant/src/main/webapp2/src/components/Footer.tsx +++ b/ugs-pendant/src/main/webapp2/src/components/Footer.tsx @@ -1,32 +1,50 @@ -import { - Button, - Dropdown, - DropdownButton, - Nav, - NavDropdown, - Navbar, -} from "react-bootstrap"; +import { faPause, faPlay, faStop } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Button, Nav, Navbar } from "react-bootstrap"; +import { cancelSend, pause, send } from "../services/machine"; +import { useAppSelector } from "../hooks/useAppSelector"; +import "./Footer.scss"; const Footer = () => { + const state = useAppSelector((state) => state.status.state); + return ( - - - - - - - + + ); }; diff --git a/ugs-pendant/src/main/webapp2/src/components/Header.tsx b/ugs-pendant/src/main/webapp2/src/components/Header.tsx index c516ce1523..f24843edda 100644 --- a/ugs-pendant/src/main/webapp2/src/components/Header.tsx +++ b/ugs-pendant/src/main/webapp2/src/components/Header.tsx @@ -1,24 +1,28 @@ import { - faPause, faPlugCircleXmark, faRefresh, - faStop, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useState } from "react"; -import { Navbar, Nav, NavLink, Button } from "react-bootstrap"; +import { Button, Nav, Navbar } from "react-bootstrap"; import { useAppSelector } from "../hooks/useAppSelector"; import { disconnect, softReset } from "../services/machine"; +import AccessoryState from "./AccessoryState"; import ControllerState from "./ControllerState"; const Header = () => { const [activeKey, setActiveKey] = useState("/home"); const isConnected = useAppSelector((state) => state.socket.isConnected); - const state = useAppSelector((state) => state.status.state); + const status = useAppSelector((state) => state.status); return ( <> - +