diff --git a/component-drivers.md b/component-drivers.md
new file mode 100644
index 0000000..bb5a29c
--- /dev/null
+++ b/component-drivers.md
@@ -0,0 +1,111 @@
+# Component Drivers
+This document describes the general methodology for writing component drivers that operate within your rail system to connect it to the online system's up- and down-link services.
+
+The following types of components are supported by Rail Signal:
+- `SIGNAL`
+- `SEGMENT_BOUNDARY`
+- `SWITCH`
+
+The following information is generally required for any driver to be able to connect to the system and operate nominally:
+- A valid link token
+- The base URL of the system's API. Usually `http://localhost:8080` or whatever you've configured it to be.
+- Live connection information. This differs depending on what type of communication your device supports.
+ - For devices with **websocket** support, you will need the base URL of the websocket. Usually `ws://localhost:8080` or whatever you've configured your server to use.
+ - For devices with **TCP socket** support, you will need the hostname and port of the system's server socket. By default, this is `localhost:8081`.
+
+A device is not limited to a single component, but will act as a relay for all components linked to the device's link token. Generally, there is no limit to the number of components that a single device can manage, but more components will lead to more load on the device.
+
+## Live Communication
+The main purpose of component drivers is to relay real-time messages between actual component devices, and their representations in the online rail system. While multiple types of communication are available, in general, all messages are sent as JSON UTF-8 encoded strings. Devices must present their link token when they initiate the connection.
+
+If the link token is valid, the connection will be initiated, and the device will immediately receive a `COMPONENT_DATA` message for each component that the token is linked to.
+
+### Websocket
+Websocket connections should be made to `{BASE_WS_URL}/api/ws/component?token={token}`, where `{BASE_WS_URL}` is the base websocket URL, such as `ws://localhost:8080`, and `{token}` is the device's link token.
+
+- If the link token is missing or improperly formatted, a 400 Bad Request response is given.
+- If the link token is not correct or not active or otherwise set to reject connections, a 401 Unauthorized response is given.
+
+### TCP Socket
+TCP socket connections should be made to the server's TCP socket address, which by default is `localhost:8081`. The device should immediately send 2 bytes indicating the length of its token string, followed by the token string's bytes. The client should expect to receive in response a *connect message*:
+```json
+{
+ "valid": true,
+ "message": "Connection established."
+}
+```
+
+- If the token is invalid, a `"valid": false` is returned and the server closes the socket.
+
+Note: All messages sent via TCP are sent as JSON messages with a 2-byte length header.
+
+## Components
+Each device should be designed to handle multiple independent components concurrently. The device may receive messages at any time pertaining to any of the components, and the device may send messages at any time, pertaining to any of the components. Messages are only sent regarding a single component.
+
+Every component message should contain at least the following two properties:
+```json
+{
+ "cId": 123,
+ "type": "COMPONENT_DATA",
+ ...
+}
+```
+`cId` is the id of the component that this message is about. `type` is the type of message. This defines what additional structure to expect.
+
+All components may receive `COMPONENT_DATA` messages. For example, the following could be a message regarding a signal:
+```json
+{
+ "cId": 123,
+ "type": "COMPONENT_DATA",
+ "data": {
+ "id": 123,
+ "position": {"x": 0, "y": 0, "z": 0},
+ "name": "my-component",
+ "type": "SIGNAL",
+ "online": true,
+ "segment": {
+ "id": 4,
+ "name": "my-segment",
+ "occupied": false
+ }
+ }
+}
+```
+
+The following sections will provide more detail about the other types of messages that can be sent and received by the different components.
+
+### Signal
+Signals display the status of a connected segment, and as such can only receive data. They will receive `SEGMENT_STATUS` messages:
+```json
+{
+ "cId": 123,
+ "type": "SEGMENT_STATUS",
+ "sId": 4,
+ "occupied": true
+}
+```
+`sId` is the id of the segment that was updated. `occupied` contains the current status of the segment.
+
+### Segment Boundary
+Segment boundaries send updates as trains pass them, in order to provide information to the system about the state of connected segments.
+```json
+{
+ "cId": 123,
+ "type": "SEGMENT_BOUNDARY_UPDATE",
+ "toSegmentId": 3,
+ "eventType": "ENTERING"
+}
+```
+`toSegmentId` is the id of the segment a train is moving towards. `eventType` is the type of boundary event. This can either be `ENTERING` if a train has just begun entering the segment, or `ENTERED` if a train has just left the boundary and completely entered the segment.
+
+### Switch
+Switches can send information about their status, if it's been updated, and they can also receive messages that direct them to change their status.
+
+```json
+{
+ "cId": 123,
+ "type": "SWITCH_UPDATE",
+ "activeConfigId": 497238
+}
+```
+`activeConfigId` is the id of the switch configuration that's active. This message can be sent by either the system or the switch.
diff --git a/railsignal-app/.env.development b/railsignal-app/.env.development
deleted file mode 100644
index a90eb52..0000000
--- a/railsignal-app/.env.development
+++ /dev/null
@@ -1,2 +0,0 @@
-VITE_API_URL=http://localhost:8080/api
-VITE_WS_URL=ws://localhost:8080/api/ws/app
\ No newline at end of file
diff --git a/railsignal-app/.env.production b/railsignal-app/.env.production
deleted file mode 100644
index a90eb52..0000000
--- a/railsignal-app/.env.production
+++ /dev/null
@@ -1,2 +0,0 @@
-VITE_API_URL=http://localhost:8080/api
-VITE_WS_URL=ws://localhost:8080/api/ws/app
\ No newline at end of file
diff --git a/railsignal-app/.eslintrc.cjs b/railsignal-app/.eslintrc.cjs
deleted file mode 100644
index deed24f..0000000
--- a/railsignal-app/.eslintrc.cjs
+++ /dev/null
@@ -1,11 +0,0 @@
-/* eslint-env node */
-module.exports = {
- "root": true,
- "extends": [
- "plugin:vue/vue3-essential",
- "eslint:recommended"
- ],
- "env": {
- "vue/setup-compiler-macros": true
- }
-}
diff --git a/railsignal-app/.gitignore b/railsignal-app/.gitignore
deleted file mode 100644
index 38adffa..0000000
--- a/railsignal-app/.gitignore
+++ /dev/null
@@ -1,28 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-.DS_Store
-dist
-dist-ssr
-coverage
-*.local
-
-/cypress/videos/
-/cypress/screenshots/
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/railsignal-app/README.md b/railsignal-app/README.md
deleted file mode 100644
index 6e6e3ef..0000000
--- a/railsignal-app/README.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# railsignal-app
-
-This template should help get you started developing with Vue 3 in Vite.
-
-## Recommended IDE Setup
-
-[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin).
-
-## Customize configuration
-
-See [Vite Configuration Reference](https://vitejs.dev/config/).
-
-## Project Setup
-
-```sh
-npm install
-```
-
-### Compile and Hot-Reload for Development
-
-```sh
-npm run dev
-```
-
-### Compile and Minify for Production
-
-```sh
-npm run build
-```
-
-### Lint with [ESLint](https://eslint.org/)
-
-```sh
-npm run lint
-```
diff --git a/railsignal-app/deploy_to_spring.d b/railsignal-app/deploy_to_spring.d
deleted file mode 100755
index bd136d8..0000000
--- a/railsignal-app/deploy_to_spring.d
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env dub
-/+ dub.sdl:
- dependency "dsh" version="~>1.6.1"
-+/
-import dsh;
-
-const DEST = "../src/main/resources/static";
-
-void main() {
- print("Deploying Vue app to Spring's /static directory.");
- runOrQuit("vite build --base=/app/");
- rmdirRecurse(DEST);
- copyDir("./dist", DEST);
-}
-
diff --git a/railsignal-app/index.html b/railsignal-app/index.html
deleted file mode 100644
index ecca371..0000000
--- a/railsignal-app/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
- Rail Signal
-
-
-
-
-
-
diff --git a/railsignal-app/package-lock.json b/railsignal-app/package-lock.json
deleted file mode 100644
index 0b2610b..0000000
--- a/railsignal-app/package-lock.json
+++ /dev/null
@@ -1,3226 +0,0 @@
-{
- "name": "railsignal-app",
- "version": "0.0.0",
- "lockfileVersion": 2,
- "requires": true,
- "packages": {
- "": {
- "name": "railsignal-app",
- "version": "0.0.0",
- "dependencies": {
- "@popperjs/core": "^2.11.5",
- "axios": "^0.27.2",
- "bootstrap": "^5.1.3",
- "pinia": "^2.0.14",
- "three": "^0.140.0",
- "vue": "^3.2.33",
- "vue-router": "^4.0.14"
- },
- "devDependencies": {
- "@vitejs/plugin-vue": "^2.3.2",
- "eslint": "^8.5.0",
- "eslint-plugin-vue": "^8.2.0",
- "vite": "^2.9.8"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.17.10",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.10.tgz",
- "integrity": "sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==",
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz",
- "integrity": "sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg==",
- "dev": true,
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^9.3.1",
- "globals": "^13.9.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.0.4",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/@humanwhocodes/config-array": {
- "version": "0.9.5",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
- "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
- "dev": true,
- "dependencies": {
- "@humanwhocodes/object-schema": "^1.2.1",
- "debug": "^4.1.1",
- "minimatch": "^3.0.4"
- },
- "engines": {
- "node": ">=10.10.0"
- }
- },
- "node_modules/@humanwhocodes/object-schema": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
- "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
- "dev": true
- },
- "node_modules/@popperjs/core": {
- "version": "2.11.5",
- "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz",
- "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/popperjs"
- }
- },
- "node_modules/@vitejs/plugin-vue": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.2.tgz",
- "integrity": "sha512-umyypfSHS4kQLdYAnJHhaASq7FRzNCdvcRoQ3uYGNk1/M4a+hXUd7ysN7BLhCrWH6uBokyCkFeUAaFDzSaaSrQ==",
- "dev": true,
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "vite": "^2.5.10",
- "vue": "^3.2.25"
- }
- },
- "node_modules/@vue/compiler-core": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.33.tgz",
- "integrity": "sha512-AAmr52ji3Zhk7IKIuigX2osWWsb2nQE5xsdFYjdnmtQ4gymmqXbjLvkSE174+fF3A3kstYrTgGkqgOEbsdLDpw==",
- "dependencies": {
- "@babel/parser": "^7.16.4",
- "@vue/shared": "3.2.33",
- "estree-walker": "^2.0.2",
- "source-map": "^0.6.1"
- }
- },
- "node_modules/@vue/compiler-dom": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.33.tgz",
- "integrity": "sha512-GhiG1C8X98Xz9QUX/RlA6/kgPBWJkjq0Rq6//5XTAGSYrTMBgcLpP9+CnlUg1TFxnnCVughAG+KZl28XJqw8uQ==",
- "dependencies": {
- "@vue/compiler-core": "3.2.33",
- "@vue/shared": "3.2.33"
- }
- },
- "node_modules/@vue/compiler-sfc": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.33.tgz",
- "integrity": "sha512-H8D0WqagCr295pQjUYyO8P3IejM3vEzeCO1apzByAEaAR/WimhMYczHfZVvlCE/9yBaEu/eu9RdiWr0kF8b71Q==",
- "dependencies": {
- "@babel/parser": "^7.16.4",
- "@vue/compiler-core": "3.2.33",
- "@vue/compiler-dom": "3.2.33",
- "@vue/compiler-ssr": "3.2.33",
- "@vue/reactivity-transform": "3.2.33",
- "@vue/shared": "3.2.33",
- "estree-walker": "^2.0.2",
- "magic-string": "^0.25.7",
- "postcss": "^8.1.10",
- "source-map": "^0.6.1"
- }
- },
- "node_modules/@vue/compiler-ssr": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.33.tgz",
- "integrity": "sha512-XQh1Xdk3VquDpXsnoCd7JnMoWec9CfAzQDQsaMcSU79OrrO2PNR0ErlIjm/mGq3GmBfkQjzZACV+7GhfRB8xMQ==",
- "dependencies": {
- "@vue/compiler-dom": "3.2.33",
- "@vue/shared": "3.2.33"
- }
- },
- "node_modules/@vue/devtools-api": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.4.tgz",
- "integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ=="
- },
- "node_modules/@vue/reactivity": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.33.tgz",
- "integrity": "sha512-62Sq0mp9/0bLmDuxuLD5CIaMG2susFAGARLuZ/5jkU1FCf9EDbwUuF+BO8Ub3Rbodx0ziIecM/NsmyjardBxfQ==",
- "dependencies": {
- "@vue/shared": "3.2.33"
- }
- },
- "node_modules/@vue/reactivity-transform": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.33.tgz",
- "integrity": "sha512-4UL5KOIvSQb254aqenW4q34qMXbfZcmEsV/yVidLUgvwYQQ/D21bGX3DlgPUGI3c4C+iOnNmDCkIxkILoX/Pyw==",
- "dependencies": {
- "@babel/parser": "^7.16.4",
- "@vue/compiler-core": "3.2.33",
- "@vue/shared": "3.2.33",
- "estree-walker": "^2.0.2",
- "magic-string": "^0.25.7"
- }
- },
- "node_modules/@vue/runtime-core": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.33.tgz",
- "integrity": "sha512-N2D2vfaXsBPhzCV3JsXQa2NECjxP3eXgZlFqKh4tgakp3iX6LCGv76DLlc+IfFZq+TW10Y8QUfeihXOupJ1dGw==",
- "dependencies": {
- "@vue/reactivity": "3.2.33",
- "@vue/shared": "3.2.33"
- }
- },
- "node_modules/@vue/runtime-dom": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.33.tgz",
- "integrity": "sha512-LSrJ6W7CZTSUygX5s8aFkraDWlO6K4geOwA3quFF2O+hC3QuAMZt/0Xb7JKE3C4JD4pFwCSO7oCrZmZ0BIJUnw==",
- "dependencies": {
- "@vue/runtime-core": "3.2.33",
- "@vue/shared": "3.2.33",
- "csstype": "^2.6.8"
- }
- },
- "node_modules/@vue/server-renderer": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.33.tgz",
- "integrity": "sha512-4jpJHRD4ORv8PlbYi+/MfP8ec1okz6rybe36MdpkDrGIdEItHEUyaHSKvz+ptNEyQpALmmVfRteHkU9F8vxOew==",
- "dependencies": {
- "@vue/compiler-ssr": "3.2.33",
- "@vue/shared": "3.2.33"
- },
- "peerDependencies": {
- "vue": "3.2.33"
- }
- },
- "node_modules/@vue/shared": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.33.tgz",
- "integrity": "sha512-UBc1Pg1T3yZ97vsA2ueER0F6GbJebLHYlEi4ou1H5YL4KWvMOOWwpYo9/QpWq93wxKG6Wo13IY74Hcn/f7c7Bg=="
- },
- "node_modules/acorn": {
- "version": "8.7.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
- "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
- "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": "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/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/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
- },
- "node_modules/axios": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
- "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
- "dependencies": {
- "follow-redirects": "^1.14.9",
- "form-data": "^4.0.0"
- }
- },
- "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/boolbase": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
- "dev": true
- },
- "node_modules/bootstrap": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz",
- "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/bootstrap"
- },
- "peerDependencies": {
- "@popperjs/core": "^2.10.2"
- }
- },
- "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/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/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/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/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/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
- "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/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "dev": true,
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/csstype": {
- "version": "2.6.20",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
- "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
- },
- "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/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "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/esbuild": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.38.tgz",
- "integrity": "sha512-12fzJ0fsm7gVZX1YQ1InkOE5f9Tl7cgf6JPYXRJtPIoE0zkWAbHdPHVPPaLi9tYAcEBqheGzqLn/3RdTOyBfcA==",
- "dev": true,
- "hasInstallScript": true,
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "esbuild-android-64": "0.14.38",
- "esbuild-android-arm64": "0.14.38",
- "esbuild-darwin-64": "0.14.38",
- "esbuild-darwin-arm64": "0.14.38",
- "esbuild-freebsd-64": "0.14.38",
- "esbuild-freebsd-arm64": "0.14.38",
- "esbuild-linux-32": "0.14.38",
- "esbuild-linux-64": "0.14.38",
- "esbuild-linux-arm": "0.14.38",
- "esbuild-linux-arm64": "0.14.38",
- "esbuild-linux-mips64le": "0.14.38",
- "esbuild-linux-ppc64le": "0.14.38",
- "esbuild-linux-riscv64": "0.14.38",
- "esbuild-linux-s390x": "0.14.38",
- "esbuild-netbsd-64": "0.14.38",
- "esbuild-openbsd-64": "0.14.38",
- "esbuild-sunos-64": "0.14.38",
- "esbuild-windows-32": "0.14.38",
- "esbuild-windows-64": "0.14.38",
- "esbuild-windows-arm64": "0.14.38"
- }
- },
- "node_modules/esbuild-android-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.38.tgz",
- "integrity": "sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-android-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.38.tgz",
- "integrity": "sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-darwin-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.38.tgz",
- "integrity": "sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-darwin-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.38.tgz",
- "integrity": "sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-freebsd-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.38.tgz",
- "integrity": "sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-freebsd-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.38.tgz",
- "integrity": "sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-32": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.38.tgz",
- "integrity": "sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.38.tgz",
- "integrity": "sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-arm": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.38.tgz",
- "integrity": "sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.38.tgz",
- "integrity": "sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-mips64le": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.38.tgz",
- "integrity": "sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-ppc64le": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.38.tgz",
- "integrity": "sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-riscv64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.38.tgz",
- "integrity": "sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-s390x": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.38.tgz",
- "integrity": "sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-netbsd-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.38.tgz",
- "integrity": "sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-openbsd-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.38.tgz",
- "integrity": "sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-sunos-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.38.tgz",
- "integrity": "sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-windows-32": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.38.tgz",
- "integrity": "sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-windows-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.38.tgz",
- "integrity": "sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-windows-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.38.tgz",
- "integrity": "sha512-k3FGCNmHBkqdJXuJszdWciAH77PukEyDsdIryEHn9cKLQFxzhT39dSumeTuggaQcXY57UlmLGIkklWZo2qzHpw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "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": {
- "version": "8.14.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.14.0.tgz",
- "integrity": "sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw==",
- "dev": true,
- "dependencies": {
- "@eslint/eslintrc": "^1.2.2",
- "@humanwhocodes/config-array": "^0.9.2",
- "ajv": "^6.10.0",
- "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.1.1",
- "eslint-utils": "^3.0.0",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
- "esquery": "^1.4.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
- "functional-red-black-tree": "^1.0.1",
- "glob-parent": "^6.0.1",
- "globals": "^13.6.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.0.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "js-yaml": "^4.1.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.0.4",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.1",
- "regexpp": "^3.2.0",
- "strip-ansi": "^6.0.1",
- "strip-json-comments": "^3.1.0",
- "text-table": "^0.2.0",
- "v8-compile-cache": "^2.0.3"
- },
- "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-vue": {
- "version": "8.7.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz",
- "integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==",
- "dev": true,
- "dependencies": {
- "eslint-utils": "^3.0.0",
- "natural-compare": "^1.4.0",
- "nth-check": "^2.0.1",
- "postcss-selector-parser": "^6.0.9",
- "semver": "^7.3.5",
- "vue-eslint-parser": "^8.0.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "peerDependencies": {
- "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
- "dev": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/eslint-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
- "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
- "dev": true,
- "dependencies": {
- "eslint-visitor-keys": "^2.0.0"
- },
- "engines": {
- "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- },
- "peerDependencies": {
- "eslint": ">=5"
- }
- },
- "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
- "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/espree": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz",
- "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==",
- "dev": true,
- "dependencies": {
- "acorn": "^8.7.0",
- "acorn-jsx": "^5.3.1",
- "eslint-visitor-keys": "^3.3.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
- "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/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
- },
- "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-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": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
- "dev": true
- },
- "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/flat-cache": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
- "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
- "dev": true,
- "dependencies": {
- "flatted": "^3.1.0",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/flatted": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
- "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
- "dev": true
- },
- "node_modules/follow-redirects": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz",
- "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==",
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "engines": {
- "node": ">=4.0"
- },
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
- }
- },
- "node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
- "dev": true
- },
- "node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "dev": true
- },
- "node_modules/functional-red-black-tree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
- "dev": true
- },
- "node_modules/glob": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
- "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "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/globals": {
- "version": "13.13.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz",
- "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==",
- "dev": true,
- "dependencies": {
- "type-fest": "^0.20.2"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "dev": true,
- "dependencies": {
- "function-bind": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "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/ignore": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
- "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
- "dev": true,
- "engines": {
- "node": ">= 4"
- }
- },
- "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": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
- "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": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "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/is-core-module": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
- "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
- "dev": true,
- "dependencies": {
- "has": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "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/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
- "dev": true
- },
- "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/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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
- "dev": true
- },
- "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/lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "dev": true
- },
- "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/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/magic-string": {
- "version": "0.25.9",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
- "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
- "dependencies": {
- "sourcemap-codec": "^1.4.8"
- }
- },
- "node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "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/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.4",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
- "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
- "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": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
- "dev": true
- },
- "node_modules/nth-check": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
- "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
- "dev": true,
- "dependencies": {
- "boolbase": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/fb55/nth-check?sponsor=1"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "dev": true,
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/optionator": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
- "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
- "dev": true,
- "dependencies": {
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0",
- "word-wrap": "^1.2.3"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "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-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
- "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-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true
- },
- "node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
- },
- "node_modules/pinia": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.14.tgz",
- "integrity": "sha512-0nPuZR4TetT/WcLN+feMSjWJku3SQU7dBbXC6uw+R6FLQJCsg+/0pzXyD82T1FmAYe0lsx+jnEDQ1BLgkRKlxA==",
- "dependencies": {
- "@vue/devtools-api": "^6.1.4",
- "vue-demi": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/posva"
- },
- "peerDependencies": {
- "@vue/composition-api": "^1.4.0",
- "typescript": ">=4.4.4",
- "vue": "^2.6.14 || ^3.2.0"
- },
- "peerDependenciesMeta": {
- "@vue/composition-api": {
- "optional": true
- },
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/pinia/node_modules/vue-demi": {
- "version": "0.12.5",
- "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz",
- "integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==",
- "hasInstallScript": true,
- "bin": {
- "vue-demi-fix": "bin/vue-demi-fix.js",
- "vue-demi-switch": "bin/vue-demi-switch.js"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- },
- "peerDependencies": {
- "@vue/composition-api": "^1.0.0-rc.1",
- "vue": "^3.0.0-0 || ^2.6.0"
- },
- "peerDependenciesMeta": {
- "@vue/composition-api": {
- "optional": true
- }
- }
- },
- "node_modules/postcss": {
- "version": "8.4.13",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.13.tgz",
- "integrity": "sha512-jtL6eTBrza5MPzy8oJLFuUscHDXTV5KcLlqAWHl5q5WYRfnNRGSmOZmOZ1T6Gy7A99mOZfqungmZMpMmCVJ8ZA==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- }
- ],
- "dependencies": {
- "nanoid": "^3.3.3",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-selector-parser": {
- "version": "6.0.10",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
- "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
- "dev": true,
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "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/punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/regexpp": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
- "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.0",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
- "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
- "dev": true,
- "dependencies": {
- "is-core-module": "^2.8.1",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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/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": "2.72.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.72.0.tgz",
- "integrity": "sha512-KqtR2YcO35/KKijg4nx4STO3569aqCUeGRkKWnJ6r+AvBBrVY9L4pmf4NHVrQr4mTOq6msbohflxr2kpihhaOA==",
- "dev": true,
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=10.0.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/semver": {
- "version": "7.3.7",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
- "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "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/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/sourcemap-codec": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
- "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
- },
- "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": "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/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
- "dev": true
- },
- "node_modules/three": {
- "version": "0.140.0",
- "resolved": "https://registry.npmjs.org/three/-/three-0.140.0.tgz",
- "integrity": "sha512-jcHjbnYspPLDdsDQChmzyAoZ5KhJbgFk6pNGlAIc9fQMvsfPGjF5H9glrngqvb2CR/qXcClMyp5PYdF996lldA=="
- },
- "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/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/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
- "dev": true
- },
- "node_modules/v8-compile-cache": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
- "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
- "dev": true
- },
- "node_modules/vite": {
- "version": "2.9.8",
- "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.8.tgz",
- "integrity": "sha512-zsBGwn5UT3YS0NLSJ7hnR54+vUKfgzMUh/Z9CxF1YKEBVIe213+63jrFLmZphgGI5zXwQCSmqIdbPuE8NJywPw==",
- "dev": true,
- "dependencies": {
- "esbuild": "^0.14.27",
- "postcss": "^8.4.13",
- "resolve": "^1.22.0",
- "rollup": "^2.59.0"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": ">=12.2.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- },
- "peerDependencies": {
- "less": "*",
- "sass": "*",
- "stylus": "*"
- },
- "peerDependenciesMeta": {
- "less": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "stylus": {
- "optional": true
- }
- }
- },
- "node_modules/vue": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.33.tgz",
- "integrity": "sha512-si1ExAlDUrLSIg/V7D/GgA4twJwfsfgG+t9w10z38HhL/HA07132pUQ2KuwAo8qbCyMJ9e6OqrmWrOCr+jW7ZQ==",
- "dependencies": {
- "@vue/compiler-dom": "3.2.33",
- "@vue/compiler-sfc": "3.2.33",
- "@vue/runtime-dom": "3.2.33",
- "@vue/server-renderer": "3.2.33",
- "@vue/shared": "3.2.33"
- }
- },
- "node_modules/vue-eslint-parser": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
- "integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==",
- "dev": true,
- "dependencies": {
- "debug": "^4.3.2",
- "eslint-scope": "^7.0.0",
- "eslint-visitor-keys": "^3.1.0",
- "espree": "^9.0.0",
- "esquery": "^1.4.0",
- "lodash": "^4.17.21",
- "semver": "^7.3.5"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- },
- "peerDependencies": {
- "eslint": ">=6.0.0"
- }
- },
- "node_modules/vue-router": {
- "version": "4.0.15",
- "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.15.tgz",
- "integrity": "sha512-xa+pIN9ZqORdIW1MkN2+d9Ui2pCM1b/UMgwYUCZOiFYHAvz/slKKBDha8DLrh5aCG/RibtrpyhKjKOZ85tYyWg==",
- "dependencies": {
- "@vue/devtools-api": "^6.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/posva"
- },
- "peerDependencies": {
- "vue": "^3.2.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/word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
- "dev": true
- },
- "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
- }
- },
- "dependencies": {
- "@babel/parser": {
- "version": "7.17.10",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.10.tgz",
- "integrity": "sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ=="
- },
- "@eslint/eslintrc": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz",
- "integrity": "sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg==",
- "dev": true,
- "requires": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^9.3.1",
- "globals": "^13.9.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.0.4",
- "strip-json-comments": "^3.1.1"
- }
- },
- "@humanwhocodes/config-array": {
- "version": "0.9.5",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
- "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
- "dev": true,
- "requires": {
- "@humanwhocodes/object-schema": "^1.2.1",
- "debug": "^4.1.1",
- "minimatch": "^3.0.4"
- }
- },
- "@humanwhocodes/object-schema": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
- "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
- "dev": true
- },
- "@popperjs/core": {
- "version": "2.11.5",
- "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz",
- "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw=="
- },
- "@vitejs/plugin-vue": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.2.tgz",
- "integrity": "sha512-umyypfSHS4kQLdYAnJHhaASq7FRzNCdvcRoQ3uYGNk1/M4a+hXUd7ysN7BLhCrWH6uBokyCkFeUAaFDzSaaSrQ==",
- "dev": true,
- "requires": {}
- },
- "@vue/compiler-core": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.33.tgz",
- "integrity": "sha512-AAmr52ji3Zhk7IKIuigX2osWWsb2nQE5xsdFYjdnmtQ4gymmqXbjLvkSE174+fF3A3kstYrTgGkqgOEbsdLDpw==",
- "requires": {
- "@babel/parser": "^7.16.4",
- "@vue/shared": "3.2.33",
- "estree-walker": "^2.0.2",
- "source-map": "^0.6.1"
- }
- },
- "@vue/compiler-dom": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.33.tgz",
- "integrity": "sha512-GhiG1C8X98Xz9QUX/RlA6/kgPBWJkjq0Rq6//5XTAGSYrTMBgcLpP9+CnlUg1TFxnnCVughAG+KZl28XJqw8uQ==",
- "requires": {
- "@vue/compiler-core": "3.2.33",
- "@vue/shared": "3.2.33"
- }
- },
- "@vue/compiler-sfc": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.33.tgz",
- "integrity": "sha512-H8D0WqagCr295pQjUYyO8P3IejM3vEzeCO1apzByAEaAR/WimhMYczHfZVvlCE/9yBaEu/eu9RdiWr0kF8b71Q==",
- "requires": {
- "@babel/parser": "^7.16.4",
- "@vue/compiler-core": "3.2.33",
- "@vue/compiler-dom": "3.2.33",
- "@vue/compiler-ssr": "3.2.33",
- "@vue/reactivity-transform": "3.2.33",
- "@vue/shared": "3.2.33",
- "estree-walker": "^2.0.2",
- "magic-string": "^0.25.7",
- "postcss": "^8.1.10",
- "source-map": "^0.6.1"
- }
- },
- "@vue/compiler-ssr": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.33.tgz",
- "integrity": "sha512-XQh1Xdk3VquDpXsnoCd7JnMoWec9CfAzQDQsaMcSU79OrrO2PNR0ErlIjm/mGq3GmBfkQjzZACV+7GhfRB8xMQ==",
- "requires": {
- "@vue/compiler-dom": "3.2.33",
- "@vue/shared": "3.2.33"
- }
- },
- "@vue/devtools-api": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.4.tgz",
- "integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ=="
- },
- "@vue/reactivity": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.33.tgz",
- "integrity": "sha512-62Sq0mp9/0bLmDuxuLD5CIaMG2susFAGARLuZ/5jkU1FCf9EDbwUuF+BO8Ub3Rbodx0ziIecM/NsmyjardBxfQ==",
- "requires": {
- "@vue/shared": "3.2.33"
- }
- },
- "@vue/reactivity-transform": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.33.tgz",
- "integrity": "sha512-4UL5KOIvSQb254aqenW4q34qMXbfZcmEsV/yVidLUgvwYQQ/D21bGX3DlgPUGI3c4C+iOnNmDCkIxkILoX/Pyw==",
- "requires": {
- "@babel/parser": "^7.16.4",
- "@vue/compiler-core": "3.2.33",
- "@vue/shared": "3.2.33",
- "estree-walker": "^2.0.2",
- "magic-string": "^0.25.7"
- }
- },
- "@vue/runtime-core": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.33.tgz",
- "integrity": "sha512-N2D2vfaXsBPhzCV3JsXQa2NECjxP3eXgZlFqKh4tgakp3iX6LCGv76DLlc+IfFZq+TW10Y8QUfeihXOupJ1dGw==",
- "requires": {
- "@vue/reactivity": "3.2.33",
- "@vue/shared": "3.2.33"
- }
- },
- "@vue/runtime-dom": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.33.tgz",
- "integrity": "sha512-LSrJ6W7CZTSUygX5s8aFkraDWlO6K4geOwA3quFF2O+hC3QuAMZt/0Xb7JKE3C4JD4pFwCSO7oCrZmZ0BIJUnw==",
- "requires": {
- "@vue/runtime-core": "3.2.33",
- "@vue/shared": "3.2.33",
- "csstype": "^2.6.8"
- }
- },
- "@vue/server-renderer": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.33.tgz",
- "integrity": "sha512-4jpJHRD4ORv8PlbYi+/MfP8ec1okz6rybe36MdpkDrGIdEItHEUyaHSKvz+ptNEyQpALmmVfRteHkU9F8vxOew==",
- "requires": {
- "@vue/compiler-ssr": "3.2.33",
- "@vue/shared": "3.2.33"
- }
- },
- "@vue/shared": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.33.tgz",
- "integrity": "sha512-UBc1Pg1T3yZ97vsA2ueER0F6GbJebLHYlEi4ou1H5YL4KWvMOOWwpYo9/QpWq93wxKG6Wo13IY74Hcn/f7c7Bg=="
- },
- "acorn": {
- "version": "8.7.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
- "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
- "dev": true
- },
- "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,
- "requires": {}
- },
- "ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- }
- },
- "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
- },
- "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,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "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
- },
- "asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
- },
- "axios": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
- "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
- "requires": {
- "follow-redirects": "^1.14.9",
- "form-data": "^4.0.0"
- }
- },
- "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
- },
- "boolbase": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
- "dev": true
- },
- "bootstrap": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz",
- "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==",
- "requires": {}
- },
- "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,
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "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,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "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
- },
- "combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "requires": {
- "delayed-stream": "~1.0.0"
- }
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
- "dev": true
- },
- "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,
- "requires": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- }
- },
- "cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "dev": true
- },
- "csstype": {
- "version": "2.6.20",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
- "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
- },
- "debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "dev": true,
- "requires": {
- "ms": "2.1.2"
- }
- },
- "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
- },
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
- },
- "doctrine": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
- "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "dev": true,
- "requires": {
- "esutils": "^2.0.2"
- }
- },
- "esbuild": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.38.tgz",
- "integrity": "sha512-12fzJ0fsm7gVZX1YQ1InkOE5f9Tl7cgf6JPYXRJtPIoE0zkWAbHdPHVPPaLi9tYAcEBqheGzqLn/3RdTOyBfcA==",
- "dev": true,
- "requires": {
- "esbuild-android-64": "0.14.38",
- "esbuild-android-arm64": "0.14.38",
- "esbuild-darwin-64": "0.14.38",
- "esbuild-darwin-arm64": "0.14.38",
- "esbuild-freebsd-64": "0.14.38",
- "esbuild-freebsd-arm64": "0.14.38",
- "esbuild-linux-32": "0.14.38",
- "esbuild-linux-64": "0.14.38",
- "esbuild-linux-arm": "0.14.38",
- "esbuild-linux-arm64": "0.14.38",
- "esbuild-linux-mips64le": "0.14.38",
- "esbuild-linux-ppc64le": "0.14.38",
- "esbuild-linux-riscv64": "0.14.38",
- "esbuild-linux-s390x": "0.14.38",
- "esbuild-netbsd-64": "0.14.38",
- "esbuild-openbsd-64": "0.14.38",
- "esbuild-sunos-64": "0.14.38",
- "esbuild-windows-32": "0.14.38",
- "esbuild-windows-64": "0.14.38",
- "esbuild-windows-arm64": "0.14.38"
- }
- },
- "esbuild-android-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.38.tgz",
- "integrity": "sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw==",
- "dev": true,
- "optional": true
- },
- "esbuild-android-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.38.tgz",
- "integrity": "sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA==",
- "dev": true,
- "optional": true
- },
- "esbuild-darwin-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.38.tgz",
- "integrity": "sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA==",
- "dev": true,
- "optional": true
- },
- "esbuild-darwin-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.38.tgz",
- "integrity": "sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ==",
- "dev": true,
- "optional": true
- },
- "esbuild-freebsd-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.38.tgz",
- "integrity": "sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig==",
- "dev": true,
- "optional": true
- },
- "esbuild-freebsd-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.38.tgz",
- "integrity": "sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-32": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.38.tgz",
- "integrity": "sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.38.tgz",
- "integrity": "sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-arm": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.38.tgz",
- "integrity": "sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.38.tgz",
- "integrity": "sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-mips64le": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.38.tgz",
- "integrity": "sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-ppc64le": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.38.tgz",
- "integrity": "sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-riscv64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.38.tgz",
- "integrity": "sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-s390x": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.38.tgz",
- "integrity": "sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ==",
- "dev": true,
- "optional": true
- },
- "esbuild-netbsd-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.38.tgz",
- "integrity": "sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q==",
- "dev": true,
- "optional": true
- },
- "esbuild-openbsd-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.38.tgz",
- "integrity": "sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ==",
- "dev": true,
- "optional": true
- },
- "esbuild-sunos-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.38.tgz",
- "integrity": "sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA==",
- "dev": true,
- "optional": true
- },
- "esbuild-windows-32": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.38.tgz",
- "integrity": "sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw==",
- "dev": true,
- "optional": true
- },
- "esbuild-windows-64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.38.tgz",
- "integrity": "sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw==",
- "dev": true,
- "optional": true
- },
- "esbuild-windows-arm64": {
- "version": "0.14.38",
- "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.38.tgz",
- "integrity": "sha512-k3FGCNmHBkqdJXuJszdWciAH77PukEyDsdIryEHn9cKLQFxzhT39dSumeTuggaQcXY57UlmLGIkklWZo2qzHpw==",
- "dev": true,
- "optional": true
- },
- "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
- },
- "eslint": {
- "version": "8.14.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.14.0.tgz",
- "integrity": "sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw==",
- "dev": true,
- "requires": {
- "@eslint/eslintrc": "^1.2.2",
- "@humanwhocodes/config-array": "^0.9.2",
- "ajv": "^6.10.0",
- "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.1.1",
- "eslint-utils": "^3.0.0",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
- "esquery": "^1.4.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
- "functional-red-black-tree": "^1.0.1",
- "glob-parent": "^6.0.1",
- "globals": "^13.6.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.0.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "js-yaml": "^4.1.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.0.4",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.1",
- "regexpp": "^3.2.0",
- "strip-ansi": "^6.0.1",
- "strip-json-comments": "^3.1.0",
- "text-table": "^0.2.0",
- "v8-compile-cache": "^2.0.3"
- }
- },
- "eslint-plugin-vue": {
- "version": "8.7.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz",
- "integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==",
- "dev": true,
- "requires": {
- "eslint-utils": "^3.0.0",
- "natural-compare": "^1.4.0",
- "nth-check": "^2.0.1",
- "postcss-selector-parser": "^6.0.9",
- "semver": "^7.3.5",
- "vue-eslint-parser": "^8.0.1"
- }
- },
- "eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
- "dev": true,
- "requires": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- }
- },
- "eslint-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
- "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
- "dev": true,
- "requires": {
- "eslint-visitor-keys": "^2.0.0"
- },
- "dependencies": {
- "eslint-visitor-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
- "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
- "dev": true
- }
- }
- },
- "eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "dev": true
- },
- "espree": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz",
- "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==",
- "dev": true,
- "requires": {
- "acorn": "^8.7.0",
- "acorn-jsx": "^5.3.1",
- "eslint-visitor-keys": "^3.3.0"
- }
- },
- "esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
- "dev": true,
- "requires": {
- "estraverse": "^5.1.0"
- }
- },
- "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,
- "requires": {
- "estraverse": "^5.2.0"
- }
- },
- "estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true
- },
- "estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
- },
- "esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true
- },
- "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
- },
- "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
- },
- "fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
- "dev": true
- },
- "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,
- "requires": {
- "flat-cache": "^3.0.4"
- }
- },
- "flat-cache": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
- "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
- "dev": true,
- "requires": {
- "flatted": "^3.1.0",
- "rimraf": "^3.0.2"
- }
- },
- "flatted": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
- "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
- "dev": true
- },
- "follow-redirects": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz",
- "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ=="
- },
- "form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
- "dev": true
- },
- "fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "optional": true
- },
- "function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "dev": true
- },
- "functional-red-black-tree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
- "dev": true
- },
- "glob": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
- "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
- "dev": true,
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "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,
- "requires": {
- "is-glob": "^4.0.3"
- }
- },
- "globals": {
- "version": "13.13.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz",
- "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==",
- "dev": true,
- "requires": {
- "type-fest": "^0.20.2"
- }
- },
- "has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "dev": true,
- "requires": {
- "function-bind": "^1.1.1"
- }
- },
- "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
- },
- "ignore": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
- "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
- "dev": true
- },
- "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,
- "requires": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- }
- },
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
- "dev": true
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "dev": true,
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
- },
- "is-core-module": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
- "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
- "dev": true,
- "requires": {
- "has": "^1.0.3"
- }
- },
- "is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "dev": true
- },
- "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,
- "requires": {
- "is-extglob": "^2.1.1"
- }
- },
- "isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
- "dev": true
- },
- "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,
- "requires": {
- "argparse": "^2.0.1"
- }
- },
- "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
- },
- "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
- "dev": true
- },
- "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,
- "requires": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- }
- },
- "lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "dev": true
- },
- "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
- },
- "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,
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "magic-string": {
- "version": "0.25.9",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
- "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
- "requires": {
- "sourcemap-codec": "^1.4.8"
- }
- },
- "mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
- },
- "mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "requires": {
- "mime-db": "1.52.0"
- }
- },
- "minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "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
- },
- "nanoid": {
- "version": "3.3.4",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
- "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
- },
- "natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
- "dev": true
- },
- "nth-check": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
- "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
- "dev": true,
- "requires": {
- "boolbase": "^1.0.0"
- }
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "dev": true,
- "requires": {
- "wrappy": "1"
- }
- },
- "optionator": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
- "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
- "dev": true,
- "requires": {
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0",
- "word-wrap": "^1.2.3"
- }
- },
- "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,
- "requires": {
- "callsites": "^3.0.0"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
- "dev": true
- },
- "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
- },
- "path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true
- },
- "picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
- },
- "pinia": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.14.tgz",
- "integrity": "sha512-0nPuZR4TetT/WcLN+feMSjWJku3SQU7dBbXC6uw+R6FLQJCsg+/0pzXyD82T1FmAYe0lsx+jnEDQ1BLgkRKlxA==",
- "requires": {
- "@vue/devtools-api": "^6.1.4",
- "vue-demi": "*"
- },
- "dependencies": {
- "vue-demi": {
- "version": "0.12.5",
- "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz",
- "integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==",
- "requires": {}
- }
- }
- },
- "postcss": {
- "version": "8.4.13",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.13.tgz",
- "integrity": "sha512-jtL6eTBrza5MPzy8oJLFuUscHDXTV5KcLlqAWHl5q5WYRfnNRGSmOZmOZ1T6Gy7A99mOZfqungmZMpMmCVJ8ZA==",
- "requires": {
- "nanoid": "^3.3.3",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- }
- },
- "postcss-selector-parser": {
- "version": "6.0.10",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
- "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
- "dev": true,
- "requires": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- }
- },
- "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
- },
- "punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
- "dev": true
- },
- "regexpp": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
- "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
- "dev": true
- },
- "resolve": {
- "version": "1.22.0",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
- "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
- "dev": true,
- "requires": {
- "is-core-module": "^2.8.1",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- }
- },
- "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
- },
- "rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "requires": {
- "glob": "^7.1.3"
- }
- },
- "rollup": {
- "version": "2.72.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.72.0.tgz",
- "integrity": "sha512-KqtR2YcO35/KKijg4nx4STO3569aqCUeGRkKWnJ6r+AvBBrVY9L4pmf4NHVrQr4mTOq6msbohflxr2kpihhaOA==",
- "dev": true,
- "requires": {
- "fsevents": "~2.3.2"
- }
- },
- "semver": {
- "version": "7.3.7",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
- "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
- "dev": true,
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "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,
- "requires": {
- "shebang-regex": "^3.0.0"
- }
- },
- "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
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- },
- "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=="
- },
- "sourcemap-codec": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
- "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
- },
- "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,
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- },
- "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
- },
- "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,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true
- },
- "text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
- "dev": true
- },
- "three": {
- "version": "0.140.0",
- "resolved": "https://registry.npmjs.org/three/-/three-0.140.0.tgz",
- "integrity": "sha512-jcHjbnYspPLDdsDQChmzyAoZ5KhJbgFk6pNGlAIc9fQMvsfPGjF5H9glrngqvb2CR/qXcClMyp5PYdF996lldA=="
- },
- "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,
- "requires": {
- "prelude-ls": "^1.2.1"
- }
- },
- "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
- },
- "uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "requires": {
- "punycode": "^2.1.0"
- }
- },
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
- "dev": true
- },
- "v8-compile-cache": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
- "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
- "dev": true
- },
- "vite": {
- "version": "2.9.8",
- "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.8.tgz",
- "integrity": "sha512-zsBGwn5UT3YS0NLSJ7hnR54+vUKfgzMUh/Z9CxF1YKEBVIe213+63jrFLmZphgGI5zXwQCSmqIdbPuE8NJywPw==",
- "dev": true,
- "requires": {
- "esbuild": "^0.14.27",
- "fsevents": "~2.3.2",
- "postcss": "^8.4.13",
- "resolve": "^1.22.0",
- "rollup": "^2.59.0"
- }
- },
- "vue": {
- "version": "3.2.33",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.33.tgz",
- "integrity": "sha512-si1ExAlDUrLSIg/V7D/GgA4twJwfsfgG+t9w10z38HhL/HA07132pUQ2KuwAo8qbCyMJ9e6OqrmWrOCr+jW7ZQ==",
- "requires": {
- "@vue/compiler-dom": "3.2.33",
- "@vue/compiler-sfc": "3.2.33",
- "@vue/runtime-dom": "3.2.33",
- "@vue/server-renderer": "3.2.33",
- "@vue/shared": "3.2.33"
- }
- },
- "vue-eslint-parser": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
- "integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==",
- "dev": true,
- "requires": {
- "debug": "^4.3.2",
- "eslint-scope": "^7.0.0",
- "eslint-visitor-keys": "^3.1.0",
- "espree": "^9.0.0",
- "esquery": "^1.4.0",
- "lodash": "^4.17.21",
- "semver": "^7.3.5"
- }
- },
- "vue-router": {
- "version": "4.0.15",
- "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.15.tgz",
- "integrity": "sha512-xa+pIN9ZqORdIW1MkN2+d9Ui2pCM1b/UMgwYUCZOiFYHAvz/slKKBDha8DLrh5aCG/RibtrpyhKjKOZ85tYyWg==",
- "requires": {
- "@vue/devtools-api": "^6.0.0"
- }
- },
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
- },
- "word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
- "dev": true
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
- "dev": true
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- }
- }
-}
diff --git a/railsignal-app/package.json b/railsignal-app/package.json
deleted file mode 100644
index 65879a2..0000000
--- a/railsignal-app/package.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "name": "railsignal-app",
- "version": "0.0.0",
- "scripts": {
- "dev": "vite",
- "build": "vite build --base=/app/ --mode=development",
- "preview": "vite preview --port 5050",
- "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
- },
- "dependencies": {
- "@popperjs/core": "^2.11.5",
- "axios": "^0.27.2",
- "bootstrap": "^5.1.3",
- "pinia": "^2.0.14",
- "three": "^0.140.0",
- "vue": "^3.2.33",
- "vue-router": "^4.0.14"
- },
- "devDependencies": {
- "@vitejs/plugin-vue": "^2.3.2",
- "eslint": "^8.5.0",
- "eslint-plugin-vue": "^8.2.0",
- "vite": "^2.9.8"
- }
-}
diff --git a/railsignal-app/public/android-chrome-192x192.png b/railsignal-app/public/android-chrome-192x192.png
deleted file mode 100644
index 8805d9e..0000000
Binary files a/railsignal-app/public/android-chrome-192x192.png and /dev/null differ
diff --git a/railsignal-app/public/android-chrome-512x512.png b/railsignal-app/public/android-chrome-512x512.png
deleted file mode 100644
index cdaaf8f..0000000
Binary files a/railsignal-app/public/android-chrome-512x512.png and /dev/null differ
diff --git a/railsignal-app/public/apple-touch-icon.png b/railsignal-app/public/apple-touch-icon.png
deleted file mode 100644
index 2d3fad7..0000000
Binary files a/railsignal-app/public/apple-touch-icon.png and /dev/null differ
diff --git a/railsignal-app/public/favicon-16x16.png b/railsignal-app/public/favicon-16x16.png
deleted file mode 100644
index 04cca12..0000000
Binary files a/railsignal-app/public/favicon-16x16.png and /dev/null differ
diff --git a/railsignal-app/public/favicon-32x32.png b/railsignal-app/public/favicon-32x32.png
deleted file mode 100644
index f6c9b79..0000000
Binary files a/railsignal-app/public/favicon-32x32.png and /dev/null differ
diff --git a/railsignal-app/public/favicon.ico b/railsignal-app/public/favicon.ico
deleted file mode 100644
index e6e52ff..0000000
Binary files a/railsignal-app/public/favicon.ico and /dev/null differ
diff --git a/railsignal-app/public/site.webmanifest b/railsignal-app/public/site.webmanifest
deleted file mode 100644
index 45dc8a2..0000000
--- a/railsignal-app/public/site.webmanifest
+++ /dev/null
@@ -1 +0,0 @@
-{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
\ No newline at end of file
diff --git a/railsignal-app/src/App.vue b/railsignal-app/src/App.vue
deleted file mode 100644
index bce83e1..0000000
--- a/railsignal-app/src/App.vue
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/railsignal-app/src/api/components.js b/railsignal-app/src/api/components.js
deleted file mode 100644
index 57268cb..0000000
--- a/railsignal-app/src/api/components.js
+++ /dev/null
@@ -1,101 +0,0 @@
-import axios from "axios";
-import {API_URL} from "./constants";
-
-export function refreshComponents(rs) {
- return new Promise((resolve, reject) => {
- axios.get(`${API_URL}/rs/${rs.id}/c`)
- .then(response => {
- const previousSelectedComponentId = rs.selectedComponent ? rs.selectedComponent.id : null;
- rs.components = response.data;
- if (previousSelectedComponentId !== null) {
- const previousComponent = rs.components.find(c => c.id === previousSelectedComponentId);
- if (previousComponent) {
- rs.selectedComponent = previousComponent;
- } else {
- rs.selectedComponent = null;
- }
- } else {
- rs.selectedComponent = null;
- }
- resolve();
- })
- .catch(reject);
- });
-}
-
-export function refreshSomeComponents(rs, components) {
- const promises = [];
- for (let i = 0; i < components.length; i++) {
- const promise = new Promise((resolve, reject) => {
- axios.get(`${API_URL}/rs/${rs.id}/c/${components[i].id}`)
- .then(resp => {
- const idx = rs.components.findIndex(c => c.id === resp.data.id);
- if (idx > -1) rs.components[idx] = resp.data;
- resolve();
- })
- .catch(reject);
- });
- promises.push(promise);
- }
- return Promise.all(promises);
-}
-
-export function getComponent(rs, id) {
- return new Promise((resolve, reject) => {
- axios.get(`${this.apiUrl}/rs/${rs.id}/c/${id}`)
- .then(response => resolve(response.data))
- .catch(reject);
- });
-}
-
-/**
- * Searches through the rail system's components.
- * @param {RailSystem} rs
- * @param {string|null} searchQuery
- * @return {Promise}
- */
-export function searchComponents(rs, searchQuery) {
- return new Promise((resolve, reject) => {
- const params = {
- page: 0,
- size: 25
- };
- if (searchQuery) params.q = searchQuery;
- axios.get(`${API_URL}/rs/${rs.id}/c/search`, {params: params})
- .then(response => {
- resolve(response.data);
- })
- .catch(reject);
- });
-}
-
-export function createComponent(rs, data) {
- return new Promise((resolve, reject) => {
- axios.post(`${API_URL}/rs/${rs.id}/c`, data)
- .then(response => {
- const newComponentId = response.data.id;
- refreshComponents(rs)
- .then(() => {
- const newComponent = rs.components.find(c => c.id === newComponentId);
- if (newComponent) {
- rs.selectedComponent = newComponent;
- }
- resolve();
- })
- .catch(reject);
- })
- .catch(reject);
- });
-}
-
-export function removeComponent(rs, id) {
- return new Promise((resolve, reject) => {
- axios.delete(`${API_URL}/rs/${rs.id}/c/${id}`)
- .then(() => {
- refreshComponents(rs)
- .then(resolve)
- .catch(reject);
- })
- .catch(reject);
- });
-}
diff --git a/railsignal-app/src/api/constants.js b/railsignal-app/src/api/constants.js
deleted file mode 100644
index 51239b5..0000000
--- a/railsignal-app/src/api/constants.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export const API_URL = import.meta.env.VITE_API_URL;
-export const WS_URL = import.meta.env.VITE_WS_URL;
\ No newline at end of file
diff --git a/railsignal-app/src/api/linkTokens.js b/railsignal-app/src/api/linkTokens.js
deleted file mode 100644
index 38e601c..0000000
--- a/railsignal-app/src/api/linkTokens.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import {API_URL} from "./constants";
-import axios from "axios";
-
-/**
- * A token that's used by components to provide real-time up and down links.
- */
-export class LinkToken {
- constructor(data) {
- this.id = data.id;
- this.label = data.label;
- this.components = data.components;
- }
-}
-
-/**
- * Gets the list of link tokens in a rail system.
- * @param {RailSystem} rs
- * @return {Promise}
- */
-export function getTokens(rs) {
- return new Promise((resolve, reject) => {
- axios.get(`${API_URL}/rs/${rs.id}/lt`)
- .then(response => {
- resolve(response.data.map(obj => new LinkToken(obj)));
- })
- .catch(reject);
- });
-}
-
-/**
- * Creates a new link token.
- * @param {RailSystem} rs
- * @param {LinkToken} data
- * @return {Promise} A promise that resolves to the token that was created.
- */
-export function createLinkToken(rs, data) {
- return new Promise((resolve, reject) => {
- axios.post(`${API_URL}/rs/${rs.id}/lt`, data)
- .then(response => {
- resolve(response.data.token);
- })
- .catch(reject);
- });
-}
-
-/**
- * Deletes a link token.
- * @param {RailSystem} rs
- * @param {Number} tokenId
- */
-export function deleteToken(rs, tokenId) {
- return new Promise((resolve, reject) => {
- axios.delete(`${API_URL}/rs/${rs.id}/lt/${tokenId}`)
- .then(resolve)
- .catch(reject);
- });
-}
\ No newline at end of file
diff --git a/railsignal-app/src/api/paths.js b/railsignal-app/src/api/paths.js
deleted file mode 100644
index 0e2db39..0000000
--- a/railsignal-app/src/api/paths.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import axios from "axios";
-import {API_URL} from "./constants";
-import {refreshSomeComponents} from "./components";
-
-/**
- * Updates the connections to a path node.
- * @param {RailSystem} rs The rail system to which the node belongs.
- * @param {Object} node The node to update.
- * @returns {Promise}
- */
-export function updateConnections(rs, node) {
- return new Promise((resolve, reject) => {
- axios.patch(
- `${API_URL}/rs/${rs.id}/c/${node.id}/connectedNodes`,
- node
- )
- .then(response => {
- node.connectedNodes = response.data.connectedNodes;
- resolve();
- })
- .catch(reject);
- });
-}
-
-/**
- * Adds a connection to a path node.
- * @param {RailSystem} rs
- * @param {Object} node
- * @param {Object} other
- * @returns {Promise}
- */
-export function addConnection(rs, node, other) {
- node.connectedNodes.push(other);
- return updateConnections(rs, node);
-}
-
-/**
- * Removes a connection from a path node.
- * @param {RailSystem} rs
- * @param {Object} node
- * @param {Object} other
- * @returns {Promise}
- */
-export function removeConnection(rs, node, other) {
- const idx = node.connectedNodes.findIndex(n => n.id === other.id);
- return new Promise((resolve, reject) => {
- if (idx > -1) {
- node.connectedNodes.splice(idx, 1);
- updateConnections(rs, node)
- .then(() => {
- const nodes = [];
- nodes.push(...node.connectedNodes);
- nodes.push(other);
- refreshSomeComponents(rs, nodes)
- .then(resolve)
- .catch(reject);
- })
- .catch(reject);
- } else {
- resolve();
- }
- });
-
-}
\ No newline at end of file
diff --git a/railsignal-app/src/api/railSystems.js b/railsignal-app/src/api/railSystems.js
deleted file mode 100644
index c01c1d9..0000000
--- a/railsignal-app/src/api/railSystems.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import axios from "axios";
-import {API_URL} from "./constants";
-
-export class RailSystem {
- constructor(data) {
- this.id = data.id;
- this.name = data.name;
- this.segments = [];
- this.components = [];
- this.websocket = null;
- this.selectedComponent = null;
- }
-}
-
-export function refreshRailSystems(rsStore) {
- return new Promise(resolve => {
- axios.get(`${API_URL}/rs`)
- .then(response => {
- const rsItems = response.data;
- rsStore.railSystems.length = 0;
- for (let i = 0; i < rsItems.length; i++) {
- rsStore.railSystems.push(new RailSystem(rsItems[i]));
- }
- resolve();
- })
- .catch(error => console.error(error));
- })
-}
-
-export function createRailSystem(rsStore, name) {
- return new Promise((resolve, reject) => {
- axios.post(`${API_URL}/rs`, {name: name})
- .then(response => {
- const newId = response.data.id;
- refreshRailSystems(rsStore)
- .then(() => resolve(rsStore.railSystems.find(rs => rs.id === newId)))
- .catch(error => reject(error));
- })
- .catch(error => reject(error));
- });
-}
-
-export function removeRailSystem(rsStore, id) {
- return new Promise((resolve, reject) => {
- axios.delete(`${API_URL}/rs/${id}`)
- .then(() => {
- rsStore.selectedRailSystem = null;
- refreshRailSystems(rsStore)
- .then(() => resolve)
- .catch(error => reject(error));
- });
- });
-}
diff --git a/railsignal-app/src/api/segments.js b/railsignal-app/src/api/segments.js
deleted file mode 100644
index c49e0ec..0000000
--- a/railsignal-app/src/api/segments.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import axios from "axios";
-import {API_URL} from "./constants";
-
-/**
- * Fetches the set of segments for a rail system.
- * @param {Number} rsId
- * @returns {Promise<[Object]>}
- */
-export function getSegments(rsId) {
- return new Promise((resolve, reject) => {
- axios.get(`${API_URL}/rs/${rsId}/s`)
- .then(response => resolve(response.data))
- .catch(error => reject(error));
- });
-}
-
-export function refreshSegments(rs) {
- return new Promise(resolve => {
- getSegments(rs.id)
- .then(segments => {
- rs.segments = segments;
- resolve();
- })
- .catch(error => console.error(error));
- });
-}
-
-export function createSegment(rs, name) {
- return new Promise((resolve, reject) => {
- axios.post(`${API_URL}/rs/${rs.id}/s`, {name: name})
- .then(() => {
- refreshSegments(rs)
- .then(() => resolve())
- .catch(error => reject(error));
- })
- .catch(error => reject(error));
- });
-}
-
-export function removeSegment(rs, segmentId) {
- return new Promise((resolve, reject) => {
- axios.delete(`${API_URL}/rs/${rs.id}/${segmentId}`)
- .then(() => {
- refreshSegments(rs)
- .then(() => resolve())
- .catch(error => reject(error));
- })
- .catch(error => reject(error));
- });
-}
diff --git a/railsignal-app/src/api/websocket.js b/railsignal-app/src/api/websocket.js
deleted file mode 100644
index 741c548..0000000
--- a/railsignal-app/src/api/websocket.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import {WS_URL} from "./constants";
-
-/**
- * Establishes a websocket connection to the given rail system.
- * @param {RailSystem} rs
- */
-export function establishWebsocketConnection(rs) {
- closeWebsocketConnection(rs);
- rs.websocket = new WebSocket(`${WS_URL}/${rs.id}`);
- rs.websocket.onopen = () => {
- console.log("Opened websocket connection to rail system " + rs.id);
- };
- rs.websocket.onclose = event => {
- if (event.code !== 1000) {
- console.warn("Lost websocket connection. Attempting to reestablish.");
- setTimeout(() => {
- establishWebsocketConnection(rs);
- }, 3000);
- }
- console.log("Closed websocket connection to rail system " + rs.id);
- };
- rs.websocket.onmessage = msg => {
- console.log(msg);
- };
- rs.websocket.onerror = error => {
- console.log(error);
- };
-}
-
-/**
- * Closes the websocket connection to a rail system, if possible.
- * @param {RailSystem} rs
- */
-export function closeWebsocketConnection(rs) {
- if (rs.websocket) {
- rs.websocket.close();
- rs.websocket = null;
- }
-}
diff --git a/railsignal-app/src/assets/icon.png b/railsignal-app/src/assets/icon.png
deleted file mode 100644
index 3c98a5e..0000000
Binary files a/railsignal-app/src/assets/icon.png and /dev/null differ
diff --git a/railsignal-app/src/assets/icon.svg b/railsignal-app/src/assets/icon.svg
deleted file mode 100644
index 2684f47..0000000
--- a/railsignal-app/src/assets/icon.svg
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-
-
-
-
-
-
-
- image/svg+xml
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/railsignal-app/src/components/AppNavbar.vue b/railsignal-app/src/components/AppNavbar.vue
deleted file mode 100644
index b946953..0000000
--- a/railsignal-app/src/components/AppNavbar.vue
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
-
-
- Rail Signal
-
-
-
-
-
-
-
-
-
- {{rs.name}}
-
-
-
-
-
- Remove this Rail System
-
-
-
-
- Add Rail System
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/ConfirmModal.vue b/railsignal-app/src/components/ConfirmModal.vue
deleted file mode 100644
index 9df94b8..0000000
--- a/railsignal-app/src/components/ConfirmModal.vue
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/RailSystem.vue b/railsignal-app/src/components/RailSystem.vue
deleted file mode 100644
index a7870e8..0000000
--- a/railsignal-app/src/components/RailSystem.vue
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
diff --git a/railsignal-app/src/components/railsystem/AddRailSystemModal.vue b/railsignal-app/src/components/railsystem/AddRailSystemModal.vue
deleted file mode 100644
index 0289ace..0000000
--- a/railsignal-app/src/components/railsystem/AddRailSystemModal.vue
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/AddSegmentModal.vue b/railsignal-app/src/components/railsystem/AddSegmentModal.vue
deleted file mode 100644
index 7cc8aa3..0000000
--- a/railsignal-app/src/components/railsystem/AddSegmentModal.vue
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
-
-
-
-
- Add a new segment to this rail system. A segment is the
- basic organizational unit of any rail system. It is a section of
- the network that signals can monitor, and segment boundary nodes
- define the extent of the segment, and monitor trains entering and
- leaving the segment.
-
-
- You can think of a segment as a single, secure block of of the rail
- network that only one train may pass through at once. For example,
- a junction or station siding.
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/CreateLinkTokenModal.vue b/railsignal-app/src/components/railsystem/CreateLinkTokenModal.vue
deleted file mode 100644
index 746380f..0000000
--- a/railsignal-app/src/components/railsystem/CreateLinkTokenModal.vue
+++ /dev/null
@@ -1,115 +0,0 @@
-
-
-
-
-
-
-
- Create a link token to link components in this rail system
- to actual devices in your system, so your world can talk to this
- system. Each link token should have a unique label that can be used
- to identify it, and a list of components that it's linked to.
-
-
- Note that for security purposes, the raw token that's generated is
- only shown once, and is never available again. If you lose the
- token, you must create a new one instead and delete the old one.
-
-
-
-
- Created token: {{token}}
-
- Copy this token now; it will not be shown again.
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/MapView.vue b/railsignal-app/src/components/railsystem/MapView.vue
deleted file mode 100644
index 3ce9e1a..0000000
--- a/railsignal-app/src/components/railsystem/MapView.vue
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
- Your browser doesn't support canvas!
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/RailSystemPropertiesView.vue b/railsignal-app/src/components/railsystem/RailSystemPropertiesView.vue
deleted file mode 100644
index a7e25e8..0000000
--- a/railsignal-app/src/components/railsystem/RailSystemPropertiesView.vue
+++ /dev/null
@@ -1,112 +0,0 @@
-
- Rail System: {{railSystem.name}}
-
-
-
- Add Component
-
-
-
-
-
- Create Link Token
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/SegmentsView.vue b/railsignal-app/src/components/railsystem/SegmentsView.vue
deleted file mode 100644
index 8b4fe0a..0000000
--- a/railsignal-app/src/components/railsystem/SegmentsView.vue
+++ /dev/null
@@ -1,52 +0,0 @@
-
- Segments
-
-
-
- {{segment.name}}
- Remove
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/canvasUtils.js b/railsignal-app/src/components/railsystem/canvasUtils.js
deleted file mode 100644
index 726b394..0000000
--- a/railsignal-app/src/components/railsystem/canvasUtils.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export function roundedRect(ctx, x, y, w, h, r) {
- if (w < 2 * r) r = w / 2;
- if (h < 2 * r) r = h / 2;
- ctx.beginPath();
- ctx.moveTo(x+r, y);
- ctx.arcTo(x+w, y, x+w, y+h, r);
- ctx.arcTo(x+w, y+h, x, y+h, r);
- ctx.arcTo(x, y+h, x, y, r);
- ctx.arcTo(x, y, x+w, y, r);
- ctx.closePath();
-}
-
-export function circle(ctx, x, y, r) {
- ctx.beginPath();
- ctx.arc(x, y, r, 0, Math.PI * 2);
-}
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/component/AddSegmentBoundaryModal.vue b/railsignal-app/src/components/railsystem/component/AddSegmentBoundaryModal.vue
deleted file mode 100644
index 9ce6272..0000000
--- a/railsignal-app/src/components/railsystem/component/AddSegmentBoundaryModal.vue
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
-
-
- A segment boundary is a component that defines a link
- between one segment and another. This component can be used to
- monitor trains entering and exiting the connected segments. Usually
- used in conjunction with signals for classic railway signalling
- systems.
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/component/AddSignalModal.vue b/railsignal-app/src/components/railsystem/component/AddSignalModal.vue
deleted file mode 100644
index 863eada..0000000
--- a/railsignal-app/src/components/railsystem/component/AddSignalModal.vue
+++ /dev/null
@@ -1,99 +0,0 @@
-
-
-
-
-
-
-
- A signal is a component that relays information about your
- rail system to in-world devices. Classically, rail signals show a
- lamp indicator to tell information about the segment of the network
- they're attached to.
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/component/AddSwitchModal.vue b/railsignal-app/src/components/railsystem/component/AddSwitchModal.vue
deleted file mode 100644
index 4c8ac54..0000000
--- a/railsignal-app/src/components/railsystem/component/AddSwitchModal.vue
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/component/ComponentView.vue b/railsignal-app/src/components/railsystem/component/ComponentView.vue
deleted file mode 100644
index fdfb31c..0000000
--- a/railsignal-app/src/components/railsystem/component/ComponentView.vue
+++ /dev/null
@@ -1,88 +0,0 @@
-
-
-
{{component.name}}
-
- {{component.type}}
-
-
-
-
- Id {{component.id}}
-
-
- Position
-
-
-
-
- X = {{component.position.x}}
- Y = {{component.position.y}}
- Z = {{component.position.z}}
-
-
-
-
-
-
-
-
-
-
-
-
Remove
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/component/PathNodeComponentView.vue b/railsignal-app/src/components/railsystem/component/PathNodeComponentView.vue
deleted file mode 100644
index 422547a..0000000
--- a/railsignal-app/src/components/railsystem/component/PathNodeComponentView.vue
+++ /dev/null
@@ -1,84 +0,0 @@
-
- Connected Nodes
-
-
- {{node.name}}
-
- Remove
-
-
-
-
- There are no connected nodes.
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/component/SegmentBoundaryNodeComponentView.vue b/railsignal-app/src/components/railsystem/component/SegmentBoundaryNodeComponentView.vue
deleted file mode 100644
index 672e3e4..0000000
--- a/railsignal-app/src/components/railsystem/component/SegmentBoundaryNodeComponentView.vue
+++ /dev/null
@@ -1,28 +0,0 @@
-
- Segments Connected
-
-
- {{segment.name}}
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/component/SignalComponentView.vue b/railsignal-app/src/components/railsystem/component/SignalComponentView.vue
deleted file mode 100644
index 5f7c9dc..0000000
--- a/railsignal-app/src/components/railsystem/component/SignalComponentView.vue
+++ /dev/null
@@ -1,27 +0,0 @@
-
- Signal Properties
-
-
-
- Connected to
- {{signal.segment.name}}, Occupied: {{signal.segment.occupied}}
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/component/SwitchComponentView.vue b/railsignal-app/src/components/railsystem/component/SwitchComponentView.vue
deleted file mode 100644
index f6b4e68..0000000
--- a/railsignal-app/src/components/railsystem/component/SwitchComponentView.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-
- Switch Configurations
-
-
-
- {{node.name}}
-
-
- Active
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/components/railsystem/drawing.js b/railsignal-app/src/components/railsystem/drawing.js
deleted file mode 100644
index b32f834..0000000
--- a/railsignal-app/src/components/railsystem/drawing.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
-Helper functions to actually perform rendering of different components.
-*/
-
-import {getScaleFactor, isComponentHovered} from "./mapRenderer";
-import {roundedRect, circle} from "./canvasUtils";
-
-export function drawComponent(ctx, worldTx, component) {
- const tx = DOMMatrix.fromMatrix(worldTx);
- tx.translateSelf(component.position.x, component.position.z, 0);
- const s = getScaleFactor();
- tx.scaleSelf(1/s, 1/s, 1/s);
- tx.scaleSelf(20, 20, 20);
- ctx.setTransform(tx);
-
- if (component.type === "SIGNAL") {
- drawSignal(ctx, component);
- } else if (component.type === "SEGMENT_BOUNDARY") {
- drawSegmentBoundary(ctx, component);
- } else if (component.type === "SWITCH") {
- drawSwitch(ctx, component);
- }
-
- ctx.setTransform(tx.translate(0.75, -0.75));
- if (component.online !== undefined && component.online !== null) {
- drawOnlineIndicator(ctx, component);
- }
-
- ctx.setTransform(tx);
- // Draw hovered status.
- if (isComponentHovered(component)) {
- ctx.fillStyle = `rgba(255, 255, 0, 0.5)`;
- circle(ctx, 0, 0, 0.75);
- ctx.fill();
- }
-}
-
-function drawSignal(ctx) {
- roundedRect(ctx, -0.3, -0.5, 0.6, 1, 0.25);
- ctx.fillStyle = "black";
- ctx.fill();
- ctx.fillStyle = "rgb(0, 255, 0)";
- circle(ctx, 0, -0.2, 0.15);
- ctx.fill();
-}
-
-function drawSegmentBoundary(ctx) {
- ctx.fillStyle = `rgb(150, 58, 224)`;
- ctx.beginPath();
- ctx.moveTo(0, -0.5);
- ctx.lineTo(-0.5, 0);
- ctx.lineTo(0, 0.5);
- ctx.lineTo(0.5, 0);
- ctx.lineTo(0, -0.5);
- ctx.fill();
-}
-
-function drawSwitch(ctx, sw) {
- const colors = [
- `rgba(61, 148, 66, 0.25)`,
- `rgba(59, 22, 135, 0.25)`,
- `rgba(145, 17, 90, 0.25)`,
- `rgba(191, 49, 10, 0.25)`
- ];
- ctx.lineWidth = 1;
- for (let i = 0; i < sw.possibleConfigurations.length; i++) {
- const config = sw.possibleConfigurations[i];
- ctx.strokeStyle = colors[i];
- for (let j = 0; j < config.nodes.length; j++) {
- const node = config.nodes[j];
- const diff = {
- x: sw.position.x - node.position.x,
- y: sw.position.z - node.position.z,
- };
- const mag = Math.sqrt(Math.pow(diff.x, 2) + Math.pow(diff.y, 2));
- diff.x = 2 * -diff.x / mag;
- diff.y = 2 * -diff.y / mag;
- ctx.beginPath();
- ctx.moveTo(0, 0);
- ctx.lineTo(diff.x, diff.y);
- ctx.stroke();
- }
- }
- ctx.fillStyle = `rgb(245, 188, 66)`;
- ctx.strokeStyle = `rgb(245, 188, 66)`;
- ctx.lineWidth = 0.2;
- circle(ctx, 0, 0.3, 0.2);
- ctx.fill();
- circle(ctx, -0.3, -0.3, 0.2);
- ctx.fill();
- circle(ctx, 0.3, -0.3, 0.2);
- ctx.fill();
- ctx.beginPath();
- ctx.moveTo(0, 0.3);
- ctx.lineTo(0, 0);
- ctx.lineTo(0.3, -0.3);
- ctx.moveTo(0, 0);
- ctx.lineTo(-0.3, -0.3);
- ctx.stroke();
-}
-
-function drawOnlineIndicator(ctx, component) {
- ctx.lineWidth = 0.1;
- if (component.online) {
- ctx.fillStyle = `rgba(52, 174, 235, 128)`;
- ctx.strokeStyle = `rgba(52, 174, 235, 128)`;
- } else {
- ctx.fillStyle = `rgba(153, 153, 153, 128)`;
- ctx.strokeStyle = `rgba(153, 153, 153, 128)`;
- }
- ctx.beginPath();
- ctx.arc(0, 0.2, 0.125, 0, Math.PI * 2);
- ctx.fill();
- for (let r = 0; r < 3; r++) {
- ctx.beginPath();
- ctx.arc(0, 0, 0.1 + 0.2 * r, 7 * Math.PI / 6, 11 * Math.PI / 6);
- ctx.stroke();
- }
-}
-
-export function drawConnectedNodes(ctx, worldTx, component) {
- const s = getScaleFactor();
- ctx.lineWidth = 5 / s;
- ctx.strokeStyle = "black";
- for (let i = 0; i < component.connectedNodes.length; i++) {
- const node = component.connectedNodes[i];
- ctx.beginPath();
- ctx.moveTo(component.position.x, component.position.z);
- ctx.lineTo(node.position.x, node.position.z);
- ctx.stroke();
- }
-}
diff --git a/railsignal-app/src/components/railsystem/mapRenderer.js b/railsignal-app/src/components/railsystem/mapRenderer.js
deleted file mode 100644
index c31c7dd..0000000
--- a/railsignal-app/src/components/railsystem/mapRenderer.js
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
-This component is responsible for the rendering of a RailSystem in a 2d map
-view.
- */
-
-import {drawComponent, drawConnectedNodes} from "./drawing";
-
-const SCALE_VALUES = [0.01, 0.1, 0.25, 0.5, 1.0, 1.25, 1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 12.0, 16.0, 20.0, 30.0, 45.0, 60.0, 80.0, 100.0];
-const SCALE_INDEX_NORMAL = 7;
-const HOVER_RADIUS = 10;
-
-let mapContainerDiv = null;
-let mapCanvas = null;
-let railSystem = null;
-
-let mapScaleIndex = SCALE_INDEX_NORMAL;
-let mapTranslation = {x: 0, y: 0};
-let mapDragOrigin = null;
-let mapDragTranslation = null;
-let lastMousePoint = new DOMPoint(0, 0, 0, 0);
-const hoveredElements = [];
-
-export function initMap(rs) {
- railSystem = rs;
- console.log("Initializing map for rail system: " + rs.name);
- hoveredElements.length = 0;
- mapCanvas = document.getElementById("railSystemMapCanvas");
- mapContainerDiv = document.getElementById("railSystemMapCanvasContainer");
- mapCanvas.removeEventListener("wheel", onMouseWheel);
- mapCanvas.addEventListener("wheel", onMouseWheel);
- mapCanvas.removeEventListener("mousedown", onMouseDown);
- mapCanvas.addEventListener("mousedown", onMouseDown);
- mapCanvas.removeEventListener("mouseup", onMouseUp);
- mapCanvas.addEventListener("mouseup", onMouseUp);
- mapCanvas.removeEventListener("mousemove", onMouseMove);
- mapCanvas.addEventListener("mousemove", onMouseMove);
-
- // Do an initial draw.
- draw();
-}
-
-export function draw() {
- if (!(mapCanvas && railSystem && railSystem.components)) {
- console.warn("Attempted to draw map without canvas or railSystem.");
- return;
- }
- const ctx = mapCanvas.getContext("2d");
- if (mapCanvas.width !== mapContainerDiv.clientWidth) {
- mapCanvas.width = mapContainerDiv.clientWidth;
- }
- if (mapCanvas.height !== mapContainerDiv.clientHeight) {
- mapCanvas.height = mapContainerDiv.clientHeight;
- }
- const width = mapCanvas.width;
- const height = mapCanvas.height;
- ctx.resetTransform();
- ctx.fillStyle = `rgb(240, 240, 240)`;
- ctx.fillRect(0, 0, width, height);
- const worldTx = getWorldTransform();
- ctx.setTransform(worldTx);
-
- // Draw segments!
- const segmentPoints = new Map();
- railSystem.segments.forEach(segment => segmentPoints.set(segment.id, []));
- for (let i = 0; i < railSystem.components.length; i++) {
- const c = railSystem.components[i];
- if (c.type === "SEGMENT_BOUNDARY") {
- for (let j = 0; j < c.segments.length; j++) {
- segmentPoints.get(c.segments[j].id).push({x: c.position.x, y: c.position.z});
- }
- }
- }
- railSystem.segments.forEach(segment => {
- const points = segmentPoints.get(segment.id);
- const avgPoint = {x: 0, y: 0};
- points.forEach(point => {
- avgPoint.x += point.x;
- avgPoint.y += point.y;
- });
- avgPoint.x /= points.length;
- avgPoint.y /= points.length;
- let r = 5;
- points.forEach(point => {
- const dist2 = Math.pow(avgPoint.x - point.x, 2) + Math.pow(avgPoint.y - point.y, 2);
- if (dist2 > r * r) {
- r = Math.sqrt(dist2);
- }
- });
- ctx.fillStyle = `rgba(200, 200, 200, 0.25)`;
- const p = worldPointToMap(new DOMPoint(avgPoint.x, avgPoint.y, 0, 0));
- const s = getScaleFactor();
- ctx.beginPath();
- ctx.arc(p.x / s, p.y / s, r, 0, Math.PI * 2);
- ctx.fill();
- ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
- ctx.font = "3px Sans-Serif";
- ctx.fillText(`${segment.name}`, p.x / s, p.y / s);
- });
-
- for (let i = 0; i < railSystem.components.length; i++) {
- const c = railSystem.components[i];
- if (c.connectedNodes !== undefined && c.connectedNodes !== null) {
- drawConnectedNodes(ctx, worldTx, c);
- }
- }
-
- for (let i = 0; i < railSystem.components.length; i++) {
- drawComponent(ctx, worldTx, railSystem.components[i]);
- }
-
- // Draw debug info.
- ctx.resetTransform();
- ctx.fillStyle = "black";
- ctx.strokeStyle = "black";
- ctx.font = "10px Sans-Serif";
- const lastWorldPoint = mapPointToWorld(lastMousePoint);
- const lines = [
- "Scale factor: " + getScaleFactor(),
- `(x = ${lastWorldPoint.x.toFixed(2)}, y = ${lastWorldPoint.y.toFixed(2)}, z = ${lastWorldPoint.z.toFixed(2)})`,
- `Components: ${railSystem.components.length}`,
- `Hovered elements: ${hoveredElements.length}`
- ]
- for (let i = 0; i < lines.length; i++) {
- ctx.fillText(lines[i], 10, 20 + (i * 15));
- }
-}
-
-export function getScaleFactor() {
- return SCALE_VALUES[mapScaleIndex];
-}
-
-function getWorldTransform() {
- const canvasRect = mapCanvas.getBoundingClientRect();
- const scale = getScaleFactor();
- const tx = new DOMMatrix();
- tx.translateSelf(canvasRect.width / 2, canvasRect.height / 2, 0);
- tx.scaleSelf(scale, scale, scale);
- tx.translateSelf(mapTranslation.x, mapTranslation.y, 0);
- if (mapDragOrigin !== null && mapDragTranslation !== null) {
- tx.translateSelf(mapDragTranslation.x, mapDragTranslation.y, 0);
- }
- return tx;
-}
-
-export function isComponentHovered(component) {
- for (let i = 0; i < hoveredElements.length; i++) {
- if (hoveredElements[i].id === component.id) return true;
- }
- return false;
-}
-
-/**
- * Maps a point on the map coordinates to world coordinates.
- * @param {DOMPoint} p
- * @returns {DOMPoint}
- */
-function mapPointToWorld(p) {
- return getWorldTransform().invertSelf().transformPoint(p);
-}
-
-/**
- * Maps a point in the world to map coordinates.
- * @param {DOMPoint} p
- * @returns {DOMPoint}
- */
-function worldPointToMap(p) {
- return getWorldTransform().transformPoint(p);
-}
-
-/*
-EVENT HANDLING
-*/
-
-/**
- * @param {WheelEvent} event
- */
-function onMouseWheel(event) {
- const s = event.deltaY;
- if (s > 0) {
- mapScaleIndex = Math.max(0, mapScaleIndex - 1);
- } else if (s < 0) {
- mapScaleIndex = Math.min(SCALE_VALUES.length - 1, mapScaleIndex + 1);
- }
- draw();
- event.stopPropagation();
- return false;
-}
-
-/**
- * @param {MouseEvent} event
- */
-function onMouseDown(event) {
- const p = getMousePoint(event);
- mapDragOrigin = {x: p.x, y: p.y};
-}
-
-function onMouseUp() {
- if (mapDragTranslation !== null) {
- mapTranslation.x += mapDragTranslation.x;
- mapTranslation.y += mapDragTranslation.y;
- }
- if (hoveredElements.length === 1) {
- railSystem.selectedComponent = hoveredElements[0];
- } else {
- railSystem.selectedComponent = null;
- }
- mapDragOrigin = null;
- mapDragTranslation = null;
-}
-
-/**
- * @param {MouseEvent} event
- */
-function onMouseMove(event) {
- const p = getMousePoint(event);
- lastMousePoint = p;
- if (mapDragOrigin !== null) {
- const scale = getScaleFactor();
- const dx = p.x - mapDragOrigin.x;
- const dy = p.y - mapDragOrigin.y;
- mapDragTranslation = {x: dx / scale, y: dy / scale};
- } else {
- hoveredElements.length = 0;
- // Populate with list of hovered elements.
- for (let i = 0; i < railSystem.components.length; i++) {
- const c = railSystem.components[i];
- const componentPoint = new DOMPoint(c.position.x, c.position.z, 0, 1);
- const mapComponentPoint = worldPointToMap(componentPoint);
- const dist2 = (p.x - mapComponentPoint.x) * (p.x - mapComponentPoint.x) + (p.y - mapComponentPoint.y) * (p.y - mapComponentPoint.y);
- if (dist2 < HOVER_RADIUS * HOVER_RADIUS) {
- hoveredElements.push(c);
- }
- }
- }
- draw();
-}
-
-/**
- * Gets the point at which the user clicked on the map.
- * @param {MouseEvent} event
- * @returns {DOMPoint}
- */
-function getMousePoint(event) {
- const rect = mapCanvas.getBoundingClientRect();
- const x = event.clientX - rect.left;
- const y = event.clientY - rect.top;
- return new DOMPoint(x, y, 0, 1);
-}
diff --git a/railsignal-app/src/components/railsystem/util/ComponentSelector.vue b/railsignal-app/src/components/railsystem/util/ComponentSelector.vue
deleted file mode 100644
index 835b00f..0000000
--- a/railsignal-app/src/components/railsystem/util/ComponentSelector.vue
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
-
-
- {{component.name}}
-
-
- Select
-
- Selected
-
-
-
-
- {{component.name}}
-
- X
-
-
-
-
- Clear All
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/railsignal-app/src/main.js b/railsignal-app/src/main.js
deleted file mode 100644
index b50d2ca..0000000
--- a/railsignal-app/src/main.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import {createApp} from 'vue';
-import {createPinia} from 'pinia';
-import App from './App.vue'
-import "bootstrap/dist/css/bootstrap.min.css";
-import "bootstrap";
-
-
-const pinia = createPinia();
-const app = createApp(App);
-app.use(pinia);
-app.mount('#app')
diff --git a/railsignal-app/src/stores/railSystemsStore.js b/railsignal-app/src/stores/railSystemsStore.js
deleted file mode 100644
index 6defbda..0000000
--- a/railsignal-app/src/stores/railSystemsStore.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import {defineStore} from "pinia";
-import {refreshSegments} from "../api/segments"
-import {refreshComponents} from "../api/components";
-import {closeWebsocketConnection, establishWebsocketConnection} from "../api/websocket";
-
-export const useRailSystemsStore = defineStore('RailSystemsStore', {
- state: () => ({
- /**
- * @type {RailSystem[]}
- */
- railSystems: [],
- /**
- * @type {RailSystem | null}
- */
- selectedRailSystem: null
- }),
- actions: {
- onSelectedRailSystemChanged() {
- this.railSystems.forEach(rs => closeWebsocketConnection(rs));
- if (!this.selectedRailSystem) return;
- refreshSegments(this.selectedRailSystem);
- refreshComponents(this.selectedRailSystem);
- establishWebsocketConnection(this.selectedRailSystem);
- }
- },
- getters: {
- rsId() {
- if (this.selectedRailSystem === null) return null;
- return this.selectedRailSystem.id;
- }
- }
-});
\ No newline at end of file
diff --git a/railsignal-app/vite.config.js b/railsignal-app/vite.config.js
deleted file mode 100644
index 802da0a..0000000
--- a/railsignal-app/vite.config.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { fileURLToPath, URL } from 'url'
-
-import { defineConfig } from 'vite'
-import vue from '@vitejs/plugin-vue'
-
-// https://vitejs.dev/config/
-export default defineConfig(({command, mode}) => {
- return {
- plugins: [vue()],
- resolve: {
- alias: {
- '@': fileURLToPath(new URL('./src', import.meta.url))
- }
- },
- base: mode === "production" ? "/app/" : undefined
- }
-})
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/ComponentDownlink.java b/src/main/java/nl/andrewl/railsignalapi/live/ComponentDownlink.java
index db3aafb..ab61eb3 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/ComponentDownlink.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/ComponentDownlink.java
@@ -3,7 +3,7 @@ package nl.andrewl.railsignalapi.live;
import lombok.Getter;
/**
- * A downlink connection to one or more components (linked by a {@link nl.andrewl.railsignalapi.model.LinkToken}
+ * A downlink connection to one or more components (linked by a {@link nl.andrewl.railsignalapi.model.LinkToken})
* which we can send messages to.
*/
public abstract class ComponentDownlink {
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/ComponentDownlinkService.java b/src/main/java/nl/andrewl/railsignalapi/live/ComponentDownlinkService.java
index 5cf293c..a0ba9ee 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/ComponentDownlinkService.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/ComponentDownlinkService.java
@@ -4,6 +4,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import nl.andrewl.railsignalapi.dao.ComponentRepository;
import nl.andrewl.railsignalapi.dao.LinkTokenRepository;
+import nl.andrewl.railsignalapi.live.dto.ComponentDataMessage;
+import nl.andrewl.railsignalapi.live.dto.ComponentMessage;
import nl.andrewl.railsignalapi.live.websocket.AppUpdateService;
import nl.andrewl.railsignalapi.model.component.Component;
import org.springframework.stereotype.Service;
@@ -31,13 +33,18 @@ public class ComponentDownlinkService {
* @param downlink The downlink to register.
*/
@Transactional
- public synchronized void registerDownlink(ComponentDownlink downlink) {
+ public synchronized void registerDownlink(ComponentDownlink downlink) throws Exception {
Set components = tokenRepository.findById(downlink.getTokenId()).orElseThrow().getComponents();
componentDownlinks.put(downlink, components.stream().map(Component::getId).collect(Collectors.toSet()));
for (var c : components) {
c.setOnline(true);
componentRepository.save(c);
- appUpdateService.sendComponentUpdate(c.getRailSystem().getId(), c.getId());
+
+ // Immediately send a data message to the downlink and app for each component that comes online.
+ var msg = new ComponentDataMessage(c);
+ downlink.send(msg);
+ appUpdateService.sendUpdate(c.getRailSystem().getId(), msg);
+
Set downlinks = downlinksByCId.computeIfAbsent(c.getId(), aLong -> new HashSet<>());
downlinks.add(downlink);
}
@@ -97,4 +104,8 @@ public class ComponentDownlinkService {
}
}
}
+
+ public void sendMessage(ComponentMessage msg) {
+ sendMessage(msg.cId, msg);
+ }
}
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/ComponentUplinkMessageHandler.java b/src/main/java/nl/andrewl/railsignalapi/live/ComponentUplinkMessageHandler.java
index c2f837b..c3baf01 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/ComponentUplinkMessageHandler.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/ComponentUplinkMessageHandler.java
@@ -2,7 +2,7 @@ package nl.andrewl.railsignalapi.live;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import nl.andrewl.railsignalapi.live.dto.ComponentUplinkMessage;
+import nl.andrewl.railsignalapi.live.dto.ComponentMessage;
import nl.andrewl.railsignalapi.live.dto.SegmentBoundaryUpdateMessage;
import nl.andrewl.railsignalapi.live.dto.SwitchUpdateMessage;
import nl.andrewl.railsignalapi.service.SegmentService;
@@ -22,7 +22,7 @@ public class ComponentUplinkMessageHandler {
private final SegmentService segmentService;
@Transactional
- public void messageReceived(ComponentUplinkMessage msg) {
+ public void messageReceived(ComponentMessage msg) {
if (msg instanceof SegmentBoundaryUpdateMessage sb) {
segmentService.onBoundaryUpdate(sb);
} else if (msg instanceof SwitchUpdateMessage sw) {
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/dto/ComponentDataMessage.java b/src/main/java/nl/andrewl/railsignalapi/live/dto/ComponentDataMessage.java
new file mode 100644
index 0000000..4896d67
--- /dev/null
+++ b/src/main/java/nl/andrewl/railsignalapi/live/dto/ComponentDataMessage.java
@@ -0,0 +1,19 @@
+package nl.andrewl.railsignalapi.live.dto;
+
+import lombok.Getter;
+import nl.andrewl.railsignalapi.model.component.Component;
+import nl.andrewl.railsignalapi.rest.dto.component.out.ComponentResponse;
+
+/**
+ * A message that's sent to devices which contains the full component response
+ * for a specific component.
+ */
+@Getter
+public class ComponentDataMessage extends ComponentMessage {
+ private final ComponentResponse data;
+
+ public ComponentDataMessage(Component c) {
+ super(c.getId(), "COMPONENT_DATA");
+ this.data = ComponentResponse.of(c);
+ }
+}
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/dto/ComponentUplinkMessage.java b/src/main/java/nl/andrewl/railsignalapi/live/dto/ComponentMessage.java
similarity index 55%
rename from src/main/java/nl/andrewl/railsignalapi/live/dto/ComponentUplinkMessage.java
rename to src/main/java/nl/andrewl/railsignalapi/live/dto/ComponentMessage.java
index 43f8e96..37ffd19 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/dto/ComponentUplinkMessage.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/dto/ComponentMessage.java
@@ -3,18 +3,32 @@ package nl.andrewl.railsignalapi.live.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import lombok.NoArgsConstructor;
/**
- * The parent class for all uplink messages that can be sent by connected
- * components.
+ * Base class for all messages that will be sent to components.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", include = JsonTypeInfo.As.EXISTING_PROPERTY, visible = true)
@JsonSubTypes({
- @JsonSubTypes.Type(value = SegmentBoundaryUpdateMessage.class, name = "sb"),
- @JsonSubTypes.Type(value = SwitchUpdateMessage.class, name = "sw")
+ @JsonSubTypes.Type(value = SegmentBoundaryUpdateMessage.class, name = "SEGMENT_BOUNDARY_UPDATE"),
+ @JsonSubTypes.Type(value = SwitchUpdateMessage.class, name = "SWITCH_UPDATE"),
+ @JsonSubTypes.Type(value = ErrorMessage.class, name = "ERROR")
})
-public abstract class ComponentUplinkMessage {
+@NoArgsConstructor
+public abstract class ComponentMessage {
+ /**
+ * The id of the component that this message is for.
+ */
public long cId;
+
+ /**
+ * The type of message.
+ */
public String type;
+
+ public ComponentMessage(long cId, String type) {
+ this.cId = cId;
+ this.type = type;
+ }
}
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/dto/ErrorMessage.java b/src/main/java/nl/andrewl/railsignalapi/live/dto/ErrorMessage.java
new file mode 100644
index 0000000..8921aec
--- /dev/null
+++ b/src/main/java/nl/andrewl/railsignalapi/live/dto/ErrorMessage.java
@@ -0,0 +1,13 @@
+package nl.andrewl.railsignalapi.live.dto;
+
+/**
+ * A message that's sent regarding an error that occurred.
+ */
+public class ErrorMessage extends ComponentMessage {
+ public String message;
+
+ public ErrorMessage(long cId, String message) {
+ super(cId, "ERROR");
+ this.message = message;
+ }
+}
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/dto/SegmentBoundaryUpdateMessage.java b/src/main/java/nl/andrewl/railsignalapi/live/dto/SegmentBoundaryUpdateMessage.java
index 4c7da55..382941d 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/dto/SegmentBoundaryUpdateMessage.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/dto/SegmentBoundaryUpdateMessage.java
@@ -1,9 +1,12 @@
package nl.andrewl.railsignalapi.live.dto;
+import lombok.NoArgsConstructor;
+
/**
* Message that's sent by segment boundaries when a train crosses it.
*/
-public class SegmentBoundaryUpdateMessage extends ComponentUplinkMessage {
+@NoArgsConstructor
+public class SegmentBoundaryUpdateMessage extends ComponentMessage {
/**
* The id of the segment that a train detected by the segment boundary is
* moving towards.
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/dto/SegmentStatusMessage.java b/src/main/java/nl/andrewl/railsignalapi/live/dto/SegmentStatusMessage.java
index be90693..1ebb3c7 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/dto/SegmentStatusMessage.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/dto/SegmentStatusMessage.java
@@ -1,6 +1,26 @@
package nl.andrewl.railsignalapi.live.dto;
-public record SegmentStatusMessage (
- long cId,
- boolean occupied
-) {}
+import lombok.Getter;
+
+/**
+ * A message that's sent to signal components regarding a change in a segment's
+ * status.
+ */
+@Getter
+public class SegmentStatusMessage extends ComponentMessage {
+ /**
+ * The id of the segment that updated.
+ */
+ private final long sId;
+
+ /**
+ * Whether the segment is occupied.
+ */
+ private final boolean occupied;
+
+ public SegmentStatusMessage(long cId, long sId, boolean occupied) {
+ super(cId, "SEGMENT_STATUS");
+ this.sId = sId;
+ this.occupied = occupied;
+ }
+}
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/dto/SwitchUpdateMessage.java b/src/main/java/nl/andrewl/railsignalapi/live/dto/SwitchUpdateMessage.java
index ea1e91b..74b6cbc 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/dto/SwitchUpdateMessage.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/dto/SwitchUpdateMessage.java
@@ -1,13 +1,19 @@
package nl.andrewl.railsignalapi.live.dto;
-import java.util.Set;
+import lombok.NoArgsConstructor;
/**
* Message that's sent by a switch when its active configuration is updated.
*/
-public class SwitchUpdateMessage extends ComponentUplinkMessage {
+@NoArgsConstructor
+public class SwitchUpdateMessage extends ComponentMessage {
/**
- * A set of path node ids that represents the active configuration.
+ * The id of the configuration that's active.
*/
- public Set configuration;
+ public long activeConfigId;
+
+ public SwitchUpdateMessage(long cId, long activeConfigId) {
+ super(cId, "SWITCH_UPDATE");
+ this.activeConfigId = activeConfigId;
+ }
}
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/tcp_socket/ConnectMessage.java b/src/main/java/nl/andrewl/railsignalapi/live/tcp_socket/ConnectMessage.java
index 26c55a0..75139f8 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/tcp_socket/ConnectMessage.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/tcp_socket/ConnectMessage.java
@@ -1,5 +1,10 @@
package nl.andrewl.railsignalapi.live.tcp_socket;
+/**
+ * A message that's sent in response to a client's attempt to connect.
+ * @param valid Whether the connection is valid.
+ * @param message A message.
+ */
public record ConnectMessage(
boolean valid,
String message
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/tcp_socket/TcpLinkManager.java b/src/main/java/nl/andrewl/railsignalapi/live/tcp_socket/TcpLinkManager.java
index bf78068..63befe6 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/tcp_socket/TcpLinkManager.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/tcp_socket/TcpLinkManager.java
@@ -4,7 +4,7 @@ import lombok.extern.slf4j.Slf4j;
import nl.andrewl.railsignalapi.live.ComponentDownlink;
import nl.andrewl.railsignalapi.live.ComponentDownlinkService;
import nl.andrewl.railsignalapi.live.ComponentUplinkMessageHandler;
-import nl.andrewl.railsignalapi.live.dto.ComponentUplinkMessage;
+import nl.andrewl.railsignalapi.live.dto.ComponentMessage;
import nl.andrewl.railsignalapi.util.JsonUtils;
import java.io.DataInputStream;
@@ -43,10 +43,20 @@ public class TcpLinkManager extends ComponentDownlink implements Runnable {
@Override
public void run() {
- downlinkService.registerDownlink(this);
+ try {
+ downlinkService.registerDownlink(this);
+ } catch (Exception e) {
+ log.error("An error occurred while registering a downlink.");
+ try {
+ shutdown();
+ } catch (IOException ex) {
+ log.error("An error occurred while shutting down a downlink.", ex);
+ }
+ return;
+ }
while (!socket.isClosed()) {
try {
- var msg = JsonUtils.readMessage(in, ComponentUplinkMessage.class);
+ var msg = JsonUtils.readMessage(in, ComponentMessage.class);
uplinkMessageHandler.messageReceived(msg);
} catch (IOException e) {
log.warn("An error occurred while receiving an uplink message.", e);
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/websocket/AppUpdateService.java b/src/main/java/nl/andrewl/railsignalapi/live/websocket/AppUpdateService.java
index 0c066e2..b21c974 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/websocket/AppUpdateService.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/websocket/AppUpdateService.java
@@ -53,6 +53,11 @@ public class AppUpdateService {
log.info("De-registered an app websocket session.");
}
+ /**
+ * Sends an update to any connected apps.
+ * @param rsId The id of the rail system that the update pertains to.
+ * @param msg The message to send.
+ */
public synchronized void sendUpdate(long rsId, Object msg) {
Set sessionsForRs = sessions.get(rsId);
if (sessionsForRs != null) {
diff --git a/src/main/java/nl/andrewl/railsignalapi/live/websocket/ComponentWebsocketHandler.java b/src/main/java/nl/andrewl/railsignalapi/live/websocket/ComponentWebsocketHandler.java
index 3ec526e..237d1ac 100644
--- a/src/main/java/nl/andrewl/railsignalapi/live/websocket/ComponentWebsocketHandler.java
+++ b/src/main/java/nl/andrewl/railsignalapi/live/websocket/ComponentWebsocketHandler.java
@@ -4,7 +4,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import nl.andrewl.railsignalapi.live.ComponentDownlinkService;
import nl.andrewl.railsignalapi.live.ComponentUplinkMessageHandler;
-import nl.andrewl.railsignalapi.live.dto.ComponentUplinkMessage;
+import nl.andrewl.railsignalapi.live.dto.ComponentMessage;
import nl.andrewl.railsignalapi.util.JsonUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -13,6 +13,8 @@ import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
+import java.io.IOException;
+
/**
* Handler for websocket connections that components open to send and receive
* real-time updates from the server.
@@ -28,12 +30,21 @@ public class ComponentWebsocketHandler extends TextWebSocketHandler {
@Transactional(readOnly = true)
public void afterConnectionEstablished(WebSocketSession session) {
long tokenId = (long) session.getAttributes().get("tokenId");
- componentDownlinkService.registerDownlink(new WebsocketDownlink(tokenId, session));
+ try {
+ componentDownlinkService.registerDownlink(new WebsocketDownlink(tokenId, session));
+ } catch (Exception e) {
+ log.error("An error occurred while registering a new websocket downlink.", e);
+ try {
+ session.close();
+ } catch (IOException ex) {
+ log.error("An error occurred while closing a websocket downlink.", e);
+ }
+ }
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
- var msg = JsonUtils.readMessage(message.getPayload(), ComponentUplinkMessage.class);
+ var msg = JsonUtils.readMessage(message.getPayload(), ComponentMessage.class);
uplinkMessageHandler.messageReceived(msg);
}
diff --git a/src/main/java/nl/andrewl/railsignalapi/model/component/Switch.java b/src/main/java/nl/andrewl/railsignalapi/model/component/Switch.java
index f77d192..ce3b1e9 100644
--- a/src/main/java/nl/andrewl/railsignalapi/model/component/Switch.java
+++ b/src/main/java/nl/andrewl/railsignalapi/model/component/Switch.java
@@ -7,9 +7,7 @@ import lombok.Setter;
import nl.andrewl.railsignalapi.model.RailSystem;
import javax.persistence.*;
-import java.util.Optional;
import java.util.Set;
-import java.util.stream.Collectors;
/**
* A switch is a component that directs traffic between several connected
@@ -38,12 +36,4 @@ public class Switch extends PathNode {
this.possibleConfigurations = possibleConfigurations;
this.activeConfiguration = activeConfiguration;
}
-
- public Optional findConfiguration(Set pathNodeIds) {
- for (var config : possibleConfigurations) {
- Set configNodeIds = config.getNodes().stream().map(Component::getId).collect(Collectors.toSet());
- if (pathNodeIds.equals(configNodeIds)) return Optional.of(config);
- }
- return Optional.empty();
- }
}
diff --git a/src/main/java/nl/andrewl/railsignalapi/rest/WebConfig.java b/src/main/java/nl/andrewl/railsignalapi/rest/WebConfig.java
index ad2091f..3fe5ae4 100644
--- a/src/main/java/nl/andrewl/railsignalapi/rest/WebConfig.java
+++ b/src/main/java/nl/andrewl/railsignalapi/rest/WebConfig.java
@@ -14,6 +14,10 @@ public class WebConfig implements WebMvcConfigurer {
// Configure resource handlers to use the /app directory for all vue frontend stuff.
registry.addResourceHandler("/app/**")
.addResourceLocations("classpath:/app/");
+
+ // Configure resource handlers for driver files.
+ registry.addResourceHandler("/driver/**")
+ .addResourceLocations("classpath:/driver/");
}
@Override
diff --git a/src/main/java/nl/andrewl/railsignalapi/service/SegmentService.java b/src/main/java/nl/andrewl/railsignalapi/service/SegmentService.java
index 0513697..553748f 100644
--- a/src/main/java/nl/andrewl/railsignalapi/service/SegmentService.java
+++ b/src/main/java/nl/andrewl/railsignalapi/service/SegmentService.java
@@ -68,11 +68,15 @@ public class SegmentService {
private void sendSegmentOccupiedStatus(Segment segment) {
for (var signal : segment.getSignals()) {
- downlinkService.sendMessage(signal.getId(), new SegmentStatusMessage(signal.getId(), segment.isOccupied()));
+ downlinkService.sendMessage(signal.getId(), new SegmentStatusMessage(signal.getId(), segment.getId(), segment.isOccupied()));
appUpdateService.sendComponentUpdate(segment.getRailSystem().getId(), signal.getId());
}
}
+ /**
+ * Handles updates from segment boundary components.
+ * @param msg The update message.
+ */
@Transactional
public void onBoundaryUpdate(SegmentBoundaryUpdateMessage msg) {
var segmentBoundary = segmentBoundaryRepository.findById(msg.cId)
diff --git a/src/main/java/nl/andrewl/railsignalapi/service/SwitchService.java b/src/main/java/nl/andrewl/railsignalapi/service/SwitchService.java
index c1df8ed..81876d5 100644
--- a/src/main/java/nl/andrewl/railsignalapi/service/SwitchService.java
+++ b/src/main/java/nl/andrewl/railsignalapi/service/SwitchService.java
@@ -3,9 +3,11 @@ package nl.andrewl.railsignalapi.service;
import lombok.RequiredArgsConstructor;
import nl.andrewl.railsignalapi.dao.ComponentRepository;
import nl.andrewl.railsignalapi.live.ComponentDownlinkService;
+import nl.andrewl.railsignalapi.live.dto.ErrorMessage;
import nl.andrewl.railsignalapi.live.dto.SwitchUpdateMessage;
import nl.andrewl.railsignalapi.live.websocket.AppUpdateService;
import nl.andrewl.railsignalapi.model.component.Switch;
+import nl.andrewl.railsignalapi.model.component.SwitchConfiguration;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -23,11 +25,16 @@ public class SwitchService {
@Transactional
public void onSwitchUpdate(SwitchUpdateMessage msg) {
switchRepository.findById(msg.cId).ifPresent(sw -> {
- sw.findConfiguration(msg.configuration).ifPresent(config -> {
- sw.setActiveConfiguration(config);
- switchRepository.save(sw);
- appUpdateService.sendComponentUpdate(sw.getRailSystem().getId(), sw.getId());
- });
+ sw.getPossibleConfigurations().stream()
+ .filter(c -> c.getId().equals(msg.activeConfigId))
+ .findFirst()
+ .ifPresentOrElse(config -> {
+ sw.setActiveConfiguration(config);
+ switchRepository.save(sw);
+ appUpdateService.sendComponentUpdate(sw.getRailSystem().getId(), sw.getId());
+ }, () -> {
+ downlinkService.sendMessage(new ErrorMessage(sw.getId(), "Invalid active config id."));
+ });
});
}
}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index b47e28e..77f5b55 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -5,8 +5,6 @@ spring.jpa.open-in-view=false
spring.datasource.hikari.maximum-pool-size=5
spring.datasource.hikari.minimum-idle=1
-spring.thymeleaf.enabled=false
-
server.port=8080
server.tomcat.threads.max=10
server.tomcat.threads.min-spare=2
diff --git a/src/main/resources/driver/utils.lua b/src/main/resources/driver/utils.lua
new file mode 100644
index 0000000..d3ee215
--- /dev/null
+++ b/src/main/resources/driver/utils.lua
@@ -0,0 +1,41 @@
+function tableLength(t)
+ local c = 0
+ for _ in pairs(t) do
+ c = c + 1
+ end
+ return c
+end
+
+function startsWith(str, s)
+ return str:find(s, 1, true) == 1
+end
+
+function readNum(validationFunction)
+ local func = validationFunction or function (n)
+ return n ~= nil
+ end
+ local num = nil
+ while true do
+ local s = io.read()
+ if s ~= nil then num = tonumber(s) end
+ if not func(num) then
+ print("The number you entered is not valid.")
+ else
+ return num
+ end
+ end
+end
+
+function readStr(validationFunction)
+ local func = validationFunction or function (s)
+ return s ~= nil and string.len(s) > 0
+ end
+ while true do
+ local str = io.read()
+ if func(str) then
+ return str
+ else
+ print("The string you entered is not valid.")
+ end
+ end
+end