diff --git a/.editorconfig b/.editorconfig index c0bb3e8..37d7c1d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,5 +5,4 @@ charset = utf-8 end_of_line = lf [*.{json,js,jsx,ts,tsx}] -indent_style = space -indent_size = 2 +indent_style = tab diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 52844e7..0000000 --- a/.eslintrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "root": true, - "extends": "airbnb-typescript-prettier", - "ignorePatterns": ["dist/"], - "rules": { - "no-restricted-syntax": "off", // Allow using for-of syntax - "react/react-in-jsx-scope": "off", // Not necessary for react@>=17 - "react/jsx-props-no-spreading": "off", - "@typescript-eslint/no-non-null-assertion": "off" // Will be removed - } -} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c69aab4..badba29 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,4 +6,4 @@ jobs: - uses: actions/checkout@v3 - run: npm ci - run: npm run type-check - - run: npm run lint + - run: npm run check diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..3238a74 --- /dev/null +++ b/biome.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + } +} diff --git a/package-lock.json b/package-lock.json index 0a34a57..ba901fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,33 +8,30 @@ "name": "create-cpu", "version": "0.0.0", "dependencies": { - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "@mui/icons-material": "^5.11.16", - "@mui/material": "^5.13.5", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@mui/icons-material": "^6.3.0", + "@mui/material": "^6.3.0", "eventemitter3": "^5.0.1", "memoize-one": "^6.0.0", "mnemonist": "^0.39.8", "nullthrows": "^1.1.1", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-use": "^17.5.1", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-use": "^17.6.0", "tiny-invariant": "^1.3.3", "transformation-matrix": "^2.16.1", - "zustand": "^4.3.9" + "zustand": "^5.0.2" }, "devDependencies": { - "@tsconfig/esm": "^1.0.5", + "@biomejs/biome": "^1.9.4", "@tsconfig/strictest": "^2.0.5", - "@types/react": "^18.3.12", - "@types/react-dom": "^18.3.1", - "@vitejs/plugin-react": "^4.3.3", - "eslint": "^8.43.0", - "eslint-config-airbnb-typescript-prettier": "^5.0.0", - "prettier": "^2.8.8", - "type-fest": "^3.12.0", - "typescript": "^5.6.3", - "vite": "^4.3.9" + "@types/react": "^19.0.2", + "@types/react-dom": "^19.0.2", + "@vitejs/plugin-react": "^4.3.4", + "type-fest": "^4.31.0", + "typescript": "^5.7.2", + "vite": "^6.0.6" } }, "node_modules/@ampproject/remapping": { @@ -277,11 +274,12 @@ } }, "node_modules/@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -332,17 +330,181 @@ "node": ">=6.9.0" } }, + "node_modules/@biomejs/biome": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", + "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", + "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.9.4", + "@biomejs/cli-darwin-x64": "1.9.4", + "@biomejs/cli-linux-arm64": "1.9.4", + "@biomejs/cli-linux-arm64-musl": "1.9.4", + "@biomejs/cli-linux-x64": "1.9.4", + "@biomejs/cli-linux-x64-musl": "1.9.4", + "@biomejs/cli-win32-arm64": "1.9.4", + "@biomejs/cli-win32-x64": "1.9.4" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", + "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", + "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", + "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", + "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", + "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", + "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", + "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", + "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, "node_modules/@emotion/babel-plugin": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", - "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", - "@emotion/serialize": "^1.2.0", + "@emotion/serialize": "^1.3.3", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", @@ -352,14 +514,14 @@ } }, "node_modules/@emotion/cache": { - "version": "11.13.1", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", - "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", "license": "MIT", "dependencies": { "@emotion/memoize": "^0.9.0", "@emotion/sheet": "^1.4.0", - "@emotion/utils": "^1.4.0", + "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "stylis": "4.2.0" } @@ -386,17 +548,17 @@ "license": "MIT" }, "node_modules/@emotion/react": { - "version": "11.13.3", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", - "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/cache": "^11.13.0", - "@emotion/serialize": "^1.3.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "hoist-non-react-statics": "^3.3.1" }, @@ -410,15 +572,15 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", - "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", "license": "MIT", "dependencies": { "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", "@emotion/unitless": "^0.10.0", - "@emotion/utils": "^1.4.1", + "@emotion/utils": "^1.4.2", "csstype": "^3.0.2" } }, @@ -429,17 +591,17 @@ "license": "MIT" }, "node_modules/@emotion/styled": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", - "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", + "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", + "@emotion/babel-plugin": "^11.13.5", "@emotion/is-prop-valid": "^1.3.0", - "@emotion/serialize": "^1.3.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0" + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" }, "peerDependencies": { "@emotion/react": "^11.0.0-rc.0", @@ -458,18 +620,18 @@ "license": "MIT" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", - "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", "license": "MIT", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", - "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", "license": "MIT" }, "node_modules/@emotion/weak-memoize": { @@ -478,474 +640,431 @@ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", "license": "MIT" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", - "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", - "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", - "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", - "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", - "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", - "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", - "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", - "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", - "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", - "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", - "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", - "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", - "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", - "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", - "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", - "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", - "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", - "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", - "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", - "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", - "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", - "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.2", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/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/@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "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/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -993,65 +1112,35 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@mui/base": { - "version": "5.0.0-beta.4", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.4.tgz", - "integrity": "sha512-ejhtqYJpjDgHGEljjMBQWZ22yEK0OzIXNa7toJmmXsP4TT3W7xVy8bTJ0TniPDf+JNjrsgfgiFTDGdlEhV1E+g==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@emotion/is-prop-valid": "^1.2.1", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.1", - "@popperjs/core": "^2.11.8", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.13.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.4.tgz", - "integrity": "sha512-yFrMWcrlI0TqRN5jpb6Ma9iI7sGTHpytdzzL33oskFHNQ8UgrtPas33Y1K7sWAMwCrr1qbWDrOHLAQG4tAzuSw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.3.0.tgz", + "integrity": "sha512-/d8NwSuC3rMwCjswmGB3oXC4sdDuhIUJ8inVQAxGrADJhf0eq/kmy+foFKvpYhHl2siOZR+MLdFttw6/Bzqtqg==", + "license": "MIT", "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.11.16", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.11.16.tgz", - "integrity": "sha512-oKkx9z9Kwg40NtcIajF9uOXhxiyTZrrm9nmIJ4UjkU2IdHpd4QVLbCc/5hZN/y0C6qzi2Zlxyr9TGddQx2vx2A==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.3.0.tgz", + "integrity": "sha512-3uWws6DveDn5KxCS34p+sUNMxehuclQY6OmoJeJJ+Sfg9L7LGBpksY/nX5ywKAqickTZnn+sQyVcp963ep9jvw==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.21.0" + "@babel/runtime": "^7.26.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^5.0.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@mui/material": "^6.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -1060,36 +1149,38 @@ } }, "node_modules/@mui/material": { - "version": "5.13.5", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.5.tgz", - "integrity": "sha512-eMay+Ue1OYXOFMQA5Aau7qbAa/kWHLAyi0McsbPTWssCbGehqkF6CIdPsfVGw6tlO+xPee1hUitphHJNL3xpOQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.3.0.tgz", + "integrity": "sha512-qhlTFyRMxfoVPxUtA5e8IvqxP0dWo2Ij7cvot7Orag+etUlZH+3UwD8gZGt+3irOoy7Ms3UNBflYjwEikUXtAQ==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/base": "5.0.0-beta.4", - "@mui/core-downloads-tracker": "^5.13.4", - "@mui/system": "^5.13.5", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.1", - "@types/react-transition-group": "^4.4.6", - "clsx": "^1.2.1", - "csstype": "^3.1.2", + "@babel/runtime": "^7.26.0", + "@mui/core-downloads-tracker": "^6.3.0", + "@mui/system": "^6.3.0", + "@mui/types": "^7.2.20", + "@mui/utils": "^6.3.0", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", "prop-types": "^15.8.1", - "react-is": "^18.2.0", + "react-is": "^19.0.0", "react-transition-group": "^4.4.5" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "@mui/material-pigment-css": "^6.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -1098,30 +1189,34 @@ "@emotion/styled": { "optional": true }, + "@mui/material-pigment-css": { + "optional": true + }, "@types/react": { "optional": true } } }, "node_modules/@mui/private-theming": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.1.tgz", - "integrity": "sha512-HW4npLUD9BAkVppOUZHeO1FOKUJWAwbpy0VQoGe3McUYTlck1HezGHQCfBQ5S/Nszi7EViqiimECVl9xi+/WjQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.3.0.tgz", + "integrity": "sha512-tdS8jvqMokltNTXg6ioRCCbVdDmZUJZa/T9VtTnX2Lwww3FTgCakst9tWLZSxm1fEE9Xp0m7onZJmgeUmWQYVw==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/utils": "^5.13.1", + "@babel/runtime": "^7.26.0", + "@mui/utils": "^6.3.0", "prop-types": "^15.8.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -1130,26 +1225,29 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.13.2", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz", - "integrity": "sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.3.0.tgz", + "integrity": "sha512-iWA6eyiPkO07AlHxRUvI7dwVRSc+84zV54kLmjUms67GJeOWVuXlu8ZO+UhCnwJxHacghxnabsMEqet5PYQmHg==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.21.0", - "@emotion/cache": "^11.11.0", - "csstype": "^3.1.2", + "@babel/runtime": "^7.26.0", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -1161,31 +1259,32 @@ } }, "node_modules/@mui/system": { - "version": "5.13.5", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.13.5.tgz", - "integrity": "sha512-n0gzUxoZ2ZHZgnExkh2Htvo9uW2oakofgPRQrDoa/GQOWyRD0NH9MDszBwOb6AAoXZb+OV5TE7I4LeZ/dzgHYA==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/private-theming": "^5.13.1", - "@mui/styled-engine": "^5.13.2", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.1", - "clsx": "^1.2.1", - "csstype": "^3.1.2", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.3.0.tgz", + "integrity": "sha512-L+8hUHMNlfReKSqcnVslFrVhoNfz/jw7Fe9NfDE85R3KarvZ4O3MU9daF/lZeqEAvnYxEilkkTfDwQ7qCgJdFg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/private-theming": "^6.3.0", + "@mui/styled-engine": "^6.3.0", + "@mui/types": "^7.2.20", + "@mui/utils": "^6.3.0", + "clsx": "^2.1.1", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -1200,11 +1299,12 @@ } }, "node_modules/@mui/types": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", - "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "version": "7.2.20", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.20.tgz", + "integrity": "sha512-straFHD7L8v05l/N5vcWk+y7eL9JF0C2mtph/y4BPm3gn2Eh61dDwDB65pa8DLss3WJfDXYC7Kx5yjP0EmXpgw==", + "license": "MIT", "peerDependencies": { - "@types/react": "*" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -1213,78 +1313,310 @@ } }, "node_modules/@mui/utils": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.13.1.tgz", - "integrity": "sha512-6lXdWwmlUbEU2jUI8blw38Kt+3ly7xkmV9ljzY4Q20WhsJMWiNry9CX8M+TaP/HbtuyR8XKsdMgQW7h7MM3n3A==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.3.0.tgz", + "integrity": "sha512-MkDBF08OPVwXhAjedyMykRojgvmf0y/jxkBWjystpfI/pasyTYrfdv4jic6s7j3y2+a+SJzS9qrD6X8ZYj/8AQ==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.21.0", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^18.2.0", + "@babel/runtime": "^7.26.0", + "@mui/types": "^7.2.20", + "@types/prop-types": "^15.7.14", + "clsx": "^2.1.1", "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "react-is": "^19.0.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "react": "^17.0.0 || ^18.0.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, - "engines": { - "node": ">= 8" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, - "node_modules/@tsconfig/esm": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@tsconfig/esm/-/esm-1.0.5.tgz", - "integrity": "sha512-JzoZ0h299JRLPfV5VBsMq1TuMy+OmU9bdV/7NcjfRojL0eIcA1k5ESrtjWrDwJRJnk9B0QmgR0rq04LERbdfWw==", - "deprecated": "this package has been deprecated", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz", + "integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz", + "integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz", + "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz", + "integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz", + "integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz", + "integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz", + "integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz", + "integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz", + "integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz", + "integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz", + "integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz", + "integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz", + "integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz", + "integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz", + "integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz", + "integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz", + "integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz", + "integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz", + "integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@tsconfig/strictest": { "version": "2.0.5", @@ -1338,24 +1670,19 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/js-cookie": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==", "license": "MIT" }, - "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", @@ -1363,2327 +1690,479 @@ "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", - "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.2.tgz", + "integrity": "sha512-USU8ZI/xyKJwFTpjSVIrSeHBVAGagkHQKPNbxeWwql/vDmnTIBgx+TJnhFnj1NXgz8XfprU0egV2dROLGpsBEg==", "license": "MIT", "dependencies": { - "@types/prop-types": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.2.tgz", + "integrity": "sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==", "dev": true, "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-1vz2yObaQkLL7YFe/pme2cpvDsCwI1WXIfL+5eLz0MI9gFG24Re16RzUsI8t9XZn9ZWvgLNDrJBmrqXJO7GNQQ==", - "dependencies": { - "@types/react": "*" + "peerDependencies": { + "@types/react": "^19.0.0" } }, "node_modules/@types/react-transition-group": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", - "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", - "dependencies": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { "@types/react": "*" } }, - "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", - "integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", + "node_modules/@vitejs/plugin-react": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/type-utils": "5.59.11", - "@typescript-eslint/utils": "5.59.11", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/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, + "node_modules/@xobotyi/scrollbar-width": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", + "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==", + "license": "MIT" + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", "dependencies": { - "yallist": "^4.0.0" + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" }, "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", - "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", - "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", - "integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.11", - "@typescript-eslint/utils": "5.59.11", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", - "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=10", + "npm": ">=6" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", - "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } - } - }, - "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", - "dev": true, + ], + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" }, "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", - "integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@typescript-eslint/utils/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" + "browserslist": "cli.js" }, "engines": { - "node": ">=10" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "engines": { - "node": ">=10" + "node": ">=6" } }, - "node_modules/@typescript-eslint/utils/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", - "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "node_modules/caniuse-lite": { + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.11", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" }, - "node_modules/@vitejs/plugin-react": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz", - "integrity": "sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==", - "dev": true, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", - "dependencies": { - "@babel/core": "^7.25.2", - "@babel/plugin-transform-react-jsx-self": "^7.24.7", - "@babel/plugin-transform-react-jsx-source": "^7.24.7", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.14.2" - }, "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0" + "node": ">=6" } }, - "node_modules/@xobotyi/scrollbar-width": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", - "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==", + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "license": "MIT" }, - "node_modules/acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", - "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/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/aria-query": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.2.1.tgz", - "integrity": "sha512-7uFg4b+lETFgdaJyETnILsXgnnzVnkHcgRbwbPwevm5x/LmUlt3MjczMRe1zg824iBgXZNRPTBftNYyRSKLp2g==", - "dev": true, - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" + "toggle-selection": "^1.0.6" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", - "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.1.3" - } - }, - "node_modules/ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", - "dev": true - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axe-core": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", - "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", - "dev": true, - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "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/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/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001680", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", - "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "license": "MIT", - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "license": "MIT", + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "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/css-in-js-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", - "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", - "license": "MIT", - "dependencies": { - "hyphenate-style-name": "^1.0.3" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/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==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "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/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.56", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", - "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "license": "MIT", - "dependencies": { - "stackframe": "^1.3.4" - } - }, - "node_modules/es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/esbuild": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", - "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.17.19", - "@esbuild/android-arm64": "0.17.19", - "@esbuild/android-x64": "0.17.19", - "@esbuild/darwin-arm64": "0.17.19", - "@esbuild/darwin-x64": "0.17.19", - "@esbuild/freebsd-arm64": "0.17.19", - "@esbuild/freebsd-x64": "0.17.19", - "@esbuild/linux-arm": "0.17.19", - "@esbuild/linux-arm64": "0.17.19", - "@esbuild/linux-ia32": "0.17.19", - "@esbuild/linux-loong64": "0.17.19", - "@esbuild/linux-mips64el": "0.17.19", - "@esbuild/linux-ppc64": "0.17.19", - "@esbuild/linux-riscv64": "0.17.19", - "@esbuild/linux-s390x": "0.17.19", - "@esbuild/linux-x64": "0.17.19", - "@esbuild/netbsd-x64": "0.17.19", - "@esbuild/openbsd-x64": "0.17.19", - "@esbuild/sunos-x64": "0.17.19", - "@esbuild/win32-arm64": "0.17.19", - "@esbuild/win32-ia32": "0.17.19", - "@esbuild/win32-x64": "0.17.19" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "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.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-airbnb": { - "version": "19.0.4", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", - "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", - "dev": true, - "dependencies": { - "eslint-config-airbnb-base": "^15.0.0", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5" - }, - "engines": { - "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.28.0", - "eslint-plugin-react-hooks": "^4.3.0" - } - }, - "node_modules/eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-config-airbnb-typescript-prettier": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript-prettier/-/eslint-config-airbnb-typescript-prettier-5.0.0.tgz", - "integrity": "sha512-SVphutDwxEJedWKHF+q6FDC4+aKaOn5R8hOBxCpfWnn5qCYAChngPf86Svz78bHgMgbZfohwHPbQeETTPUN9Wg==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "^5.6.0", - "@typescript-eslint/parser": "^5.6.0", - "eslint-config-airbnb": "^19.0.2", - "eslint-config-prettier": "^6.15.0", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^3.1.4", - "eslint-plugin-react": "^7.27.1", - "eslint-plugin-react-hooks": "^4.3.0" - }, - "engines": { - "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "prettier": "^1.18.2 || ^2.0.0", - "typescript": ">=3.3.1" - } - }, - "node_modules/eslint-config-prettier": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", - "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", - "dev": true, - "dependencies": { - "get-stdin": "^6.0.0" - }, - "bin": { - "eslint-config-prettier-check": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=3.14.1" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", - "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.11.0", - "resolve": "^1.22.1" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", - "has": "^1.0.3", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", - "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.7", - "aria-query": "^5.1.3", - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.6.2", - "axobject-query": "^3.1.1", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.3.3", - "language-tags": "=1.0.5", - "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.32.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", - "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.4", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.8" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "dev": true, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", - "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "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/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/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/eslint/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/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", - "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" - }, - "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==" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-shallow-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", - "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" - }, - "node_modules/fastest-stable-stringify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", - "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==", - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "license": "MIT" - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.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.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.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==" - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/hyphenate-style-name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", - "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", - "license": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "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==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, + }, "engines": { - "node": ">=0.8.19" + "node": ">=10" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" } }, - "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/inline-style-prefixer": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", - "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==", + "node_modules/css-in-js-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", + "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", "license": "MIT", "dependencies": { - "css-in-js-utils": "^3.1.0" + "hyphenate-style-name": "^1.0.3" } }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "mdn-data": "2.0.14", + "source-map": "^0.6.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8.0.0" } }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/css-tree/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==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { - "has-bigints": "^1.0.1" + "ms": "2.1.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "node_modules/electron-to-chromium": { + "version": "1.5.56", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", + "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==", "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "ISC" }, - "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "is-arrayish": "^0.2.1" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "stackframe": "^1.3.4" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" } }, - "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==", + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, + "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==", "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "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==" + }, + "node_modules/fast-shallow-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", + "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" + }, + "node_modules/fastest-stable-stringify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", + "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==", + "license": "MIT" + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.12.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "react-is": "^16.7.0" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/hyphenate-style-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" + }, + "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==", "dependencies": { - "has-tostringtag": "^1.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/inline-style-prefixer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", + "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==", + "license": "MIT", + "dependencies": { + "css-in-js-utils": "^3.1.0" } }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -3692,24 +2171,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", @@ -3721,18 +2182,6 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -3751,18 +2200,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "license": "MIT" }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -3776,74 +2213,12 @@ "node": ">=6" } }, - "node_modules/jsx-ast-utils": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", - "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.5", - "object.assign": "^4.1.3" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/language-subtag-registry": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", - "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", - "dev": true - }, - "node_modules/language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", - "dev": true, - "dependencies": { - "language-subtag-registry": "~0.3.2" - } - }, - "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/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -3877,49 +2252,6 @@ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", "license": "MIT" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "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/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/mnemonist": { "version": "0.39.8", "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz", @@ -3961,9 +2293,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { @@ -3971,6 +2303,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -3978,18 +2311,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", @@ -4010,164 +2331,11 @@ "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.hasown": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", - "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/obliterator": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.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/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4197,33 +2365,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -4243,22 +2384,10 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/postcss": { - "version": "8.4.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", - "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -4274,51 +2403,16 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -4334,64 +2428,32 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", + "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", "license": "MIT", "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" + "scheduler": "^0.25.0" }, "peerDependencies": { - "react": "^18.3.1" + "react": "^19.0.0" } }, "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", + "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==", + "license": "MIT" }, "node_modules/react-refresh": { "version": "0.14.2", @@ -4407,6 +2469,7 @@ "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -4428,9 +2491,9 @@ } }, "node_modules/react-use": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.5.1.tgz", - "integrity": "sha512-LG/uPEVRflLWMwi3j/sZqR00nF6JGqTTDblkXK2nzXsIvij06hXl1V/MZIlwj1OKIQUtlh1l9jK8gLsRyCQxMg==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.6.0.tgz", + "integrity": "sha512-OmedEScUMKFfzn1Ir8dBxiLLSOzhKe/dPZwVxcujweSj45aNM7BEGPb9BEVIgVEqEXx6f3/TsXzwIktNgUR02g==", "license": "Unlicense", "dependencies": { "@types/js-cookie": "^2.2.6", @@ -4457,29 +2520,13 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "license": "0BSD" - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "0BSD" + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", @@ -4511,44 +2558,42 @@ "node": ">=4" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/rollup": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz", + "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==", "dev": true, + "license": "MIT", "dependencies": { - "glob": "^7.1.3" + "@types/estree": "1.0.6" }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz", - "integrity": "sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==", - "dev": true, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.29.1", + "@rollup/rollup-android-arm64": "4.29.1", + "@rollup/rollup-darwin-arm64": "4.29.1", + "@rollup/rollup-darwin-x64": "4.29.1", + "@rollup/rollup-freebsd-arm64": "4.29.1", + "@rollup/rollup-freebsd-x64": "4.29.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.29.1", + "@rollup/rollup-linux-arm-musleabihf": "4.29.1", + "@rollup/rollup-linux-arm64-gnu": "4.29.1", + "@rollup/rollup-linux-arm64-musl": "4.29.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.29.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1", + "@rollup/rollup-linux-riscv64-gnu": "4.29.1", + "@rollup/rollup-linux-s390x-gnu": "4.29.1", + "@rollup/rollup-linux-x64-gnu": "4.29.1", + "@rollup/rollup-linux-x64-musl": "4.29.1", + "@rollup/rollup-win32-arm64-msvc": "4.29.1", + "@rollup/rollup-win32-ia32-msvc": "4.29.1", + "@rollup/rollup-win32-x64-msvc": "4.29.1", "fsevents": "~2.3.2" } }, @@ -4561,51 +2606,11 @@ "@babel/runtime": "^7.1.2" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "license": "MIT" }, "node_modules/screenfull": { "version": "5.2.0", @@ -4637,50 +2642,6 @@ "node": ">=6.9" } }, - "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/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -4691,10 +2652,11 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -4744,107 +2706,11 @@ "stacktrace-gps": "^3.0.4" } }, - "node_modules/string.prototype.matchall": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", - "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.3", - "side-channel": "^1.0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "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/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", @@ -4857,12 +2723,6 @@ "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": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, "node_modules/throttle-debounce": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", @@ -4878,18 +2738,6 @@ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "license": "MIT" }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/toggle-selection": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", @@ -4911,92 +2759,29 @@ "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==", "license": "Unlicense" }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "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" - } + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true }, "node_modules/type-fest": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.12.0.tgz", - "integrity": "sha512-qj9wWsnFvVEMUDbESiilKeXeHL7FwwiFcogfhfyjmvT968RXSvnl23f1JOClTHYItsi7o501C/7qVllscUP3oA==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.31.0.tgz", + "integrity": "sha512-yCxltHW07Nkhv/1F6wWBr8kz+5BGMfP+RbRSYFnegVb0qV/UMT0G0ElBloPVerqn4M2ZV80Ir1FtCcYv1cT6vQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=14.16" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -5007,21 +2792,6 @@ "node": ">=14.17" } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/update-browserslist-db": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", @@ -5053,60 +2823,61 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/vite": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", - "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.6.tgz", + "integrity": "sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.17.5", - "postcss": "^8.4.23", - "rollup": "^3.21.0" + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -5115,75 +2886,15 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, - "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/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "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": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -5192,46 +2903,46 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", "dev": true, - "engines": { - "node": ">=10" + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 14" } }, "node_modules/zustand": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.3.9.tgz", - "integrity": "sha512-Tat5r8jOMG1Vcsj8uldMyqYKC5IZvQif8zetmLHs9WoZlntTHmIoNM8TpLRY31ExncuUvUOXehd0kvahkuHjDw==", - "dependencies": { - "use-sync-external-store": "1.2.0" - }, + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.2.tgz", + "integrity": "sha512-8qNdnJVJlHlrKXi50LDqqUNmUbuBjoKLrYQBnoChIbVph7vni+sY+YpvdjXG9YLd/Bxr6scMcR+rm5H3aSqPaw==", + "license": "MIT", "engines": { - "node": ">=12.7.0" + "node": ">=12.20.0" }, "peerDependencies": { - "immer": ">=9.0", - "react": ">=16.8" + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" }, "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, "immer": { "optional": true }, "react": { "optional": true + }, + "use-sync-external-store": { + "optional": true } } } diff --git a/package.json b/package.json index 982617a..e1a49f1 100644 --- a/package.json +++ b/package.json @@ -1,44 +1,41 @@ { - "name": "create-cpu", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "preview": "vite preview", - "type-check": "tsc", - "type-check:watch": "tsc --watch", - "lint": "eslint .", - "lint:fix": "eslint . --fix" - }, - "dependencies": { - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "@mui/icons-material": "^5.11.16", - "@mui/material": "^5.13.5", - "eventemitter3": "^5.0.1", - "memoize-one": "^6.0.0", - "mnemonist": "^0.39.8", - "nullthrows": "^1.1.1", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-use": "^17.5.1", - "tiny-invariant": "^1.3.3", - "transformation-matrix": "^2.16.1", - "zustand": "^4.3.9" - }, - "devDependencies": { - "@tsconfig/esm": "^1.0.5", - "@tsconfig/strictest": "^2.0.5", - "@types/react": "^18.3.12", - "@types/react-dom": "^18.3.1", - "@vitejs/plugin-react": "^4.3.3", - "eslint": "^8.43.0", - "eslint-config-airbnb-typescript-prettier": "^5.0.0", - "prettier": "^2.8.8", - "type-fest": "^3.12.0", - "typescript": "^5.6.3", - "vite": "^4.3.9" - } + "name": "create-cpu", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "type-check": "tsc", + "type-check:watch": "tsc --watch", + "check": "biome check", + "check:fix": "biome check --fix" + }, + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@mui/icons-material": "^6.3.0", + "@mui/material": "^6.3.0", + "eventemitter3": "^5.0.1", + "memoize-one": "^6.0.0", + "mnemonist": "^0.39.8", + "nullthrows": "^1.1.1", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-use": "^17.6.0", + "tiny-invariant": "^1.3.3", + "transformation-matrix": "^2.16.1", + "zustand": "^5.0.2" + }, + "devDependencies": { + "@biomejs/biome": "^1.9.4", + "@tsconfig/strictest": "^2.0.5", + "@types/react": "^19.0.2", + "@types/react-dom": "^19.0.2", + "@vitejs/plugin-react": "^4.3.4", + "type-fest": "^4.31.0", + "typescript": "^5.7.2", + "vite": "^6.0.6" + } } diff --git a/src/App.tsx b/src/App.tsx index 103f6c0..857ed4a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,34 +1,34 @@ import { Box } from "@mui/material"; import { useState } from "react"; import GlobalHeader from "./components/GlobalHeader"; -import type { CCComponentId } from "./store/component"; import EditPage from "./pages/edit"; import HomePage from "./pages/home"; +import type { CCComponentId } from "./store/component"; export default function App() { - const [editedComponentId, setEditedComponentId] = - useState(null); + const [editedComponentId, setEditedComponentId] = + useState(null); - return ( - - - {editedComponentId ? ( - { - setEditedComponentId(null); - }} - /> - ) : ( - - )} - - ); + return ( + + + {editedComponentId ? ( + { + setEditedComponentId(null); + }} + /> + ) : ( + + )} + + ); } diff --git a/src/common/serialization.ts b/src/common/serialization.ts index 81ec880..ec6b03f 100644 --- a/src/common/serialization.ts +++ b/src/common/serialization.ts @@ -3,16 +3,16 @@ import type { CCComponentId } from "../store/component"; export const componentIdMimeType = "application/x.create-cpu.component"; export function setDataTransferAsComponent( - dataTransfer: DataTransfer, - componentId: CCComponentId + dataTransfer: DataTransfer, + componentId: CCComponentId, ): void { - dataTransfer.setData(componentIdMimeType, componentId); + dataTransfer.setData(componentIdMimeType, componentId); } export function parseDataTransferAsComponent( - dataTransfer: DataTransfer + dataTransfer: DataTransfer, ): CCComponentId | null { - const id = dataTransfer.getData(componentIdMimeType); - if (!id) return null; - return id as CCComponentId; + const id = dataTransfer.getData(componentIdMimeType); + if (!id) return null; + return id as CCComponentId; } diff --git a/src/common/theme.ts b/src/common/theme.ts index e8210d3..4f16107 100644 --- a/src/common/theme.ts +++ b/src/common/theme.ts @@ -3,14 +3,13 @@ import { createTheme } from "@mui/material"; // See https://www.figma.com/file/M3dC0Gk98IGSGlxY901rBh/ export const blackColor = "#000000"; export const whiteColor = "#ffffff"; -export const primaryColor = "#00d372"; -export const activeColor = "#00aaff"; +export const primaryColor = "#009966"; export const errorColor = "#ff0000"; export const editorBackgroundColor = "#fafafa"; export const editorGridColor = "#dddddd"; export const theme = createTheme({ - palette: { - primary: { main: primaryColor }, - }, + palette: { + primary: { main: primaryColor }, + }, }); diff --git a/src/common/vector2.ts b/src/common/vector2.ts index 4ae63e4..639730b 100644 --- a/src/common/vector2.ts +++ b/src/common/vector2.ts @@ -1,25 +1,25 @@ export type Vector2 = { x: number; y: number }; export const vector2 = { - zero: { x: 0, y: 0 }, - add: (a: Vector2, b: Vector2): Vector2 => ({ - x: a.x + b.x, - y: a.y + b.y, - }), - sub: (a: Vector2, b: Vector2): Vector2 => ({ - x: a.x - b.x, - y: a.y - b.y, - }), - mul: (a: Vector2, b: number): Vector2 => ({ - x: a.x * b, - y: a.y * b, - }), - div: (a: Vector2, b: number): Vector2 => ({ - x: a.x / b, - y: a.y / b, - }), - fromDomEvent: (e: { offsetX: number; offsetY: number }): Vector2 => ({ - x: e.offsetX, - y: e.offsetY, - }), + zero: { x: 0, y: 0 }, + add: (a: Vector2, b: Vector2): Vector2 => ({ + x: a.x + b.x, + y: a.y + b.y, + }), + sub: (a: Vector2, b: Vector2): Vector2 => ({ + x: a.x - b.x, + y: a.y - b.y, + }), + mul: (a: Vector2, b: number): Vector2 => ({ + x: a.x * b, + y: a.y * b, + }), + div: (a: Vector2, b: number): Vector2 => ({ + x: a.x / b, + y: a.y / b, + }), + fromDomEvent: (e: { offsetX: number; offsetY: number }): Vector2 => ({ + x: e.offsetX, + y: e.offsetY, + }), }; diff --git a/src/components/ComponentPropertyDialog.tsx b/src/components/ComponentPropertyDialog.tsx index 6e4ae4c..e8cf37d 100644 --- a/src/components/ComponentPropertyDialog.tsx +++ b/src/components/ComponentPropertyDialog.tsx @@ -1,59 +1,59 @@ import { - Button, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - TextField, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + TextField, } from "@mui/material"; import { useState } from "react"; export type ComponentPropertyDialogProps = { - defaultName: string; - onAccept(newName: string): void; - onCancel(): void; + defaultName: string; + onAccept(newName: string): void; + onCancel(): void; }; export function ComponentPropertyDialog({ - defaultName, - onAccept, - onCancel, + defaultName, + onAccept, + onCancel, }: ComponentPropertyDialogProps) { - const [newName, setNewName] = useState(defaultName); + const [newName, setNewName] = useState(defaultName); - return ( - -
{ - e.preventDefault(); - if (!newName) return; - onAccept(newName); - }} - > - Component property - - setNewName(e.target.value)} - placeholder="Name" - /> - - - - - -
-
- ); + return ( + +
{ + e.preventDefault(); + if (!newName) return; + onAccept(newName); + }} + > + Component property + + setNewName(e.target.value)} + placeholder="Name" + /> + + + + + +
+
+ ); } diff --git a/src/components/GlobalHeader.tsx b/src/components/GlobalHeader.tsx index 40c388b..183c966 100644 --- a/src/components/GlobalHeader.tsx +++ b/src/components/GlobalHeader.tsx @@ -3,24 +3,24 @@ import type { CSSProperties } from "react"; import { whiteColor } from "../common/theme"; export type GlobalHeaderProps = { - style: CSSProperties; + style: CSSProperties; }; export default function GlobalHeader({ style }: GlobalHeaderProps) { - return ( - - CreateCPU - - ); + return ( + + CreateCPU + + ); } diff --git a/src/index.css b/src/index.css index cc73a3e..b341723 100644 --- a/src/index.css +++ b/src/index.css @@ -1,12 +1,14 @@ :root { - font-family: sans-serif; + font-family: sans-serif; } -:root, body, #root { - height: 100%; +:root, +body, +#root { + height: 100%; } body { - margin: 0; - overflow: hidden; + margin: 0; + overflow: hidden; } diff --git a/src/main.tsx b/src/main.tsx index 55ede6b..bcecf9f 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -3,15 +3,15 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import "./index.css"; -import { StoreProvider } from "./store/react"; import { theme } from "./common/theme"; +import { StoreProvider } from "./store/react"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - - - - - - - + + + + + + + , ); diff --git a/src/pages/edit/Editor/components/ContextMenu.tsx b/src/pages/edit/Editor/components/ContextMenu.tsx index 50f9df1..5daf777 100644 --- a/src/pages/edit/Editor/components/ContextMenu.tsx +++ b/src/pages/edit/Editor/components/ContextMenu.tsx @@ -1,175 +1,175 @@ import { - ClickAwayListener, - MenuList, - Paper, - MenuItem, - Divider, + ClickAwayListener, + Divider, + MenuItem, + MenuList, + Paper, } from "@mui/material"; import nullthrows from "nullthrows"; import invariant from "tiny-invariant"; import { - CCComponentStore, - type CCComponentId, + type CCComponentId, + CCComponentStore, } from "../../../../store/component"; import { - type CCConnection, - CCConnectionStore, + type CCConnection, + CCConnectionStore, } from "../../../../store/connection"; import { - type CCNodeId, - type CCNode, - CCNodeStore, + type CCNode, + type CCNodeId, + CCNodeStore, } from "../../../../store/node"; -import { useComponentEditorStore } from "../store"; import { useStore } from "../../../../store/react"; +import { useComponentEditorStore } from "../store"; export type CCComponentEditorContextMenuProps = { - onEditComponent: (componentId: CCComponentId) => void; + onEditComponent: (componentId: CCComponentId) => void; }; export default function CCComponentEditorContextMenu({ - onEditComponent, + onEditComponent, }: CCComponentEditorContextMenuProps) { - const { store } = useStore(); - const componentEditorState = useComponentEditorStore()(); + const { store } = useStore(); + const componentEditorState = useComponentEditorStore()(); - if (!componentEditorState.contextMenuState) return null; + if (!componentEditorState.contextMenuState) return null; - return ( - - - - Create a node - - {componentEditorState.selectedNodeIds.size > 0 && ( - { - const oldNodes = [...componentEditorState.selectedNodeIds].map( - (nodeId) => { - const node = store.nodes.get(nodeId); - invariant(node); - return node; - } - ); - const oldConnections = [ - ...componentEditorState.selectedConnectionIds, - ].map((connectionId) => { - const connection = store.connections.get(connectionId); - invariant(connection); - return connection; - }); - const newComponent = CCComponentStore.create({ - name: "New Component", - }); - store.components.register(newComponent); - const oldToNewNodeIdMap = new Map(); - const newNodes = oldNodes.map((oldNode) => { - const newNode = CCNodeStore.create({ - parentComponentId: newComponent.id, - position: oldNode.position, - componentId: oldNode.componentId, - }); - oldToNewNodeIdMap.set(oldNode.id, newNode.id); - return newNode; - }); - for (const node of newNodes) store.nodes.register(node); - const newConnections = oldConnections.flatMap( - (oldConnection) => { - const oldFromNodePin = nullthrows( - store.nodePins.get(oldConnection.from) - ); - const oldToNodePin = nullthrows( - store.nodePins.get(oldConnection.to) - ); - const newFromNodeId = nullthrows( - oldToNewNodeIdMap.get(oldFromNodePin.nodeId) - ); - const newToNodeId = nullthrows( - oldToNewNodeIdMap.get(oldToNodePin.nodeId) - ); - return CCConnectionStore.create({ - parentComponentId: newComponent.id, - from: store.nodePins.getByImplementationNodeIdAndPinId( - newFromNodeId, - oldFromNodePin.componentPinId - ).id, - to: store.nodePins.getByImplementationNodeIdAndPinId( - newToNodeId, - oldToNodePin.componentPinId - ).id, - bentPortion: oldConnection.bentPortion, - }); - } - ); - for (const connection of newConnections) - store.connections.register(connection); - store.connections.unregister([ - ...componentEditorState.selectedConnectionIds, - ]); - store.nodes.unregister([...componentEditorState.selectedNodeIds]); - componentEditorState.closeContextMenu(); - onEditComponent(newComponent.id); - }} - > - Create a new component... - - )} - {(componentEditorState.selectedNodeIds.size > 0 || - componentEditorState.selectedConnectionIds.size > 0) && ( - { - if (componentEditorState.selectedNodeIds.size > 0) - store.nodes.unregister([ - ...componentEditorState.selectedNodeIds, - ]); - if (componentEditorState.selectedConnectionIds.size > 0) - store.connections.unregister([ - ...componentEditorState.selectedConnectionIds, - ]); - componentEditorState.selectNode([], true); - componentEditorState.selectConnection([], false); - componentEditorState.closeContextMenu(); - }} - > - Delete - - )} - {(() => { - if (componentEditorState.selectedNodeIds.size !== 1) return undefined; - const iteratorResult = componentEditorState.selectedNodeIds - .values() - .next(); - invariant(!iteratorResult.done); - const targetNode = store.nodes.get(iteratorResult.value); - invariant(targetNode); - const targetComponent = store.components.get(targetNode.componentId); - invariant(targetComponent); - if (targetComponent.intrinsicType) return undefined; - return ( - <> - - { - invariant(targetNode); - componentEditorState.closeContextMenu(); - onEditComponent(targetNode.componentId); - }} - > - Edit... - - - ); - })()} - - - ); + return ( + + + + Create a node + + {componentEditorState.selectedNodeIds.size > 0 && ( + { + const oldNodes = [...componentEditorState.selectedNodeIds].map( + (nodeId) => { + const node = store.nodes.get(nodeId); + invariant(node); + return node; + }, + ); + const oldConnections = [ + ...componentEditorState.selectedConnectionIds, + ].map((connectionId) => { + const connection = store.connections.get(connectionId); + invariant(connection); + return connection; + }); + const newComponent = CCComponentStore.create({ + name: "New Component", + }); + store.components.register(newComponent); + const oldToNewNodeIdMap = new Map(); + const newNodes = oldNodes.map((oldNode) => { + const newNode = CCNodeStore.create({ + parentComponentId: newComponent.id, + position: oldNode.position, + componentId: oldNode.componentId, + }); + oldToNewNodeIdMap.set(oldNode.id, newNode.id); + return newNode; + }); + for (const node of newNodes) store.nodes.register(node); + const newConnections = oldConnections.flatMap( + (oldConnection) => { + const oldFromNodePin = nullthrows( + store.nodePins.get(oldConnection.from), + ); + const oldToNodePin = nullthrows( + store.nodePins.get(oldConnection.to), + ); + const newFromNodeId = nullthrows( + oldToNewNodeIdMap.get(oldFromNodePin.nodeId), + ); + const newToNodeId = nullthrows( + oldToNewNodeIdMap.get(oldToNodePin.nodeId), + ); + return CCConnectionStore.create({ + parentComponentId: newComponent.id, + from: store.nodePins.getByImplementationNodeIdAndPinId( + newFromNodeId, + oldFromNodePin.componentPinId, + ).id, + to: store.nodePins.getByImplementationNodeIdAndPinId( + newToNodeId, + oldToNodePin.componentPinId, + ).id, + bentPortion: oldConnection.bentPortion, + }); + }, + ); + for (const connection of newConnections) + store.connections.register(connection); + store.connections.unregister([ + ...componentEditorState.selectedConnectionIds, + ]); + store.nodes.unregister([...componentEditorState.selectedNodeIds]); + componentEditorState.closeContextMenu(); + onEditComponent(newComponent.id); + }} + > + Create a new component... + + )} + {(componentEditorState.selectedNodeIds.size > 0 || + componentEditorState.selectedConnectionIds.size > 0) && ( + { + if (componentEditorState.selectedNodeIds.size > 0) + store.nodes.unregister([ + ...componentEditorState.selectedNodeIds, + ]); + if (componentEditorState.selectedConnectionIds.size > 0) + store.connections.unregister([ + ...componentEditorState.selectedConnectionIds, + ]); + componentEditorState.selectNode([], true); + componentEditorState.selectConnection([], false); + componentEditorState.closeContextMenu(); + }} + > + Delete + + )} + {(() => { + if (componentEditorState.selectedNodeIds.size !== 1) return undefined; + const iteratorResult = componentEditorState.selectedNodeIds + .values() + .next(); + invariant(!iteratorResult.done); + const targetNode = store.nodes.get(iteratorResult.value); + invariant(targetNode); + const targetComponent = store.components.get(targetNode.componentId); + invariant(targetComponent); + if (targetComponent.intrinsicType) return undefined; + return ( + <> + + { + invariant(targetNode); + componentEditorState.closeContextMenu(); + onEditComponent(targetNode.componentId); + }} + > + Edit... + + + ); + })()} + + + ); } diff --git a/src/pages/edit/Editor/components/Grid.tsx b/src/pages/edit/Editor/components/Grid.tsx index 2653d5a..09ae30d 100644 --- a/src/pages/edit/Editor/components/Grid.tsx +++ b/src/pages/edit/Editor/components/Grid.tsx @@ -1,59 +1,59 @@ import type { ReactElement } from "react"; -import { useComponentEditorStore } from "../store"; import { vector2 } from "../../../../common/vector2"; +import { useComponentEditorStore } from "../store"; export default function CCComponentEditorGrid() { - const componentEditorState = useComponentEditorStore()(); - const logScale = Math.log2(componentEditorState.perspective.scale); - const canvasOriginPosition = componentEditorState.fromStageToCanvas( - vector2.zero - ); - const canvasGridSize = 100 * 2 ** (Math.ceil(logScale) - logScale); + const componentEditorState = useComponentEditorStore()(); + const logScale = Math.log2(componentEditorState.perspective.scale); + const canvasOriginPosition = componentEditorState.fromStageToCanvas( + vector2.zero, + ); + const canvasGridSize = 100 * 2 ** (Math.ceil(logScale) - logScale); - const elements: ReactElement[] = []; - let i = 0; - for ( - let x = (canvasOriginPosition.x % canvasGridSize) - canvasGridSize; - x <= componentEditorState.rendererSize.x; - x += canvasGridSize - ) { - elements.push( -
- ); - i += 1; - } - for ( - let y = (canvasOriginPosition.y % canvasGridSize) - canvasGridSize; - y <= componentEditorState.rendererSize.y; - y += canvasGridSize - ) { - elements.push( -
- ); - i += 1; - } + const elements: ReactElement[] = []; + let i = 0; + for ( + let x = (canvasOriginPosition.x % canvasGridSize) - canvasGridSize; + x <= componentEditorState.rendererSize.x; + x += canvasGridSize + ) { + elements.push( +
, + ); + i += 1; + } + for ( + let y = (canvasOriginPosition.y % canvasGridSize) - canvasGridSize; + y <= componentEditorState.rendererSize.y; + y += canvasGridSize + ) { + elements.push( +
, + ); + i += 1; + } - return
{elements}
; + return
{elements}
; } diff --git a/src/pages/edit/Editor/components/TitleBar.tsx b/src/pages/edit/Editor/components/TitleBar.tsx index 825a010..bce64bd 100644 --- a/src/pages/edit/Editor/components/TitleBar.tsx +++ b/src/pages/edit/Editor/components/TitleBar.tsx @@ -1,48 +1,48 @@ -import { KeyboardDoubleArrowRight, Edit, Close } from "@mui/icons-material"; -import { Paper, Box, IconButton } from "@mui/material"; +import { Close, Edit, KeyboardDoubleArrowRight } from "@mui/icons-material"; +import { Box, IconButton, Paper } from "@mui/material"; import nullthrows from "nullthrows"; -import { useComponentEditorStore } from "../store"; import { useStore } from "../../../../store/react"; +import { useComponentEditorStore } from "../store"; export type CCComponentEditorTitleBarProps = { - onEditorClose: () => void; - onComponentPropertyDialogOpen: () => void; + onEditorClose: () => void; + onComponentPropertyDialogOpen: () => void; }; export default function CCComponentEditorTitleBar({ - onEditorClose, - onComponentPropertyDialogOpen, + onEditorClose, + onComponentPropertyDialogOpen, }: CCComponentEditorTitleBarProps) { - const componentEditorStore = useComponentEditorStore(); - const componentEditorState = componentEditorStore(); - const { store } = useStore(); - const component = nullthrows( - store.components.get(componentEditorState.componentId) - ); + const componentEditorStore = useComponentEditorStore(); + const componentEditorState = componentEditorStore(); + const { store } = useStore(); + const component = nullthrows( + store.components.get(componentEditorState.componentId), + ); - return ( - - Components - - {component.name} - - - -
- - - - - ); + return ( + + Components + + {component.name} + + + +
+ + + + + ); } diff --git a/src/pages/edit/Editor/components/ViewModeSwitcher.tsx b/src/pages/edit/Editor/components/ViewModeSwitcher.tsx index 1940d41..bfac716 100644 --- a/src/pages/edit/Editor/components/ViewModeSwitcher.tsx +++ b/src/pages/edit/Editor/components/ViewModeSwitcher.tsx @@ -3,31 +3,31 @@ import { Fab } from "@mui/material"; import { useComponentEditorStore } from "../store"; export default function CCComponentEditorViewModeSwitcher() { - const componentEditorState = useComponentEditorStore()(); + const componentEditorState = useComponentEditorStore()(); - return ( - <> - { - componentEditorState.setEditorMode( - componentEditorState.editorMode === "edit" ? "play" : "edit" - ); - componentEditorState.resetTimeStep(); - }} - > - {componentEditorState.editorMode === "edit" ? : } - - {componentEditorState.editorMode === "play" && ( - componentEditorState.incrementTimeStep()} - > - - - )} - - ); + return ( + <> + { + componentEditorState.setEditorMode( + componentEditorState.editorMode === "edit" ? "play" : "edit", + ); + componentEditorState.resetTimeStep(); + }} + > + {componentEditorState.editorMode === "edit" ? : } + + {componentEditorState.editorMode === "play" && ( + componentEditorState.incrementTimeStep()} + > + + + )} + + ); } diff --git a/src/pages/edit/Editor/index.tsx b/src/pages/edit/Editor/index.tsx index a614ecd..7574b00 100644 --- a/src/pages/edit/Editor/index.tsx +++ b/src/pages/edit/Editor/index.tsx @@ -1,72 +1,72 @@ import { Box } from "@mui/material"; -import { useState } from "react"; import nullthrows from "nullthrows"; -import { useStore } from "../../../store/react"; -import { ComponentEditorStoreProvider } from "./store"; +import { useState } from "react"; +import { editorBackgroundColor } from "../../../common/theme"; import { ComponentPropertyDialog } from "../../../components/ComponentPropertyDialog"; +import type { CCComponentId } from "../../../store/component"; +import { useStore } from "../../../store/react"; +import CCComponentEditorContextMenu from "./components/ContextMenu"; +import CCComponentEditorGrid from "./components/Grid"; import CCComponentEditorTitleBar from "./components/TitleBar"; import CCComponentEditorViewModeSwitcher from "./components/ViewModeSwitcher"; -import CCComponentEditorContextMenu from "./components/ContextMenu"; -import type { CCComponentId } from "../../../store/component"; import CCComponentEditorRenderer from "./renderer"; -import CCComponentEditorGrid from "./components/Grid"; -import { editorBackgroundColor } from "../../../common/theme"; +import { ComponentEditorStoreProvider } from "./store"; export type CCComponentEditorProps = { - componentId: CCComponentId; - onEditComponent: (componentId: CCComponentId) => void; - onClose: () => void; + componentId: CCComponentId; + onEditComponent: (componentId: CCComponentId) => void; + onClose: () => void; }; function CCComponentEditorContent({ - componentId, - onEditComponent, - onClose, + componentId, + onEditComponent, + onClose, }: CCComponentEditorProps) { - const { store } = useStore(); - const component = nullthrows(store.components.get(componentId)); - const [isComponentPropertyDialogOpen, setIsComponentPropertyDialogOpen] = - useState(false); + const { store } = useStore(); + const component = nullthrows(store.components.get(componentId)); + const [isComponentPropertyDialogOpen, setIsComponentPropertyDialogOpen] = + useState(false); - return ( - - - - - setIsComponentPropertyDialogOpen(true) - } - onEditorClose={onClose} - /> - - - {isComponentPropertyDialogOpen && ( - { - store.components.update(componentId, { name: newName }); - setIsComponentPropertyDialogOpen(false); - }} - onCancel={() => { - setIsComponentPropertyDialogOpen(false); - }} - /> - )} - - ); + return ( + + + + + setIsComponentPropertyDialogOpen(true) + } + onEditorClose={onClose} + /> + + + {isComponentPropertyDialogOpen && ( + { + store.components.update(componentId, { name: newName }); + setIsComponentPropertyDialogOpen(false); + }} + onCancel={() => { + setIsComponentPropertyDialogOpen(false); + }} + /> + )} + + ); } export default function CCComponentEditor(props: CCComponentEditorProps) { - const { componentId } = props; - return ( - - - - ); + const { componentId } = props; + return ( + + + + ); } diff --git a/src/pages/edit/Editor/renderer/Background.tsx b/src/pages/edit/Editor/renderer/Background.tsx index a63595b..1145852 100644 --- a/src/pages/edit/Editor/renderer/Background.tsx +++ b/src/pages/edit/Editor/renderer/Background.tsx @@ -1,57 +1,57 @@ -import { useComponentEditorStore } from "../store"; import { vector2 } from "../../../../common/vector2"; +import { useComponentEditorStore } from "../store"; export default function CCComponentEditorRendererBackground() { - const componentEditorState = useComponentEditorStore()(); - const viewBox = componentEditorState.getViewBox(); + const componentEditorState = useComponentEditorStore()(); + const viewBox = componentEditorState.getViewBox(); - return ( - { - componentEditorState.selectNode([], true); - }} - onPointerDown={(pointerDownEvent) => { - const { currentTarget } = pointerDownEvent; - const startPerspective = componentEditorState.perspective; - const startPoint = vector2.fromDomEvent(pointerDownEvent.nativeEvent); - const onPointerMove = (pointerMoveEvent: PointerEvent) => { - const endPoint = vector2.fromDomEvent(pointerMoveEvent); - componentEditorState.setPerspective({ - ...startPerspective, - center: vector2.sub( - startPerspective.center, - vector2.mul( - vector2.sub(endPoint, startPoint), - startPerspective.scale - ) - ), - }); - }; - currentTarget.addEventListener("pointermove", onPointerMove); - const onPointerUp = () => { - currentTarget.removeEventListener("pointermove", onPointerMove); - currentTarget.removeEventListener("pointerup", onPointerUp); - }; - currentTarget.addEventListener("pointerup", onPointerUp); - }} - onWheel={(wheelEvent) => { - const scaleDelta = Math.exp(wheelEvent.deltaY / 256); - const scaleCenter = componentEditorState.fromCanvasToStage( - vector2.fromDomEvent(wheelEvent.nativeEvent) - ); - componentEditorState.setPerspective({ - scale: componentEditorState.perspective.scale * scaleDelta, - center: vector2.add( - scaleCenter, - vector2.mul( - vector2.sub(componentEditorState.perspective.center, scaleCenter), - scaleDelta - ) - ), - }); - }} - fill="transparent" - /> - ); + return ( + { + componentEditorState.selectNode([], true); + }} + onPointerDown={(pointerDownEvent) => { + const { currentTarget } = pointerDownEvent; + const startPerspective = componentEditorState.perspective; + const startPoint = vector2.fromDomEvent(pointerDownEvent.nativeEvent); + const onPointerMove = (pointerMoveEvent: PointerEvent) => { + const endPoint = vector2.fromDomEvent(pointerMoveEvent); + componentEditorState.setPerspective({ + ...startPerspective, + center: vector2.sub( + startPerspective.center, + vector2.mul( + vector2.sub(endPoint, startPoint), + startPerspective.scale, + ), + ), + }); + }; + currentTarget.addEventListener("pointermove", onPointerMove); + const onPointerUp = () => { + currentTarget.removeEventListener("pointermove", onPointerMove); + currentTarget.removeEventListener("pointerup", onPointerUp); + }; + currentTarget.addEventListener("pointerup", onPointerUp); + }} + onWheel={(wheelEvent) => { + const scaleDelta = Math.exp(wheelEvent.deltaY / 256); + const scaleCenter = componentEditorState.fromCanvasToStage( + vector2.fromDomEvent(wheelEvent.nativeEvent), + ); + componentEditorState.setPerspective({ + scale: componentEditorState.perspective.scale * scaleDelta, + center: vector2.add( + scaleCenter, + vector2.mul( + vector2.sub(componentEditorState.perspective.center, scaleCenter), + scaleDelta, + ), + ), + }); + }} + fill="transparent" + /> + ); } diff --git a/src/pages/edit/Editor/renderer/Connection.tsx b/src/pages/edit/Editor/renderer/Connection.tsx index 85eb569..cca0971 100644 --- a/src/pages/edit/Editor/renderer/Connection.tsx +++ b/src/pages/edit/Editor/renderer/Connection.tsx @@ -1,76 +1,76 @@ import nullthrows from "nullthrows"; import type { CCConnectionId } from "../../../../store/connection"; import { useStore } from "../../../../store/react"; +import ensureStoreItem from "../../../../store/react/error"; import { useNode } from "../../../../store/react/selectors"; import getCCComponentEditorRendererNodeGeometry from "./Node.geometry"; -import ensureStoreItem from "../../../../store/react/error"; export type CCComponentEditorRendererConnectionCoreProps = { - from: { x: number; y: number }; - to: { x: number; y: number }; + from: { x: number; y: number }; + to: { x: number; y: number }; }; export function CCComponentEditorRendererConnectionCore({ - from, - to, + from, + to, }: CCComponentEditorRendererConnectionCoreProps) { - const straightGap = 10; - const direction = from.x < to.x ? 1 : -1; + const straightGap = 10; + const direction = from.x < to.x ? 1 : -1; - return ( - - ); + return ( + + ); } export type CCComponentEditorRendererConnectionProps = { - connectionId: CCConnectionId; + connectionId: CCConnectionId; }; const CCComponentEditorRendererConnection = ensureStoreItem( - (props, store) => store.connections.get(props.connectionId), - ({ connectionId }: CCComponentEditorRendererConnectionProps) => { - const { store } = useStore(); - const connection = nullthrows(store.connections.get(connectionId)); - const fromNodePin = nullthrows(store.nodePins.get(connection.from)); - const toNodePin = nullthrows(store.nodePins.get(connection.to)); - const fromNode = useNode(fromNodePin.nodeId); - const toNode = useNode(toNodePin.nodeId); - const fromNodeGeometry = getCCComponentEditorRendererNodeGeometry( - store, - fromNode.id - ); - const toNodeGeometry = getCCComponentEditorRendererNodeGeometry( - store, - toNode.id - ); - const fromNodePinPosition = nullthrows( - fromNodeGeometry.nodePinPositionById.get(fromNodePin.id) - ); - const toNodePinPosition = nullthrows( - toNodeGeometry.nodePinPositionById.get(toNodePin.id) - ); + (props, store) => store.connections.get(props.connectionId), + ({ connectionId }: CCComponentEditorRendererConnectionProps) => { + const { store } = useStore(); + const connection = nullthrows(store.connections.get(connectionId)); + const fromNodePin = nullthrows(store.nodePins.get(connection.from)); + const toNodePin = nullthrows(store.nodePins.get(connection.to)); + const fromNode = useNode(fromNodePin.nodeId); + const toNode = useNode(toNodePin.nodeId); + const fromNodeGeometry = getCCComponentEditorRendererNodeGeometry( + store, + fromNode.id, + ); + const toNodeGeometry = getCCComponentEditorRendererNodeGeometry( + store, + toNode.id, + ); + const fromNodePinPosition = nullthrows( + fromNodeGeometry.nodePinPositionById.get(fromNodePin.id), + ); + const toNodePinPosition = nullthrows( + toNodeGeometry.nodePinPositionById.get(toNodePin.id), + ); - return ( - - ); - } + return ( + + ); + }, ); export default CCComponentEditorRendererConnection; diff --git a/src/pages/edit/Editor/renderer/Node.geometry.ts b/src/pages/edit/Editor/renderer/Node.geometry.ts index 1e08687..57aa6d1 100644 --- a/src/pages/edit/Editor/renderer/Node.geometry.ts +++ b/src/pages/edit/Editor/renderer/Node.geometry.ts @@ -4,59 +4,59 @@ import type { CCNodeId } from "../../../../store/node"; import type { CCNodePinId } from "../../../../store/nodePin"; export default function getCCComponentEditorRendererNodeGeometry( - store: CCStore, - nodeId: CCNodeId + store: CCStore, + nodeId: CCNodeId, ) { - const width = 100; - const gapY = 20; - const paddingY = 20; + const width = 100; + const gapY = 20; + const paddingY = 20; - const node = nullthrows(store.nodes.get(nodeId)); - const nodePins = store.nodePins.getManyByNodeId(nodeId); + const node = nullthrows(store.nodes.get(nodeId)); + const nodePins = store.nodePins.getManyByNodeId(nodeId); - const x = node.position.x - width / 2; + const x = node.position.x - width / 2; - let inputPinCount = 0; - let outputPinCount = 0; - const nodePinPositionById = new Map(); - for (const nodePin of nodePins) { - const position = { x: 0, y: 0 }; - const componentPin = nullthrows( - store.componentPins.get(nodePin.componentPinId) - ); - if (componentPin.type === "input") { - position.x = node.position.x - width / 2; - position.y = node.position.y + inputPinCount * gapY; - inputPinCount += 1; - } else { - position.x = node.position.x + width / 2; - position.y = node.position.y + outputPinCount * gapY; - outputPinCount += 1; - } - nodePinPositionById.set(nodePin.id, position); - } + let inputPinCount = 0; + let outputPinCount = 0; + const nodePinPositionById = new Map(); + for (const nodePin of nodePins) { + const position = { x: 0, y: 0 }; + const componentPin = nullthrows( + store.componentPins.get(nodePin.componentPinId), + ); + if (componentPin.type === "input") { + position.x = node.position.x - width / 2; + position.y = node.position.y + inputPinCount * gapY; + inputPinCount += 1; + } else { + position.x = node.position.x + width / 2; + position.y = node.position.y + outputPinCount * gapY; + outputPinCount += 1; + } + nodePinPositionById.set(nodePin.id, position); + } - const height = - (Math.max(inputPinCount, outputPinCount) - 1) * gapY + paddingY * 2; - const y = node.position.y - height / 2; + const height = + (Math.max(inputPinCount, outputPinCount) - 1) * gapY + paddingY * 2; + const y = node.position.y - height / 2; - for (const nodePin of nodePins) { - const componentPin = nullthrows( - store.componentPins.get(nodePin.componentPinId) - ); - const position = nullthrows(nodePinPositionById.get(nodePin.id)); - if (componentPin.type === "input") { - position.y -= ((inputPinCount - 1) * gapY) / 2; - } else { - position.y -= ((outputPinCount - 1) * gapY) / 2; - } - } + for (const nodePin of nodePins) { + const componentPin = nullthrows( + store.componentPins.get(nodePin.componentPinId), + ); + const position = nullthrows(nodePinPositionById.get(nodePin.id)); + if (componentPin.type === "input") { + position.y -= ((inputPinCount - 1) * gapY) / 2; + } else { + position.y -= ((outputPinCount - 1) * gapY) / 2; + } + } - return { - x, - y, - width, - height, - nodePinPositionById, - }; + return { + x, + y, + width, + height, + nodePinPositionById, + }; } diff --git a/src/pages/edit/Editor/renderer/Node.tsx b/src/pages/edit/Editor/renderer/Node.tsx index 9819e3a..0332275 100644 --- a/src/pages/edit/Editor/renderer/Node.tsx +++ b/src/pages/edit/Editor/renderer/Node.tsx @@ -1,104 +1,102 @@ import nullthrows from "nullthrows"; import { useState } from "react"; +import { blackColor, primaryColor, whiteColor } from "../../../../common/theme"; +import { vector2 } from "../../../../common/vector2"; import type { CCNodeId } from "../../../../store/node"; -import { useNode } from "../../../../store/react/selectors"; import { useStore } from "../../../../store/react"; +import ensureStoreItem from "../../../../store/react/error"; +import { useNode } from "../../../../store/react/selectors"; import { useComponentEditorStore } from "../store"; -import CCComponentEditorRendererNodePin from "./NodePin"; import getCCComponentEditorRendererNodeGeometry from "./Node.geometry"; -import ensureStoreItem from "../../../../store/react/error"; -import { blackColor, primaryColor, whiteColor } from "../../../../common/theme"; -import { vector2 } from "../../../../common/vector2"; +import CCComponentEditorRendererNodePin from "./NodePin"; export type CCComponentEditorRendererNodeProps = { - nodeId: CCNodeId; + nodeId: CCNodeId; }; const CCComponentEditorRendererNode = ensureStoreItem( - (props, store) => store.nodes.get(props.nodeId), - ({ nodeId }: CCComponentEditorRendererNodeProps) => { - const { store } = useStore(); - const node = useNode(nodeId); - const component = nullthrows(store.components.get(node.componentId)); - const geometry = getCCComponentEditorRendererNodeGeometry(store, nodeId); - const componentEditorState = useComponentEditorStore()(); - const [dragging, setDragging] = useState(false); - const [dragStartPosition, setDragStartPosition] = useState(vector2.zero); - const [previousNodePosition, setPreviousNodePosition] = useState( - vector2.zero - ); + (props, store) => store.nodes.get(props.nodeId), + ({ nodeId }: CCComponentEditorRendererNodeProps) => { + const { store } = useStore(); + const node = useNode(nodeId); + const component = nullthrows(store.components.get(node.componentId)); + const geometry = getCCComponentEditorRendererNodeGeometry(store, nodeId); + const componentEditorState = useComponentEditorStore()(); + const [dragging, setDragging] = useState(false); + const [dragStartPosition, setDragStartPosition] = useState(vector2.zero); + const [previousNodePosition, setPreviousNodePosition] = useState( + vector2.zero, + ); - const handleDragStart = (e: React.PointerEvent) => { - setDragStartPosition(vector2.fromDomEvent(e.nativeEvent)); - setPreviousNodePosition(node.position); - setDragging(true); - e.currentTarget.setPointerCapture(e.pointerId); - }; + const handlePointerDown = (e: React.PointerEvent) => { + componentEditorState.selectNode([nodeId], true); + setDragStartPosition(vector2.fromDomEvent(e.nativeEvent)); + setPreviousNodePosition(node.position); + setDragging(true); + e.currentTarget.setPointerCapture(e.pointerId); + }; - const handleDragging = (e: React.PointerEvent) => { - if (dragging) { - store.nodes.update(nodeId, { - position: vector2.add( - previousNodePosition, - vector2.mul( - vector2.sub( - vector2.fromDomEvent(e.nativeEvent), - dragStartPosition - ), - componentEditorState.perspective.scale - ) - ), - }); - } - }; + const handlePointerMove = (e: React.PointerEvent) => { + if (dragging) { + store.nodes.update(nodeId, { + position: vector2.add( + previousNodePosition, + vector2.mul( + vector2.sub( + vector2.fromDomEvent(e.nativeEvent), + dragStartPosition, + ), + componentEditorState.perspective.scale, + ), + ), + }); + } + }; - const handleDragEnd = (e: React.PointerEvent) => { - setDragging(false); - e.currentTarget.releasePointerCapture(e.pointerId); - }; + const handlePointerUp = (e: React.PointerEvent) => { + setDragging(false); + e.currentTarget.releasePointerCapture(e.pointerId); + }; - return ( - <> - - {component.name} - - { - componentEditorState.selectNode([nodeId], true); - }} - onContextMenu={(e) => { - e.preventDefault(); - componentEditorState.selectNode([nodeId], true); - componentEditorState.openContextMenu(e); - }} - /> - {store.nodePins.getManyByNodeId(nodeId).map((nodePin) => { - const position = nullthrows( - geometry.nodePinPositionById.get(nodePin.id) - ); - return ( - - ); - })} - - ); - } + return ( + <> + + {component.name} + + { + e.preventDefault(); + componentEditorState.selectNode([nodeId], true); + componentEditorState.openContextMenu(e); + }} + /> + {store.nodePins.getManyByNodeId(nodeId).map((nodePin) => { + const position = nullthrows( + geometry.nodePinPositionById.get(nodePin.id), + ); + return ( + + ); + })} + + ); + }, ); export default CCComponentEditorRendererNode; diff --git a/src/pages/edit/Editor/renderer/NodePin.tsx b/src/pages/edit/Editor/renderer/NodePin.tsx index 6d75a19..b382f40 100644 --- a/src/pages/edit/Editor/renderer/NodePin.tsx +++ b/src/pages/edit/Editor/renderer/NodePin.tsx @@ -1,182 +1,186 @@ -import { useState, type PointerEvent, type ReactNode } from "react"; import { KDTree } from "mnemonist"; import nullthrows from "nullthrows"; +import { type PointerEvent, type ReactNode, useState } from "react"; +import { type Vector2, vector2 } from "../../../../common/vector2"; +import { CCConnectionStore } from "../../../../store/connection"; import type { CCNodePinId } from "../../../../store/nodePin"; -import { CCComponentEditorRendererConnectionCore } from "./Connection"; -import { useComponentEditorStore } from "../store"; import { useStore } from "../../../../store/react"; -import getCCComponentEditorRendererNodeGeometry from "./Node.geometry"; -import { CCConnectionStore } from "../../../../store/connection"; +import { useComponentEditorStore } from "../store"; import type { SimulationValue } from "../store/slices/core"; -import { vector2, type Vector2 } from "../../../../common/vector2"; +import { CCComponentEditorRendererConnectionCore } from "./Connection"; +import getCCComponentEditorRendererNodeGeometry from "./Node.geometry"; const NODE_PIN_POSITION_SENSITIVITY = 10; export type CCComponentEditorRendererNodeProps = { - nodePinId: CCNodePinId; - position: Vector2; + nodePinId: CCNodePinId; + position: Vector2; }; export default function CCComponentEditorRendererNodePin({ - nodePinId, - position, + nodePinId, + position, }: CCComponentEditorRendererNodeProps) { - const { store } = useStore(); - const componentEditorState = useComponentEditorStore()(); - const nodePin = nullthrows(store.nodePins.get(nodePinId)); - const node = nullthrows(store.nodes.get(nodePin.nodeId)); - const componentPin = nullthrows( - store.componentPins.get(nodePin.componentPinId) - ); + const { store } = useStore(); + const componentEditorState = useComponentEditorStore()(); + const nodePin = nullthrows(store.nodePins.get(nodePinId)); + const node = nullthrows(store.nodes.get(nodePin.nodeId)); + const componentPin = nullthrows( + store.componentPins.get(nodePin.componentPinId), + ); - const [draggingState, setDraggingState] = useState<{ - cursorPosition: Vector2; - nodePinPositionKDTree: KDTree; - } | null>(null); - const onDrag = (e: PointerEvent) => { - let nodePinPositionKDTree = draggingState?.nodePinPositionKDTree; - if (!nodePinPositionKDTree) { - const nodes = store.nodes.getManyByParentComponentId( - node.parentComponentId - ); - nodePinPositionKDTree = KDTree.from( - nodes - .filter((yourNode) => yourNode.id !== node.id) - .flatMap((yourNode) => [ - ...getCCComponentEditorRendererNodeGeometry(store, yourNode.id) - .nodePinPositionById, - ]) - .flatMap(([yourNodePinId, yourNodePinPosition]) => { - const yourNodePin = nullthrows(store.nodePins.get(yourNodePinId)); - const yourComponentPin = nullthrows( - store.componentPins.get(yourNodePin.componentPinId) - ); - if (yourComponentPin.type === componentPin.type) return []; - return [ - [yourNodePinId, [yourNodePinPosition.x, yourNodePinPosition.y]], - ] as const; - }), - 2 - ); - } - setDraggingState({ - cursorPosition: componentEditorState.fromCanvasToStage( - vector2.fromDomEvent(e.nativeEvent) - ), - nodePinPositionKDTree, - }); - }; + const [draggingState, setDraggingState] = useState<{ + cursorPosition: Vector2; + nodePinPositionKDTree: KDTree; + } | null>(null); + const onDrag = (e: PointerEvent) => { + let nodePinPositionKDTree = draggingState?.nodePinPositionKDTree; + if (!nodePinPositionKDTree) { + const nodes = store.nodes.getManyByParentComponentId( + node.parentComponentId, + ); + nodePinPositionKDTree = KDTree.from( + nodes + .filter((yourNode) => yourNode.id !== node.id) + .flatMap((yourNode) => [ + ...getCCComponentEditorRendererNodeGeometry(store, yourNode.id) + .nodePinPositionById, + ]) + .flatMap(([yourNodePinId, yourNodePinPosition]) => { + const yourNodePin = nullthrows(store.nodePins.get(yourNodePinId)); + const yourComponentPin = nullthrows( + store.componentPins.get(yourNodePin.componentPinId), + ); + if (yourComponentPin.type === componentPin.type) return []; + return [ + [yourNodePinId, [yourNodePinPosition.x, yourNodePinPosition.y]], + ] as const; + }), + 2, + ); + } + setDraggingState({ + cursorPosition: componentEditorState.fromCanvasToStage( + vector2.fromDomEvent(e.nativeEvent), + ), + nodePinPositionKDTree, + }); + }; - let draggingView: ReactNode = null; - let nodePinIdToConnect: CCNodePinId | null = null; - if (draggingState) { - const nearestNodePinId = - draggingState.nodePinPositionKDTree.nearestNeighbor([ - draggingState.cursorPosition.x, - draggingState.cursorPosition.y, - ]); - const nearestNodePin = nullthrows(store.nodePins.get(nearestNodePinId)); - const nearestNodePinPosition = nullthrows( - getCCComponentEditorRendererNodeGeometry( - store, - nearestNodePin.nodeId - ).nodePinPositionById.get(nearestNodePinId) - ); - const distance = Math.hypot( - nearestNodePinPosition.x - draggingState.cursorPosition.x, - nearestNodePinPosition.y - draggingState.cursorPosition.y - ); - if (distance < NODE_PIN_POSITION_SENSITIVITY) { - nodePinIdToConnect = nearestNodePinId; - } - draggingView = ( - - ); - } + let draggingView: ReactNode = null; + let nodePinIdToConnect: CCNodePinId | null = null; + if (draggingState) { + const nearestNodePinId = + draggingState.nodePinPositionKDTree.nearestNeighbor([ + draggingState.cursorPosition.x, + draggingState.cursorPosition.y, + ]); + const nearestNodePin = nullthrows(store.nodePins.get(nearestNodePinId)); + const nearestNodePinPosition = nullthrows( + getCCComponentEditorRendererNodeGeometry( + store, + nearestNodePin.nodeId, + ).nodePinPositionById.get(nearestNodePinId), + ); + const distance = Math.hypot( + nearestNodePinPosition.x - draggingState.cursorPosition.x, + nearestNodePinPosition.y - draggingState.cursorPosition.y, + ); + if (distance < NODE_PIN_POSITION_SENSITIVITY) { + nodePinIdToConnect = nearestNodePinId; + } + draggingView = ( + + ); + } - const isSimulationMode = useComponentEditorStore()( - (s) => s.editorMode === "play" - ); - const hasNoConnection = - store.connections.getConnectionsByNodePinId(nodePinId).length === 0; + const isSimulationMode = useComponentEditorStore()( + (s) => s.editorMode === "play", + ); + const hasNoConnection = + store.connections.getConnectionsByNodePinId(nodePinId).length === 0; - const pinType = componentPin.type; - const simulationValueToString = (simulationValue: SimulationValue) => { - return simulationValue.reduce( - (acm, currentValue) => acm + (currentValue === true ? "1" : "0"), - "" - ); - }; - const implementedComponentPin = - store.componentPins.getByImplementation(nodePinId); - let nodePinValueInit = null; - if (isSimulationMode && hasNoConnection) { - if (pinType === "input") { - nodePinValueInit = componentEditorState.getInputValue( - implementedComponentPin!.id - )!; - } else { - nodePinValueInit = componentEditorState.getNodePinValue(nodePinId)!; - } - } - const nodePinValue = nodePinValueInit; - const updateInputValue = () => { - const updatedPinValue = [...nodePinValue!]; - updatedPinValue[0] = !updatedPinValue[0]; - componentEditorState.setInputValue( - implementedComponentPin!.id, - updatedPinValue - ); - }; + const pinType = componentPin.type; + const simulationValueToString = (simulationValue: SimulationValue) => { + return simulationValue.reduce( + (acm, currentValue) => acm + (currentValue === true ? "1" : "0"), + "", + ); + }; + const implementationComponentPin = + store.componentPins.getByImplementation(nodePinId); + let nodePinValue: SimulationValue; + let nodePinValueAsString: string | null = null; + if (isSimulationMode && hasNoConnection) { + if (implementationComponentPin) { + nodePinValue = nullthrows( + componentEditorState.getInputValue(implementationComponentPin.id), + ); + } else { + nodePinValue = nullthrows( + componentEditorState.getNodePinValue(nodePinId), + ); + } + nodePinValueAsString = simulationValueToString(nodePinValue); + } + const updateInputValue = () => { + if (!implementationComponentPin) return; + const updatedPinValue = [...nodePinValue]; + updatedPinValue[0] = !updatedPinValue[0]; + componentEditorState.setInputValue( + implementationComponentPin.id, + updatedPinValue, + ); + }; - return ( - <> - {isSimulationMode && hasNoConnection && ( - - {simulationValueToString(nodePinValue!)} - - )} - { - e.currentTarget.setPointerCapture(e.pointerId); - onDrag(e); - }} - onPointerMove={draggingState ? onDrag : undefined} - onPointerUp={() => { - if (!nodePinIdToConnect) return; - const route = { - input: { from: nodePinIdToConnect, to: nodePin.id }, - output: { from: nodePin.id, to: nodePinIdToConnect }, - }[componentPin.type]; - store.connections.register( - CCConnectionStore.create({ - parentComponentId: node.parentComponentId, - ...route, - bentPortion: 0.5, - }) - ); - }} - onLostPointerCapture={() => { - setDraggingState(null); - }} - /> - {draggingView} - - ); + return ( + <> + {nodePinValueAsString && ( + + {nodePinValueAsString} + + )} + { + e.currentTarget.setPointerCapture(e.pointerId); + onDrag(e); + }} + onPointerMove={draggingState ? onDrag : undefined} + onPointerUp={() => { + if (!nodePinIdToConnect) return; + const route = { + input: { from: nodePinIdToConnect, to: nodePin.id }, + output: { from: nodePin.id, to: nodePinIdToConnect }, + }[componentPin.type]; + store.connections.register( + CCConnectionStore.create({ + parentComponentId: node.parentComponentId, + ...route, + bentPortion: 0.5, + }), + ); + }} + onLostPointerCapture={() => { + setDraggingState(null); + }} + /> + {draggingView} + + ); } diff --git a/src/pages/edit/Editor/renderer/index.tsx b/src/pages/edit/Editor/renderer/index.tsx index 7004a9f..57237c3 100644 --- a/src/pages/edit/Editor/renderer/index.tsx +++ b/src/pages/edit/Editor/renderer/index.tsx @@ -1,62 +1,63 @@ import { parseDataTransferAsComponent } from "../../../../common/serialization"; +import { vector2 } from "../../../../common/vector2"; +import { CCNodeStore } from "../../../../store/node"; +import { useStore } from "../../../../store/react"; import { - useConnectionIds, - useNodeIds, + useConnectionIds, + useNodeIds, } from "../../../../store/react/selectors"; import { useComponentEditorStore } from "../store"; import CCComponentEditorRendererBackground from "./Background"; import CCComponentEditorRendererConnection from "./Connection"; import CCComponentEditorRendererNode from "./Node"; -import { useStore } from "../../../../store/react"; -import { CCNodeStore } from "../../../../store/node"; -import { vector2 } from "../../../../common/vector2"; export default function CCComponentEditorRenderer() { - const componentEditorState = useComponentEditorStore()(); - const { store } = useStore(); - const viewBox = componentEditorState.getViewBox(); - const nodeIds = useNodeIds(componentEditorState.componentId); - const connectionIds = useConnectionIds(componentEditorState.componentId); + const componentEditorState = useComponentEditorStore()(); + const { store } = useStore(); + const viewBox = componentEditorState.getViewBox(); + const nodeIds = useNodeIds(componentEditorState.componentId); + const connectionIds = useConnectionIds(componentEditorState.componentId); - return ( - { - e.preventDefault(); - }} - onDrop={(e) => { - const droppedComponentId = parseDataTransferAsComponent(e.dataTransfer); - if (!droppedComponentId || componentEditorState.editorMode === "play") - return; - store.nodes.register( - CCNodeStore.create({ - componentId: droppedComponentId, - parentComponentId: componentEditorState.componentId, - position: componentEditorState.fromCanvasToStage( - vector2.fromDomEvent(e.nativeEvent) - ), - }) - ); - }} - > - - {nodeIds.map((nodeId) => ( - - ))} - {connectionIds.map((connectionId) => ( - - ))} - - ); + return ( + { + e.preventDefault(); + }} + onDrop={(e) => { + const droppedComponentId = parseDataTransferAsComponent(e.dataTransfer); + if (!droppedComponentId || componentEditorState.editorMode === "play") + return; + store.nodes.register( + CCNodeStore.create({ + componentId: droppedComponentId, + parentComponentId: componentEditorState.componentId, + position: componentEditorState.fromCanvasToStage( + vector2.fromDomEvent(e.nativeEvent), + ), + }), + ); + }} + > + Component editor + + {nodeIds.map((nodeId) => ( + + ))} + {connectionIds.map((connectionId) => ( + + ))} + + ); } diff --git a/src/pages/edit/Editor/store/index.tsx b/src/pages/edit/Editor/store/index.tsx index 5628ffa..f3dc151 100644 --- a/src/pages/edit/Editor/store/index.tsx +++ b/src/pages/edit/Editor/store/index.tsx @@ -1,29 +1,29 @@ import { createContext, useContext, useState } from "react"; import invariant from "tiny-invariant"; import { create } from "zustand"; -import { useStore } from "../../../../store/react"; import type CCStore from "../../../../store"; import type { CCComponentId } from "../../../../store/component"; +import { useStore } from "../../../../store/react"; +import createComponentEditorStoreContextMenuSlice from "./slices/contextMenu"; import { createComponentEditorStoreCoreSlice } from "./slices/core"; -import type { ComponentEditorStoreValue } from "./types"; import createComponentEditorStorePerspectiveSlice from "./slices/perspective"; -import createComponentEditorStoreContextMenuSlice from "./slices/contextMenu"; +import type { ComponentEditorStoreValue } from "./types"; function createEditorStore(componentId: CCComponentId, store: CCStore) { - const props = { store, componentId }; - const coreSlice = createComponentEditorStoreCoreSlice(props); - const perspectiveSlice = createComponentEditorStorePerspectiveSlice(props); - const contextMenuSlice = createComponentEditorStoreContextMenuSlice(props); - const editorStore = create((set, get) => ({ - componentId, - ...coreSlice.define(set, get), - ...perspectiveSlice.define(set, get), - ...contextMenuSlice.define(set, get), - })); - coreSlice.postCreate?.(editorStore); - perspectiveSlice.postCreate?.(editorStore); - contextMenuSlice.postCreate?.(editorStore); - return editorStore; + const props = { store, componentId }; + const coreSlice = createComponentEditorStoreCoreSlice(props); + const perspectiveSlice = createComponentEditorStorePerspectiveSlice(props); + const contextMenuSlice = createComponentEditorStoreContextMenuSlice(props); + const editorStore = create((set, get) => ({ + componentId, + ...coreSlice.define(set, get), + ...perspectiveSlice.define(set, get), + ...contextMenuSlice.define(set, get), + })); + coreSlice.postCreate?.(editorStore); + perspectiveSlice.postCreate?.(editorStore); + contextMenuSlice.postCreate?.(editorStore); + return editorStore; } export type ComponentEditorStore = ReturnType; @@ -31,22 +31,22 @@ export type ComponentEditorStore = ReturnType; const context = createContext(null); export function ComponentEditorStoreProvider({ - componentId, - children, + componentId, + children, }: { - componentId: CCComponentId; - children: React.ReactNode; + componentId: CCComponentId; + children: React.ReactNode; }) { - const { store } = useStore(); - const [editorStore] = useState(() => createEditorStore(componentId, store)); - return {children}; + const { store } = useStore(); + const [editorStore] = useState(() => createEditorStore(componentId, store)); + return {children}; } export function useComponentEditorStore() { - const store = useContext(context); - invariant( - store, - "useComponentEditorStore must be used within a ComponentEditorStoreProvider" - ); - return store; + const store = useContext(context); + invariant( + store, + "useComponentEditorStore must be used within a ComponentEditorStoreProvider", + ); + return store; } diff --git a/src/pages/edit/Editor/store/slices/contextMenu/index.tsx b/src/pages/edit/Editor/store/slices/contextMenu/index.tsx index 0e685b5..28e8d98 100644 --- a/src/pages/edit/Editor/store/slices/contextMenu/index.tsx +++ b/src/pages/edit/Editor/store/slices/contextMenu/index.tsx @@ -1,25 +1,25 @@ -import { type ComponentEditorSliceCreator } from "../../types"; +import type { ComponentEditorSliceCreator } from "../../types"; import type { ContextMenuStoreSlice } from "./types"; const createComponentEditorStoreContextMenuSlice: ComponentEditorSliceCreator< - ContextMenuStoreSlice + ContextMenuStoreSlice > = () => ({ - define: (set) => ({ - contextMenuState: null, - openContextMenu: (e) => { - set((state) => ({ - ...state, - contextMenuState: { - position: { - x: e.nativeEvent.offsetX, - y: e.nativeEvent.offsetY, - }, - }, - })); - }, - closeContextMenu: () => - set((state) => ({ ...state, contextMenuState: null })), - }), + define: (set) => ({ + contextMenuState: null, + openContextMenu: (e) => { + set((state) => ({ + ...state, + contextMenuState: { + position: { + x: e.nativeEvent.offsetX, + y: e.nativeEvent.offsetY, + }, + }, + })); + }, + closeContextMenu: () => + set((state) => ({ ...state, contextMenuState: null })), + }), }); export default createComponentEditorStoreContextMenuSlice; diff --git a/src/pages/edit/Editor/store/slices/contextMenu/types.ts b/src/pages/edit/Editor/store/slices/contextMenu/types.ts index 35978d8..05e7b49 100644 --- a/src/pages/edit/Editor/store/slices/contextMenu/types.ts +++ b/src/pages/edit/Editor/store/slices/contextMenu/types.ts @@ -2,11 +2,11 @@ import type { MouseEvent } from "react"; import type { Vector2 } from "../../../../../../common/vector2"; export type ContextMenuState = { - position: Vector2; + position: Vector2; }; export type ContextMenuStoreSlice = { - contextMenuState: ContextMenuState | null; - openContextMenu: (e: MouseEvent) => void; - closeContextMenu: () => void; + contextMenuState: ContextMenuState | null; + openContextMenu: (e: MouseEvent) => void; + closeContextMenu: () => void; }; diff --git a/src/pages/edit/Editor/store/slices/core/index.ts b/src/pages/edit/Editor/store/slices/core/index.ts index e71a954..8891cec 100644 --- a/src/pages/edit/Editor/store/slices/core/index.ts +++ b/src/pages/edit/Editor/store/slices/core/index.ts @@ -1,184 +1,191 @@ +import nullthrows from "nullthrows"; import invariant from "tiny-invariant"; import type { CCComponentId } from "../../../../../../store/component"; +import simulateComponent from "../../../../../../store/componentEvaluator"; import type { CCComponentPinId } from "../../../../../../store/componentPin"; +import type { CCConnectionId } from "../../../../../../store/connection"; import type { CCNodeId } from "../../../../../../store/node"; import type { CCNodePinId } from "../../../../../../store/nodePin"; -import type { CCConnectionId } from "../../../../../../store/connection"; import type { ComponentEditorSliceCreator } from "../../types"; import type { EditorStoreCoreSlice } from "./types"; -import simulateComponent from "../../../../../../store/componentEvaluator"; export type SimulationValue = boolean[]; export type SimulationFrame = { - componentId: CCComponentId; - nodes: Map< - CCNodeId, - { - pins: Map; - /** null if intrinsic */ - child: SimulationFrame | null; - } - >; + componentId: CCComponentId; + nodes: Map< + CCNodeId, + { + pins: Map; + /** null if intrinsic */ + child: SimulationFrame | null; + } + >; }; export const createComponentEditorStoreCoreSlice: ComponentEditorSliceCreator< - EditorStoreCoreSlice + EditorStoreCoreSlice > = ({ store, componentId }) => { - let simulationCacheKey = ""; - /** index = timeStep */ - let simulationCachedFrames: SimulationFrame[] = []; + let simulationCacheKey = ""; + /** index = timeStep */ + let simulationCachedFrames: SimulationFrame[] = []; - return { - define: (set, get) => { - return { - editorMode: "edit", - timeStep: 0, - selectedNodeIds: new Set(), - rangeSelect: null, - selectedConnectionIds: new Set(), - /** @private */ - inputValues: new Map(), - getInputValue(componentPinId: CCComponentPinId) { - const value = get().inputValues.get(componentPinId); - if (!value) { - const multiplexability = - store.componentPins.getComponentPinMultiplexability( - componentPinId - ); - if (multiplexability === "undecidable") { - throw new Error("Cannot determine multiplexability"); - } - if (multiplexability.isMultiplexable) { - const newValue = [false]; - return newValue; - } - const newValue = new Array(multiplexability.multiplicity).fill( - false - ); - return newValue; - } - return value; - }, - setInputValue( - componentPinId: CCComponentPinId, - value: SimulationValue - ) { - set((state) => { - return { - ...state, - inputValues: new Map(state.inputValues).set( - componentPinId, - value - ), - }; - }); - }, - setRangeSelect(rangeSelect) { - set((state) => ({ ...state, rangeSelect })); - }, - setEditorMode(mode) { - set((state) => ({ ...state, editorMode: mode })); - }, - resetTimeStep() { - set((state) => ({ ...state, timeStep: 0 })); - }, - incrementTimeStep() { - set((state) => ({ ...state, timeStep: state.timeStep + 1 })); - }, - selectNode(ids: CCNodeId[], exclusive: boolean) { - set((state) => ({ - ...state, - selectedNodeIds: new Set( - exclusive ? ids : [...state.selectedNodeIds, ...ids] - ), - selectedConnectionIds: new Set(), - })); - }, - unselectNode(ids: CCNodeId[]) { - set((state) => ({ - ...state, - selectedNodeIds: new Set( - [...state.selectedNodeIds].filter( - (nodeId) => !ids.includes(nodeId) - ) - ), - selectedConnectionIds: new Set(), - })); - }, - selectConnection(ids: CCConnectionId[], exclusive: boolean) { - set((state) => ({ - ...state, - selectedConnectionIds: new Set( - exclusive ? ids : [...state.selectedConnectionIds, ...ids] - ), - selectedNodeIds: new Set(), - })); - }, - getNodePinValue(nodePinId: CCNodePinId): SimulationValue | undefined { - const { nodeId } = store.nodePins.get(nodePinId)!; - return simulationCachedFrames[get().timeStep]!.nodes.get( - nodeId - )!.pins.get(nodePinId); - }, - getComponentPinValue( - componentPinId: CCComponentPinId - ): SimulationValue | undefined { - const componentPin = store.componentPins.get(componentPinId)!; - invariant(componentPin.implementation); - const nodePinId = componentPin.implementation; - return this.getNodePinValue(nodePinId); - }, - }; - }, - postCreate: (editorStore) => { - const executeSimulation = () => { - if (editorStore.getState().editorMode !== "play") return; + return { + define: (set, get) => { + return { + editorMode: "edit", + timeStep: 0, + selectedNodeIds: new Set(), + rangeSelect: null, + selectedConnectionIds: new Set(), + /** @private */ + inputValues: new Map(), + getInputValue(componentPinId: CCComponentPinId) { + const value = get().inputValues.get(componentPinId); + if (!value) { + const multiplexability = + store.componentPins.getComponentPinMultiplexability( + componentPinId, + ); + if (multiplexability === "undecidable") { + throw new Error("Cannot determine multiplexability"); + } + if (multiplexability.isMultiplexable) { + const newValue = [false]; + return newValue; + } + const newValue = new Array(multiplexability.multiplicity).fill( + false, + ); + return newValue; + } + return value; + }, + setInputValue( + componentPinId: CCComponentPinId, + value: SimulationValue, + ) { + set((state) => { + return { + ...state, + inputValues: new Map(state.inputValues).set( + componentPinId, + value, + ), + }; + }); + }, + setRangeSelect(rangeSelect) { + set((state) => ({ ...state, rangeSelect })); + }, + setEditorMode(mode) { + set((state) => ({ ...state, editorMode: mode })); + }, + resetTimeStep() { + set((state) => ({ ...state, timeStep: 0 })); + }, + incrementTimeStep() { + set((state) => ({ ...state, timeStep: state.timeStep + 1 })); + }, + selectNode(ids: CCNodeId[], exclusive: boolean) { + set((state) => ({ + ...state, + selectedNodeIds: new Set( + exclusive ? ids : [...state.selectedNodeIds, ...ids], + ), + selectedConnectionIds: new Set(), + })); + }, + unselectNode(ids: CCNodeId[]) { + set((state) => ({ + ...state, + selectedNodeIds: new Set( + [...state.selectedNodeIds].filter( + (nodeId) => !ids.includes(nodeId), + ), + ), + selectedConnectionIds: new Set(), + })); + }, + selectConnection(ids: CCConnectionId[], exclusive: boolean) { + set((state) => ({ + ...state, + selectedConnectionIds: new Set( + exclusive ? ids : [...state.selectedConnectionIds, ...ids], + ), + selectedNodeIds: new Set(), + })); + }, + getNodePinValue(nodePinId: CCNodePinId): SimulationValue | undefined { + const { nodeId } = nullthrows(store.nodePins.get(nodePinId)); + return nullthrows( + nullthrows(simulationCachedFrames[get().timeStep]).nodes.get( + nodeId, + ), + ).pins.get(nodePinId); + }, + getComponentPinValue( + componentPinId: CCComponentPinId, + ): SimulationValue | undefined { + const componentPin = nullthrows( + store.componentPins.get(componentPinId), + ); + invariant(componentPin.implementation); + const nodePinId = componentPin.implementation; + return this.getNodePinValue(nodePinId); + }, + }; + }, + postCreate: (editorStore) => { + const executeSimulation = () => { + if (editorStore.getState().editorMode !== "play") return; - const newSimulationCacheKey = - store.nodes - .getMany() - .map((node) => node.id) - .join() + - store.connections - .getMany() - .map((connection) => connection.id) - .join() + - [...editorStore.getState().inputValues.entries()] - .map(([key, value]) => key + value.join()) - .join(); - if (newSimulationCacheKey !== simulationCacheKey) { - simulationCacheKey = newSimulationCacheKey; - simulationCachedFrames = []; - } + const newSimulationCacheKey = + store.nodes + .getMany() + .map((node) => node.id) + .join() + + store.connections + .getMany() + .map((connection) => connection.id) + .join() + + [...editorStore.getState().inputValues.entries()] + .map(([key, value]) => key + value.join()) + .join(); + if (newSimulationCacheKey !== simulationCacheKey) { + simulationCacheKey = newSimulationCacheKey; + simulationCachedFrames = []; + } - const editorState = editorStore.getState(); - let isUpdated = false; - for ( - let timeStep = simulationCachedFrames.length; - timeStep <= editorState.timeStep; - timeStep += 1 - ) { - const previousFrame = simulationCachedFrames[timeStep - 1] ?? null; - const inputValues = new Map(); - const pins = store.componentPins.getManyByComponentId(componentId); - for (const pin of pins) { - if (pin.type === "input") { - inputValues.set(pin.id, editorState.getInputValue(pin.id)); - } - } - simulationCachedFrames.push( - simulateComponent(store, componentId, inputValues, previousFrame)! - ); - isUpdated = true; - } - if (isUpdated) editorStore.setState((s) => ({ ...s })); - }; - store.nodes.on("didRegister", executeSimulation); - store.nodes.on("didUpdate", executeSimulation); - store.nodes.on("didUnregister", executeSimulation); - store.connections.on("didRegister", executeSimulation); - store.connections.on("didUnregister", executeSimulation); - editorStore.subscribe(executeSimulation); - }, - }; + const editorState = editorStore.getState(); + let isUpdated = false; + for ( + let timeStep = simulationCachedFrames.length; + timeStep <= editorState.timeStep; + timeStep += 1 + ) { + const previousFrame = simulationCachedFrames[timeStep - 1] ?? null; + const inputValues = new Map(); + const pins = store.componentPins.getManyByComponentId(componentId); + for (const pin of pins) { + if (pin.type === "input") { + inputValues.set(pin.id, editorState.getInputValue(pin.id)); + } + } + simulationCachedFrames.push( + nullthrows( + simulateComponent(store, componentId, inputValues, previousFrame), + ), + ); + isUpdated = true; + } + if (isUpdated) editorStore.setState((s) => ({ ...s })); + }; + store.nodes.on("didRegister", executeSimulation); + store.nodes.on("didUpdate", executeSimulation); + store.nodes.on("didUnregister", executeSimulation); + store.connections.on("didRegister", executeSimulation); + store.connections.on("didUnregister", executeSimulation); + editorStore.subscribe(executeSimulation); + }, + }; }; diff --git a/src/pages/edit/Editor/store/slices/core/types.ts b/src/pages/edit/Editor/store/slices/core/types.ts index 710ba7a..1f11208 100644 --- a/src/pages/edit/Editor/store/slices/core/types.ts +++ b/src/pages/edit/Editor/store/slices/core/types.ts @@ -1,9 +1,9 @@ +import type { SimulationValue } from "."; +import type { Vector2 } from "../../../../../../common/vector2"; import type { CCComponentPinId } from "../../../../../../store/componentPin"; -import type { CCNodeId } from "../../../../../../store/node"; import type { CCConnectionId } from "../../../../../../store/connection"; -import type { SimulationValue } from "."; +import type { CCNodeId } from "../../../../../../store/node"; import type { CCNodePinId } from "../../../../../../store/nodePin"; -import type { Vector2 } from "../../../../../../common/vector2"; export type EditorMode = EditorModeEdit | EditorModePlay; export type EditorModeEdit = "edit"; @@ -14,23 +14,23 @@ export type RangeSelect = { start: Vector2; end: Vector2 } | null; export type InputValueKey = CCComponentPinId; export type EditorStoreCoreSlice = { - editorMode: EditorMode; - timeStep: number; - selectedNodeIds: Set; - rangeSelect: RangeSelect; - setRangeSelect(rangeSelect: RangeSelect): void; - selectedConnectionIds: Set; - inputValues: Map; - getInputValue(componentPinId: CCComponentPinId): SimulationValue; - setInputValue(componentPinId: CCComponentPinId, value: SimulationValue): void; - setEditorMode(mode: EditorMode): void; - resetTimeStep(): void; - incrementTimeStep(): void; - selectNode(ids: CCNodeId[], exclusive: boolean): void; - unselectNode(ids: CCNodeId[]): void; - selectConnection(ids: CCConnectionId[], exclusive: boolean): void; - getNodePinValue(nodePinId: CCNodePinId): SimulationValue | undefined; - getComponentPinValue( - componentPinId: CCComponentPinId - ): SimulationValue | undefined; + editorMode: EditorMode; + timeStep: number; + selectedNodeIds: Set; + rangeSelect: RangeSelect; + setRangeSelect(rangeSelect: RangeSelect): void; + selectedConnectionIds: Set; + inputValues: Map; + getInputValue(componentPinId: CCComponentPinId): SimulationValue; + setInputValue(componentPinId: CCComponentPinId, value: SimulationValue): void; + setEditorMode(mode: EditorMode): void; + resetTimeStep(): void; + incrementTimeStep(): void; + selectNode(ids: CCNodeId[], exclusive: boolean): void; + unselectNode(ids: CCNodeId[]): void; + selectConnection(ids: CCConnectionId[], exclusive: boolean): void; + getNodePinValue(nodePinId: CCNodePinId): SimulationValue | undefined; + getComponentPinValue( + componentPinId: CCComponentPinId, + ): SimulationValue | undefined; }; diff --git a/src/pages/edit/Editor/store/slices/perspective/index.tsx b/src/pages/edit/Editor/store/slices/perspective/index.tsx index a934104..9e5512e 100644 --- a/src/pages/edit/Editor/store/slices/perspective/index.tsx +++ b/src/pages/edit/Editor/store/slices/perspective/index.tsx @@ -1,66 +1,66 @@ import * as matrix from "transformation-matrix"; -import { type ComponentEditorSliceCreator } from "../../types"; -import type { PerspectiveStoreSlice } from "./types"; import { vector2 } from "../../../../../../common/vector2"; +import type { ComponentEditorSliceCreator } from "../../types"; +import type { PerspectiveStoreSlice } from "./types"; const createComponentEditorStorePerspectiveSlice: ComponentEditorSliceCreator< - PerspectiveStoreSlice + PerspectiveStoreSlice > = () => { - let resizeObserver: ResizeObserver | null; - let resizeObserverObservedElement: SVGSVGElement | null; - const registerRendererElement = (element: SVGSVGElement | null) => { - if (!resizeObserver) return; - if (resizeObserverObservedElement) - resizeObserver.unobserve(resizeObserverObservedElement); - if (element) resizeObserver.observe(element); - resizeObserverObservedElement = element; - }; - return { - define: (set, get) => ({ - perspective: { center: vector2.zero, scale: 1 }, - rendererSize: vector2.zero, - userPerspectiveTransformation: matrix.identity(), - setPerspective: (perspective) => set((s) => ({ ...s, perspective })), - registerRendererElement, - fromCanvasToStage: (point) => - vector2.add( - vector2.mul( - vector2.sub(point, vector2.div(get().rendererSize, 2)), - get().perspective.scale - ), - get().perspective.center - ), - fromStageToCanvas: (point) => - vector2.add( - vector2.div( - vector2.sub(point, get().perspective.center), - get().perspective.scale - ), - vector2.div(get().rendererSize, 2) - ), - getViewBox: () => { - const viewBoxTopLeft = get().fromCanvasToStage(vector2.zero); - const viewBoxBottomRight = get().fromCanvasToStage(get().rendererSize); - return { - x: viewBoxTopLeft.x, - y: viewBoxTopLeft.y, - width: viewBoxBottomRight.x - viewBoxTopLeft.x, - height: viewBoxBottomRight.y - viewBoxTopLeft.y, - }; - }, - }), - postCreate(editorStore) { - resizeObserver = new ResizeObserver((entries) => { - if (!entries[0]) return; - editorStore.setState({ - rendererSize: { - x: entries[0].contentRect.width, - y: entries[0].contentRect.height, - }, - }); - }); - }, - }; + let resizeObserver: ResizeObserver | null; + let resizeObserverObservedElement: SVGSVGElement | null; + const registerRendererElement = (element: SVGSVGElement | null) => { + if (!resizeObserver) return; + if (resizeObserverObservedElement) + resizeObserver.unobserve(resizeObserverObservedElement); + if (element) resizeObserver.observe(element); + resizeObserverObservedElement = element; + }; + return { + define: (set, get) => ({ + perspective: { center: vector2.zero, scale: 1 }, + rendererSize: vector2.zero, + userPerspectiveTransformation: matrix.identity(), + setPerspective: (perspective) => set((s) => ({ ...s, perspective })), + registerRendererElement, + fromCanvasToStage: (point) => + vector2.add( + vector2.mul( + vector2.sub(point, vector2.div(get().rendererSize, 2)), + get().perspective.scale, + ), + get().perspective.center, + ), + fromStageToCanvas: (point) => + vector2.add( + vector2.div( + vector2.sub(point, get().perspective.center), + get().perspective.scale, + ), + vector2.div(get().rendererSize, 2), + ), + getViewBox: () => { + const viewBoxTopLeft = get().fromCanvasToStage(vector2.zero); + const viewBoxBottomRight = get().fromCanvasToStage(get().rendererSize); + return { + x: viewBoxTopLeft.x, + y: viewBoxTopLeft.y, + width: viewBoxBottomRight.x - viewBoxTopLeft.x, + height: viewBoxBottomRight.y - viewBoxTopLeft.y, + }; + }, + }), + postCreate(editorStore) { + resizeObserver = new ResizeObserver((entries) => { + if (!entries[0]) return; + editorStore.setState({ + rendererSize: { + x: entries[0].contentRect.width, + y: entries[0].contentRect.height, + }, + }); + }); + }, + }; }; export default createComponentEditorStorePerspectiveSlice; diff --git a/src/pages/edit/Editor/store/slices/perspective/types.ts b/src/pages/edit/Editor/store/slices/perspective/types.ts index b4203fc..1c774e1 100644 --- a/src/pages/edit/Editor/store/slices/perspective/types.ts +++ b/src/pages/edit/Editor/store/slices/perspective/types.ts @@ -2,11 +2,11 @@ import type { Perspective } from "../../../../../../common/types"; import type { Vector2 } from "../../../../../../common/vector2"; export type PerspectiveStoreSlice = { - perspective: Perspective; - rendererSize: Vector2; - setPerspective: (perspective: Perspective) => void; - registerRendererElement: (element: SVGSVGElement | null) => void; - fromCanvasToStage: (point: Vector2) => Vector2; - fromStageToCanvas: (point: Vector2) => Vector2; - getViewBox: () => { x: number; y: number; width: number; height: number }; + perspective: Perspective; + rendererSize: Vector2; + setPerspective: (perspective: Perspective) => void; + registerRendererElement: (element: SVGSVGElement | null) => void; + fromCanvasToStage: (point: Vector2) => Vector2; + fromStageToCanvas: (point: Vector2) => Vector2; + getViewBox: () => { x: number; y: number; width: number; height: number }; }; diff --git a/src/pages/edit/Editor/store/types.ts b/src/pages/edit/Editor/store/types.ts index d8be9ec..a3acc55 100644 --- a/src/pages/edit/Editor/store/types.ts +++ b/src/pages/edit/Editor/store/types.ts @@ -1,23 +1,23 @@ import type { StoreApi } from "zustand"; import type CCStore from "../../../../store"; import type { CCComponentId } from "../../../../store/component"; -import type { EditorStoreCoreSlice } from "./slices/core/types"; import type { ContextMenuStoreSlice } from "./slices/contextMenu/types"; +import type { EditorStoreCoreSlice } from "./slices/core/types"; import type { PerspectiveStoreSlice } from "./slices/perspective/types"; export type ComponentEditorStoreValue = { - readonly componentId: CCComponentId; + readonly componentId: CCComponentId; } & EditorStoreCoreSlice & - PerspectiveStoreSlice & - ContextMenuStoreSlice; + PerspectiveStoreSlice & + ContextMenuStoreSlice; export type ComponentEditorSliceCreator = (props: { - store: CCStore; - componentId: CCComponentId; + store: CCStore; + componentId: CCComponentId; }) => { - define: ( - set: (reducer: (state: T) => T) => void, - get: () => ComponentEditorStoreValue - ) => T; - postCreate?: (editorStore: StoreApi) => void; + define: ( + set: (reducer: (state: T) => T) => void, + get: () => ComponentEditorStoreValue, + ) => T; + postCreate?: (editorStore: StoreApi) => void; }; diff --git a/src/pages/edit/SidePanel.tsx b/src/pages/edit/SidePanel.tsx index af60463..b985e15 100644 --- a/src/pages/edit/SidePanel.tsx +++ b/src/pages/edit/SidePanel.tsx @@ -1,138 +1,138 @@ +import { Search } from "@mui/icons-material"; import { Box, InputAdornment, TextField } from "@mui/material"; -import invariant from "tiny-invariant"; import nullthrows from "nullthrows"; import { useState } from "react"; -import { Search } from "@mui/icons-material"; -import { useComponents } from "../../store/react/selectors"; -import { useStore } from "../../store/react"; -import { isIncluding, type CCComponentId } from "../../store/component"; -import { ccPinTypes } from "../../store/componentPin"; -import { blackColor, whiteColor } from "../../common/theme"; +import invariant from "tiny-invariant"; import { setDataTransferAsComponent } from "../../common/serialization"; +import { blackColor, whiteColor } from "../../common/theme"; +import { type CCComponentId, isIncluding } from "../../store/component"; +import { ccPinTypes } from "../../store/componentPin"; +import { useStore } from "../../store/react"; +import { useComponents } from "../../store/react/selectors"; export type SidePanelProps = { - editedComponentId: CCComponentId; + editedComponentId: CCComponentId; }; function ComponentRenderer({ componentId }: { componentId: CCComponentId }) { - const { store } = useStore(); - const component = store.components.get(componentId); - invariant(component); - const pins = store.componentPins - .getPinIdsByComponentId(componentId) - .filter((pinId) => store.componentPins.isInterfacePin(pinId)) - .map((ccPinId) => nullthrows(store.componentPins.get(ccPinId))); + const { store } = useStore(); + const component = store.components.get(componentId); + invariant(component); + const pins = store.componentPins + .getPinIdsByComponentId(componentId) + .filter((pinId) => store.componentPins.isInterfacePin(pinId)) + .map((ccPinId) => nullthrows(store.componentPins.get(ccPinId))); - return ( -
-
{component.name}
-
- {ccPinTypes.map((type) => ( -
- {pins - .filter((pin) => pin.type === type) - .map((pin) => ( -
-
-
{pin.name}
-
- ))} -
- ))} -
-
- ); + return ( +
+
{component.name}
+
+ {ccPinTypes.map((type) => ( +
+ {pins + .filter((pin) => pin.type === type) + .map((pin) => ( +
+
+
{pin.name}
+
+ ))} +
+ ))} +
+
+ ); } export default function SidePanel(sidePanelProps: SidePanelProps) { - const { editedComponentId } = sidePanelProps; - const { store } = useStore(); - const components = useComponents(); - const [searchText, setSearchText] = useState(""); + const { editedComponentId } = sidePanelProps; + const { store } = useStore(); + const components = useComponents(); + const [searchText, setSearchText] = useState(""); - return ( - - - - - ), - }} - value={searchText} - onChange={(e) => { - setSearchText(e.target.value); - }} - /> - - {components - .filter((component) => component.name.includes(searchText)) - .filter((component) => component.id !== editedComponentId) - .filter( - (component) => !isIncluding(store, component.id, editedComponentId) - ) - .map((component) => ( - { - setDataTransferAsComponent(e.dataTransfer, component.id); - }} - > - - - ))} - - - ); + return ( + + + + + ), + }} + value={searchText} + onChange={(e) => { + setSearchText(e.target.value); + }} + /> + + {components + .filter((component) => component.name.includes(searchText)) + .filter((component) => component.id !== editedComponentId) + .filter( + (component) => !isIncluding(store, component.id, editedComponentId), + ) + .map((component) => ( + { + setDataTransferAsComponent(e.dataTransfer, component.id); + }} + > + + + ))} + + + ); } diff --git a/src/pages/edit/index.tsx b/src/pages/edit/index.tsx index 12956b9..89b0ef6 100644 --- a/src/pages/edit/index.tsx +++ b/src/pages/edit/index.tsx @@ -1,33 +1,33 @@ import { Divider } from "@mui/material"; -import SidePanel from "./SidePanel"; -import CCComponentEditor from "./Editor"; import type { CCComponentId } from "../../store/component"; +import CCComponentEditor from "./Editor"; +import SidePanel from "./SidePanel"; export type EditPageProps = { - editedComponentId: CCComponentId; - onEditOtherComponent: (componentId: CCComponentId) => void; - onClose: () => void; + editedComponentId: CCComponentId; + onEditOtherComponent: (componentId: CCComponentId) => void; + onClose: () => void; }; export default function EditPage({ - editedComponentId, - onEditOtherComponent, - onClose, + editedComponentId, + onEditOtherComponent, + onClose, }: EditPageProps) { - return ( -
- - - -
- ); + return ( +
+ + + +
+ ); } diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index afb8be0..9661bd1 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -1,148 +1,148 @@ -import { useRef, useState } from "react"; -import { Box, Button, Container, Typography } from "@mui/material"; import { - Save as SaveIcon, - FileOpen as FileOpenIcon, - Add as AddIcon, + Add as AddIcon, + FileOpen as FileOpenIcon, + Save as SaveIcon, } from "@mui/icons-material"; -import { CCComponentStore, type CCComponentId } from "../../store/component"; -import { useComponents } from "../../store/react/selectors"; -import { useStore } from "../../store/react"; -import { type CCStorePropsFromJson } from "../../store"; +import { Box, Button, Container, Typography } from "@mui/material"; +import { useRef, useState } from "react"; import { ComponentPropertyDialog } from "../../components/ComponentPropertyDialog"; +import type { CCStorePropsFromJson } from "../../store"; +import { type CCComponentId, CCComponentStore } from "../../store/component"; +import { useStore } from "../../store/react"; +import { useComponents } from "../../store/react/selectors"; export type HomePageProps = { - onComponentSelected: (componentId: CCComponentId) => void; + onComponentSelected: (componentId: CCComponentId) => void; }; export default function HomePage({ onComponentSelected }: HomePageProps) { - const { store, resetStore } = useStore(); - const components = useComponents().filter( - (component) => !component.intrinsicType - ); - const downloadStore = () => { - const storeJSON = store.toJSON(); - const blob = new Blob([storeJSON], { - type: "application/json", - }); - const url = URL.createObjectURL(blob); - const a = document.createElement("a"); - a.href = url; - a.download = "store.json"; - a.click(); - URL.revokeObjectURL(url); - }; + const { store, resetStore } = useStore(); + const components = useComponents().filter( + (component) => !component.intrinsicType, + ); + const downloadStore = () => { + const storeJSON = store.toJSON(); + const blob = new Blob([storeJSON], { + type: "application/json", + }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "store.json"; + a.click(); + URL.revokeObjectURL(url); + }; - const uploadStore = (e: React.ChangeEvent) => { - const file = e.target.files?.[0]; - if (!file) return; - const reader = new FileReader(); - reader.onload = () => { - const storeJSON = reader.result as string; - const storeData = JSON.parse(storeJSON); - resetStore(storeData as CCStorePropsFromJson); - }; - reader.readAsText(file); - }; + const uploadStore = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + const reader = new FileReader(); + reader.onload = () => { + const storeJSON = reader.result as string; + const storeData = JSON.parse(storeJSON); + resetStore(storeData as CCStorePropsFromJson); + }; + reader.readAsText(file); + }; - const inputRef = useRef(null); + const inputRef = useRef(null); - const [isComponentPropertyDialogOpen, setIsComponentPropertyDialogOpen] = - useState(false); + const [isComponentPropertyDialogOpen, setIsComponentPropertyDialogOpen] = + useState(false); - return ( -
- - - File - - - - uploadStore(e)} - /> - - - -
- - Components - - - Select a component to start editing. - -
-
- -
-
- - {components.map((component) => ( - - ))} - - {isComponentPropertyDialogOpen && ( - { - const newComponent = CCComponentStore.create({ - name: newName, - }); - store.components.register(newComponent); - onComponentSelected(newComponent.id); - }} - onCancel={() => { - setIsComponentPropertyDialogOpen(false); - }} - /> - )} -
-
- ); + return ( +
+ + + File + + + + uploadStore(e)} + /> + + + +
+ + Components + + + Select a component to start editing. + +
+
+ +
+
+ + {components.map((component) => ( + + ))} + + {isComponentPropertyDialogOpen && ( + { + const newComponent = CCComponentStore.create({ + name: newName, + }); + store.components.register(newComponent); + onComponentSelected(newComponent.id); + }} + onCancel={() => { + setIsComponentPropertyDialogOpen(false); + }} + /> + )} +
+
+ ); } diff --git a/src/store/component.ts b/src/store/component.ts index 9132651..b7c4b22 100644 --- a/src/store/component.ts +++ b/src/store/component.ts @@ -1,121 +1,121 @@ -import type { Opaque } from "type-fest"; import EventEmitter from "eventemitter3"; +import nullthrows from "nullthrows"; import invariant from "tiny-invariant"; +import type { Opaque } from "type-fest"; import type CCStore from "."; import type { CCIntrinsicComponentType } from "./intrinsics"; export type CCComponentId = Opaque; export type CCComponent = { - readonly id: CCComponentId; - /** null for user-defined components */ - readonly intrinsicType: CCIntrinsicComponentType | null; - name: string; + readonly id: CCComponentId; + /** null for user-defined components */ + readonly intrinsicType: CCIntrinsicComponentType | null; + name: string; }; export type CCComponentStoreEvents = { - didRegister(component: CCComponent): void; - willUnregister(component: CCComponent): void; - didUnregister(component: CCComponent): void; - didUpdate(component: CCComponent): void; + didRegister(component: CCComponent): void; + willUnregister(component: CCComponent): void; + didUnregister(component: CCComponent): void; + didUpdate(component: CCComponent): void; }; /** * Store of components */ export class CCComponentStore extends EventEmitter { - #store: CCStore; - - #components: Map = new Map(); - - /** - * Constructor of CCComponentStore - * @param store store - * @param rootComponent root component - * @param rootComponentId id of root component - * @param components initial components - */ - constructor(store: CCStore) { - super(); - this.#store = store; - } - - import(components: CCComponent[]) { - for (const component of components) { - this.register(component); - } - } - - // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-empty-function - mount() {} - - /** - * Register a component - * @param component component to be registered - */ - register(component: CCComponent): void { - invariant(!this.#components.has(component.id)); - this.#components.set(component.id, component); - this.emit("didRegister", component); - } - - /** - * Unregister a component - * @param id id of a component to be unregistered - */ - async unregister(id: CCComponentId): Promise { - const component = this.#components.get(id); - if (!component) throw new Error(`Component ${id} not found`); - await this.#store.transactionManager.runInTransaction(() => { - this.emit("willUnregister", component); - this.#components.delete(id); - }); - this.emit("didUnregister", component); - } - - /** - * Get a component by CCComponentId - * @param id id of component - * @returns component of `id` - */ - get(id: CCComponentId): CCComponent | undefined { - return this.#components.get(id); - } - - /** - * Update the name of component - * @param id id of component - * @param value new name - */ - update(id: CCComponentId, value: Pick): void { - const component = this.#components.get(id); - invariant(component); - this.#components.set(id, { ...component, ...value }); - this.emit("didUpdate", component); - } - - /** - * Create a new component - * @param partialComponent component without `id` and `isIntrinsic` - * @returns a new component - */ - static create( - partialComponent: Omit - ): CCComponent { - return { - id: crypto.randomUUID() as CCComponentId, - intrinsicType: null, - ...partialComponent, - }; - } - - /** - * Get array of components - * @returns array of components - */ - getMany(): CCComponent[] { - return [...this.#components.values()]; - } + #store: CCStore; + + #components: Map = new Map(); + + /** + * Constructor of CCComponentStore + * @param store store + * @param rootComponent root component + * @param rootComponentId id of root component + * @param components initial components + */ + constructor(store: CCStore) { + super(); + this.#store = store; + } + + import(components: CCComponent[]) { + for (const component of components) { + this.register(component); + } + } + + mount() {} + + /** + * Register a component + * @param component component to be registered + */ + register(component: CCComponent): void { + invariant(!this.#components.has(component.id)); + this.#components.set(component.id, component); + this.emit("didRegister", component); + } + + /** + * Unregister a component + * @param id id of a component to be unregistered + */ + async unregister(id: CCComponentId): Promise { + const component = this.#components.get(id); + if (!component) throw new Error(`Component ${id} not found`); + await this.#store.transactionManager.runInTransaction(() => { + this.emit("willUnregister", component); + this.#components.delete(id); + }); + this.emit("didUnregister", component); + } + + /** + * Get a component by CCComponentId + * @param id id of component + * @returns component of `id` + */ + get(id: CCComponentId): CCComponent | undefined { + return this.#components.get(id); + } + + /** + * Update the name of component + * @param id id of component + * @param value new name + */ + update(id: CCComponentId, value: Pick): void { + const component = this.#components.get(id); + invariant(component); + this.#components.set(id, { ...component, ...value }); + this.emit("didUpdate", component); + } + + /** + * Create a new component + * @param partialComponent component without `id` and `isIntrinsic` + * @returns a new component + */ + static create( + partialComponent: Omit, + ): CCComponent { + return { + id: crypto.randomUUID() as CCComponentId, + intrinsicType: null, + ...partialComponent, + }; + } + + /** + * Get array of components + * @returns array of components + */ + getMany(): CCComponent[] { + return [...this.#components.values()]; + } } /** @@ -126,94 +126,94 @@ export class CCComponentStore extends EventEmitter { * @returns if the component of `componentId` is including the component of `targetComponentId`, `true` returns (otherwise `false`) */ export function isIncluding( - store: CCStore, - componentId: CCComponentId, - targetComponentId: CCComponentId + store: CCStore, + componentId: CCComponentId, + targetComponentId: CCComponentId, ) { - const component = store.components.get(componentId)!; - if (component.intrinsicType) return false; - - const checkedComponentIds = new Set(); - const dfs = (_componentId: CCComponentId): boolean => { - const nodes = store.nodes.getManyByParentComponentId(_componentId); - for (const node of nodes) { - if (!checkedComponentIds.has(node.componentId)) { - if (node.componentId === targetComponentId) return true; - if (isIncluding(store, node.componentId, targetComponentId)) - return true; - checkedComponentIds.add(node.componentId); - } - } - return false; - }; - return dfs(componentId); + const component = nullthrows(store.components.get(componentId)); + if (component.intrinsicType) return false; + + const checkedComponentIds = new Set(); + const dfs = (_componentId: CCComponentId): boolean => { + const nodes = store.nodes.getManyByParentComponentId(_componentId); + for (const node of nodes) { + if (!checkedComponentIds.has(node.componentId)) { + if (node.componentId === targetComponentId) return true; + if (isIncluding(store, node.componentId, targetComponentId)) + return true; + checkedComponentIds.add(node.componentId); + } + } + return false; + }; + return dfs(componentId); } function validateComponent(store: CCStore, componentId: CCComponentId) { - const component = store.components.get(componentId)!; - if (component.intrinsicType) return; - - const nodes = store.nodes.getManyByParentComponentId(componentId); - const connections = store.connections.getManyByParentComponentId(componentId); - const parentComponentPins = - store.componentPins.getManyByComponentId(componentId); - - // check nodePins and componentPins of each node - for (const node of nodes) { - const nodePins = new Set(store.nodePins.getManyByNodeId(node.id)); - const componentPinIds = new Set( - store.componentPins - .getManyByComponentId(node.componentId) - .map((pin) => pin.id) - ); - invariant(componentPinIds.size === nodePins.size); - for (const nodePin of nodePins) { - invariant(componentPinIds.has(nodePin.componentPinId)); - - // check whether each nodePin without connections corresponds to a parentComponentPin - // and nodePin with connections corresponds to no parentComponentPin - const connectionsAssociatedWithNodePin = - store.connections.getConnectionsByNodePinId(nodePin.id); - const parentComponentPin = parentComponentPins.find( - (pin) => pin.implementation === nodePin.id - ); - if (connectionsAssociatedWithNodePin.length === 0) { - invariant(parentComponentPin); - } else { - invariant(!parentComponentPin); - } - } - } - - // check whether each connection has valid nodePins and componentPins - for (const connection of connections) { - const fromNodePin = store.nodePins.get(connection.from); - const toNodePin = store.nodePins.get(connection.to); - invariant(fromNodePin && toNodePin); - invariant(fromNodePin.nodeId !== toNodePin.nodeId); - const fromComponentPin = store.componentPins.get( - fromNodePin.componentPinId - ); - const toComponentPin = store.componentPins.get(toNodePin.componentPinId); - invariant(fromComponentPin && toComponentPin); - invariant(fromComponentPin.type !== toComponentPin.type); - } - - // check whether implementation of each componentPin has no connections - for (const componentPin of parentComponentPins) { - invariant(componentPin.implementation); - const implementationNodePin = store.nodePins.get( - componentPin.implementation - ); - invariant(implementationNodePin); - const connectionsAssociatedWithNodePin = - store.connections.getConnectionsByNodePinId(implementationNodePin.id); - invariant(connectionsAssociatedWithNodePin.length === 0); - } + const component = nullthrows(store.components.get(componentId)); + if (component.intrinsicType) return; + + const nodes = store.nodes.getManyByParentComponentId(componentId); + const connections = store.connections.getManyByParentComponentId(componentId); + const parentComponentPins = + store.componentPins.getManyByComponentId(componentId); + + // check nodePins and componentPins of each node + for (const node of nodes) { + const nodePins = new Set(store.nodePins.getManyByNodeId(node.id)); + const componentPinIds = new Set( + store.componentPins + .getManyByComponentId(node.componentId) + .map((pin) => pin.id), + ); + invariant(componentPinIds.size === nodePins.size); + for (const nodePin of nodePins) { + invariant(componentPinIds.has(nodePin.componentPinId)); + + // check whether each nodePin without connections corresponds to a parentComponentPin + // and nodePin with connections corresponds to no parentComponentPin + const connectionsAssociatedWithNodePin = + store.connections.getConnectionsByNodePinId(nodePin.id); + const parentComponentPin = parentComponentPins.find( + (pin) => pin.implementation === nodePin.id, + ); + if (connectionsAssociatedWithNodePin.length === 0) { + invariant(parentComponentPin); + } else { + invariant(!parentComponentPin); + } + } + } + + // check whether each connection has valid nodePins and componentPins + for (const connection of connections) { + const fromNodePin = store.nodePins.get(connection.from); + const toNodePin = store.nodePins.get(connection.to); + invariant(fromNodePin && toNodePin); + invariant(fromNodePin.nodeId !== toNodePin.nodeId); + const fromComponentPin = store.componentPins.get( + fromNodePin.componentPinId, + ); + const toComponentPin = store.componentPins.get(toNodePin.componentPinId); + invariant(fromComponentPin && toComponentPin); + invariant(fromComponentPin.type !== toComponentPin.type); + } + + // check whether implementation of each componentPin has no connections + for (const componentPin of parentComponentPins) { + invariant(componentPin.implementation); + const implementationNodePin = store.nodePins.get( + componentPin.implementation, + ); + invariant(implementationNodePin); + const connectionsAssociatedWithNodePin = + store.connections.getConnectionsByNodePinId(implementationNodePin.id); + invariant(connectionsAssociatedWithNodePin.length === 0); + } } export function validateAllComponents(store: CCStore) { - for (const component of store.components.getMany()) { - validateComponent(store, component.id); - } + for (const component of store.components.getMany()) { + validateComponent(store, component.id); + } } diff --git a/src/store/componentEvaluator.ts b/src/store/componentEvaluator.ts index cea8c51..befd5c5 100644 --- a/src/store/componentEvaluator.ts +++ b/src/store/componentEvaluator.ts @@ -1,559 +1,652 @@ +import nullthrows from "nullthrows"; import invariant from "tiny-invariant"; import type CCStore from "."; +import type { + SimulationFrame, + SimulationValue, +} from "../pages/edit/Editor/store/slices/core"; import type { CCComponentId } from "./component"; -import type { CCNodeId } from "./node"; +import type { CCComponentPinId } from "./componentPin"; import * as intrinsics from "./intrinsics"; +import type { CCNodeId } from "./node"; import type { CCNodePin, CCNodePinId } from "./nodePin"; -import type { CCComponentPinId } from "./componentPin"; -import type { - SimulationFrame, - SimulationValue, -} from "../pages/edit/Editor/store/slices/core"; function simulateIntrinsic( - store: CCStore, - nodeId: CCNodeId, - inputValues: Map, - parentPreviousFrame: SimulationFrame | null + store: CCStore, + nodeId: CCNodeId, + inputValues: Map, + parentPreviousFrame: SimulationFrame | null, ): Map | null { - const node = store.nodes.get(nodeId)!; - const { componentId } = node; - const pinIds = store.componentPins.getPinIdsByComponentId(componentId); - const nodePins = store.nodePins.getManyByNodeId(nodeId); - const inputNodePins = nodePins.filter((nodePin: CCNodePin) => { - const componentPin = store.componentPins.get(nodePin.componentPinId)!; - return componentPin.type === "input"; - }); - const outputNodePins = nodePins.filter((nodePin: CCNodePin) => { - const componentPin = store.componentPins.get(nodePin.componentPinId)!; - return componentPin.type === "output"; - }); - switch (componentId) { - case intrinsics.notIntrinsicComponentDefinition.component.id: { - invariant(pinIds.length === 2); - const inputPinId = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.notIntrinsicComponentDefinition.inputPins[0]!.id - )!.id; - const inputValue = inputValues.get(inputPinId); - const outputPinId = outputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.notIntrinsicComponentDefinition.outputPins[0]!.id - )!.id; - const outputValue = []; - for (const value of inputValue!) { - outputValue.push(!value); - } - const outputValues = new Map(); - outputValues.set(outputPinId, outputValue); - return outputValues; - } - case intrinsics.andIntrinsicComponentDefinition.component.id: { - invariant(pinIds.length === 3); - const inputPinId0 = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.andIntrinsicComponentDefinition.inputPins[0]!.id - )!.id; - const inputPinId1 = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.andIntrinsicComponentDefinition.inputPins[1]!.id - )!.id; - const inputValue0 = inputValues.get(inputPinId0); - const inputValue1 = inputValues.get(inputPinId1); - const outputPinId = outputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.andIntrinsicComponentDefinition.outputPins[0]!.id - )!.id; - const outputValue = []; - if (inputValue0!.length !== inputValue1!.length) { - return null; - } - for (let i = 0; i < inputValue0!.length; i += 1) { - outputValue.push(inputValue0![i]! && inputValue1![i]!); - } - const outputValues = new Map(); - outputValues.set(outputPinId, outputValue); - return outputValues; - } - case intrinsics.orIntrinsicComponentDefinition.component.id: { - invariant(pinIds.length === 3); - const inputPinId0 = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.orIntrinsicComponentDefinition.inputPins[0]!.id - )!.id; - const inputPinId1 = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.orIntrinsicComponentDefinition.inputPins[1]!.id - )!.id; - const inputValue0 = inputValues.get(inputPinId0); - const inputValue1 = inputValues.get(inputPinId1); - const outputPinId = outputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.orIntrinsicComponentDefinition.outputPins[0]!.id - )!.id; - const outputValue = []; - if (inputValue0!.length !== inputValue1!.length) { - return null; - } - for (let i = 0; i < inputValue0!.length; i += 1) { - outputValue.push(inputValue0![i]! || inputValue1![i]!); - } - const outputValues = new Map(); - outputValues.set(outputPinId, outputValue); - return outputValues; - } - case intrinsics.xorIntrinsicComponentDefinition.component.id: { - invariant(pinIds.length === 3); - const inputPinId0 = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.xorIntrinsicComponentDefinition.inputPins[0]!.id - )!.id; - const inputPinId1 = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.xorIntrinsicComponentDefinition.inputPins[1]!.id - )!.id; - const inputValue0 = inputValues.get(inputPinId0); - const inputValue1 = inputValues.get(inputPinId1); - const outputPinId = outputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.xorIntrinsicComponentDefinition.outputPins[0]!.id - )!.id; - const outputValue = []; - if (inputValue0!.length !== inputValue1!.length) { - return null; - } - for (let i = 0; i < inputValue0!.length; i += 1) { - outputValue.push(inputValue0![i]! !== inputValue1![i]!); - } - const outputValues = new Map(); - outputValues.set(outputPinId, outputValue); - return outputValues; - } - case intrinsics.inputIntrinsicComponentDefinition.component.id: { - invariant(pinIds.length === 2); - const inputPinId = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.inputIntrinsicComponentDefinition.inputPins[0]!.id - )!.id; - const inputValue = inputValues.get(inputPinId); - const outputPinId = outputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.inputIntrinsicComponentDefinition.outputPins[0]!.id - )!.id; - const outputValue = []; - for (const value of inputValue!) { - outputValue.push(value); - } - const outputValues = new Map(); - outputValues.set(outputPinId, outputValue); - return outputValues; - } - case intrinsics.aggregateIntrinsicComponentDefinition.component.id: { - const outputPin = outputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.aggregateIntrinsicComponentDefinition.outputPins[0]!.id - )!; - const outputValue = new Array( - outputPin.userSpecifiedBitWidth! - ).fill(false); - for (const pin of inputNodePins) { - outputValue[pin.order] = inputValues.get(pin.id)![pin.order]!; - } - const outputMap = new Map(); - outputMap.set(outputPin.id, outputValue); - return outputMap; - } - case intrinsics.decomposeIntrinsicComponentDefinition.component.id: { - const inputPinId = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.decomposeIntrinsicComponentDefinition.inputPins[0]!.id - )!.id; - const inputs = inputValues.get(inputPinId)!; - const outputMap = new Map(); - for (const pin of outputNodePins) { - outputMap.set(pin.id, [inputs[pin.order]!]); - } - return outputMap; - } - case intrinsics.flipFlopIntrinsicComponentDefinition.component.id: { - invariant(pinIds.length === 2); - const inputPinId = inputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.flipFlopIntrinsicComponentDefinition.inputPins[0]!.id - )!.id; - const outputPinId = outputNodePins.find( - (nodePin: CCNodePin) => - nodePin.componentPinId === - intrinsics.flipFlopIntrinsicComponentDefinition.outputPins[0]!.id - )!.id; - const outputValues = new Map(); + const node = nullthrows(store.nodes.get(nodeId)); + const { componentId } = node; + const pinIds = store.componentPins.getPinIdsByComponentId(componentId); + const nodePins = store.nodePins.getManyByNodeId(nodeId); + const inputNodePins = nodePins.filter((nodePin: CCNodePin) => { + const componentPin = nullthrows( + store.componentPins.get(nodePin.componentPinId), + ); + return componentPin.type === "input"; + }); + const outputNodePins = nodePins.filter((nodePin: CCNodePin) => { + const componentPin = nullthrows( + store.componentPins.get(nodePin.componentPinId), + ); + return componentPin.type === "output"; + }); + switch (componentId) { + case intrinsics.notIntrinsicComponentDefinition.component.id: { + invariant(pinIds.length === 2); + const inputPinId = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.notIntrinsicComponentDefinition.inputPins[0]) + .id, + ), + ).id; + const inputValue = nullthrows(inputValues.get(inputPinId)); + const outputPinId = nullthrows( + outputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.notIntrinsicComponentDefinition.outputPins[0]) + .id, + ), + ).id; + const outputValue = []; + for (const value of inputValue) { + outputValue.push(!value); + } + const outputValues = new Map(); + outputValues.set(outputPinId, outputValue); + return outputValues; + } + case intrinsics.andIntrinsicComponentDefinition.component.id: { + invariant(pinIds.length === 3); + const inputPinId0 = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.andIntrinsicComponentDefinition.inputPins[0]) + .id, + ), + ).id; + const inputPinId1 = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.andIntrinsicComponentDefinition.inputPins[1]) + .id, + ), + ).id; + const inputValue0 = nullthrows(inputValues.get(inputPinId0)); + const inputValue1 = nullthrows(inputValues.get(inputPinId1)); + const outputPinId = nullthrows( + outputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.andIntrinsicComponentDefinition.outputPins[0]) + .id, + ), + ).id; + const outputValue: SimulationValue = []; + if (inputValue0.length !== inputValue1.length) { + return null; + } + for (let i = 0; i < inputValue0.length; i += 1) { + outputValue.push(nullthrows(inputValue0[i] && inputValue1[i])); + } + const outputValues = new Map(); + outputValues.set(outputPinId, outputValue); + return outputValues; + } + case intrinsics.orIntrinsicComponentDefinition.component.id: { + invariant(pinIds.length === 3); + const inputPinId0 = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.orIntrinsicComponentDefinition.inputPins[0]) + .id, + ), + ).id; + const inputPinId1 = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.orIntrinsicComponentDefinition.inputPins[1]) + .id, + ), + ).id; + const inputValue0 = nullthrows(inputValues.get(inputPinId0)); + const inputValue1 = nullthrows(inputValues.get(inputPinId1)); + const outputPinId = nullthrows( + outputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.orIntrinsicComponentDefinition.outputPins[0]) + .id, + ), + ).id; + const outputValue: SimulationValue = []; + if (inputValue0.length !== inputValue1.length) { + return null; + } + for (let i = 0; i < inputValue0.length; i += 1) { + outputValue.push(nullthrows(inputValue0[i] || inputValue1[i])); + } + const outputValues = new Map(); + outputValues.set(outputPinId, outputValue); + return outputValues; + } + case intrinsics.xorIntrinsicComponentDefinition.component.id: { + invariant(pinIds.length === 3); + const inputPinId0 = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.xorIntrinsicComponentDefinition.inputPins[0]) + .id, + ), + ).id; + const inputPinId1 = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.xorIntrinsicComponentDefinition.inputPins[1]) + .id, + ), + ).id; + const inputValue0 = nullthrows(inputValues.get(inputPinId0)); + const inputValue1 = nullthrows(inputValues.get(inputPinId1)); + const outputPinId = nullthrows( + outputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows(intrinsics.xorIntrinsicComponentDefinition.outputPins[0]) + .id, + ), + ).id; + const outputValue: SimulationValue = []; + if (inputValue0.length !== inputValue1.length) { + return null; + } + for (let i = 0; i < inputValue0.length; i += 1) { + outputValue.push(nullthrows(inputValue0[i] !== inputValue1[i])); + } + const outputValues = new Map(); + outputValues.set(outputPinId, outputValue); + return outputValues; + } + case intrinsics.inputIntrinsicComponentDefinition.component.id: { + invariant(pinIds.length === 2); + const inputPinId = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows( + intrinsics.inputIntrinsicComponentDefinition.inputPins[0], + ).id, + ), + ).id; + const inputValue = nullthrows(inputValues.get(inputPinId)); + const outputPinId = nullthrows( + outputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows( + intrinsics.inputIntrinsicComponentDefinition.outputPins[0], + ).id, + ), + ).id; + const outputValue = []; + for (const value of inputValue) { + outputValue.push(value); + } + const outputValues = new Map(); + outputValues.set(outputPinId, outputValue); + return outputValues; + } + case intrinsics.aggregateIntrinsicComponentDefinition.component.id: { + const outputPin = nullthrows( + outputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows( + intrinsics.aggregateIntrinsicComponentDefinition.outputPins[0], + ).id, + ), + ); + const outputValue = new Array( + nullthrows(outputPin.userSpecifiedBitWidth), + ).fill(false); + for (const pin of inputNodePins) { + outputValue[pin.order] = nullthrows( + nullthrows(inputValues.get(pin.id))[pin.order], + ); + } + const outputMap = new Map(); + outputMap.set(outputPin.id, outputValue); + return outputMap; + } + case intrinsics.decomposeIntrinsicComponentDefinition.component.id: { + const inputPinId = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows( + intrinsics.decomposeIntrinsicComponentDefinition.inputPins[0], + ).id, + ), + ).id; + const inputs = nullthrows(inputValues.get(inputPinId)); + const outputMap = new Map(); + for (const pin of outputNodePins) { + outputMap.set(pin.id, [nullthrows(inputs[pin.order])]); + } + return outputMap; + } + case intrinsics.flipFlopIntrinsicComponentDefinition.component.id: { + invariant(pinIds.length === 2); + const inputPinId = nullthrows( + inputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows( + intrinsics.flipFlopIntrinsicComponentDefinition.inputPins[0], + ).id, + ), + ).id; + const outputPinId = nullthrows( + outputNodePins.find( + (nodePin: CCNodePin) => + nodePin.componentPinId === + nullthrows( + intrinsics.flipFlopIntrinsicComponentDefinition.outputPins[0], + ).id, + ), + ).id; + const outputValues = new Map(); - if (!parentPreviousFrame) { - const multiplicity = - store.nodePins.getNodePinMultiplexability(inputPinId); - if (multiplicity.isMultiplexable) { - outputValues.set(outputPinId, [false]); - } else { - outputValues.set( - outputPinId, - Array.from({ length: multiplicity.multiplicity }, () => false) - ); - } - } else { - const previousValue = parentPreviousFrame.nodes.get(nodeId)!.pins; - const previousInputValue = previousValue.get(inputPinId)!; - outputValues.set(outputPinId, previousInputValue); - } - return outputValues; - } - // case "Sample": - // return true; - default: - throw new Error(`invalid component (${componentId})`); - } + if (!parentPreviousFrame) { + const multiplicity = + store.nodePins.getNodePinMultiplexability(inputPinId); + if (multiplicity.isMultiplexable) { + outputValues.set(outputPinId, [false]); + } else { + outputValues.set( + outputPinId, + Array.from({ length: multiplicity.multiplicity }, () => false), + ); + } + } else { + const previousValue = nullthrows( + parentPreviousFrame.nodes.get(nodeId), + ).pins; + const previousInputValue = nullthrows(previousValue.get(inputPinId)); + outputValues.set(outputPinId, previousInputValue); + } + return outputValues; + } + // case "Sample": + // return true; + default: + throw new Error(`invalid component (${componentId})`); + } } function simulateNode( - store: CCStore, - nodeId: CCNodeId, - inputValues: Map, - previousFrame: SimulationFrame | null + store: CCStore, + nodeId: CCNodeId, + inputValues: Map, + previousFrame: SimulationFrame | null, ): { - outputValues: Map; - pins: Map; - child: SimulationFrame | null; + outputValues: Map; + pins: Map; + child: SimulationFrame | null; } | null { - const node = store.nodes.get(nodeId)!; - const component = store.components.get(node.componentId); - if (!component) throw new Error(`Component ${component} is not defined.`); - if (component.intrinsicType) { - const outputValues = simulateIntrinsic( - store, - nodeId, - inputValues, - previousFrame - ); - if (!outputValues) { - return null; - } - const pins = new Map(); - for (const [key, value] of inputValues) { - pins.set(key, value); - } - for (const [key, value] of outputValues) { - pins.set(key, value); - } - return { outputValues, pins, child: null }; - } - const childMap = new Map< - CCNodeId, - { - pins: Map; - /** null if intrinsic */ - child: SimulationFrame | null; - } - >(); - const nodePins = store.nodePins.getManyByNodeId(nodeId); - const children = store.nodes.getManyByParentComponentId(component.id); - const foundInputNumber = new Map(); - const nodePinInputNumber = new Map(); - const nodePinInputValues = new Map(); - for (const child of children) { - foundInputNumber.set(child.id, 0); - const innerPins = store.nodePins.getManyByNodeId(child.id); - let inputPinNumber = 0; - for (const innerPin of innerPins) { - const componentPin = store.componentPins.get(innerPin.componentPinId)!; - if (componentPin.type === "input") { - inputPinNumber += 1; - } - } - nodePinInputNumber.set(child.id, inputPinNumber); - } - for (const nodePin of nodePins) { - const componentPin = store.componentPins.get(nodePin.componentPinId)!; - if (componentPin.type === "input" && componentPin.implementation) { - const connectedNodePin = store.nodePins.get(componentPin.implementation)!; - nodePinInputValues.set(connectedNodePin.id, inputValues.get(nodePin.id)!); - foundInputNumber.set( - connectedNodePin.nodeId, - foundInputNumber.get(connectedNodePin.nodeId)! + 1 - ); - } - } - const unevaluatedNodes = new Set(); - for (const child of children) { - unevaluatedNodes.add(child.id); - } + const node = nullthrows(store.nodes.get(nodeId)); + const component = store.components.get(node.componentId); + if (!component) throw new Error(`Component ${component} is not defined.`); + if (component.intrinsicType) { + const outputValues = simulateIntrinsic( + store, + nodeId, + inputValues, + previousFrame, + ); + if (!outputValues) { + return null; + } + const pins = new Map(); + for (const [key, value] of inputValues) { + pins.set(key, value); + } + for (const [key, value] of outputValues) { + pins.set(key, value); + } + return { outputValues, pins, child: null }; + } + const childMap = new Map< + CCNodeId, + { + pins: Map; + /** null if intrinsic */ + child: SimulationFrame | null; + } + >(); + const nodePins = store.nodePins.getManyByNodeId(nodeId); + const children = store.nodes.getManyByParentComponentId(component.id); + const foundInputNumber = new Map(); + const nodePinInputNumber = new Map(); + const nodePinInputValues = new Map(); + for (const child of children) { + foundInputNumber.set(child.id, 0); + const innerPins = store.nodePins.getManyByNodeId(child.id); + let inputPinNumber = 0; + for (const innerPin of innerPins) { + const componentPin = nullthrows( + store.componentPins.get(innerPin.componentPinId), + ); + if (componentPin.type === "input") { + inputPinNumber += 1; + } + } + nodePinInputNumber.set(child.id, inputPinNumber); + } + for (const nodePin of nodePins) { + const componentPin = nullthrows( + store.componentPins.get(nodePin.componentPinId), + ); + if (componentPin.type === "input" && componentPin.implementation) { + const connectedNodePin = nullthrows( + store.nodePins.get(componentPin.implementation), + ); + nodePinInputValues.set( + connectedNodePin.id, + nullthrows(inputValues.get(nodePin.id)), + ); + foundInputNumber.set( + connectedNodePin.nodeId, + nullthrows(foundInputNumber.get(connectedNodePin.nodeId)) + 1, + ); + } + } + const unevaluatedNodes = new Set(); + for (const child of children) { + unevaluatedNodes.add(child.id); + } - const outputValues = new Map(); - const visitedFlipFlops = new Set(); + const outputValues = new Map(); + const visitedFlipFlops = new Set(); - while (unevaluatedNodes.size > 0) { - const currentNodeId = [...unevaluatedNodes][0]!; - unevaluatedNodes.delete(currentNodeId); - const currentNode = store.nodes.get(currentNodeId)!; - const currentComponentId = currentNode.componentId; + while (unevaluatedNodes.size > 0) { + const currentNodeId = nullthrows([...unevaluatedNodes][0]); + unevaluatedNodes.delete(currentNodeId); + const currentNode = nullthrows(store.nodes.get(currentNodeId)); + const currentComponentId = currentNode.componentId; - if ( - nodePinInputNumber.get(currentNodeId)! === - foundInputNumber.get(currentNodeId)! - ) { - const frame = previousFrame - ? previousFrame!.nodes.get(currentNodeId)!.child - : null; - const result = simulateNode( - store, - currentNodeId, - nodePinInputValues, - frame - ); - if (!result) { - return null; - } - childMap.set(currentNodeId, result); - for (const [outputPinId, outputValue] of result.outputValues) { - if (!visitedFlipFlops.has(currentNodeId)) { - const connections = - store.connections.getConnectionsByNodePinId(outputPinId)!; - if (connections.length !== 0) { - for (const connection of connections) { - const connectedNodePin = store.nodePins.get(connection.to)!; - nodePinInputValues.set(connectedNodePin.id, outputValue); - foundInputNumber.set( - connectedNodePin.nodeId, - foundInputNumber.get(connectedNodePin.nodeId)! + 1 - ); - } - } else { - const parentNodePin = nodePins.find((nodePin) => { - const componentPin = store.componentPins.get( - nodePin.componentPinId - )!; - return ( - componentPin.type === "output" && - componentPin.implementation === outputPinId - ); - })!; - outputValues.set(parentNodePin.id, outputValue); - } - if ( - currentComponentId === - intrinsics.flipFlopIntrinsicComponentDefinition.component.id - ) { - visitedFlipFlops.add(currentNodeId); - } - } - } - } else if ( - currentComponentId === - intrinsics.flipFlopIntrinsicComponentDefinition.component.id && - !visitedFlipFlops.has(currentNodeId) - ) { - const frame = previousFrame - ? previousFrame?.nodes.get(currentNodeId)!.child - : null; - const result = simulateNode( - store, - currentNodeId, - nodePinInputValues, - frame - ); - if (!result) { - return null; - } - childMap.set(currentNodeId, result); - for (const [outputPinId, outputValue] of result.outputValues) { - if (!visitedFlipFlops.has(currentNodeId)) { - const connections = - store.connections.getConnectionsByNodePinId(outputPinId)!; - if (connections.length !== 0) { - for (const connection of connections) { - const connectedNodePin = store.nodePins.get(connection.to)!; - nodePinInputValues.set(connectedNodePin.id, outputValue); - foundInputNumber.set( - connectedNodePin.nodeId, - foundInputNumber.get(connectedNodePin.nodeId)! + 1 - ); - } - } else { - const parentNodePin = nodePins.find((nodePin) => { - const componentPin = store.componentPins.get( - nodePin.componentPinId - )!; - return ( - componentPin.type === "output" && - componentPin.implementation === outputPinId - ); - })!; - outputValues.set(parentNodePin.id, outputValue); - } - if ( - currentComponentId === - intrinsics.flipFlopIntrinsicComponentDefinition.component.id - ) { - visitedFlipFlops.add(currentNodeId); - } - } - } - visitedFlipFlops.add(currentNodeId); - unevaluatedNodes.add(currentNodeId); - } else { - unevaluatedNodes.add(currentNodeId); - } - } + if ( + nullthrows(nodePinInputNumber.get(currentNodeId)) === + nullthrows(foundInputNumber.get(currentNodeId)) + ) { + const frame = previousFrame + ? nullthrows(nullthrows(previousFrame).nodes.get(currentNodeId)).child + : null; + const result = simulateNode( + store, + currentNodeId, + nodePinInputValues, + frame, + ); + if (!result) { + return null; + } + childMap.set(currentNodeId, result); + for (const [outputPinId, outputValue] of result.outputValues) { + if (!visitedFlipFlops.has(currentNodeId)) { + const connections = nullthrows( + store.connections.getConnectionsByNodePinId(outputPinId), + ); + if (connections.length !== 0) { + for (const connection of connections) { + const connectedNodePin = nullthrows( + store.nodePins.get(connection.to), + ); + nodePinInputValues.set(connectedNodePin.id, outputValue); + foundInputNumber.set( + connectedNodePin.nodeId, + nullthrows(foundInputNumber.get(connectedNodePin.nodeId)) + 1, + ); + } + } else { + const parentNodePin = nullthrows( + nodePins.find((nodePin) => { + const componentPin = nullthrows( + store.componentPins.get(nodePin.componentPinId), + ); + return ( + componentPin.type === "output" && + componentPin.implementation === outputPinId + ); + }), + ); + outputValues.set(parentNodePin.id, outputValue); + } + if ( + currentComponentId === + intrinsics.flipFlopIntrinsicComponentDefinition.component.id + ) { + visitedFlipFlops.add(currentNodeId); + } + } + } + } else if ( + currentComponentId === + intrinsics.flipFlopIntrinsicComponentDefinition.component.id && + !visitedFlipFlops.has(currentNodeId) + ) { + const frame = previousFrame + ? nullthrows(previousFrame?.nodes.get(currentNodeId)).child + : null; + const result = simulateNode( + store, + currentNodeId, + nodePinInputValues, + frame, + ); + if (!result) { + return null; + } + childMap.set(currentNodeId, result); + for (const [outputPinId, outputValue] of result.outputValues) { + if (!visitedFlipFlops.has(currentNodeId)) { + const connections = nullthrows( + store.connections.getConnectionsByNodePinId(outputPinId), + ); + if (connections.length !== 0) { + for (const connection of connections) { + const connectedNodePin = nullthrows( + store.nodePins.get(connection.to), + ); + nodePinInputValues.set(connectedNodePin.id, outputValue); + foundInputNumber.set( + connectedNodePin.nodeId, + nullthrows(foundInputNumber.get(connectedNodePin.nodeId)) + 1, + ); + } + } else { + const parentNodePin = nullthrows( + nodePins.find((nodePin) => { + const componentPin = nullthrows( + store.componentPins.get(nodePin.componentPinId), + ); + return ( + componentPin.type === "output" && + componentPin.implementation === outputPinId + ); + }), + ); + outputValues.set(parentNodePin.id, outputValue); + } + if ( + currentComponentId === + intrinsics.flipFlopIntrinsicComponentDefinition.component.id + ) { + visitedFlipFlops.add(currentNodeId); + } + } + } + visitedFlipFlops.add(currentNodeId); + unevaluatedNodes.add(currentNodeId); + } else { + unevaluatedNodes.add(currentNodeId); + } + } - const pins = new Map(); - for (const [key, value] of inputValues) { - pins.set(key, value); - } - for (const [key, value] of outputValues) { - pins.set(key, value); - } - const child = { componentId: node.componentId, nodes: childMap }; - return { outputValues, pins, child }; + const pins = new Map(); + for (const [key, value] of inputValues) { + pins.set(key, value); + } + for (const [key, value] of outputValues) { + pins.set(key, value); + } + const child = { componentId: node.componentId, nodes: childMap }; + return { outputValues, pins, child }; } export default function simulateComponent( - store: CCStore, - componentId: CCComponentId, - inputValues: Map, - previousFrame: SimulationFrame | null + store: CCStore, + componentId: CCComponentId, + inputValues: Map, + previousFrame: SimulationFrame | null, ): SimulationFrame | null { - const component = store.components.get(componentId); - if (!component) throw new Error(`Component ${component} is not defined.`); - const childMap = new Map< - CCNodeId, - { - pins: Map; - /** null if intrinsic */ - child: SimulationFrame | null; - } - >(); - const componentPins = store.componentPins.getManyByComponentId(componentId); - const children = store.nodes.getManyByParentComponentId(component.id); - const foundInputNumber = new Map(); - const nodePinInputNumber = new Map(); - const nodePinInputValues = new Map(); - for (const child of children) { - foundInputNumber.set(child.id, 0); - const innerPins = store.nodePins.getManyByNodeId(child.id); - let inputPinNumber = 0; - for (const innerPin of innerPins) { - const componentPin = store.componentPins.get(innerPin.componentPinId)!; - if (componentPin.type === "input") { - inputPinNumber += 1; - } - } - nodePinInputNumber.set(child.id, inputPinNumber); - } - for (const componentPin of componentPins) { - if (componentPin.type === "input" && componentPin.implementation) { - const connectedNodePin = store.nodePins.get(componentPin.implementation)!; - nodePinInputValues.set( - connectedNodePin.id, - inputValues.get(componentPin.id)! - ); - foundInputNumber.set( - connectedNodePin.nodeId, - foundInputNumber.get(connectedNodePin.nodeId)! + 1 - ); - } - } - const unevaluatedNodes = new Set(); - for (const child of children) { - unevaluatedNodes.add(child.id); - } + const component = store.components.get(componentId); + if (!component) throw new Error(`Component ${component} is not defined.`); + const childMap = new Map< + CCNodeId, + { + pins: Map; + /** null if intrinsic */ + child: SimulationFrame | null; + } + >(); + const componentPins = store.componentPins.getManyByComponentId(componentId); + const children = store.nodes.getManyByParentComponentId(component.id); + const foundInputNumber = new Map(); + const nodePinInputNumber = new Map(); + const nodePinInputValues = new Map(); + for (const child of children) { + foundInputNumber.set(child.id, 0); + const innerPins = store.nodePins.getManyByNodeId(child.id); + let inputPinNumber = 0; + for (const innerPin of innerPins) { + const componentPin = nullthrows( + store.componentPins.get(innerPin.componentPinId), + ); + if (componentPin.type === "input") { + inputPinNumber += 1; + } + } + nodePinInputNumber.set(child.id, inputPinNumber); + } + for (const componentPin of componentPins) { + if (componentPin.type === "input" && componentPin.implementation) { + const connectedNodePin = nullthrows( + store.nodePins.get(componentPin.implementation), + ); + nodePinInputValues.set( + connectedNodePin.id, + nullthrows(inputValues.get(componentPin.id)), + ); + foundInputNumber.set( + connectedNodePin.nodeId, + nullthrows(foundInputNumber.get(connectedNodePin.nodeId)) + 1, + ); + } + } + const unevaluatedNodes = new Set(); + for (const child of children) { + unevaluatedNodes.add(child.id); + } - const outputValues = new Map(); - const outputNodePinValues = new Map(); - const visitedFlipFlops = new Set(); + const outputValues = new Map(); + const outputNodePinValues = new Map(); + const visitedFlipFlops = new Set(); - while (unevaluatedNodes.size > 0) { - const currentNodeId = [...unevaluatedNodes][0]!; - unevaluatedNodes.delete(currentNodeId); - const currentNode = store.nodes.get(currentNodeId)!; - const currentComponentId = currentNode.componentId; - const currentComponent = store.components.get(currentComponentId)!; + while (unevaluatedNodes.size > 0) { + const currentNodeId = nullthrows([...unevaluatedNodes][0]); + unevaluatedNodes.delete(currentNodeId); + const currentNode = nullthrows(store.nodes.get(currentNodeId)); + const currentComponentId = currentNode.componentId; + const currentComponent = nullthrows( + store.components.get(currentComponentId), + ); - if ( - nodePinInputNumber.get(currentNodeId)! === - foundInputNumber.get(currentNodeId)! - ) { - const frame = (() => { - if (!previousFrame) return null; - if (currentComponent.intrinsicType) { - return previousFrame; - } - return previousFrame.nodes.get(currentNodeId)!.child; - })(); - const currentNodePinInputValues = new Map(); - for (const nodePin of store.nodePins.getManyByNodeId(currentNodeId)) { - currentNodePinInputValues.set( - nodePin.id, - nodePinInputValues.get(nodePin.id)! - ); - } - const result = simulateNode( - store, - currentNodeId, - currentNodePinInputValues, - frame - ); - if (!result) { - return null; - } - childMap.set(currentNodeId, result); - for (const [outputPinId, outputValue] of result.outputValues) { - outputNodePinValues.set(outputPinId, outputValue); - if (!visitedFlipFlops.has(currentNodeId)) { - const connections = - store.connections.getConnectionsByNodePinId(outputPinId)!; - if (connections.length !== 0) { - for (const connection of connections) { - const connectedNodePin = store.nodePins.get(connection.to)!; - nodePinInputValues.set(connectedNodePin.id, outputValue); - foundInputNumber.set( - connectedNodePin.nodeId, - foundInputNumber.get(connectedNodePin.nodeId)! + 1 - ); - } - } else { - const parentComponentPin = componentPins.find((componentPin) => { - return ( - componentPin.type === "output" && - componentPin.implementation === outputPinId - ); - })!; - outputValues.set(parentComponentPin.id, outputValue); - } - if ( - currentComponentId === - intrinsics.flipFlopIntrinsicComponentDefinition.component.id - ) { - visitedFlipFlops.add(currentNodeId); - } - } - } - } else { - unevaluatedNodes.add(currentNodeId); - } - } - return { componentId, nodes: childMap }; + if ( + nodePinInputNumber.get(currentNodeId) === + foundInputNumber.get(currentNodeId) + ) { + const frame = (() => { + if (!previousFrame) return null; + if (currentComponent.intrinsicType) { + return previousFrame; + } + return nullthrows(previousFrame.nodes.get(currentNodeId)).child; + })(); + const currentNodePinInputValues = new Map(); + for (const nodePin of store.nodePins.getManyByNodeId(currentNodeId)) { + const inputValue = nodePinInputValues.get(nodePin.id); + if (inputValue) currentNodePinInputValues.set(nodePin.id, inputValue); + } + const result = simulateNode( + store, + currentNodeId, + currentNodePinInputValues, + frame, + ); + if (!result) { + return null; + } + childMap.set(currentNodeId, result); + for (const [outputPinId, outputValue] of result.outputValues) { + outputNodePinValues.set(outputPinId, outputValue); + if (!visitedFlipFlops.has(currentNodeId)) { + const connections = + store.connections.getConnectionsByNodePinId(outputPinId); + if (connections.length !== 0) { + for (const connection of connections) { + const connectedNodePin = nullthrows( + store.nodePins.get(connection.to), + ); + nodePinInputValues.set(connectedNodePin.id, outputValue); + foundInputNumber.set( + connectedNodePin.nodeId, + nullthrows(foundInputNumber.get(connectedNodePin.nodeId)) + 1, + ); + } + } else { + const parentComponentPin = nullthrows( + componentPins.find((componentPin) => { + return ( + componentPin.type === "output" && + componentPin.implementation === outputPinId + ); + }), + ); + outputValues.set(parentComponentPin.id, outputValue); + } + if ( + currentComponentId === + intrinsics.flipFlopIntrinsicComponentDefinition.component.id + ) { + visitedFlipFlops.add(currentNodeId); + } + } + } + } else { + unevaluatedNodes.add(currentNodeId); + } + } + return { componentId, nodes: childMap }; } diff --git a/src/store/componentPin.ts b/src/store/componentPin.ts index 9441110..f27d330 100644 --- a/src/store/componentPin.ts +++ b/src/store/componentPin.ts @@ -1,19 +1,19 @@ -import type { Opaque } from "type-fest"; import EventEmitter from "eventemitter3"; -import invariant from "tiny-invariant"; import nullthrows from "nullthrows"; +import invariant from "tiny-invariant"; +import type { Opaque } from "type-fest"; import type CCStore from "."; -import { type CCComponentId } from "./component"; +import type { CCComponentId } from "./component"; import * as intrinsic from "./intrinsics"; import type { CCNodePinId } from "./nodePin"; export type CCComponentPin = { - readonly id: CCComponentPinId; - readonly componentId: CCComponentId; - readonly type: CCPinType; - readonly implementation: CCPinImplementation; - order: number; - name: string; + readonly id: CCComponentPinId; + readonly componentId: CCComponentId; + readonly type: CCPinType; + readonly implementation: CCPinImplementation; + order: number; + name: string; }; export type CCComponentPinId = Opaque; @@ -36,275 +36,298 @@ export type CCPinImplementation = CCNodePinId | null; // }; export type CCPinMultiplexability = - | { isMultiplexable: true } - | { isMultiplexable: false; multiplicity: number }; + | { isMultiplexable: true } + | { isMultiplexable: false; multiplicity: number }; export type CCComponentPinMultiplexability = - | CCPinMultiplexability - | "undecidable"; + | CCPinMultiplexability + | "undecidable"; export type CCComponentPinStoreEvents = { - didRegister(pin: CCComponentPin): void; - willUnregister(pin: CCComponentPin): void; - didUnregister(pin: CCComponentPin): void; - didUpdate(pin: CCComponentPin): void; + didRegister(pin: CCComponentPin): void; + willUnregister(pin: CCComponentPin): void; + didUnregister(pin: CCComponentPin): void; + didUpdate(pin: CCComponentPin): void; }; /** * Store of pins */ export class CCComponentPinStore extends EventEmitter { - #store: CCStore; + #store: CCStore; - #pins: Map = new Map(); + #pins: Map = new Map(); - /** - * Constructor of CCComponentPinStore - * @param store store - * @param pins initial pins - */ - constructor(store: CCStore) { - super(); - this.#store = store; - } + /** + * Constructor of CCComponentPinStore + * @param store store + * @param pins initial pins + */ + constructor(store: CCStore) { + super(); + this.#store = store; + } - import(componentPins: CCComponentPin[]): void { - for (const pin of componentPins) { - this.#pins.set(pin.id, pin); - } - } + import(componentPins: CCComponentPin[]): void { + for (const pin of componentPins) { + this.#pins.set(pin.id, pin); + } + } - mount() { - this.#store.nodePins.on("didRegister", (nodePin) => { - this.register(this.createForNodePin(nodePin.id)); - }); - this.#store.nodePins.on("willUnregister", (nodePin) => { - const pin = this.getByImplementation(nodePin.id); - if (pin) this.unregister(pin.id); - }); - this.#store.connections.on("didRegister", (connection) => { - const { from, to } = connection; - const fromComponentPin = this.getByImplementation(from); - if (fromComponentPin) this.unregister(fromComponentPin.id); - const toComponentPin = this.getByImplementation(to); - if (toComponentPin) this.unregister(toComponentPin.id); - }); - this.#store.connections.on("willUnregister", (connection) => { - if ( - !this.#store.nodePins.isMarkedAsDeleted(connection.to) && - this.#store.nodePins.get(connection.to) - ) { - this.register(this.createForNodePin(connection.to)); - } - // output pins can have multiple connections - // so we need to check if the connection is the last one - if ( - this.#store.connections.getConnectionsByNodePinId(connection.from) - .length === 1 - ) { - if ( - !this.#store.nodePins.isMarkedAsDeleted(connection.from) && - this.#store.nodePins.get(connection.from) - ) { - this.register(this.createForNodePin(connection.from)); - } - } - }); - } + mount() { + this.#store.nodePins.on("didRegister", (nodePin) => { + this.register(this.createForNodePin(nodePin.id)); + }); + this.#store.nodePins.on("willUnregister", (nodePin) => { + const pin = this.getByImplementation(nodePin.id); + if (pin) this.unregister(pin.id); + }); + this.#store.connections.on("didRegister", (connection) => { + const { from, to } = connection; + const fromComponentPin = this.getByImplementation(from); + if (fromComponentPin) this.unregister(fromComponentPin.id); + const toComponentPin = this.getByImplementation(to); + if (toComponentPin) this.unregister(toComponentPin.id); + }); + this.#store.connections.on("willUnregister", (connection) => { + if ( + !this.#store.nodePins.isMarkedAsDeleted(connection.to) && + this.#store.nodePins.get(connection.to) + ) { + this.register(this.createForNodePin(connection.to)); + } + // output pins can have multiple connections + // so we need to check if the connection is the last one + if ( + this.#store.connections.getConnectionsByNodePinId(connection.from) + .length === 1 + ) { + if ( + !this.#store.nodePins.isMarkedAsDeleted(connection.from) && + this.#store.nodePins.get(connection.from) + ) { + this.register(this.createForNodePin(connection.from)); + } + } + }); + } - /** - * Register a pin - * @param pin pin to be registered - */ - register(pin: CCComponentPin): void { - invariant(this.#store.components.get(pin.componentId)); - this.#pins.set(pin.id, pin); - this.emit("didRegister", pin); - } + /** + * Register a pin + * @param pin pin to be registered + */ + register(pin: CCComponentPin): void { + invariant(this.#store.components.get(pin.componentId)); + this.#pins.set(pin.id, pin); + this.emit("didRegister", pin); + } - createForNodePin(nodePinId: CCNodePinId): CCComponentPin { - const targetNodePin = this.#store.nodePins.get(nodePinId)!; - const targetComponentPin = this.#store.componentPins.get( - targetNodePin.componentPinId - )!; - const targetNode = this.#store.nodes.get(targetNodePin.nodeId)!; - const existingComponentPins = this.getManyByComponentId( - targetNode.parentComponentId - ); - const maxOrder = Math.max( - ...existingComponentPins.map((pin) => pin.order), - -1 - ); - return CCComponentPinStore.create({ - type: targetComponentPin.type, - componentId: targetNode.parentComponentId, - name: targetComponentPin.name, - implementation: targetNodePin.id, - order: maxOrder + 1, - }); - } + createForNodePin(nodePinId: CCNodePinId): CCComponentPin { + const targetNodePin = nullthrows(this.#store.nodePins.get(nodePinId)); + const targetComponentPin = nullthrows( + this.#store.componentPins.get(targetNodePin.componentPinId), + ); + const targetNode = nullthrows(this.#store.nodes.get(targetNodePin.nodeId)); + const existingComponentPins = this.getManyByComponentId( + targetNode.parentComponentId, + ); + const maxOrder = Math.max( + ...existingComponentPins.map((pin) => pin.order), + -1, + ); + return CCComponentPinStore.create({ + type: targetComponentPin.type, + componentId: targetNode.parentComponentId, + name: targetComponentPin.name, + implementation: targetNodePin.id, + order: maxOrder + 1, + }); + } - /** - * Unregister a pin - * @param id id of a pin to be unregistered - */ - async unregister(id: CCComponentPinId): Promise { - const pin = nullthrows(this.#pins.get(id)); - await this.#store.transactionManager.runInTransaction(() => { - this.emit("willUnregister", pin); - this.#pins.delete(id); - }); - this.emit("didUnregister", pin); - } + /** + * Unregister a pin + * @param id id of a pin to be unregistered + */ + async unregister(id: CCComponentPinId): Promise { + const pin = nullthrows(this.#pins.get(id)); + await this.#store.transactionManager.runInTransaction(() => { + this.emit("willUnregister", pin); + this.#pins.delete(id); + }); + this.emit("didUnregister", pin); + } - /** - * Get a pin by id - * @param id id of pin - * @returns pin of `id` - */ - get(id: CCComponentPinId): CCComponentPin | undefined { - return this.#pins.get(id); - } + /** + * Get a pin by id + * @param id id of pin + * @returns pin of `id` + */ + get(id: CCComponentPinId): CCComponentPin | undefined { + return this.#pins.get(id); + } - /** - * Get all of pins - * @returns all pins - */ - getByNodePinId(nodePinId: CCNodePinId): CCComponentPin { - const pin = [...this.#pins.values()].find( - ({ implementation }) => implementation && implementation === nodePinId - ); - invariant(pin); - return pin; - } + /** + * Get all of pins + * @returns all pins + */ + getByNodePinId(nodePinId: CCNodePinId): CCComponentPin { + const pin = [...this.#pins.values()].find( + ({ implementation }) => implementation && implementation === nodePinId, + ); + invariant(pin); + return pin; + } - /** - * Get all of pins by component id - * @param componentId id of component - * @returns pins of component - * @deprecated in favor of {@link getManyByComponentId} - */ - getPinIdsByComponentId(componentId: CCComponentId): CCComponentPinId[] { - return this.getManyByComponentId(componentId).map((pin) => pin.id); - } + /** + * Get all of pins by component id + * @param componentId id of component + * @returns pins of component + * @deprecated in favor of {@link getManyByComponentId} + */ + getPinIdsByComponentId(componentId: CCComponentId): CCComponentPinId[] { + return this.getManyByComponentId(componentId).map((pin) => pin.id); + } - /** - * Get all of pins by component id - * @param componentId id of component - * @returns pins of component - */ - getManyByComponentId(componentId: CCComponentId): CCComponentPin[] { - return [...this.#pins.values()].filter( - (pin) => pin.componentId === componentId - ); - } + /** + * Get all of pins by component id + * @param componentId id of component + * @returns pins of component + */ + getManyByComponentId(componentId: CCComponentId): CCComponentPin[] { + return [...this.#pins.values()].filter( + (pin) => pin.componentId === componentId, + ); + } - getByImplementation(implementation: CCNodePinId): CCComponentPin | null { - return ( - [...this.#pins.values()].find( - (pin) => pin.implementation === implementation - ) ?? null - ); - } + getByImplementation(implementation: CCNodePinId): CCComponentPin | null { + return ( + [...this.#pins.values()].find( + (pin) => pin.implementation === implementation, + ) ?? null + ); + } - /** - * Update name of pin - * @param id id of a pin to be updated - * @param value new name - */ - update( - id: CCComponentPinId, - value: Partial> - ): void { - const pin = this.#pins.get(id); - invariant(pin); - this.#pins.set(id, { ...pin, ...value }); - this.emit("didUpdate", pin); - } + /** + * Update name of pin + * @param id id of a pin to be updated + * @param value new name + */ + update( + id: CCComponentPinId, + value: Partial>, + ): void { + const pin = this.#pins.get(id); + invariant(pin); + this.#pins.set(id, { ...pin, ...value }); + this.emit("didUpdate", pin); + } - /** - * Get the multiplexability of a component pin - * @param pinId id of pin - * @returns multiplexability of the pin - */ - getComponentPinMultiplexability( - pinId: CCComponentPinId - ): CCComponentPinMultiplexability { - const pin = this.#pins.get(pinId); - invariant(pin); - switch (pin.id) { - case intrinsic.andIntrinsicComponentDefinition.inputPins[0]!.id: - case intrinsic.andIntrinsicComponentDefinition.inputPins[1]!.id: - case intrinsic.andIntrinsicComponentDefinition.outputPins[0]!.id: - case intrinsic.orIntrinsicComponentDefinition.inputPins[0]!.id: - case intrinsic.orIntrinsicComponentDefinition.inputPins[1]!.id: - case intrinsic.orIntrinsicComponentDefinition.outputPins[0]!.id: - case intrinsic.notIntrinsicComponentDefinition.inputPins[0]!.id: - case intrinsic.notIntrinsicComponentDefinition.outputPins[0]!.id: - case intrinsic.xorIntrinsicComponentDefinition.inputPins[0]!.id: - case intrinsic.xorIntrinsicComponentDefinition.inputPins[1]!.id: - case intrinsic.xorIntrinsicComponentDefinition.outputPins[0]!.id: - case intrinsic.inputIntrinsicComponentDefinition.inputPins[0]!.id: - case intrinsic.inputIntrinsicComponentDefinition.outputPins[0]!.id: - case intrinsic.flipFlopIntrinsicComponentDefinition.inputPins[0]!.id: - case intrinsic.flipFlopIntrinsicComponentDefinition.outputPins[0]!.id: { - return { isMultiplexable: true }; - } - case intrinsic.aggregateIntrinsicComponentDefinition.inputPins[0]!.id: { - return { isMultiplexable: false, multiplicity: 1 }; - } - case intrinsic.aggregateIntrinsicComponentDefinition.outputPins[0]!.id: { - return "undecidable"; - // return { isMultiplexable: false, multiplicity: 4 }; - } - case intrinsic.decomposeIntrinsicComponentDefinition.outputPins[0]!.id: { - return "undecidable"; - // return { isMultiplexable: false, multiplicity: 4 }; - } - case intrinsic.decomposeIntrinsicComponentDefinition.inputPins[0]!.id: { - return { isMultiplexable: false, multiplicity: 1 }; - } - default: { - if (pin.implementation === null) { - throw new Error("unreachable"); - } - return this.#store.nodePins.getNodePinMultiplexability( - pin.implementation - ); - } - } - } + /** + * Get the multiplexability of a component pin + * @param pinId id of pin + * @returns multiplexability of the pin + */ + getComponentPinMultiplexability( + pinId: CCComponentPinId, + ): CCComponentPinMultiplexability { + const pin = this.#pins.get(pinId); + invariant(pin); + switch (pin.id) { + case nullthrows(intrinsic.andIntrinsicComponentDefinition.inputPins[0]) + .id: + case nullthrows(intrinsic.andIntrinsicComponentDefinition.inputPins[1]) + .id: + case nullthrows(intrinsic.andIntrinsicComponentDefinition.outputPins[0]) + .id: + case nullthrows(intrinsic.orIntrinsicComponentDefinition.inputPins[0]).id: + case nullthrows(intrinsic.orIntrinsicComponentDefinition.inputPins[1]).id: + case nullthrows(intrinsic.orIntrinsicComponentDefinition.outputPins[0]) + .id: + case nullthrows(intrinsic.notIntrinsicComponentDefinition.inputPins[0]) + .id: + case nullthrows(intrinsic.notIntrinsicComponentDefinition.outputPins[0]) + .id: + case nullthrows(intrinsic.xorIntrinsicComponentDefinition.inputPins[0]) + .id: + case nullthrows(intrinsic.xorIntrinsicComponentDefinition.inputPins[1]) + .id: + case nullthrows(intrinsic.xorIntrinsicComponentDefinition.outputPins[0]) + .id: + case nullthrows(intrinsic.inputIntrinsicComponentDefinition.inputPins[0]) + .id: + case nullthrows(intrinsic.inputIntrinsicComponentDefinition.outputPins[0]) + .id: + case nullthrows( + intrinsic.flipFlopIntrinsicComponentDefinition.inputPins[0], + ).id: + case nullthrows( + intrinsic.flipFlopIntrinsicComponentDefinition.outputPins[0], + ).id: { + return { isMultiplexable: true }; + } + case nullthrows( + intrinsic.aggregateIntrinsicComponentDefinition.inputPins[0], + ).id: { + return { isMultiplexable: false, multiplicity: 1 }; + } + case nullthrows( + intrinsic.aggregateIntrinsicComponentDefinition.outputPins[0], + ).id: { + return "undecidable"; + // return { isMultiplexable: false, multiplicity: 4 }; + } + case nullthrows( + intrinsic.decomposeIntrinsicComponentDefinition.outputPins[0], + ).id: { + return "undecidable"; + // return { isMultiplexable: false, multiplicity: 4 }; + } + case nullthrows( + intrinsic.decomposeIntrinsicComponentDefinition.inputPins[0], + ).id: { + return { isMultiplexable: false, multiplicity: 1 }; + } + default: { + if (pin.implementation === null) { + throw new Error("unreachable"); + } + return this.#store.nodePins.getNodePinMultiplexability( + pin.implementation, + ); + } + } + } - /** - * Create a new pin - * @param partialPin pin without `id` - * @returns a new pin - */ - static create(partialPin: Omit): CCComponentPin { - return { - id: crypto.randomUUID() as CCComponentPinId, - ...partialPin, - }; - } + /** + * Create a new pin + * @param partialPin pin without `id` + * @returns a new pin + */ + static create(partialPin: Omit): CCComponentPin { + return { + id: crypto.randomUUID() as CCComponentPinId, + ...partialPin, + }; + } - /** - * Get array of pins - * @returns array of pins - */ - getMany(): CCComponentPin[] { - return [...this.#pins.values()]; - } + /** + * Get array of pins + * @returns array of pins + */ + getMany(): CCComponentPin[] { + return [...this.#pins.values()]; + } - /** - * Check if the pin is an interface pin - * @param pinId id of pin - * @returns if the pin is an interface pin, `true` returns (otherwise `false`) - */ - isInterfacePin(pinId: CCComponentPinId): boolean { - const pin = this.#store.componentPins.get(pinId)!; - return ( - !pin.implementation || - this.#store.connections.hasNoConnectionOf(pin.implementation) - ); - } + /** + * Check if the pin is an interface pin + * @param pinId id of pin + * @returns if the pin is an interface pin, `true` returns (otherwise `false`) + */ + isInterfacePin(pinId: CCComponentPinId): boolean { + const pin = nullthrows(this.#store.componentPins.get(pinId)); + return ( + !pin.implementation || + this.#store.connections.hasNoConnectionOf(pin.implementation) + ); + } } diff --git a/src/store/connection.ts b/src/store/connection.ts index 1edcd84..d91f970 100644 --- a/src/store/connection.ts +++ b/src/store/connection.ts @@ -1,169 +1,171 @@ -import type { Opaque } from "type-fest"; import EventEmitter from "eventemitter3"; -import invariant from "tiny-invariant"; import nullthrows from "nullthrows"; +import invariant from "tiny-invariant"; +import type { Opaque } from "type-fest"; import type CCStore from "."; -import type { CCNodeId } from "./node"; -import type { CCComponentPinId } from "./componentPin"; import type { CCComponentId } from "./component"; +import type { CCComponentPinId } from "./componentPin"; +import type { CCNodeId } from "./node"; import type { CCNodePinId } from "./nodePin"; export type CCConnectionId = Opaque; export type CCConnectionEndpoint = { - readonly nodeId: CCNodeId; - readonly pinId: CCComponentPinId; + readonly nodeId: CCNodeId; + readonly pinId: CCComponentPinId; }; export type CCConnection = { - readonly id: CCConnectionId; - readonly from: CCNodePinId; - readonly to: CCNodePinId; - readonly parentComponentId: CCComponentId; - bentPortion: number; + readonly id: CCConnectionId; + readonly from: CCNodePinId; + readonly to: CCNodePinId; + readonly parentComponentId: CCComponentId; + bentPortion: number; }; export type CCConnectionStoreEvents = { - didRegister(Connection: CCConnection): void; - willUnregister(Connection: CCConnection): void; - didUnregister(Connection: CCConnection): void; + didRegister(Connection: CCConnection): void; + willUnregister(Connection: CCConnection): void; + didUnregister(Connection: CCConnection): void; }; /** * Store of connections */ export class CCConnectionStore extends EventEmitter { - #store: CCStore; - - #connections: Map = new Map(); - - /** - * Constructor of CCConnectionStore - * @param store store - * @param connections initial connections - */ - constructor(store: CCStore) { - super(); - this.#store = store; - } - - import(connections: CCConnection[]): void { - for (const connection of connections) { - this.#connections.set(connection.id, connection); - } - } - - mount() { - this.#store.nodePins.on("willUnregister", (nodePin) => { - const connections = this.getConnectionsByNodePinId(nodePin.id); - if (connections.length > 0) { - this.unregister(connections.map((connection) => connection.id)); - } - }); - } - - /** - * Register a connection - * @param connection connection to be registered - */ - register(connection: CCConnection): void { - const fromNodeId = this.#store.nodePins.get(connection.from)!.nodeId; - const toNodeId = this.#store.nodePins.get(connection.to)!.nodeId; - const fromNode = this.#store.nodes.get(fromNodeId); - const toNode = this.#store.nodes.get(toNodeId); - invariant(fromNode && toNode); - invariant(fromNode.parentComponentId === toNode.parentComponentId); - this.#connections.set(connection.id, connection); - this.emit("didRegister", connection); - } - - /** - * Unregister a connection - * @param ids ids of connections to be unregistered - */ - async unregister(ids: CCConnectionId[]): Promise { - const connections = ids.map((id) => nullthrows(this.#connections.get(id))); - await this.#store.transactionManager.runInTransaction(() => { - for (const connection of connections) { - this.emit("willUnregister", connection); - this.#connections.delete(connection.id); - } - }); - for (const connection of connections) { - this.emit("didUnregister", connection); - } - } - - /** - * Get a connection by CCConnectionId - * @param id id of connection - * @returns connection of `id` - */ - get(id: CCConnectionId): CCConnection | undefined { - return this.#connections.get(id); - } - - /** - * Get all of connections - * @returns map of id and connection (read only) - */ - getConnectionIdsByParentComponentId( - parentComponentId: CCComponentId - ): CCConnectionId[] { - return [...this.#connections.values()] - .filter( - (connection) => connection.parentComponentId === parentComponentId - ) - .map((connection) => connection.id); - } - - getManyByParentComponentId(parentComponentId: CCComponentId): CCConnection[] { - return [...this.#connections.values()].filter( - (connection) => connection.parentComponentId === parentComponentId - ); - } - - /** - * Get connections by id of node and pin - * @param nodeId id of node - * @param pinId id of pin - * @returns connections connected to the pin of the node - */ - getConnectionsByNodePinId(nodePinId: CCNodePinId): CCConnection[] { - return [...this.#connections.values()].filter( - (connection) => - connection.from === nodePinId || connection.to === nodePinId - ); - } - - /** - * Check if no connection of the pin of the node existsno connection of the pin of the node exists - * @param nodeId id of node - * @param pinId id of pin - * @returns if no connection of the pin of the node exists, `true` returns (otherwise `false`) - * @deprecated in favor of {@link getConnectionsByNodePinId} - */ - hasNoConnectionOf(nodePinId: CCNodePinId): boolean { - return this.getConnectionsByNodePinId(nodePinId).length === 0; - } - - /** - * Create a new connection - * @param partialConnection connection without `id` - * @returns a new connection - */ - static create(partialConnection: Omit): CCConnection { - return { - id: crypto.randomUUID() as CCConnectionId, - ...partialConnection, - }; - } - - /** - * Get array of connections - * @returns array of connections - */ - getMany(): CCConnection[] { - return [...this.#connections.values()]; - } + #store: CCStore; + + #connections: Map = new Map(); + + /** + * Constructor of CCConnectionStore + * @param store store + * @param connections initial connections + */ + constructor(store: CCStore) { + super(); + this.#store = store; + } + + import(connections: CCConnection[]): void { + for (const connection of connections) { + this.#connections.set(connection.id, connection); + } + } + + mount() { + this.#store.nodePins.on("willUnregister", (nodePin) => { + const connections = this.getConnectionsByNodePinId(nodePin.id); + if (connections.length > 0) { + this.unregister(connections.map((connection) => connection.id)); + } + }); + } + + /** + * Register a connection + * @param connection connection to be registered + */ + register(connection: CCConnection): void { + const fromNodeId = nullthrows( + this.#store.nodePins.get(connection.from), + ).nodeId; + const toNodeId = nullthrows(this.#store.nodePins.get(connection.to)).nodeId; + const fromNode = this.#store.nodes.get(fromNodeId); + const toNode = this.#store.nodes.get(toNodeId); + invariant(fromNode && toNode); + invariant(fromNode.parentComponentId === toNode.parentComponentId); + this.#connections.set(connection.id, connection); + this.emit("didRegister", connection); + } + + /** + * Unregister a connection + * @param ids ids of connections to be unregistered + */ + async unregister(ids: CCConnectionId[]): Promise { + const connections = ids.map((id) => nullthrows(this.#connections.get(id))); + await this.#store.transactionManager.runInTransaction(() => { + for (const connection of connections) { + this.emit("willUnregister", connection); + this.#connections.delete(connection.id); + } + }); + for (const connection of connections) { + this.emit("didUnregister", connection); + } + } + + /** + * Get a connection by CCConnectionId + * @param id id of connection + * @returns connection of `id` + */ + get(id: CCConnectionId): CCConnection | undefined { + return this.#connections.get(id); + } + + /** + * Get all of connections + * @returns map of id and connection (read only) + */ + getConnectionIdsByParentComponentId( + parentComponentId: CCComponentId, + ): CCConnectionId[] { + return [...this.#connections.values()] + .filter( + (connection) => connection.parentComponentId === parentComponentId, + ) + .map((connection) => connection.id); + } + + getManyByParentComponentId(parentComponentId: CCComponentId): CCConnection[] { + return [...this.#connections.values()].filter( + (connection) => connection.parentComponentId === parentComponentId, + ); + } + + /** + * Get connections by id of node and pin + * @param nodeId id of node + * @param pinId id of pin + * @returns connections connected to the pin of the node + */ + getConnectionsByNodePinId(nodePinId: CCNodePinId): CCConnection[] { + return [...this.#connections.values()].filter( + (connection) => + connection.from === nodePinId || connection.to === nodePinId, + ); + } + + /** + * Check if no connection of the pin of the node existsno connection of the pin of the node exists + * @param nodeId id of node + * @param pinId id of pin + * @returns if no connection of the pin of the node exists, `true` returns (otherwise `false`) + * @deprecated in favor of {@link getConnectionsByNodePinId} + */ + hasNoConnectionOf(nodePinId: CCNodePinId): boolean { + return this.getConnectionsByNodePinId(nodePinId).length === 0; + } + + /** + * Create a new connection + * @param partialConnection connection without `id` + * @returns a new connection + */ + static create(partialConnection: Omit): CCConnection { + return { + id: crypto.randomUUID() as CCConnectionId, + ...partialConnection, + }; + } + + /** + * Get array of connections + * @returns array of connections + */ + getMany(): CCConnection[] { + return [...this.#connections.values()]; + } } diff --git a/src/store/index.ts b/src/store/index.ts index c25ca3c..58be503 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,78 +1,78 @@ import invariant from "tiny-invariant"; -import { CCComponentStore, type CCComponent } from "./component"; -import { CCNodeStore, type CCNode } from "./node"; -import { CCComponentPinStore, type CCComponentPin } from "./componentPin"; -import { CCNodePinStore, type CCNodePin } from "./nodePin"; -import { CCConnectionStore, type CCConnection } from "./connection"; +import { type CCComponent, CCComponentStore } from "./component"; +import { type CCComponentPin, CCComponentPinStore } from "./componentPin"; +import { type CCConnection, CCConnectionStore } from "./connection"; import { registerIntrinsics } from "./intrinsics"; +import { type CCNode, CCNodeStore } from "./node"; +import { type CCNodePin, CCNodePinStore } from "./nodePin"; import TransactionManager from "./transaction"; /** * Properties of CCStore from JSON used when restoring store from JSON */ export type CCStorePropsFromJson = { - components: CCComponent[]; - nodes: CCNode[]; - componentPins: CCComponentPin[]; - nodePins: CCNodePin[]; - connections: CCConnection[]; + components: CCComponent[]; + nodes: CCNode[]; + componentPins: CCComponentPin[]; + nodePins: CCNodePin[]; + connections: CCConnection[]; }; /** * Store of components, nodes, pins, and connections */ export default class CCStore { - components: CCComponentStore; + components: CCComponentStore; - nodes: CCNodeStore; + nodes: CCNodeStore; - componentPins: CCComponentPinStore; + componentPins: CCComponentPinStore; - nodePins: CCNodePinStore; + nodePins: CCNodePinStore; - connections: CCConnectionStore; + connections: CCConnectionStore; - transactionManager = new TransactionManager(); + transactionManager = new TransactionManager(); - /** - * Constructor of CCStore - * @param rootComponent root component - * @param props properties of store from JSON used when restoring store from JSON - */ - constructor(props?: CCStorePropsFromJson) { - this.components = new CCComponentStore(this); - this.nodes = new CCNodeStore(this); - this.componentPins = new CCComponentPinStore(this); - this.nodePins = new CCNodePinStore(this); - this.connections = new CCConnectionStore(this); - if (props) { - invariant(props); - const { components, nodes, componentPins, nodePins, connections } = props; - this.components.import(components); - this.nodes.import(nodes); - this.componentPins.import(componentPins); - this.nodePins.import(nodePins); - this.connections.import(connections); - } - registerIntrinsics(this); - this.components.mount(); - this.nodes.mount(); - this.componentPins.mount(); - this.nodePins.mount(); - this.connections.mount(); - } + /** + * Constructor of CCStore + * @param rootComponent root component + * @param props properties of store from JSON used when restoring store from JSON + */ + constructor(props?: CCStorePropsFromJson) { + this.components = new CCComponentStore(this); + this.nodes = new CCNodeStore(this); + this.componentPins = new CCComponentPinStore(this); + this.nodePins = new CCNodePinStore(this); + this.connections = new CCConnectionStore(this); + if (props) { + invariant(props); + const { components, nodes, componentPins, nodePins, connections } = props; + this.components.import(components); + this.nodes.import(nodes); + this.componentPins.import(componentPins); + this.nodePins.import(nodePins); + this.connections.import(connections); + } + registerIntrinsics(this); + this.components.mount(); + this.nodes.mount(); + this.componentPins.mount(); + this.nodePins.mount(); + this.connections.mount(); + } - /** - * Get the JSON representation of the store - * @returns JSON representation of the store - */ - toJSON() { - return JSON.stringify({ - components: this.components.getMany(), - nodes: this.nodes.getMany(), - componentPins: this.componentPins.getMany(), - nodePins: this.nodePins.getMany(), - connections: this.connections.getMany(), - }); - } + /** + * Get the JSON representation of the store + * @returns JSON representation of the store + */ + toJSON() { + return JSON.stringify({ + components: this.components.getMany(), + nodes: this.nodes.getMany(), + componentPins: this.componentPins.getMany(), + nodePins: this.nodePins.getMany(), + connections: this.connections.getMany(), + }); + } } diff --git a/src/store/intrinsics.ts b/src/store/intrinsics.ts index 9033e10..60c450b 100644 --- a/src/store/intrinsics.ts +++ b/src/store/intrinsics.ts @@ -1,394 +1,393 @@ -/* eslint-disable max-classes-per-file */ import type CCStore from "."; import type { CCComponent, CCComponentId } from "./component"; import type { CCComponentPin, CCComponentPinId } from "./componentPin"; export const ccIntrinsicComponentTypes = { - AND: "AND", - OR: "OR", - NOT: "NOT", - XOR: "XOR", - INPUT: "INPUT", - AGGREGATE: "AGGREGATE", - BROADCAST: "BROADCAST", - DECOMPOSE: "DECOMPOSE", - FLIPFLOP: "FLIPFLOP", + AND: "AND", + OR: "OR", + NOT: "NOT", + XOR: "XOR", + INPUT: "INPUT", + AGGREGATE: "AGGREGATE", + BROADCAST: "BROADCAST", + DECOMPOSE: "DECOMPOSE", + FLIPFLOP: "FLIPFLOP", } as const; export type CCIntrinsicComponentType = keyof typeof ccIntrinsicComponentTypes; export interface CCIntrinsicComponentDefinition { - type: CCIntrinsicComponentType; - component: CCComponent; - inputPins: CCComponentPin[]; - outputPins: CCComponentPin[]; - componentPinCanHaveMultipleNodePins?: (pin: CCComponentPin) => boolean; - componentPinHasUserSpecifiedBitWidth?: (pin: CCComponentPin) => boolean; + type: CCIntrinsicComponentType; + component: CCComponent; + inputPins: CCComponentPin[]; + outputPins: CCComponentPin[]; + componentPinCanHaveMultipleNodePins?: (pin: CCComponentPin) => boolean; + componentPinHasUserSpecifiedBitWidth?: (pin: CCComponentPin) => boolean; } const andComponentId = "ffffffff-0001-4000-8000-000000000000" as CCComponentId; const andInputPinAId = - "ffffffff-0001-4000-8000-000000000001" as CCComponentPinId; + "ffffffff-0001-4000-8000-000000000001" as CCComponentPinId; const andInputPinBId = - "ffffffff-0001-4000-8000-000000000002" as CCComponentPinId; + "ffffffff-0001-4000-8000-000000000002" as CCComponentPinId; const andOutputPinId = - "ffffffff-0001-4000-8000-000000000003" as CCComponentPinId; + "ffffffff-0001-4000-8000-000000000003" as CCComponentPinId; export const andIntrinsicComponentDefinition: CCIntrinsicComponentDefinition = { - type: ccIntrinsicComponentTypes.AND, - component: { - id: andComponentId, - intrinsicType: ccIntrinsicComponentTypes.AND, - name: "And", - }, - inputPins: [ - { - id: andInputPinAId, - componentId: andComponentId, - type: "input", - implementation: null, - order: 0, - name: "A", - }, - { - id: andInputPinBId, - componentId: andComponentId, - type: "input", - implementation: null, - order: 1, - name: "B", - }, - ], - outputPins: [ - { - id: andOutputPinId, - componentId: andComponentId, - type: "output", - implementation: null, - order: 0, - name: "Out", - }, - ], + type: ccIntrinsicComponentTypes.AND, + component: { + id: andComponentId, + intrinsicType: ccIntrinsicComponentTypes.AND, + name: "And", + }, + inputPins: [ + { + id: andInputPinAId, + componentId: andComponentId, + type: "input", + implementation: null, + order: 0, + name: "A", + }, + { + id: andInputPinBId, + componentId: andComponentId, + type: "input", + implementation: null, + order: 1, + name: "B", + }, + ], + outputPins: [ + { + id: andOutputPinId, + componentId: andComponentId, + type: "output", + implementation: null, + order: 0, + name: "Out", + }, + ], }; const orComponentId = "ffffffff-0002-4000-8000-000000000000" as CCComponentId; const orInputPinAId = - "ffffffff-0002-4000-8000-000000000001" as CCComponentPinId; + "ffffffff-0002-4000-8000-000000000001" as CCComponentPinId; const orInputPinBId = - "ffffffff-0002-4000-8000-000000000002" as CCComponentPinId; + "ffffffff-0002-4000-8000-000000000002" as CCComponentPinId; const orOutputPinId = - "ffffffff-0002-4000-8000-000000000003" as CCComponentPinId; + "ffffffff-0002-4000-8000-000000000003" as CCComponentPinId; export const orIntrinsicComponentDefinition: CCIntrinsicComponentDefinition = { - type: "OR", - component: { - id: orComponentId, - intrinsicType: ccIntrinsicComponentTypes.OR, - name: "Or", - }, - inputPins: [ - { - id: orInputPinAId, - componentId: orComponentId, - type: "input", - implementation: null, - order: 0, - name: "A", - }, - { - id: orInputPinBId, - componentId: orComponentId, - type: "input", - implementation: null, - order: 1, - name: "B", - }, - ], - outputPins: [ - { - id: orOutputPinId, - componentId: orComponentId, - type: "output", - implementation: null, - order: 0, - name: "Out", - }, - ], + type: "OR", + component: { + id: orComponentId, + intrinsicType: ccIntrinsicComponentTypes.OR, + name: "Or", + }, + inputPins: [ + { + id: orInputPinAId, + componentId: orComponentId, + type: "input", + implementation: null, + order: 0, + name: "A", + }, + { + id: orInputPinBId, + componentId: orComponentId, + type: "input", + implementation: null, + order: 1, + name: "B", + }, + ], + outputPins: [ + { + id: orOutputPinId, + componentId: orComponentId, + type: "output", + implementation: null, + order: 0, + name: "Out", + }, + ], }; const notComponentId = "ffffffff-0003-4000-8000-000000000000" as CCComponentId; const notInputPinId = - "ffffffff-0003-4000-8000-000000000001" as CCComponentPinId; + "ffffffff-0003-4000-8000-000000000001" as CCComponentPinId; const notOutputPinId = - "ffffffff-0003-4000-8000-000000000002" as CCComponentPinId; + "ffffffff-0003-4000-8000-000000000002" as CCComponentPinId; export const notIntrinsicComponentDefinition: CCIntrinsicComponentDefinition = { - type: "NOT", - component: { - id: notComponentId, - intrinsicType: ccIntrinsicComponentTypes.NOT, - name: "Not", - }, - inputPins: [ - { - id: notInputPinId, - componentId: notComponentId, - type: "input", - implementation: null, - order: 0, - name: "In", - }, - ], - outputPins: [ - { - id: notOutputPinId, - componentId: notComponentId, - type: "output", - implementation: null, - order: 0, - name: "Out", - }, - ], + type: "NOT", + component: { + id: notComponentId, + intrinsicType: ccIntrinsicComponentTypes.NOT, + name: "Not", + }, + inputPins: [ + { + id: notInputPinId, + componentId: notComponentId, + type: "input", + implementation: null, + order: 0, + name: "In", + }, + ], + outputPins: [ + { + id: notOutputPinId, + componentId: notComponentId, + type: "output", + implementation: null, + order: 0, + name: "Out", + }, + ], }; const xorComponentId = "ffffffff-0004-4000-8000-000000000000" as CCComponentId; const xorInputPinAId = - "ffffffff-0004-4000-8000-000000000001" as CCComponentPinId; + "ffffffff-0004-4000-8000-000000000001" as CCComponentPinId; const xorInputPinBId = - "ffffffff-0004-4000-8000-000000000002" as CCComponentPinId; + "ffffffff-0004-4000-8000-000000000002" as CCComponentPinId; const xorOutputPinId = - "ffffffff-0004-4000-8000-000000000003" as CCComponentPinId; + "ffffffff-0004-4000-8000-000000000003" as CCComponentPinId; export const xorIntrinsicComponentDefinition: CCIntrinsicComponentDefinition = { - type: "XOR", - component: { - id: xorComponentId, - intrinsicType: ccIntrinsicComponentTypes.XOR, - name: "Xor", - }, - inputPins: [ - { - id: xorInputPinAId, - componentId: xorComponentId, - type: "input", - implementation: null, - order: 0, - name: "A", - }, - { - id: xorInputPinBId, - componentId: xorComponentId, - type: "input", - implementation: null, - order: 1, - name: "B", - }, - ], - outputPins: [ - { - id: xorOutputPinId, - componentId: xorComponentId, - type: "output", - implementation: null, - order: 0, - name: "Out", - }, - ], + type: "XOR", + component: { + id: xorComponentId, + intrinsicType: ccIntrinsicComponentTypes.XOR, + name: "Xor", + }, + inputPins: [ + { + id: xorInputPinAId, + componentId: xorComponentId, + type: "input", + implementation: null, + order: 0, + name: "A", + }, + { + id: xorInputPinBId, + componentId: xorComponentId, + type: "input", + implementation: null, + order: 1, + name: "B", + }, + ], + outputPins: [ + { + id: xorOutputPinId, + componentId: xorComponentId, + type: "output", + implementation: null, + order: 0, + name: "Out", + }, + ], }; const inputComponentId = - "ffffffff-0005-4000-8000-000000000000" as CCComponentId; + "ffffffff-0005-4000-8000-000000000000" as CCComponentId; const inputInputPinId = - "ffffffff-0005-4000-8000-000000000001" as CCComponentPinId; + "ffffffff-0005-4000-8000-000000000001" as CCComponentPinId; const inputOutputPinId = - "ffffffff-0005-4000-8000-000000000002" as CCComponentPinId; + "ffffffff-0005-4000-8000-000000000002" as CCComponentPinId; export const inputIntrinsicComponentDefinition: CCIntrinsicComponentDefinition = - { - type: "INPUT", - component: { - id: inputComponentId, - intrinsicType: ccIntrinsicComponentTypes.INPUT, - name: "Input", - }, - inputPins: [ - { - id: inputInputPinId, - componentId: inputComponentId, - type: "input", - implementation: null, - order: 0, - name: "In", - }, - ], - outputPins: [ - { - id: inputOutputPinId, - componentId: inputComponentId, - type: "output", - implementation: null, - order: 0, - name: "Out", - }, - ], - }; + { + type: "INPUT", + component: { + id: inputComponentId, + intrinsicType: ccIntrinsicComponentTypes.INPUT, + name: "Input", + }, + inputPins: [ + { + id: inputInputPinId, + componentId: inputComponentId, + type: "input", + implementation: null, + order: 0, + name: "In", + }, + ], + outputPins: [ + { + id: inputOutputPinId, + componentId: inputComponentId, + type: "output", + implementation: null, + order: 0, + name: "Out", + }, + ], + }; const aggregateComponentId = - "ffffffff-0006-4000-8000-000000000000" as CCComponentId; + "ffffffff-0006-4000-8000-000000000000" as CCComponentId; const aggregateInputPinId = - "ffffffff-0006-4000-8000-000000000001" as CCComponentPinId; + "ffffffff-0006-4000-8000-000000000001" as CCComponentPinId; const aggregateOutputPinId = - "ffffffff-0006-4000-8000-000000000002" as CCComponentPinId; + "ffffffff-0006-4000-8000-000000000002" as CCComponentPinId; export const aggregateIntrinsicComponentDefinition: CCIntrinsicComponentDefinition = - { - type: "AGGREGATE", - component: { - id: aggregateComponentId, - intrinsicType: ccIntrinsicComponentTypes.AGGREGATE, - name: "Aggregate", - }, - inputPins: [ - { - id: aggregateInputPinId, - componentId: aggregateComponentId, - type: "input", - implementation: null, - order: 0, - name: "In", - }, - ], - outputPins: [ - { - id: aggregateOutputPinId, - componentId: aggregateComponentId, - type: "output", - implementation: null, - order: 0, - name: "Out", - }, - ], - componentPinCanHaveMultipleNodePins: (pin) => pin.type === "input", - componentPinHasUserSpecifiedBitWidth: (pin) => pin.type === "input", - }; + { + type: "AGGREGATE", + component: { + id: aggregateComponentId, + intrinsicType: ccIntrinsicComponentTypes.AGGREGATE, + name: "Aggregate", + }, + inputPins: [ + { + id: aggregateInputPinId, + componentId: aggregateComponentId, + type: "input", + implementation: null, + order: 0, + name: "In", + }, + ], + outputPins: [ + { + id: aggregateOutputPinId, + componentId: aggregateComponentId, + type: "output", + implementation: null, + order: 0, + name: "Out", + }, + ], + componentPinCanHaveMultipleNodePins: (pin) => pin.type === "input", + componentPinHasUserSpecifiedBitWidth: (pin) => pin.type === "input", + }; const broadcastComponentId = - "ffffffff-0007-4000-8000-000000000000" as CCComponentId; + "ffffffff-0007-4000-8000-000000000000" as CCComponentId; const broadcastInputPinId = - "ffffffff-0007-4000-8000-000000000001" as CCComponentPinId; + "ffffffff-0007-4000-8000-000000000001" as CCComponentPinId; const broadcastOutputPinId = - "ffffffff-0007-4000-8000-000000000002" as CCComponentPinId; + "ffffffff-0007-4000-8000-000000000002" as CCComponentPinId; export const broadcastIntrinsicComponentDefinition: CCIntrinsicComponentDefinition = - { - type: "BROADCAST", - component: { - id: broadcastComponentId, - intrinsicType: ccIntrinsicComponentTypes.BROADCAST, - name: "Broadcast", - }, - inputPins: [ - { - id: broadcastInputPinId, - componentId: broadcastComponentId, - type: "input", - implementation: null, - order: 0, - name: "In", - }, - ], - outputPins: [ - { - id: broadcastOutputPinId, - componentId: broadcastComponentId, - type: "output", - implementation: null, - order: 0, - name: "Out", - }, - ], - componentPinHasUserSpecifiedBitWidth: (pin) => pin.type === "output", - }; + { + type: "BROADCAST", + component: { + id: broadcastComponentId, + intrinsicType: ccIntrinsicComponentTypes.BROADCAST, + name: "Broadcast", + }, + inputPins: [ + { + id: broadcastInputPinId, + componentId: broadcastComponentId, + type: "input", + implementation: null, + order: 0, + name: "In", + }, + ], + outputPins: [ + { + id: broadcastOutputPinId, + componentId: broadcastComponentId, + type: "output", + implementation: null, + order: 0, + name: "Out", + }, + ], + componentPinHasUserSpecifiedBitWidth: (pin) => pin.type === "output", + }; const decomposeComponentId = - "ffffffff-0008-4000-8000-000000000000" as CCComponentId; + "ffffffff-0008-4000-8000-000000000000" as CCComponentId; const decomposeInputPinId = - "ffffffff-0008-4000-8000-000000000001" as CCComponentPinId; + "ffffffff-0008-4000-8000-000000000001" as CCComponentPinId; const decomposeOutputPinId = - "ffffffff-0008-4000-8000-000000000002" as CCComponentPinId; + "ffffffff-0008-4000-8000-000000000002" as CCComponentPinId; export const decomposeIntrinsicComponentDefinition: CCIntrinsicComponentDefinition = - { - type: "DECOMPOSE", - component: { - id: decomposeComponentId, - intrinsicType: ccIntrinsicComponentTypes.DECOMPOSE, - name: "Decompose", - }, - inputPins: [ - { - id: decomposeInputPinId, - componentId: decomposeComponentId, - type: "input", - implementation: null, - order: 0, - name: "In", - }, - ], - outputPins: [ - { - id: decomposeOutputPinId, - componentId: decomposeComponentId, - type: "output", - implementation: null, - order: 0, - name: "Out", - }, - ], - componentPinCanHaveMultipleNodePins: (pin) => pin.type === "output", - componentPinHasUserSpecifiedBitWidth: (pin) => pin.type === "output", - }; + { + type: "DECOMPOSE", + component: { + id: decomposeComponentId, + intrinsicType: ccIntrinsicComponentTypes.DECOMPOSE, + name: "Decompose", + }, + inputPins: [ + { + id: decomposeInputPinId, + componentId: decomposeComponentId, + type: "input", + implementation: null, + order: 0, + name: "In", + }, + ], + outputPins: [ + { + id: decomposeOutputPinId, + componentId: decomposeComponentId, + type: "output", + implementation: null, + order: 0, + name: "Out", + }, + ], + componentPinCanHaveMultipleNodePins: (pin) => pin.type === "output", + componentPinHasUserSpecifiedBitWidth: (pin) => pin.type === "output", + }; export const flipFlopIntrinsicComponentId = - "ffffffff-0009-4000-8000-000000000000" as CCComponentId; + "ffffffff-0009-4000-8000-000000000000" as CCComponentId; export const flipFlopIntrinsicComponentInputPinId = - "ffffffff-0009-4000-8000-000000000001" as CCComponentPinId; + "ffffffff-0009-4000-8000-000000000001" as CCComponentPinId; export const flipFlopIntrinsicComponentOutputPinId = - "ffffffff-0009-4000-8000-000000000002" as CCComponentPinId; + "ffffffff-0009-4000-8000-000000000002" as CCComponentPinId; export const flipFlopIntrinsicComponentDefinition: CCIntrinsicComponentDefinition = - { - type: "FLIPFLOP", - component: { - id: flipFlopIntrinsicComponentId, - intrinsicType: ccIntrinsicComponentTypes.FLIPFLOP, - name: "FlipFlop", - }, - inputPins: [ - { - id: flipFlopIntrinsicComponentInputPinId, - componentId: flipFlopIntrinsicComponentId, - type: "input", - implementation: null, - order: 0, - name: "In", - }, - ], - outputPins: [ - { - id: flipFlopIntrinsicComponentOutputPinId, - componentId: flipFlopIntrinsicComponentId, - type: "output", - implementation: null, - order: 0, - name: "Out", - }, - ], - }; + { + type: "FLIPFLOP", + component: { + id: flipFlopIntrinsicComponentId, + intrinsicType: ccIntrinsicComponentTypes.FLIPFLOP, + name: "FlipFlop", + }, + inputPins: [ + { + id: flipFlopIntrinsicComponentInputPinId, + componentId: flipFlopIntrinsicComponentId, + type: "input", + implementation: null, + order: 0, + name: "In", + }, + ], + outputPins: [ + { + id: flipFlopIntrinsicComponentOutputPinId, + componentId: flipFlopIntrinsicComponentId, + type: "output", + implementation: null, + order: 0, + name: "Out", + }, + ], + }; export const ccIntrinsicComponentDefinitions: Record< - CCIntrinsicComponentType, - CCIntrinsicComponentDefinition + CCIntrinsicComponentType, + CCIntrinsicComponentDefinition > = { - [ccIntrinsicComponentTypes.AND]: andIntrinsicComponentDefinition, - [ccIntrinsicComponentTypes.OR]: orIntrinsicComponentDefinition, - [ccIntrinsicComponentTypes.NOT]: notIntrinsicComponentDefinition, - [ccIntrinsicComponentTypes.XOR]: xorIntrinsicComponentDefinition, - [ccIntrinsicComponentTypes.INPUT]: inputIntrinsicComponentDefinition, - [ccIntrinsicComponentTypes.AGGREGATE]: aggregateIntrinsicComponentDefinition, - [ccIntrinsicComponentTypes.BROADCAST]: broadcastIntrinsicComponentDefinition, - [ccIntrinsicComponentTypes.DECOMPOSE]: decomposeIntrinsicComponentDefinition, - [ccIntrinsicComponentTypes.FLIPFLOP]: flipFlopIntrinsicComponentDefinition, + [ccIntrinsicComponentTypes.AND]: andIntrinsicComponentDefinition, + [ccIntrinsicComponentTypes.OR]: orIntrinsicComponentDefinition, + [ccIntrinsicComponentTypes.NOT]: notIntrinsicComponentDefinition, + [ccIntrinsicComponentTypes.XOR]: xorIntrinsicComponentDefinition, + [ccIntrinsicComponentTypes.INPUT]: inputIntrinsicComponentDefinition, + [ccIntrinsicComponentTypes.AGGREGATE]: aggregateIntrinsicComponentDefinition, + [ccIntrinsicComponentTypes.BROADCAST]: broadcastIntrinsicComponentDefinition, + [ccIntrinsicComponentTypes.DECOMPOSE]: decomposeIntrinsicComponentDefinition, + [ccIntrinsicComponentTypes.FLIPFLOP]: flipFlopIntrinsicComponentDefinition, }; /** @@ -397,9 +396,13 @@ export const ccIntrinsicComponentDefinitions: Record< * @returns void */ export function registerIntrinsics(store: CCStore) { - Object.values(ccIntrinsicComponentDefinitions).forEach((definition) => { - store.components.register(definition.component); - definition.inputPins.forEach((pin) => store.componentPins.register(pin)); - definition.outputPins.forEach((pin) => store.componentPins.register(pin)); - }); + for (const definition of Object.values(ccIntrinsicComponentDefinitions)) { + store.components.register(definition.component); + for (const pin of definition.inputPins) { + store.componentPins.register(pin); + } + for (const pin of definition.outputPins) { + store.componentPins.register(pin); + } + } } diff --git a/src/store/node.ts b/src/store/node.ts index 81a52ab..c59584b 100644 --- a/src/store/node.ts +++ b/src/store/node.ts @@ -1,150 +1,149 @@ -import type { Opaque } from "type-fest"; import EventEmitter from "eventemitter3"; -import invariant from "tiny-invariant"; import nullthrows from "nullthrows"; +import invariant from "tiny-invariant"; +import type { Opaque } from "type-fest"; import type CCStore from "."; -import type { CCComponentId } from "./component"; import type { Vector2 } from "../common/vector2"; +import type { CCComponentId } from "./component"; export type CCNodeId = Opaque; export type CCNode = { - readonly id: CCNodeId; - readonly parentComponentId: CCComponentId; - readonly componentId: CCComponentId; - position: Vector2; + readonly id: CCNodeId; + readonly parentComponentId: CCComponentId; + readonly componentId: CCComponentId; + position: Vector2; }; export type CCNodeStoreEvents = { - didRegister(node: CCNode): void; - willUnregister(node: CCNode): void; - didUnregister(node: CCNode): void; - didUpdate(node: CCNode): void; + didRegister(node: CCNode): void; + willUnregister(node: CCNode): void; + didUnregister(node: CCNode): void; + didUpdate(node: CCNode): void; }; /** * Store of nodes */ export class CCNodeStore extends EventEmitter { - #store: CCStore; - - #nodes: Map = new Map(); - - /** - * Constructor of CCNodeStore - * @param store store - * @param nodes initial nodes - */ - constructor(store: CCStore) { - super(); - this.#store = store; - } - - import(nodes: CCNode[]): void { - for (const node of nodes) { - node.position = { x: node.position.x, y: node.position.y }; - this.register(node); - } - } - - // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-empty-function - mount() {} - - /** - * Register a node - * @param node node to be registered - */ - register(node: CCNode): void { - invariant(this.#store.components.get(node.componentId)); - invariant(this.#store.components.get(node.parentComponentId)); - this.#nodes.set(node.id, node); - this.emit("didRegister", node); - } - - /** - * Unregister nodes - * @param ids ids of nodes to be unregistered - */ - async unregister(ids: CCNodeId[]): Promise { - const nodes = ids.map((id) => nullthrows(this.#nodes.get(id))); - await this.#store.transactionManager.runInTransaction(() => { - for (const node of nodes) { - this.emit("willUnregister", node); - this.#nodes.delete(node.id); - } - }); - for (const node of nodes) { - this.emit("didUnregister", node); - } - } - - /** - * Get a node by id - * @param id id of node - * @returns node of `id` - */ - get(id: CCNodeId): CCNode | undefined { - return this.#nodes.get(id); - } - - /** - * Get all of nodes by parent component id - * @param parentComponentId id of parent component - * @returns nodes of parent component - * @deprecated in favor of {@link getManyByParentComponentId} - */ - getNodeIdsByParentComponentId(parentComponentId: CCComponentId): CCNodeId[] { - return this.getManyByParentComponentId(parentComponentId).map( - (node) => node.id - ); - } - - getManyByParentComponentId(parentComponentId: CCComponentId): CCNode[] { - return [...this.#nodes.values()].filter( - (node) => node.parentComponentId === parentComponentId - ); - } - - getManyByComponentId(componentId: CCComponentId): CCNode[] { - return [...this.#nodes.values()].filter( - (node) => node.componentId === componentId - ); - } - - /** - * Update position of node - * @param id id of node - * @param value new position - */ - update(id: CCNodeId, value: Pick): void { - const node = this.#nodes.get(id); - invariant(node); - this.#nodes.set(id, { ...node, ...value }); - this.emit("didUpdate", node); - } - - /** - * Create node - * @param partialNode node without `id` - * @returns new node - */ - static create(partialNode: Omit): CCNode { - // invariant( - // hasVariablePinCount(partialNode.componentId) - // ? partialNode.intrinsicVariablePinCount !== null - // : partialNode.intrinsicVariablePinCount === null - // ); - return { - id: crypto.randomUUID() as CCNodeId, - ...partialNode, - }; - } - - /** - * Get array of nodes - * @returns array of nodes - */ - getMany(): CCNode[] { - return [...this.#nodes.values()]; - } + #store: CCStore; + + #nodes: Map = new Map(); + + /** + * Constructor of CCNodeStore + * @param store store + * @param nodes initial nodes + */ + constructor(store: CCStore) { + super(); + this.#store = store; + } + + import(nodes: CCNode[]): void { + for (const node of nodes) { + node.position = { x: node.position.x, y: node.position.y }; + this.register(node); + } + } + + mount() {} + + /** + * Register a node + * @param node node to be registered + */ + register(node: CCNode): void { + invariant(this.#store.components.get(node.componentId)); + invariant(this.#store.components.get(node.parentComponentId)); + this.#nodes.set(node.id, node); + this.emit("didRegister", node); + } + + /** + * Unregister nodes + * @param ids ids of nodes to be unregistered + */ + async unregister(ids: CCNodeId[]): Promise { + const nodes = ids.map((id) => nullthrows(this.#nodes.get(id))); + await this.#store.transactionManager.runInTransaction(() => { + for (const node of nodes) { + this.emit("willUnregister", node); + this.#nodes.delete(node.id); + } + }); + for (const node of nodes) { + this.emit("didUnregister", node); + } + } + + /** + * Get a node by id + * @param id id of node + * @returns node of `id` + */ + get(id: CCNodeId): CCNode | undefined { + return this.#nodes.get(id); + } + + /** + * Get all of nodes by parent component id + * @param parentComponentId id of parent component + * @returns nodes of parent component + * @deprecated in favor of {@link getManyByParentComponentId} + */ + getNodeIdsByParentComponentId(parentComponentId: CCComponentId): CCNodeId[] { + return this.getManyByParentComponentId(parentComponentId).map( + (node) => node.id, + ); + } + + getManyByParentComponentId(parentComponentId: CCComponentId): CCNode[] { + return [...this.#nodes.values()].filter( + (node) => node.parentComponentId === parentComponentId, + ); + } + + getManyByComponentId(componentId: CCComponentId): CCNode[] { + return [...this.#nodes.values()].filter( + (node) => node.componentId === componentId, + ); + } + + /** + * Update position of node + * @param id id of node + * @param value new position + */ + update(id: CCNodeId, value: Pick): void { + const node = this.#nodes.get(id); + invariant(node); + this.#nodes.set(id, { ...node, ...value }); + this.emit("didUpdate", node); + } + + /** + * Create node + * @param partialNode node without `id` + * @returns new node + */ + static create(partialNode: Omit): CCNode { + // invariant( + // hasVariablePinCount(partialNode.componentId) + // ? partialNode.intrinsicVariablePinCount !== null + // : partialNode.intrinsicVariablePinCount === null + // ); + return { + id: crypto.randomUUID() as CCNodeId, + ...partialNode, + }; + } + + /** + * Get array of nodes + * @returns array of nodes + */ + getMany(): CCNode[] { + return [...this.#nodes.values()]; + } } diff --git a/src/store/nodePin.ts b/src/store/nodePin.ts index 8b86fe5..6f13272 100644 --- a/src/store/nodePin.ts +++ b/src/store/nodePin.ts @@ -1,265 +1,272 @@ -import type { Opaque } from "type-fest"; import EventEmitter from "eventemitter3"; import nullthrows from "nullthrows"; import invariant from "tiny-invariant"; -import type { CCNodeId } from "./node"; +import type { Opaque } from "type-fest"; +import type CCStore from "."; import type { - CCComponentPin, - CCComponentPinId, - CCPinMultiplexability, + CCComponentPin, + CCComponentPinId, + CCPinMultiplexability, } from "./componentPin"; -import type CCStore from "."; import * as intrinsic from "./intrinsics"; +import type { CCNodeId } from "./node"; export type CCNodePinId = Opaque; export type CCNodePin = { - id: CCNodePinId; - nodeId: CCNodeId; - componentPinId: CCComponentPinId; - order: number; - userSpecifiedBitWidth: number | null; + id: CCNodePinId; + nodeId: CCNodeId; + componentPinId: CCComponentPinId; + order: number; + userSpecifiedBitWidth: number | null; }; export type CCNodePinStoreEvents = { - didRegister(pin: CCNodePin): void; - willUnregister(pin: CCNodePin): void; - didUnregister(pin: CCNodePin): void; + didRegister(pin: CCNodePin): void; + willUnregister(pin: CCNodePin): void; + didUnregister(pin: CCNodePin): void; }; export class CCNodePinStore extends EventEmitter { - #store: CCStore; + #store: CCStore; - #nodePins: Map = new Map(); + #nodePins: Map = new Map(); - #markedAsDeleted: Set = new Set(); + #markedAsDeleted: Set = new Set(); - /** - * Constructor of CCNodePinStore - * @param store store - * @param nodePins initial pins - */ - constructor(store: CCStore) { - super(); - this.#store = store; - } + /** + * Constructor of CCNodePinStore + * @param store store + * @param nodePins initial pins + */ + constructor(store: CCStore) { + super(); + this.#store = store; + } - import(nodePins: CCNodePin[]) { - for (const nodePin of nodePins) { - this.register(nodePin); - } - } + import(nodePins: CCNodePin[]) { + for (const nodePin of nodePins) { + this.register(nodePin); + } + } - mount() { - const getDefaultUserSpecifiedBitWidth = (componentPin: CCComponentPin) => { - const component = this.#store.components.get(componentPin.componentId)!; - if (!component.intrinsicType) return null; - const definition = - intrinsic.ccIntrinsicComponentDefinitions[component.intrinsicType]; - return definition.componentPinHasUserSpecifiedBitWidth?.(componentPin) - ? 1 - : null; - }; - this.#store.nodes.on("didRegister", (node) => { - const componentPins = this.#store.componentPins.getManyByComponentId( - node.componentId - ); - for (const componentPin of componentPins) { - this.register( - CCNodePinStore.create({ - nodeId: node.id, - componentPinId: componentPin.id, - order: 0, - userSpecifiedBitWidth: - getDefaultUserSpecifiedBitWidth(componentPin), - }) - ); - } - }); - this.#store.nodes.on("willUnregister", (node) => { - for (const pin of this.#nodePins.values()) { - if (pin.nodeId === node.id) { - this.unregister(pin.id); - } - } - }); - this.#store.componentPins.on("didRegister", (componentPin) => { - for (const node of this.#store.nodes.getManyByComponentId( - componentPin.componentId - )) { - this.register( - CCNodePinStore.create({ - nodeId: node.id, - componentPinId: componentPin.id, - order: 0, - userSpecifiedBitWidth: - getDefaultUserSpecifiedBitWidth(componentPin), - }) - ); - } - }); - this.#store.componentPins.on("willUnregister", (componentPin) => { - for (const pin of this.#nodePins.values()) { - if (pin.componentPinId === componentPin.id) { - this.unregister(pin.id); - } - } - }); - } + mount() { + const getDefaultUserSpecifiedBitWidth = (componentPin: CCComponentPin) => { + const component = nullthrows( + this.#store.components.get(componentPin.componentId), + ); + if (!component.intrinsicType) return null; + const definition = + intrinsic.ccIntrinsicComponentDefinitions[component.intrinsicType]; + return definition.componentPinHasUserSpecifiedBitWidth?.(componentPin) + ? 1 + : null; + }; + this.#store.nodes.on("didRegister", (node) => { + const componentPins = this.#store.componentPins.getManyByComponentId( + node.componentId, + ); + for (const componentPin of componentPins) { + this.register( + CCNodePinStore.create({ + nodeId: node.id, + componentPinId: componentPin.id, + order: 0, + userSpecifiedBitWidth: + getDefaultUserSpecifiedBitWidth(componentPin), + }), + ); + } + }); + this.#store.nodes.on("willUnregister", (node) => { + for (const pin of this.#nodePins.values()) { + if (pin.nodeId === node.id) { + this.unregister(pin.id); + } + } + }); + this.#store.componentPins.on("didRegister", (componentPin) => { + for (const node of this.#store.nodes.getManyByComponentId( + componentPin.componentId, + )) { + this.register( + CCNodePinStore.create({ + nodeId: node.id, + componentPinId: componentPin.id, + order: 0, + userSpecifiedBitWidth: + getDefaultUserSpecifiedBitWidth(componentPin), + }), + ); + } + }); + this.#store.componentPins.on("willUnregister", (componentPin) => { + for (const pin of this.#nodePins.values()) { + if (pin.componentPinId === componentPin.id) { + this.unregister(pin.id); + } + } + }); + } - /** - * Register a pin - * @param nodePin pin to be registered - */ - register(nodePin: CCNodePin): void { - invariant(this.#store.componentPins.get(nodePin.componentPinId)); - invariant(this.#store.nodes.get(nodePin.nodeId)); - this.#nodePins.set(nodePin.id, nodePin); - this.emit("didRegister", nodePin); - } + /** + * Register a pin + * @param nodePin pin to be registered + */ + register(nodePin: CCNodePin): void { + invariant(this.#store.componentPins.get(nodePin.componentPinId)); + invariant(this.#store.nodes.get(nodePin.nodeId)); + this.#nodePins.set(nodePin.id, nodePin); + this.emit("didRegister", nodePin); + } - /** - * Unregister a pin - * @param id id of a pin to be unregistered - */ - async unregister(id: CCNodePinId): Promise { - const nodePin = nullthrows(this.#nodePins.get(id)); - this.#markedAsDeleted.add(id); - await this.#store.transactionManager.runInTransaction(() => { - this.emit("willUnregister", nodePin); - this.#nodePins.delete(nodePin.id); - }); - this.emit("didUnregister", nodePin); - this.#markedAsDeleted.delete(id); - } + /** + * Unregister a pin + * @param id id of a pin to be unregistered + */ + async unregister(id: CCNodePinId): Promise { + const nodePin = nullthrows(this.#nodePins.get(id)); + this.#markedAsDeleted.add(id); + await this.#store.transactionManager.runInTransaction(() => { + this.emit("willUnregister", nodePin); + this.#nodePins.delete(nodePin.id); + }); + this.emit("didUnregister", nodePin); + this.#markedAsDeleted.delete(id); + } - /** - * Get a pin by id - * @param id id of pin - * @returns pin of `id` - */ - get(id: CCNodePinId): CCNodePin | undefined { - return this.#nodePins.get(id); - } + /** + * Get a pin by id + * @param id id of pin + * @returns pin of `id` + */ + get(id: CCNodePinId): CCNodePin | undefined { + return this.#nodePins.get(id); + } - /** - * Get all of pins - * @returns all pins - */ - getByImplementationNodeIdAndPinId( - nodeId: CCNodeId, - componentPinId: CCComponentPinId - ): CCNodePin { - const pin = [...this.#nodePins.values()].find( - (candidate) => - candidate.nodeId === nodeId && - candidate.componentPinId === componentPinId - ); - invariant(pin); - return pin; - } + /** + * Get all of pins + * @returns all pins + */ + getByImplementationNodeIdAndPinId( + nodeId: CCNodeId, + componentPinId: CCComponentPinId, + ): CCNodePin { + const pin = [...this.#nodePins.values()].find( + (candidate) => + candidate.nodeId === nodeId && + candidate.componentPinId === componentPinId, + ); + invariant(pin); + return pin; + } - /** - * Get all of pins by component id - * @param componentId id of component - * @returns pins of component - */ - getManyByNodeId(nodeId: CCNodeId): CCNodePin[] { - return [...this.#nodePins.values()].filter((pin) => pin.nodeId === nodeId); - } + /** + * Get all of pins by component id + * @param componentId id of component + * @returns pins of component + */ + getManyByNodeId(nodeId: CCNodeId): CCNodePin[] { + return [...this.#nodePins.values()].filter((pin) => pin.nodeId === nodeId); + } - /** - * Get the multiplexability of a node pin - * @param pinId id of pin - * @param nodeId id of node - * @returns multiplexability of the pin - */ - getNodePinMultiplexability(nodePinId: CCNodePinId): CCPinMultiplexability { - const traverseNodePinMultiplexability = ( - nodePinId_: CCNodePinId, - seen: Set - ): CCPinMultiplexability => { - const { nodeId, componentPinId: pinId } = this.get(nodePinId_)!; - seen.add(nodeId); - const node = this.#store.nodes.get(nodeId)!; - const nodePins = this.getManyByNodeId(node.id); - const givenPinMultiplexability = - this.#store.componentPins.getComponentPinMultiplexability(pinId); - if (givenPinMultiplexability === "undecidable") { - if ( - pinId === - intrinsic.aggregateIntrinsicComponentDefinition.outputPins[0]!.id - ) { - return { isMultiplexable: false, multiplicity: nodePins.length - 1 }; - } - if ( - pinId === - intrinsic.decomposeIntrinsicComponentDefinition.inputPins[0]!.id - ) { - return { isMultiplexable: false, multiplicity: nodePins.length - 1 }; - } - throw new Error("unreachable"); - } - if (!givenPinMultiplexability.isMultiplexable) { - return givenPinMultiplexability; - } - // eslint-disable-next-line - for (const nodePin of nodePins) { - const pinMultiplexability = - this.#store.componentPins.getComponentPinMultiplexability( - nodePin.componentPinId - ); - if (pinMultiplexability === "undecidable") { - throw new Error("unreachable"); - } - if (pinMultiplexability.isMultiplexable) { - const connections = - this.#store.connections.getConnectionsByNodePinId(nodePinId)!; - for (const connection of connections) { - const componentPin = this.#store.componentPins.get( - nodePin.componentPinId - )!; - const connectedNodePinId = - componentPin.type === "input" ? connection.from : connection.to; - const connectedNodePin = this.get(connectedNodePinId)!; - if (seen.has(connectedNodePin.nodeId)) { - // eslint-disable-next-line no-continue - continue; - } - const connectedPinMultiplexability = - traverseNodePinMultiplexability(connectedNodePinId, seen); - if (!connectedPinMultiplexability.isMultiplexable) { - return connectedPinMultiplexability; - } - } - } - } - return givenPinMultiplexability; - }; - return traverseNodePinMultiplexability(nodePinId, new Set()); - } + /** + * Get the multiplexability of a node pin + * @param pinId id of pin + * @param nodeId id of node + * @returns multiplexability of the pin + */ + getNodePinMultiplexability(nodePinId: CCNodePinId): CCPinMultiplexability { + const traverseNodePinMultiplexability = ( + nodePinId_: CCNodePinId, + seen: Set, + ): CCPinMultiplexability => { + const { nodeId, componentPinId: pinId } = nullthrows( + this.get(nodePinId_), + ); + seen.add(nodeId); + const node = nullthrows(this.#store.nodes.get(nodeId)); + const nodePins = this.getManyByNodeId(node.id); + const givenPinMultiplexability = + this.#store.componentPins.getComponentPinMultiplexability(pinId); + if (givenPinMultiplexability === "undecidable") { + if ( + pinId === + nullthrows( + intrinsic.aggregateIntrinsicComponentDefinition.outputPins[0], + ).id + ) { + return { isMultiplexable: false, multiplicity: nodePins.length - 1 }; + } + if ( + pinId === + nullthrows( + intrinsic.decomposeIntrinsicComponentDefinition.inputPins[0], + ).id + ) { + return { isMultiplexable: false, multiplicity: nodePins.length - 1 }; + } + throw new Error("unreachable"); + } + if (!givenPinMultiplexability.isMultiplexable) { + return givenPinMultiplexability; + } + for (const nodePin of nodePins) { + const pinMultiplexability = + this.#store.componentPins.getComponentPinMultiplexability( + nodePin.componentPinId, + ); + if (pinMultiplexability === "undecidable") { + throw new Error("unreachable"); + } + if (pinMultiplexability.isMultiplexable) { + const connections = nullthrows( + this.#store.connections.getConnectionsByNodePinId(nodePinId), + ); + for (const connection of connections) { + const componentPin = nullthrows( + this.#store.componentPins.get(nodePin.componentPinId), + ); + const connectedNodePinId = + componentPin.type === "input" ? connection.from : connection.to; + const connectedNodePin = nullthrows(this.get(connectedNodePinId)); + if (seen.has(connectedNodePin.nodeId)) { + continue; + } + const connectedPinMultiplexability = + traverseNodePinMultiplexability(connectedNodePinId, seen); + if (!connectedPinMultiplexability.isMultiplexable) { + return connectedPinMultiplexability; + } + } + } + } + return givenPinMultiplexability; + }; + return traverseNodePinMultiplexability(nodePinId, new Set()); + } - isMarkedAsDeleted(id: CCNodePinId) { - return this.#markedAsDeleted.has(id); - } + isMarkedAsDeleted(id: CCNodePinId) { + return this.#markedAsDeleted.has(id); + } - /** - * Create a new pin - * @param partialPin pin without `id` - * @returns a new pin - */ - static create(partialPin: Omit): CCNodePin { - return { - id: crypto.randomUUID() as CCNodePinId, - ...partialPin, - }; - } + /** + * Create a new pin + * @param partialPin pin without `id` + * @returns a new pin + */ + static create(partialPin: Omit): CCNodePin { + return { + id: crypto.randomUUID() as CCNodePinId, + ...partialPin, + }; + } - /** - * Get array of pins - * @returns array of pins - */ - getMany(): CCNodePin[] { - return [...this.#nodePins.values()]; - } + /** + * Get array of pins + * @returns array of pins + */ + getMany(): CCNodePin[] { + return [...this.#nodePins.values()]; + } } diff --git a/src/store/react/error.tsx b/src/store/react/error.tsx index cbae792..bd9c794 100644 --- a/src/store/react/error.tsx +++ b/src/store/react/error.tsx @@ -1,14 +1,14 @@ -import { createElement, type ComponentType } from "react"; -import type CCStore from ".."; +import { type ComponentType, createElement } from "react"; import { useStore } from "."; +import type CCStore from ".."; export default function ensureStoreItem

>( - check: (props: P, store: CCStore) => unknown, - component: ComponentType

+ check: (props: P, store: CCStore) => unknown, + component: ComponentType

, ): ComponentType

{ - return function EnsureStoreItem(props: P) { - const { store } = useStore(); - if (!check(props, store)) return null; - return createElement(component, props); - }; + return function EnsureStoreItem(props: P) { + const { store } = useStore(); + if (!check(props, store)) return null; + return createElement(component, props); + }; } diff --git a/src/store/react/index.tsx b/src/store/react/index.tsx index 91af931..8f535e9 100644 --- a/src/store/react/index.tsx +++ b/src/store/react/index.tsx @@ -1,96 +1,98 @@ +import nullthrows from "nullthrows"; import { - createContext, - useCallback, - useContext, - useEffect, - useMemo, - useState, + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useState, } from "react"; import invariant from "tiny-invariant"; -import nullthrows from "nullthrows"; import CCStore, { type CCStorePropsFromJson } from ".."; import { CCComponentStore } from "../component"; -import { CCNodeStore } from "../node"; +import { CCConnectionStore } from "../connection"; import { - andIntrinsicComponentDefinition, - notIntrinsicComponentDefinition, + andIntrinsicComponentDefinition, + notIntrinsicComponentDefinition, } from "../intrinsics"; -import { CCConnectionStore } from "../connection"; +import { CCNodeStore } from "../node"; function useContextValue() { - const [store, setStore] = useState(() => { - const tempStore = new CCStore(); + const [store, setStore] = useState(() => { + const tempStore = new CCStore(); - const rootComponent = CCComponentStore.create({ - name: "Root", - }); - tempStore.components.register(rootComponent); + const rootComponent = CCComponentStore.create({ + name: "Root", + }); + tempStore.components.register(rootComponent); - const sampleNode1 = CCNodeStore.create({ - parentComponentId: rootComponent.id, - componentId: andIntrinsicComponentDefinition.component.id, - position: { x: -100, y: 0 }, - }); - tempStore.nodes.register(sampleNode1); + const sampleNode1 = CCNodeStore.create({ + parentComponentId: rootComponent.id, + componentId: andIntrinsicComponentDefinition.component.id, + position: { x: -100, y: 0 }, + }); + tempStore.nodes.register(sampleNode1); - const sampleNode2 = CCNodeStore.create({ - parentComponentId: rootComponent.id, - componentId: notIntrinsicComponentDefinition.component.id, - position: { x: 100, y: 0 }, - }); - tempStore.nodes.register(sampleNode2); + const sampleNode2 = CCNodeStore.create({ + parentComponentId: rootComponent.id, + componentId: notIntrinsicComponentDefinition.component.id, + position: { x: 100, y: 0 }, + }); + tempStore.nodes.register(sampleNode2); - const fromNodePin = nullthrows( - tempStore.nodePins - .getManyByNodeId(sampleNode1.id) - .find( - (nodePin) => - nodePin.componentPinId === - andIntrinsicComponentDefinition.outputPins[0]!.id - ) - ); - const toNodePin = nullthrows( - tempStore.nodePins - .getManyByNodeId(sampleNode2.id) - .find( - (nodePin) => - nodePin.componentPinId === - notIntrinsicComponentDefinition.inputPins[0]!.id - ) - ); - const sampleConnection = CCConnectionStore.create({ - parentComponentId: rootComponent.id, - from: fromNodePin.id, - to: toNodePin.id, - bentPortion: 0.5, - }); - tempStore.connections.register(sampleConnection); + const fromNodePin = nullthrows( + tempStore.nodePins + .getManyByNodeId(sampleNode1.id) + .find( + (nodePin) => + nodePin.componentPinId === + nullthrows(andIntrinsicComponentDefinition.outputPins[0]).id, + ), + ); + const toNodePin = nullthrows( + tempStore.nodePins + .getManyByNodeId(sampleNode2.id) + .find( + (nodePin) => + nodePin.componentPinId === + nullthrows(notIntrinsicComponentDefinition.inputPins[0]).id, + ), + ); + const sampleConnection = CCConnectionStore.create({ + parentComponentId: rootComponent.id, + from: fromNodePin.id, + to: toNodePin.id, + bentPortion: 0.5, + }); + tempStore.connections.register(sampleConnection); - return tempStore; - }); + return tempStore; + }); - // For debugging - useEffect(() => { - // eslint-disable-next-line no-underscore-dangle, @typescript-eslint/no-explicit-any - (window as any)._store = store; - }, [store]); + // For debugging + useEffect(() => { + Object.defineProperty(window, "_store", { + value: store, + enumerable: false, + }); + }, [store]); - const resetStore = useCallback((props: CCStorePropsFromJson) => { - setStore(new CCStore(props)); - }, []); - return useMemo(() => ({ store, resetStore }), [store, resetStore]); + const resetStore = useCallback((props: CCStorePropsFromJson) => { + setStore(new CCStore(props)); + }, []); + return useMemo(() => ({ store, resetStore }), [store, resetStore]); } const context = createContext | null>(null); export function StoreProvider({ children }: { children: React.ReactNode }) { - return ( - {children} - ); + return ( + {children} + ); } export function useStore() { - const store = useContext(context); - invariant(store); - return store; + const store = useContext(context); + invariant(store); + return store; } diff --git a/src/store/react/selectors.ts b/src/store/react/selectors.ts index f597a83..c67b167 100644 --- a/src/store/react/selectors.ts +++ b/src/store/react/selectors.ts @@ -1,166 +1,166 @@ -import { useCallback, useMemo, useSyncExternalStore } from "react"; import memoizeOne from "memoize-one"; import nullthrows from "nullthrows"; +import { useCallback, useMemo, useSyncExternalStore } from "react"; import { useStore } from "."; import type { CCComponentId } from "../component"; -import type { CCNode, CCNodeId } from "../node"; import type { CCComponentPin } from "../componentPin"; +import type { CCNode, CCNodeId } from "../node"; import type { CCNodePin } from "../nodePin"; export function useComponents() { - const { store } = useStore(); - const getSnapshot = useMemo( - () => memoizeOne(() => store.components.getMany()), - [store] - ); - const subscribe = useCallback( - (onStoreChange: () => void) => { - const handler = () => { - getSnapshot.clear(); - onStoreChange(); - }; - store.components.on("didRegister", handler); - store.components.on("didUpdate", handler); - store.components.on("didUnregister", handler); - return () => { - store.components.off("didRegister", handler); - store.components.off("didUpdate", handler); - store.components.off("didUnregister", handler); - }; - }, - [getSnapshot, store.components] - ); - return useSyncExternalStore(subscribe, getSnapshot); + const { store } = useStore(); + const getSnapshot = useMemo( + () => memoizeOne(() => store.components.getMany()), + [store], + ); + const subscribe = useCallback( + (onStoreChange: () => void) => { + const handler = () => { + getSnapshot.clear(); + onStoreChange(); + }; + store.components.on("didRegister", handler); + store.components.on("didUpdate", handler); + store.components.on("didUnregister", handler); + return () => { + store.components.off("didRegister", handler); + store.components.off("didUpdate", handler); + store.components.off("didUnregister", handler); + }; + }, + [getSnapshot, store.components], + ); + return useSyncExternalStore(subscribe, getSnapshot); } export function useNodeIds(parentComponentId: CCComponentId) { - const { store } = useStore(); - const getSnapshot = useMemo( - () => - memoizeOne(() => - store.nodes - .getMany() - .filter((node) => node.parentComponentId === parentComponentId) - .map((node) => node.id) - ), - [store, parentComponentId] - ); - const subscribe = useCallback( - (onStoreChange: () => void) => { - const handler = () => { - getSnapshot.clear(); - onStoreChange(); - }; - store.nodes.on("didRegister", handler); - store.nodes.on("didUnregister", handler); - return () => { - store.nodes.off("didRegister", handler); - store.nodes.off("didUnregister", handler); - }; - }, - [getSnapshot, store.nodes] - ); - return useSyncExternalStore(subscribe, getSnapshot); + const { store } = useStore(); + const getSnapshot = useMemo( + () => + memoizeOne(() => + store.nodes + .getMany() + .filter((node) => node.parentComponentId === parentComponentId) + .map((node) => node.id), + ), + [store, parentComponentId], + ); + const subscribe = useCallback( + (onStoreChange: () => void) => { + const handler = () => { + getSnapshot.clear(); + onStoreChange(); + }; + store.nodes.on("didRegister", handler); + store.nodes.on("didUnregister", handler); + return () => { + store.nodes.off("didRegister", handler); + store.nodes.off("didUnregister", handler); + }; + }, + [getSnapshot, store.nodes], + ); + return useSyncExternalStore(subscribe, getSnapshot); } export function useConnectionIds(parentComponentId: CCComponentId) { - const { store } = useStore(); - const getSnapshot = useMemo( - () => - memoizeOne(() => - store.connections - .getMany() - .filter( - (connection) => connection.parentComponentId === parentComponentId - ) - .map((connection) => connection.id) - ), - [store, parentComponentId] - ); - const subscribe = useCallback( - (onStoreChange: () => void) => { - const handler = () => { - getSnapshot.clear(); - onStoreChange(); - }; - store.connections.on("didRegister", handler); - store.connections.on("didUnregister", handler); - return () => { - store.connections.off("didRegister", handler); - store.connections.off("didUnregister", handler); - }; - }, - [getSnapshot, store.connections] - ); - return useSyncExternalStore(subscribe, getSnapshot); + const { store } = useStore(); + const getSnapshot = useMemo( + () => + memoizeOne(() => + store.connections + .getMany() + .filter( + (connection) => connection.parentComponentId === parentComponentId, + ) + .map((connection) => connection.id), + ), + [store, parentComponentId], + ); + const subscribe = useCallback( + (onStoreChange: () => void) => { + const handler = () => { + getSnapshot.clear(); + onStoreChange(); + }; + store.connections.on("didRegister", handler); + store.connections.on("didUnregister", handler); + return () => { + store.connections.off("didRegister", handler); + store.connections.off("didUnregister", handler); + }; + }, + [getSnapshot, store.connections], + ); + return useSyncExternalStore(subscribe, getSnapshot); } export function useNode(nodeId: CCNodeId) { - const { store } = useStore(); - const getSnapshot = useCallback( - () => nullthrows(store.nodes.get(nodeId)), - [store, nodeId] - ); - const subscribe = useCallback( - (onStoreChange: () => void) => { - const handler = (node: CCNode) => { - if (node.id === nodeId) onStoreChange(); - }; - store.nodes.on("didUpdate", handler); - return () => { - store.nodes.off("didUpdate", handler); - }; - }, - [store, nodeId] - ); - return useSyncExternalStore(subscribe, getSnapshot); + const { store } = useStore(); + const getSnapshot = useCallback( + () => nullthrows(store.nodes.get(nodeId)), + [store, nodeId], + ); + const subscribe = useCallback( + (onStoreChange: () => void) => { + const handler = (node: CCNode) => { + if (node.id === nodeId) onStoreChange(); + }; + store.nodes.on("didUpdate", handler); + return () => { + store.nodes.off("didUpdate", handler); + }; + }, + [store, nodeId], + ); + return useSyncExternalStore(subscribe, getSnapshot); } export function useComponentPins(componentId: CCComponentId) { - const { store } = useStore(); - const getSnapshot = useMemo( - () => - memoizeOne(() => store.componentPins.getManyByComponentId(componentId)), - [store, componentId] - ); - const subscribe = useCallback( - (onStoreChange: () => void) => { - const handler = (componentPin: CCComponentPin) => { - if (componentPin.componentId === componentId) onStoreChange(); - }; - store.componentPins.on("didRegister", handler); - store.componentPins.on("didUpdate", handler); - store.componentPins.on("didUnregister", handler); - return () => { - store.componentPins.off("didRegister", handler); - store.componentPins.off("didUpdate", handler); - store.componentPins.off("didUnregister", handler); - }; - }, - [store, componentId] - ); - return useSyncExternalStore(subscribe, getSnapshot); + const { store } = useStore(); + const getSnapshot = useMemo( + () => + memoizeOne(() => store.componentPins.getManyByComponentId(componentId)), + [store, componentId], + ); + const subscribe = useCallback( + (onStoreChange: () => void) => { + const handler = (componentPin: CCComponentPin) => { + if (componentPin.componentId === componentId) onStoreChange(); + }; + store.componentPins.on("didRegister", handler); + store.componentPins.on("didUpdate", handler); + store.componentPins.on("didUnregister", handler); + return () => { + store.componentPins.off("didRegister", handler); + store.componentPins.off("didUpdate", handler); + store.componentPins.off("didUnregister", handler); + }; + }, + [store, componentId], + ); + return useSyncExternalStore(subscribe, getSnapshot); } export function useNodePins(nodeId: CCNodeId) { - const { store } = useStore(); - const getSnapshot = useMemo( - () => memoizeOne(() => store.nodePins.getManyByNodeId(nodeId)), - [store, nodeId] - ); - const subscribe = useCallback( - (onStoreChange: () => void) => { - const handler = (nodePin: CCNodePin) => { - if (nodePin.nodeId === nodeId) onStoreChange(); - }; - store.nodePins.on("didRegister", handler); - store.nodePins.on("didUnregister", handler); - return () => { - store.nodePins.off("didRegister", handler); - store.nodePins.off("didUnregister", handler); - }; - }, - [store, nodeId] - ); - return useSyncExternalStore(subscribe, getSnapshot); + const { store } = useStore(); + const getSnapshot = useMemo( + () => memoizeOne(() => store.nodePins.getManyByNodeId(nodeId)), + [store, nodeId], + ); + const subscribe = useCallback( + (onStoreChange: () => void) => { + const handler = (nodePin: CCNodePin) => { + if (nodePin.nodeId === nodeId) onStoreChange(); + }; + store.nodePins.on("didRegister", handler); + store.nodePins.on("didUnregister", handler); + return () => { + store.nodePins.off("didRegister", handler); + store.nodePins.off("didUnregister", handler); + }; + }, + [store, nodeId], + ); + return useSyncExternalStore(subscribe, getSnapshot); } diff --git a/src/store/transaction.ts b/src/store/transaction.ts index 0a2b1a2..f7e3f29 100644 --- a/src/store/transaction.ts +++ b/src/store/transaction.ts @@ -2,27 +2,29 @@ * Class that manages the transaction of the store */ export default class TransactionManager { - #runningTaskCount = 0; + #runningTaskCount = 0; - #onTransactionEnd: (() => void)[] = []; + #onTransactionEnd: (() => void)[] = []; - /** - * Run a function in a transaction - * @param fn function to be run in a transaction - * @returns promise that resolves when the transaction ends - */ - async runInTransaction(fn: () => void | Promise): Promise { - return new Promise((resolve) => { - (async () => { - this.#runningTaskCount += 1; - this.#onTransactionEnd.push(resolve); - await fn(); - this.#runningTaskCount -= 1; - if (this.#runningTaskCount === 0) { - this.#onTransactionEnd.forEach((callback) => callback()); - this.#onTransactionEnd = []; - } - })(); - }); - } + /** + * Run a function in a transaction + * @param fn function to be run in a transaction + * @returns promise that resolves when the transaction ends + */ + async runInTransaction(fn: () => void | Promise): Promise { + return new Promise((resolve) => { + (async () => { + this.#runningTaskCount += 1; + this.#onTransactionEnd.push(resolve); + await fn(); + this.#runningTaskCount -= 1; + if (this.#runningTaskCount === 0) { + for (const callback of this.#onTransactionEnd) { + callback(); + } + this.#onTransactionEnd = []; + } + })(); + }); + } } diff --git a/tsconfig.json b/tsconfig.json index 829fd0b..70a6847 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,13 @@ { - "extends": "@tsconfig/strictest/tsconfig.json", - "compilerOptions": { - "target": "ESNext", - "lib": ["DOM", "DOM.Iterable", "ESNext"], - "module": "ESNext", - "moduleResolution": "Node", - "noEmit": true, - "jsx": "react-jsx", - "verbatimModuleSyntax": true - }, - "include": ["src"] + "extends": "@tsconfig/strictest/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "moduleResolution": "Node", + "noEmit": true, + "jsx": "react-jsx", + "verbatimModuleSyntax": true + }, + "include": ["src"] } diff --git a/vite.config.ts b/vite.config.ts index de105d9..e29a791 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,8 +1,7 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], + plugins: [react()], });