diff --git a/index.html b/index.html
index e8ae001..bb45323 100644
--- a/index.html
+++ b/index.html
@@ -1,12 +1,12 @@
-
+
-
+
- Vite + React + TS
+ PhiFans Editor
-
+
diff --git a/package.json b/package.json
index f2e1598..67dc411 100644
--- a/package.json
+++ b/package.json
@@ -8,44 +8,59 @@
"url": "https://github.com/PhiFans/editor.git"
},
"scripts": {
- "dev": "vite --config vite.config.web.ts",
+ "dev": "vite --config vite/config.web.ts",
"dev:tauri": "tauri dev",
- "build": "tsc -b && vite build --config vite.config.web.ts",
+ "build": "tsc -b && vite build --config vite/config.web.ts",
"build:tauri": "tauri build",
"lint": "eslint .",
- "preview": "vite preview --config vite.config.web.ts"
+ "preview": "vite preview --config vite/config.web.ts"
},
"dependencies": {
- "@blueprintjs/core": "^5.16.4",
+ "@chakra-ui/react": "^3.26.0",
+ "@emotion/react": "^11.14.0",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
+ "@phifans/audio": "^0.0.7",
"@pixi/react": "8.0.0",
+ "@radix-ui/react-menubar": "^1.1.16",
+ "@tauri-apps/api": "~2",
+ "@tauri-apps/plugin-fs": "~2",
+ "@tauri-apps/plugin-sql": "~2.3.0",
"@types/node": "^22.10.5",
- "audio-decode": "^2.2.2",
- "eventemitter3": "^5.0.1",
- "hotkeys-js": "^3.13.9",
+ "@zenfs/core": "^2.4.0",
+ "@zenfs/dom": "^1.2.4",
+ "dockview": "^4.7.1",
"i18next": "^24.2.3",
"i18next-browser-languagedetector": "^8.0.4",
"i18next-chained-backend": "^4.6.2",
"i18next-http-backend": "^3.0.2",
"i18next-localstorage-backend": "^4.2.0",
+ "idb-keyval": "^6.2.2",
+ "jszip": "^3.10.1",
+ "mobx-react-lite": "^4.1.0",
+ "mobx-state-tree": "^7.0.2",
+ "nanoid": "^5.1.5",
+ "next-themes": "^0.4.6",
"normalize.css": "^8.0.1",
"pixi.js": "^8.6.6",
- "rc-dock": "^3.3.0",
+ "quick-lru": "^7.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-i18next": "^15.4.1",
+ "react-icons": "^5.5.0",
"react-split-pane": "^0.1.92",
- "spark-md5": "^3.0.2",
- "uuid": "^11.0.4"
+ "setimmediate": "^1.0.5",
+ "styled-components": "^6.1.19",
+ "unstorage": "^1.17.1",
+ "zustand": "^5.0.8"
},
"devDependencies": {
+ "@chakra-ui/cli": "^3.26.0",
"@eslint/js": "^9.17.0",
"@tauri-apps/cli": "^2.2.7",
"@types/react": "^19.0.7",
"@types/react-dom": "^19.0.3",
- "@types/spark-md5": "^3.0.5",
"@vitejs/plugin-react-swc": "^3.5.0",
"eslint": "^9.17.0",
"eslint-plugin-react": "^7.37.3",
@@ -60,5 +75,6 @@
"patchedDependencies": {
"react-split-pane": "patches/react-split-pane.patch"
}
- }
+ },
+ "packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6a83a45..1c6b450 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -13,9 +13,12 @@ importers:
.:
dependencies:
- '@blueprintjs/core':
- specifier: ^5.16.4
- version: 5.16.4(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@chakra-ui/react':
+ specifier: ^3.26.0
+ version: 3.26.0(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@emotion/react':
+ specifier: ^11.14.0
+ version: 11.14.0(@types/react@19.0.7)(react@19.0.0)
'@fortawesome/fontawesome-svg-core':
specifier: ^6.7.2
version: 6.7.2
@@ -25,21 +28,36 @@ importers:
'@fortawesome/react-fontawesome':
specifier: ^0.2.2
version: 0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.0.0)
+ '@phifans/audio':
+ specifier: ^0.0.7
+ version: 0.0.7
'@pixi/react':
specifier: 8.0.0
version: 8.0.0(@types/react@19.0.7)(pixi.js@8.6.6)(react@19.0.0)
+ '@radix-ui/react-menubar':
+ specifier: ^1.1.16
+ version: 1.1.16(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@tauri-apps/api':
+ specifier: ~2
+ version: 2.8.0
+ '@tauri-apps/plugin-fs':
+ specifier: ~2
+ version: 2.4.2
+ '@tauri-apps/plugin-sql':
+ specifier: ~2.3.0
+ version: 2.3.0
'@types/node':
specifier: ^22.10.5
version: 22.10.5
- audio-decode:
- specifier: ^2.2.2
- version: 2.2.2
- eventemitter3:
- specifier: ^5.0.1
- version: 5.0.1
- hotkeys-js:
- specifier: ^3.13.9
- version: 3.13.9
+ '@zenfs/core':
+ specifier: ^2.4.0
+ version: 2.4.0
+ '@zenfs/dom':
+ specifier: ^1.2.4
+ version: 1.2.4(@zenfs/core@2.4.0)(kerium@1.3.6)(utilium@2.5.4)
+ dockview:
+ specifier: ^4.7.1
+ version: 4.7.1(react@19.0.0)
i18next:
specifier: ^24.2.3
version: 24.2.3(typescript@5.6.3)
@@ -55,15 +73,33 @@ importers:
i18next-localstorage-backend:
specifier: ^4.2.0
version: 4.2.0
+ idb-keyval:
+ specifier: ^6.2.2
+ version: 6.2.2
+ jszip:
+ specifier: ^3.10.1
+ version: 3.10.1
+ mobx-react-lite:
+ specifier: ^4.1.0
+ version: 4.1.0(mobx@6.13.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ mobx-state-tree:
+ specifier: ^7.0.2
+ version: 7.0.2(mobx@6.13.7)(typescript@5.6.3)
+ nanoid:
+ specifier: ^5.1.5
+ version: 5.1.5
+ next-themes:
+ specifier: ^0.4.6
+ version: 0.4.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
normalize.css:
specifier: ^8.0.1
version: 8.0.1
pixi.js:
specifier: ^8.6.6
version: 8.6.6
- rc-dock:
- specifier: ^3.3.0
- version: 3.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ quick-lru:
+ specifier: ^7.1.0
+ version: 7.1.0
react:
specifier: ^19.0.0
version: 19.0.0
@@ -73,16 +109,28 @@ importers:
react-i18next:
specifier: ^15.4.1
version: 15.4.1(i18next@24.2.3(typescript@5.6.3))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ react-icons:
+ specifier: ^5.5.0
+ version: 5.5.0(react@19.0.0)
react-split-pane:
specifier: ^0.1.92
version: 0.1.92(patch_hash=15b3bc41b3c9ea6e7a5c245069978ef071c4655082c4e9b0e14eb5d4eb57da5c)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- spark-md5:
- specifier: ^3.0.2
- version: 3.0.2
- uuid:
- specifier: ^11.0.4
- version: 11.0.4
+ setimmediate:
+ specifier: ^1.0.5
+ version: 1.0.5
+ styled-components:
+ specifier: ^6.1.19
+ version: 6.1.19(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ unstorage:
+ specifier: ^1.17.1
+ version: 1.17.1(idb-keyval@6.2.2)
+ zustand:
+ specifier: ^5.0.8
+ version: 5.0.8(@types/react@19.0.7)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0))
devDependencies:
+ '@chakra-ui/cli':
+ specifier: ^3.26.0
+ version: 3.26.0(@chakra-ui/react@3.26.0(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))
'@eslint/js':
specifier: ^9.17.0
version: 9.17.0
@@ -95,12 +143,9 @@ importers:
'@types/react-dom':
specifier: ^19.0.3
version: 19.0.3(@types/react@19.0.7)
- '@types/spark-md5':
- specifier: ^3.0.5
- version: 3.0.5
'@vitejs/plugin-react-swc':
specifier: ^3.5.0
- version: 3.7.2(vite@6.0.9(@types/node@22.10.5))
+ version: 3.7.2(@swc/helpers@0.5.17)(vite@6.0.9(@types/node@22.10.5))
eslint:
specifier: ^9.17.0
version: 9.17.0
@@ -128,6 +173,41 @@ importers:
packages:
+ '@ark-ui/react@5.22.0':
+ resolution: {integrity: sha512-cH3xVhKRn0ZsP2Jg2RZAziI38obIfTMC3Q6ZWtWeYL5k9fq6K8sa1XjdJclBRSD0vYYvR1ynHG9ThicWKKANtQ==}
+ peerDependencies:
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@babel/code-frame@7.27.1':
+ resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.28.3':
+ resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-globals@7.28.0':
+ resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-imports@7.27.1':
+ resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.27.1':
+ resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.28.3':
+ resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
'@babel/runtime@7.26.0':
resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==}
engines: {node: '>=6.9.0'}
@@ -136,180 +216,396 @@ packages:
resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==}
engines: {node: '>=6.9.0'}
- '@blueprintjs/colors@5.1.5':
- resolution: {integrity: sha512-IUZvQLsQmfqumTTzeb5oQLnvskJcQYKcitzhDm5+iTWl42Jn5oyUqPDW96ubH/pfWoQGHzBp91ujq6KREl4GHQ==}
+ '@babel/template@7.27.2':
+ resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.28.3':
+ resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.28.2':
+ resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==}
+ engines: {node: '>=6.9.0'}
- '@blueprintjs/core@5.16.4':
- resolution: {integrity: sha512-jgy3UJNDWPBdNn8nf2pDgzSKDJABVG4i1OPrcFJlOQl117UWMJD28/hAtyBQG1e+/6AE0a678Ko1aBmK4aWp6Q==}
+ '@chakra-ui/cli@3.26.0':
+ resolution: {integrity: sha512-BAnuzUCael9vjvq6bvNpX/UWJFu2I+pIfPqKT3I7ejo/c5JM6IDDqZQp7cs+10e0S4MXH743R/TfnVU96OOPBw==}
hasBin: true
peerDependencies:
- '@types/react': ^16.14.41 || 17 || 18
- react: ^16.8 || 17 || 18
- react-dom: ^16.8 || 17 || 18
- peerDependenciesMeta:
- '@types/react':
- optional: true
+ '@chakra-ui/react': '>=3.0.0-next.0'
+
+ '@chakra-ui/react@3.26.0':
+ resolution: {integrity: sha512-VuhFMLklzrjTWIst1B+uQggxOn9+GxVd+0LHLtsQKA+JtKUDqNfKymeWlb1/pKrmqH184+gwZJRjTtr6/+0cIQ==}
+ peerDependencies:
+ '@emotion/react': '>=11'
+ react: '>=18'
+ react-dom: '>=18'
+
+ '@clack/core@0.5.0':
+ resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==}
+
+ '@clack/prompts@0.11.0':
+ resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==}
+
+ '@emotion/babel-plugin@11.13.5':
+ resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==}
+
+ '@emotion/cache@11.14.0':
+ resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==}
- '@blueprintjs/icons@5.17.1':
- resolution: {integrity: sha512-jdwrfDb5N0KCKGFFaJn5KrQj0ZX1hqEXHor9ewsdrSgVGOzVCg9OJ/GYVjy85McHNhN9bYyYaH+8dxablEoYRA==}
+ '@emotion/hash@0.9.2':
+ resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==}
+
+ '@emotion/is-prop-valid@1.2.2':
+ resolution: {integrity: sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==}
+
+ '@emotion/is-prop-valid@1.4.0':
+ resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==}
+
+ '@emotion/memoize@0.8.1':
+ resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==}
+
+ '@emotion/memoize@0.9.0':
+ resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==}
+
+ '@emotion/react@11.14.0':
+ resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==}
peerDependencies:
- '@types/react': ^16.14.41 || 17 || 18
- react: ^16.8 || 17 || 18
- react-dom: ^16.8 || 17 || 18
+ '@types/react': '*'
+ react: '>=16.8.0'
peerDependenciesMeta:
'@types/react':
optional: true
+ '@emotion/serialize@1.3.3':
+ resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==}
+
+ '@emotion/sheet@1.4.0':
+ resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==}
+
+ '@emotion/unitless@0.10.0':
+ resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==}
+
+ '@emotion/unitless@0.8.1':
+ resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==}
+
+ '@emotion/use-insertion-effect-with-fallbacks@1.2.0':
+ resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==}
+ peerDependencies:
+ react: '>=16.8.0'
+
+ '@emotion/utils@1.4.2':
+ resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==}
+
+ '@emotion/weak-memoize@0.4.0':
+ resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==}
+
'@esbuild/aix-ppc64@0.24.2':
resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
+ '@esbuild/aix-ppc64@0.25.9':
+ resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
'@esbuild/android-arm64@0.24.2':
resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
+ '@esbuild/android-arm64@0.25.9':
+ resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
'@esbuild/android-arm@0.24.2':
resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
+ '@esbuild/android-arm@0.25.9':
+ resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
'@esbuild/android-x64@0.24.2':
resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
+ '@esbuild/android-x64@0.25.9':
+ resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
'@esbuild/darwin-arm64@0.24.2':
resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
+ '@esbuild/darwin-arm64@0.25.9':
+ resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
'@esbuild/darwin-x64@0.24.2':
resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
+ '@esbuild/darwin-x64@0.25.9':
+ resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
'@esbuild/freebsd-arm64@0.24.2':
resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
+ '@esbuild/freebsd-arm64@0.25.9':
+ resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
'@esbuild/freebsd-x64@0.24.2':
resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
+ '@esbuild/freebsd-x64@0.25.9':
+ resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
'@esbuild/linux-arm64@0.24.2':
resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
+ '@esbuild/linux-arm64@0.25.9':
+ resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
'@esbuild/linux-arm@0.24.2':
resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
+ '@esbuild/linux-arm@0.25.9':
+ resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
'@esbuild/linux-ia32@0.24.2':
resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
+ '@esbuild/linux-ia32@0.25.9':
+ resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
'@esbuild/linux-loong64@0.24.2':
resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
+ '@esbuild/linux-loong64@0.25.9':
+ resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
'@esbuild/linux-mips64el@0.24.2':
resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
+ '@esbuild/linux-mips64el@0.25.9':
+ resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
'@esbuild/linux-ppc64@0.24.2':
resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
+ '@esbuild/linux-ppc64@0.25.9':
+ resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
'@esbuild/linux-riscv64@0.24.2':
resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
+ '@esbuild/linux-riscv64@0.25.9':
+ resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
'@esbuild/linux-s390x@0.24.2':
resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
+ '@esbuild/linux-s390x@0.25.9':
+ resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
'@esbuild/linux-x64@0.24.2':
resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
+ '@esbuild/linux-x64@0.25.9':
+ resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
'@esbuild/netbsd-arm64@0.24.2':
resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
+ '@esbuild/netbsd-arm64@0.25.9':
+ resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
'@esbuild/netbsd-x64@0.24.2':
resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
+ '@esbuild/netbsd-x64@0.25.9':
+ resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
'@esbuild/openbsd-arm64@0.24.2':
resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
+ '@esbuild/openbsd-arm64@0.25.9':
+ resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
'@esbuild/openbsd-x64@0.24.2':
resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
+ '@esbuild/openbsd-x64@0.25.9':
+ resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.25.9':
+ resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
'@esbuild/sunos-x64@0.24.2':
resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
+ '@esbuild/sunos-x64@0.25.9':
+ resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
'@esbuild/win32-arm64@0.24.2':
resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
+ '@esbuild/win32-arm64@0.25.9':
+ resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
'@esbuild/win32-ia32@0.24.2':
resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
+ '@esbuild/win32-ia32@0.25.9':
+ resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
'@esbuild/win32-x64@0.24.2':
resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
+ '@esbuild/win32-x64@0.25.9':
+ resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
'@eshaz/web-worker@1.2.2':
resolution: {integrity: sha512-WxXiHFmD9u/owrzempiDlBB1ZYqiLnm9s6aPc8AlFQalq2tKmqdmMr9GXOupDgzXtqnBipj8Un0gkIm7Sjf8mw==}
@@ -347,6 +643,21 @@ packages:
resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@floating-ui/core@1.7.3':
+ resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==}
+
+ '@floating-ui/dom@1.7.4':
+ resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==}
+
+ '@floating-ui/react-dom@2.1.6':
+ resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+
+ '@floating-ui/utils@0.2.10':
+ resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
+
'@fortawesome/fontawesome-common-types@6.7.2':
resolution: {integrity: sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==}
engines: {node: '>=6'}
@@ -385,6 +696,29 @@ packages:
resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==}
engines: {node: '>=18.18'}
+ '@internationalized/date@3.8.2':
+ resolution: {integrity: sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA==}
+
+ '@internationalized/number@3.6.4':
+ resolution: {integrity: sha512-P+/h+RDaiX8EGt3shB9AYM1+QgkvHmJ5rKi4/59k4sg9g58k9rqsRW0WxRO7jCoHyvVbFRRFKmVTdFYdehrxHg==}
+
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.30':
+ resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==}
+
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -397,6 +731,12 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
+ '@pandacss/is-valid-prop@0.54.0':
+ resolution: {integrity: sha512-UhRgg1k9VKRCBAHl+XUK3lvN0k9bYifzYGZOqajDid4L1DyU813A1L0ZwN4iV9WX5TX3PfUugqtgG9LnIeFGBQ==}
+
+ '@phifans/audio@0.0.7':
+ resolution: {integrity: sha512-w/OfBMWjQ0H7MPrnQxG/grS3JUE1nCiiut9QBtf2hNO33J5I1aLsb9MY+NQptfst54A7KpMiE1wcE1Nb3Czf2A==}
+
'@pixi/colord@2.9.6':
resolution: {integrity: sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA==}
@@ -406,62 +746,329 @@ packages:
pixi.js: ^8.2.6
react: '>=19.0.0'
- '@popperjs/core@2.11.8':
- resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
-
- '@rollup/rollup-android-arm-eabi@4.34.7':
- resolution: {integrity: sha512-l6CtzHYo8D2TQ3J7qJNpp3Q1Iye56ssIAtqbM2H8axxCEEwvN7o8Ze9PuIapbxFL3OHrJU2JBX6FIIVnP/rYyw==}
- cpu: [arm]
- os: [android]
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
- '@rollup/rollup-android-arm64@4.34.7':
- resolution: {integrity: sha512-KvyJpFUueUnSp53zhAa293QBYqwm94TgYTIfXyOTtidhm5V0LbLCJQRGkQClYiX3FXDQGSvPxOTD/6rPStMMDg==}
- cpu: [arm64]
- os: [android]
+ '@radix-ui/primitive@1.1.3':
+ resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==}
- '@rollup/rollup-darwin-arm64@4.34.7':
- resolution: {integrity: sha512-jq87CjmgL9YIKvs8ybtIC98s/M3HdbqXhllcy9EdLV0yMg1DpxES2gr65nNy7ObNo/vZ/MrOTxt0bE5LinL6mA==}
- cpu: [arm64]
- os: [darwin]
+ '@radix-ui/react-arrow@1.1.7':
+ resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
- '@rollup/rollup-darwin-x64@4.34.7':
- resolution: {integrity: sha512-rSI/m8OxBjsdnMMg0WEetu/w+LhLAcCDEiL66lmMX4R3oaml3eXz3Dxfvrxs1FbzPbJMaItQiksyMfv1hoIxnA==}
- cpu: [x64]
- os: [darwin]
+ '@radix-ui/react-collection@1.1.7':
+ resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
- '@rollup/rollup-freebsd-arm64@4.34.7':
- resolution: {integrity: sha512-oIoJRy3ZrdsXpFuWDtzsOOa/E/RbRWXVokpVrNnkS7npz8GEG++E1gYbzhYxhxHbO2om1T26BZjVmdIoyN2WtA==}
- cpu: [arm64]
- os: [freebsd]
+ '@radix-ui/react-compose-refs@1.1.2':
+ resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
- '@rollup/rollup-freebsd-x64@4.34.7':
- resolution: {integrity: sha512-X++QSLm4NZfZ3VXGVwyHdRf58IBbCu9ammgJxuWZYLX0du6kZvdNqPwrjvDfwmi6wFdvfZ/s6K7ia0E5kI7m8Q==}
- cpu: [x64]
- os: [freebsd]
+ '@radix-ui/react-context@1.1.2':
+ resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
- '@rollup/rollup-linux-arm-gnueabihf@4.34.7':
- resolution: {integrity: sha512-Z0TzhrsNqukTz3ISzrvyshQpFnFRfLunYiXxlCRvcrb3nvC5rVKI+ZXPFG/Aa4jhQa1gHgH3A0exHaRRN4VmdQ==}
- cpu: [arm]
- os: [linux]
+ '@radix-ui/react-direction@1.1.1':
+ resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
- '@rollup/rollup-linux-arm-musleabihf@4.34.7':
- resolution: {integrity: sha512-nkznpyXekFAbvFBKBy4nNppSgneB1wwG1yx/hujN3wRnhnkrYVugMTCBXED4+Ni6thoWfQuHNYbFjgGH0MBXtw==}
- cpu: [arm]
- os: [linux]
+ '@radix-ui/react-dismissable-layer@1.1.11':
+ resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
- '@rollup/rollup-linux-arm64-gnu@4.34.7':
- resolution: {integrity: sha512-KCjlUkcKs6PjOcxolqrXglBDcfCuUCTVlX5BgzgoJHw+1rWH1MCkETLkLe5iLLS9dP5gKC7mp3y6x8c1oGBUtA==}
- cpu: [arm64]
- os: [linux]
+ '@radix-ui/react-focus-guards@1.1.3':
+ resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
- '@rollup/rollup-linux-arm64-musl@4.34.7':
- resolution: {integrity: sha512-uFLJFz6+utmpbR313TTx+NpPuAXbPz4BhTQzgaP0tozlLnGnQ6rCo6tLwaSa6b7l6gRErjLicXQ1iPiXzYotjw==}
- cpu: [arm64]
- os: [linux]
+ '@radix-ui/react-focus-scope@1.1.7':
+ resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
- '@rollup/rollup-linux-loongarch64-gnu@4.34.7':
- resolution: {integrity: sha512-ws8pc68UcJJqCpneDFepnwlsMUFoWvPbWXT/XUrJ7rWUL9vLoIN3GAasgG+nCvq8xrE3pIrd+qLX/jotcLy0Qw==}
- cpu: [loong64]
+ '@radix-ui/react-id@1.1.1':
+ resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-menu@2.1.16':
+ resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-menubar@1.1.16':
+ resolution: {integrity: sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-popper@1.2.8':
+ resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-portal@1.1.9':
+ resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-presence@1.1.5':
+ resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-primitive@2.1.3':
+ resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-roving-focus@1.1.11':
+ resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-slot@1.2.3':
+ resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-callback-ref@1.1.1':
+ resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-controllable-state@1.2.2':
+ resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-effect-event@0.0.2':
+ resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-escape-keydown@1.1.1':
+ resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-layout-effect@1.1.1':
+ resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-rect@1.1.1':
+ resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-size@1.1.1':
+ resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/rect@1.1.1':
+ resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
+
+ '@rollup/rollup-android-arm-eabi@4.34.7':
+ resolution: {integrity: sha512-l6CtzHYo8D2TQ3J7qJNpp3Q1Iye56ssIAtqbM2H8axxCEEwvN7o8Ze9PuIapbxFL3OHrJU2JBX6FIIVnP/rYyw==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.34.7':
+ resolution: {integrity: sha512-KvyJpFUueUnSp53zhAa293QBYqwm94TgYTIfXyOTtidhm5V0LbLCJQRGkQClYiX3FXDQGSvPxOTD/6rPStMMDg==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.34.7':
+ resolution: {integrity: sha512-jq87CjmgL9YIKvs8ybtIC98s/M3HdbqXhllcy9EdLV0yMg1DpxES2gr65nNy7ObNo/vZ/MrOTxt0bE5LinL6mA==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.34.7':
+ resolution: {integrity: sha512-rSI/m8OxBjsdnMMg0WEetu/w+LhLAcCDEiL66lmMX4R3oaml3eXz3Dxfvrxs1FbzPbJMaItQiksyMfv1hoIxnA==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.34.7':
+ resolution: {integrity: sha512-oIoJRy3ZrdsXpFuWDtzsOOa/E/RbRWXVokpVrNnkS7npz8GEG++E1gYbzhYxhxHbO2om1T26BZjVmdIoyN2WtA==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.34.7':
+ resolution: {integrity: sha512-X++QSLm4NZfZ3VXGVwyHdRf58IBbCu9ammgJxuWZYLX0du6kZvdNqPwrjvDfwmi6wFdvfZ/s6K7ia0E5kI7m8Q==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.34.7':
+ resolution: {integrity: sha512-Z0TzhrsNqukTz3ISzrvyshQpFnFRfLunYiXxlCRvcrb3nvC5rVKI+ZXPFG/Aa4jhQa1gHgH3A0exHaRRN4VmdQ==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.34.7':
+ resolution: {integrity: sha512-nkznpyXekFAbvFBKBy4nNppSgneB1wwG1yx/hujN3wRnhnkrYVugMTCBXED4+Ni6thoWfQuHNYbFjgGH0MBXtw==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.34.7':
+ resolution: {integrity: sha512-KCjlUkcKs6PjOcxolqrXglBDcfCuUCTVlX5BgzgoJHw+1rWH1MCkETLkLe5iLLS9dP5gKC7mp3y6x8c1oGBUtA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.34.7':
+ resolution: {integrity: sha512-uFLJFz6+utmpbR313TTx+NpPuAXbPz4BhTQzgaP0tozlLnGnQ6rCo6tLwaSa6b7l6gRErjLicXQ1iPiXzYotjw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loongarch64-gnu@4.34.7':
+ resolution: {integrity: sha512-ws8pc68UcJJqCpneDFepnwlsMUFoWvPbWXT/XUrJ7rWUL9vLoIN3GAasgG+nCvq8xrE3pIrd+qLX/jotcLy0Qw==}
+ cpu: [loong64]
os: [linux]
'@rollup/rollup-linux-powerpc64le-gnu@4.34.7':
@@ -504,6 +1111,10 @@ packages:
cpu: [x64]
os: [win32]
+ '@sindresorhus/merge-streams@2.3.0':
+ resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
+ engines: {node: '>=18'}
+
'@swc/core-darwin-arm64@1.10.3':
resolution: {integrity: sha512-LFFCxAUKBy69AUE+01rgazQcafIXrYs6tBa9SyKPR51ft6Tp66dAVrWg9MTykaWskuXEe80LPUvUw1ga3bOH3A==}
engines: {node: '>=10'}
@@ -576,9 +1187,15 @@ packages:
'@swc/counter@0.1.3':
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
+ '@swc/helpers@0.5.17':
+ resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
+
'@swc/types@0.1.17':
resolution: {integrity: sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==}
+ '@tauri-apps/api@2.8.0':
+ resolution: {integrity: sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw==}
+
'@tauri-apps/cli-darwin-arm64@2.2.7':
resolution: {integrity: sha512-54kcpxZ3X1Rq+pPTzk3iIcjEVY4yv493uRx/80rLoAA95vAC0c//31Whz75UVddDjJfZvXlXZ3uSZ+bnCOnt0A==}
engines: {node: '>= 10'}
@@ -644,6 +1261,12 @@ packages:
engines: {node: '>= 10'}
hasBin: true
+ '@tauri-apps/plugin-fs@2.4.2':
+ resolution: {integrity: sha512-YGhmYuTgXGsi6AjoV+5mh2NvicgWBfVJHHheuck6oHD+HC9bVWPaHvCP0/Aw4pHDejwrvT8hE3+zZAaWf+hrig==}
+
+ '@tauri-apps/plugin-sql@2.3.0':
+ resolution: {integrity: sha512-JYwIocfsLaDWa41LMiZWuzts7yCJR+EpZPRmgpO7Gd7XiAS9S67dKz306j/k/d9XntB0YopMRBol2OIWMschuA==}
+
'@thi.ng/bitstream@2.4.8':
resolution: {integrity: sha512-952h5EgVHDfQJDGydNCKCLQvtwEHbK4grl3I9N/1yWEDS05EGvwYwSaJxFBKM5kNGrE5Uxf6i4pUl0KHvsIKIg==}
engines: {node: '>=18'}
@@ -652,9 +1275,15 @@ packages:
resolution: {integrity: sha512-O7Vrdn6mlzfm9iKhGiVs1TibrNXhNjkwguTpFkkU2awZG/5ssOYidXU6RVZMqOFOvW6IQfN0nDbhvtqoNYse/w==}
engines: {node: '>=18'}
+ '@types/cli-table@0.3.4':
+ resolution: {integrity: sha512-GsALrTL69mlwbAw/MHF1IPTadSLZQnsxe7a80G8l4inN/iEXCOcVeT/S7aRc6hbhqzL9qZ314kHPDQnQ3ev+HA==}
+
'@types/css-font-loading-module@0.0.12':
resolution: {integrity: sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==}
+ '@types/debug@4.1.12':
+ resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
+
'@types/earcut@2.1.4':
resolution: {integrity: sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==}
@@ -664,9 +1293,18 @@ packages:
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
'@types/node@22.10.5':
resolution: {integrity: sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==}
+ '@types/node@24.3.1':
+ resolution: {integrity: sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==}
+
+ '@types/parse-json@4.0.2':
+ resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
+
'@types/react-dom@19.0.3':
resolution: {integrity: sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA==}
peerDependencies:
@@ -680,8 +1318,11 @@ packages:
'@types/react@19.0.7':
resolution: {integrity: sha512-MoFsEJKkAtZCrC1r6CM8U22GzhG7u2Wir8ons/aCKH6MBdD1ibV24zOSSkdZVUKqN5i396zG5VKLYZ3yaUZdLA==}
- '@types/spark-md5@3.0.5':
- resolution: {integrity: sha512-lWf05dnD42DLVKQJZrDHtWFidcLrHuip01CtnC2/S6AMhX4t9ZlEUj4iuRlAnts0PQk7KESOqKxeGE/b6sIPGg==}
+ '@types/setimmediate@1.0.4':
+ resolution: {integrity: sha512-rWPw1drMVf5zInxNpgH3nn/h6KkWqwgLT2y/ciAYQ16RAsbXOXe0AmtZ/HyzwPNw+r4GMJuI7IV7YNKO7Fs/xA==}
+
+ '@types/stylis@4.2.5':
+ resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==}
'@typescript-eslint/eslint-plugin@8.18.2':
resolution: {integrity: sha512-adig4SzPLjeQ0Tm+jvsozSGiCliI2ajeURDGHjZ2llnA+A67HihCQ+a3amtPhUakd1GlwHxSRvzOZktbEvhPPg==}
@@ -730,6 +1371,11 @@ packages:
resolution: {integrity: sha512-zORcwn4C3trOWiCqFQP1x6G3xTRyZ1LYydnj51cRnJ6hxBlr/cKPckk+PKPUw/fXmvfKTcw7bwY3w9izgx5jZw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@visulima/boxen@2.0.2':
+ resolution: {integrity: sha512-eqm/OzwETl1Zd5ehW5CUXhYf8tqb+seBCkHBKXh1rEMS94n+OhyCY0KAlZv/17qPoN73WT2nGDN9SdYlvoWbTQ==}
+ engines: {node: '>=20.18 <=24.x'}
+ os: [darwin, linux, win32]
+
'@vitejs/plugin-react-swc@3.7.2':
resolution: {integrity: sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew==}
peerDependencies:
@@ -751,131 +1397,436 @@ packages:
resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==}
engines: {node: '>=10.0.0'}
- acorn-jsx@5.3.2:
- resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
- peerDependencies:
- acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ '@xterm/xterm@5.5.0':
+ resolution: {integrity: sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==}
- acorn@8.14.0:
- resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
- engines: {node: '>=0.4.0'}
- hasBin: true
+ '@zag-js/accordion@1.22.1':
+ resolution: {integrity: sha512-P3jsauxnAGKBhuqs9gdivjEiSu7N7KnKRlgWlIpyti35askz8swHsqxsfkc2ASs9tcPKnPvuZDHIxXmJmZSLuQ==}
- ajv@6.12.6:
- resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ '@zag-js/anatomy@1.22.1':
+ resolution: {integrity: sha512-I5OvOuJBt6hEqbpqVkWCOEoDfGMnKuLx+S0h7Un5SyAwnif3F1dSqDYujU28bCy8FtKs36vsq/izxufXyiXSEg==}
- ansi-styles@4.3.0:
- resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
- engines: {node: '>=8'}
+ '@zag-js/angle-slider@1.22.1':
+ resolution: {integrity: sha512-Nitjwwo2NVUEK+PabDnOfqizErnFIZZKThtcpQikAhE1J4MX3H128MANu1hJXNkvVYXyZmhTvzjt6XZc2j7YyQ==}
- argparse@2.0.1:
- resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ '@zag-js/aria-hidden@1.22.1':
+ resolution: {integrity: sha512-vPfAE35BfYPS1UbYRcNw8/kMl7uayE7LyRncK/gPMnoQMjmEKW0nXmD5WlCHFLdGX9WFGYTIde8k4U8ay+oqcg==}
- array-buffer-byte-length@1.0.2:
- resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
- engines: {node: '>= 0.4'}
+ '@zag-js/async-list@1.22.1':
+ resolution: {integrity: sha512-/evBfhDW3Rj3An5fHW8SYINM/pkxeOe/Uk7rRlBreHVn2PdAay4sj1gax4hlUUFEbqyvBgbHpR/atwfdxSuWYQ==}
- array-includes@3.1.8:
- resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==}
- engines: {node: '>= 0.4'}
+ '@zag-js/auto-resize@1.22.1':
+ resolution: {integrity: sha512-O+tKmqwLko74DCmwdouxBZqEtIQB6Rt2pyXdlyBXLB7UnYXEIvEUzf8XK39I5AHXp6NlLqx77GtLn1qiBtKrkQ==}
- array.prototype.findlast@1.2.5:
- resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
- engines: {node: '>= 0.4'}
+ '@zag-js/avatar@1.22.1':
+ resolution: {integrity: sha512-SAz9XaFD8jg4LODkS51s6KrNcYF/PvAcRkCE9TDiuiCeFdgB6+JFKBNk0iM9og8Tk4Doe/3qIA/I12qKNW9pAw==}
- array.prototype.flat@1.3.3:
- resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==}
- engines: {node: '>= 0.4'}
+ '@zag-js/carousel@1.22.1':
+ resolution: {integrity: sha512-bFbCRe5xarBtD3NnozHmCmrGJ+nLRhqLQFq+RG13fl1hlhUJaJ5AsS7e8L1r2ZLdbVVrsB0lUuW/ocfJ/G4MSw==}
- array.prototype.flatmap@1.3.3:
- resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==}
- engines: {node: '>= 0.4'}
+ '@zag-js/checkbox@1.22.1':
+ resolution: {integrity: sha512-A/cZb89Aeb2k/KGl3ITS2fuLBXwq6Rnq9aFirfKs/UHrY16fopRbRjfqOxF6wm8lWoFk3gqmRGgybo8qsIfxog==}
- array.prototype.tosorted@1.1.4:
- resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
- engines: {node: '>= 0.4'}
+ '@zag-js/clipboard@1.22.1':
+ resolution: {integrity: sha512-rKTPRKvLtcJ1c/CDvnWDRpqAteFS20UQe+mQpO83ACMCRZAfkXP3UOzBL53mh59+LIVlDxgZbMlwRiNiqqKhmA==}
- arraybuffer.prototype.slice@1.0.4:
- resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
- engines: {node: '>= 0.4'}
+ '@zag-js/collapsible@1.22.1':
+ resolution: {integrity: sha512-vKfDe/fzm3ndDfaueqW/XgGaWCHVD8MuLFtRRyv3jX3ubdNYn5R/j7ftQURdYyqRlPI3Si50FWSAtOqtvs4y9Q==}
- audio-buffer@5.0.0:
- resolution: {integrity: sha512-gsDyj1wwUp8u7NBB+eW6yhLb9ICf+0eBmDX8NGaAS00w8/fLqFdxUlL5Ge/U8kB64DlQhdonxYC59dXy1J7H/w==}
+ '@zag-js/collection@1.22.1':
+ resolution: {integrity: sha512-jjeSKALTH3iK2vTI6uAh2NCtS9n+e2r1cGERKCfNkbt86U6VSp9xiXqalUsEI4ovNIPcgg0+/nzixoVwFO1Vgg==}
- audio-decode@2.2.2:
- resolution: {integrity: sha512-xyh7z6dpRT+5Ez4ggV2cEkSShkDvvIBBmVPR3kYY7uIBqRO1BGNjofip6JnjBnvezhrU3ypBGZjepyKFDZWnDw==}
+ '@zag-js/color-picker@1.22.1':
+ resolution: {integrity: sha512-vUx8Ef0CZ/VPARIPh2ur76HH1AL3FVObNgtX64kPNUDUI+Z/L/q6CBfIeGcElVQ/Y6QowrqAXjVyPGArmmohmw==}
- audio-type@2.2.1:
- resolution: {integrity: sha512-En9AY6EG1qYqEy5L/quryzbA4akBpJrnBZNxeKTqGHC2xT9Qc4aZ8b7CcbOMFTTc/MGdoNyp+SN4zInZNKxMYA==}
- engines: {node: '>=14'}
+ '@zag-js/color-utils@1.22.1':
+ resolution: {integrity: sha512-Bee1KvYOV0yWQbODN+O2zPmdUaH+rymEmIHLfKNipPo5GVmxWqAe8oTQDyquzsUtoPE5MFgW5avg8tgSlCFcBA==}
- available-typed-arrays@1.0.7:
- resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
- engines: {node: '>= 0.4'}
+ '@zag-js/combobox@1.22.1':
+ resolution: {integrity: sha512-N4tGTmezfHGaKB0+aDB5yMuVzBv2ShgsAx1uizom6ElcvlYD2rsQTr3xLc4wyOR7fx0z6fFDo1+63/Dt3y0t4A==}
- balanced-match@1.0.2:
- resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ '@zag-js/core@1.22.1':
+ resolution: {integrity: sha512-4BNrwO9Tadq2Z0d2xSSQs4O/o3OarEHzXM2FQqx46vrwSE57qUghnZex429ZQ51fuk8AL5Lowt26a9JxE9sVPg==}
- bowser@2.11.0:
- resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==}
+ '@zag-js/date-picker@1.22.1':
+ resolution: {integrity: sha512-ja482LloO7AGfFYXTfGV+qV484QWUM1cnF3hWtROd4Vdx/NONwn0w7TEJH+XbO3HaoUC5XpeacWLFQugGCsRjg==}
+ peerDependencies:
+ '@internationalized/date': '>=3.0.0'
- brace-expansion@1.1.11:
- resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+ '@zag-js/date-utils@1.22.1':
+ resolution: {integrity: sha512-OWIWxihfFFyQDEaA35a/Fdfp3+GyGUgTUbutMD3BrbnPjKNLm0RyvAgZiq0zPTY7CzpYRbZ2J98GDU+CTERCjA==}
+ peerDependencies:
+ '@internationalized/date': '>=3.0.0'
- brace-expansion@2.0.1:
- resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+ '@zag-js/dialog@1.22.1':
+ resolution: {integrity: sha512-b5KwMPYKc9RenZwxrAAHu6aHPz7tqPy4Mxa/YR5zo1pXBV4amA7u2xnqyncRaK65Z7y5QKmpmDuBp+0PnXxNIA==}
- braces@3.0.3:
- resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
- engines: {node: '>=8'}
+ '@zag-js/dismissable@1.22.1':
+ resolution: {integrity: sha512-0DzbykJu9QoXYw4Zcjte69Mtk6ThNRCXWxxCKBf930V8Bw3Ha7vfY5bgdb4RFT5K+BQP3E8vLT+PzIaDINn2Xw==}
- call-bind-apply-helpers@1.0.1:
- resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==}
- engines: {node: '>= 0.4'}
+ '@zag-js/dom-query@1.22.1':
+ resolution: {integrity: sha512-mtvGj2z3rkl40mkjd+QwoOHvxqpiOkY4mtVjzNzgzcbVtUN63Mz7giW8OZB+KLy37hwFX0B8JfiQncU8IOHNpw==}
- call-bind@1.0.8:
- resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
- engines: {node: '>= 0.4'}
+ '@zag-js/editable@1.22.1':
+ resolution: {integrity: sha512-NY7VeKYuNLQzi+yZYmWliif0Qd/2PTKtDeqtnVypv8XSHqTbVeS2N9dqTru1g4RP+eGQWx0za12hjmCVU4DuMQ==}
- call-bound@1.0.3:
- resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==}
- engines: {node: '>= 0.4'}
+ '@zag-js/file-upload@1.22.1':
+ resolution: {integrity: sha512-4iKpqxVLafLbQejcPoZcygtNURsezIlWRigHvVPd2pLsXPa8erbdcEZ8X4QvGp77xcW2QTkuSxB+BSCrEEAotA==}
- callsites@3.1.0:
- resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
- engines: {node: '>=6'}
+ '@zag-js/file-utils@1.22.1':
+ resolution: {integrity: sha512-cZAJ5MAZCe7IfHfN+3xSNb9e6mA812U8BPJr/jNPN+qLQh/PkQDwKaGM33o2Me50r18iGTAswEkETnaFZt3wkw==}
- camel-case@4.1.2:
- resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
+ '@zag-js/floating-panel@1.22.1':
+ resolution: {integrity: sha512-YGjLoYt2xSk4pkTgsR0z/7U7V5OdaicSOZa0HDtskH4MkKPxQxrgf2G4e8dNsw8hnQwfVuoc0RGPGW0BArVr6A==}
- capital-case@1.0.4:
- resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
+ '@zag-js/focus-trap@1.22.1':
+ resolution: {integrity: sha512-6W9cG0LEVICt0srVfWSpamKzsnRxXMdl3gV+GQ5HvkCCk1Sw6Io4tc3QvSSvaWcfyhM07feerOsa2ah7qiT/ig==}
- chalk@4.1.2:
- resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
- engines: {node: '>=10'}
+ '@zag-js/focus-visible@1.22.1':
+ resolution: {integrity: sha512-TuBEux3UTivo9VXPPe79q9JfTwaP/uIshL1KPifg51ofGYesWjMGeE5S5MAuaSzUmH9+3CpnwP7h7f65s3D0kw==}
- change-case@4.1.2:
- resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==}
+ '@zag-js/highlight-word@1.22.1':
+ resolution: {integrity: sha512-mcPg4/ED3MNDzj5b3t4EEIKkvdyvVUJ9pqbyRUoj76KI+ZWXXJIw5PNAkG5vUVVUXKKjfzPVninIqWv1Bh9Bvg==}
- classnames@2.5.1:
- resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==}
+ '@zag-js/hover-card@1.22.1':
+ resolution: {integrity: sha512-sGcWASPrt0f8oOpBdyDyka0Mkya4TdlBEOvB9qOvnkcIX2bc6YFUtWQN1L1M/K6nv8D0wSZK0p18JBaqGlHmBQ==}
- codec-parser@2.5.0:
- resolution: {integrity: sha512-Ru9t80fV8B0ZiixQl8xhMTLru+dzuis/KQld32/x5T/+3LwZb0/YvQdSKytX9JqCnRdiupvAvyYJINKrXieziQ==}
+ '@zag-js/i18n-utils@1.22.1':
+ resolution: {integrity: sha512-45KUYB9tu1br6NmgtaNW9NviozYCYUxJ8aZTI/Y6vKotXK/Pn3bIlaiOaq4Zel7TalGYT8gVnwgPe2E6H5sqTg==}
- color-convert@2.0.1:
- resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
- engines: {node: '>=7.0.0'}
+ '@zag-js/interact-outside@1.22.1':
+ resolution: {integrity: sha512-+iZ3xHC9+jVo2FCC4B9c9ntcXv19shVOqQGDr2cD30Hwmwtm9kCOdVydMqv3Lp3UhR8a105MXEVUAKg53WbCoA==}
- color-name@1.1.4:
- resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ '@zag-js/json-tree-utils@1.22.1':
+ resolution: {integrity: sha512-z/15CTtXJHGUvecAAlPnUAaAK83Wxh5WlW9qEpgXlXdB5k7gnWVzH4qN9vDwlSShyZgqaFVqn+muxqaCTYv8Zg==}
+
+ '@zag-js/listbox@1.22.1':
+ resolution: {integrity: sha512-M017Oq0s9PRR5ZwlJkmLhQHucEta/DZ5eHl/t+9yQqHnYRwWKo2ZXLyXquC1wihbHk81E0a1veDw8vBYpfRovA==}
+
+ '@zag-js/live-region@1.22.1':
+ resolution: {integrity: sha512-xjrlCbcgIw+iXxSXnjXAv+WX9r/bMwp4HOIxWOD99360XvatQ2ZGhLH9lfixiXeHLvm6hjWsP92MjYefSLDFSA==}
+
+ '@zag-js/menu@1.22.1':
+ resolution: {integrity: sha512-a5pgQgcpVTVyY6JM8k1WGqelHVKSPwV2CwOv2oGjHWXIr2fpRCAKqZRtytE5PvUP/CZArk8bCjatmgOWe1RdPQ==}
+
+ '@zag-js/number-input@1.22.1':
+ resolution: {integrity: sha512-E4DROYvSo5TFJMkSmnq+f75wSTL/N7SK6MR8ssNlA2oQp69iVWXhIlFLe4knekX02QJzK1MF97aVU332kAYTeQ==}
+
+ '@zag-js/pagination@1.22.1':
+ resolution: {integrity: sha512-Jeix+sXcfMPm5jer2W4PHSUCgu9a11aC/AOBk6dkxbX8XL23fYXJu5YyOVVq0iQIDWzX4Uij1N/vBha64ARmcA==}
+
+ '@zag-js/password-input@1.22.1':
+ resolution: {integrity: sha512-EcCH0V2tbJbexy62nVDUXCMg/XVEcd0PGcBgUfziyaLlDnJz2HWkfe0MzpEiidJwfJfhvvf2DapX9mAyqzZhhw==}
+
+ '@zag-js/pin-input@1.22.1':
+ resolution: {integrity: sha512-tyI5mVi+zmsDEVuZZTOA7fVyxxGwmD8A2snF6nRkFK11o5xnnZaXt44Z7XrPeljTMSLKt+rdF0y/9Q05Auc4tg==}
+
+ '@zag-js/popover@1.22.1':
+ resolution: {integrity: sha512-27VVkhaEOtiHJYj2j++AzYlAzpMcW0ED05TV9wIT1q0EYzASWxweSBajbnCiQf9TIYzCImDiNVDaCMl5D+TamQ==}
+
+ '@zag-js/popper@1.22.1':
+ resolution: {integrity: sha512-vBI5WpvE/3ugsimjZaNisOwcECiYfzc+3LIJwaU8od62kInZ1XF6m096BvV7JGwP0FjkMPJrgjcv7weDtY2iDQ==}
+
+ '@zag-js/presence@1.22.1':
+ resolution: {integrity: sha512-9+pkKnjcHbNxk/80HzLdDjpiKGV/I208wAe0Njmej6q6Z79ED6cb7tXiOgAS7w/ZLWxwQW7B9oMJ3guVflBHwQ==}
+
+ '@zag-js/progress@1.22.1':
+ resolution: {integrity: sha512-2U1IJLb1mhBLEgac8x8qaEv3qgr+pHdw6pn9mCCJVBcyFaSqliWps6X+vi+qKokFLrpjCjdAKuuf48ItNfFFcw==}
+
+ '@zag-js/qr-code@1.22.1':
+ resolution: {integrity: sha512-HIRlNsPNcp5buiTZx7DrX/gCtouGAH4VJc8Q6HBUkaBbiiijVEuYN0aNAjZIdm2pDtrh4KaYjMPuIH8IrV554Q==}
+
+ '@zag-js/radio-group@1.22.1':
+ resolution: {integrity: sha512-eqvY1y/Ui4nQOU8XE9tGShOCbI/YdSHFeH/tDJe2Yy+1kqO4bENxFJ3R1P097KusJgeb2SYzhID27whUslOq7g==}
+
+ '@zag-js/rating-group@1.22.1':
+ resolution: {integrity: sha512-QxBK+hpfkQ4yFHUr1YOSwEQ3LuTrdS32J9zV8UyHu8HbgwzfR7L8ZAa1PUUmG65tupzua2pbn1NioOkMvDmBOQ==}
+
+ '@zag-js/react@1.22.1':
+ resolution: {integrity: sha512-TcIKkNo9EFel+d92nb7104voKJNDiMkqq9nn7Ozq/TE8A62JPf5zk8y8zqoxTbGDTTk+tDjW7Sm1IKb4r6rX4w==}
+ peerDependencies:
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@zag-js/rect-utils@1.22.1':
+ resolution: {integrity: sha512-jtI03SR9kF0AcBffoFI/TKXn5KyhjNCtsGlqbWw0dKbhWTNy1v432FDC5opmmnH8W5LjjWebIzo4QtO5+632QQ==}
+
+ '@zag-js/remove-scroll@1.22.1':
+ resolution: {integrity: sha512-2TrS8ljp8SADX5xRB/+KGBCBYbYTeH0k5IEalG2rt8ReNyNAW1JfCrm53KCVoCg9YmxKF3MrxPgPT83MNFsJhQ==}
+
+ '@zag-js/scroll-area@1.22.1':
+ resolution: {integrity: sha512-BuWKGR3n1yMktYqfTx+U9iwpXkJJhDXW4yin7u/lLMAE0DXR4byyo8aollCkuzZdZbK7NmUG2zVQHUMZ1QaR6w==}
+
+ '@zag-js/scroll-snap@1.22.1':
+ resolution: {integrity: sha512-kctqJiteALaavoHEpYBDSPgUErIdwAoY5jcrU4Mq5L8FjtI4tSNr8BWcXzSBK2UVqaKN+vDo+PDcj7XIXTUQJA==}
+
+ '@zag-js/select@1.22.1':
+ resolution: {integrity: sha512-sWq0RqlJvmj0heJDpfS3OfM1ynSSCW+fYY5v3T/QyH4qneqB8OJjgh8EEBaHlOkbqv/oBsk855U8/o6jegfUxw==}
+
+ '@zag-js/signature-pad@1.22.1':
+ resolution: {integrity: sha512-iD8tBCHSmRI6kdtHO8dNRZrfjGTxfWgweLlNXKu5JV2JkzPBhDCxpthHI9k8LJ0cgUM5/EW4HdEpjO9h47FsaA==}
+
+ '@zag-js/slider@1.22.1':
+ resolution: {integrity: sha512-aricrX99r21RAS9TyPNTJL8gE8mNRSQMy7TIXTa9aoeRjN0Cf6+PSksKfmPdP9l249/nplGqvC25Ck7XUVJn6A==}
+
+ '@zag-js/splitter@1.22.1':
+ resolution: {integrity: sha512-ZMuFlVvqO2WYD7AECEB51iiFpN7A30Q28NfkIVR98xugwUX1OJq1IizKRSbLgC/LmseHPp3OvotxjZX6FqkK4Q==}
+
+ '@zag-js/steps@1.22.1':
+ resolution: {integrity: sha512-eJCHbHG9aGAbzb/IQCqpmk6fmwSmIfocAxNKVTljroD6OHkBtqgaZQVS3q4xyjz61nB/d/0ZlsvpCVjm1EhwBw==}
+
+ '@zag-js/store@1.22.1':
+ resolution: {integrity: sha512-KrMWi/Fa4cqOjx2zDSMIu6vztFYik+V3K6VPWRVONM4FkboLpTqAEayzwgTTNqMK9iYYZIYjhiPhAVLW9iLuBg==}
+
+ '@zag-js/switch@1.22.1':
+ resolution: {integrity: sha512-ipmBHEqtcrPYr5WS5Juj5dt4GFIqr81NYVNe8RHMW8jIHgHhRCRj3TokGXVlZ7HdseCKTTNNrcvRFBr1sJBbOw==}
+
+ '@zag-js/tabs@1.22.1':
+ resolution: {integrity: sha512-B0WHW36uuR+pu/24X0yI4eyvSwo7WmqOc5C3ohZHOf03zkmMJdtMtVQSotKr7qhGMt5updCgs68MR7jAmmc1Lw==}
+
+ '@zag-js/tags-input@1.22.1':
+ resolution: {integrity: sha512-/56pCeSIW+g+ish3Gjed7iNcPSbQEsBCBsCn6FU/JfjwyhLM0sAtn1vkE/eR92hvDX3klV12XzEMBGe4Egr3GQ==}
+
+ '@zag-js/time-picker@1.22.1':
+ resolution: {integrity: sha512-7fqCtyDbuaelffLZ8q9infns+HQKqFMjL4k2V5zALAWdYu2NzvlMYHgj2Ue9AI4VI5QaE1nnwV6hxwS4Zpglvg==}
+ peerDependencies:
+ '@internationalized/date': '>=3.0.0'
+
+ '@zag-js/timer@1.22.1':
+ resolution: {integrity: sha512-VmXnXjecuF4tXFdBRuMHxO8mQX3/vxagE4vx0M0gKwbGoGrXnhYGvULiPL3RlJj8OR8pIfYuP2lbCrt8XM625A==}
+
+ '@zag-js/toast@1.22.1':
+ resolution: {integrity: sha512-cxcfbMftA//ggOAlxG3q04WZVL/mMVklvtQ2rSyj3oRmnwocJPYXtJzKIRazWBjji3u3BOA+ZeOI1AcGrfp/TQ==}
+
+ '@zag-js/toggle-group@1.22.1':
+ resolution: {integrity: sha512-StxnGsPwzB60pGHTD7sNOqIMXjEPMl3lYQk0i2F5MIQWlTRkYdp4ivh73xBRYVtqK15gqacuWXw87EDzKcNwcA==}
+
+ '@zag-js/toggle@1.22.1':
+ resolution: {integrity: sha512-KK9VK8ZkA/ep7KxQFaeVE/zHVm90fkp9q6q4inyQkUdURUg0vovTFI3c5q/c1zm9/g51vbNf5qCXWU4m9sQK8A==}
+
+ '@zag-js/tooltip@1.22.1':
+ resolution: {integrity: sha512-0ub0p22CzYnaXv0prAnWNjqUBkdw4nO4yGk5qntaodajpLNQ4gSdq7Hj4afHzJqwbKAkwb3KzJFqcqIm9Y/dfw==}
+
+ '@zag-js/tour@1.22.1':
+ resolution: {integrity: sha512-VhHC65NgBaCjlVsw1M4Me0P6PCtmD9oi9gRzN2fEUESdpM/QT5Yw6PAAPP1AEo5okv+V2rRBgSKOu9ZyYHa+IQ==}
+
+ '@zag-js/tree-view@1.22.1':
+ resolution: {integrity: sha512-AQmOn1mB+nLJEaq0xdSVnTI8Vt3nB3OweqdB12jkbdIOcWI9eY0RfhiNHC0k0mgAw+dMjyn84op/gOd9VVdtmA==}
+
+ '@zag-js/types@1.22.1':
+ resolution: {integrity: sha512-lvpDSMR96e7H7TdwOiVpMzj6css5Ydix1nBi7BlmjME6v5OPR0KZwVDGD6h5UtTeVjPq8dPaqM8TJWw+QwbQSw==}
+
+ '@zag-js/utils@1.22.1':
+ resolution: {integrity: sha512-VXY4gjHaTENHW+wjnKKENZ2jcaW0vnG2a5lYEMuZR4dpNCKH217yFr/bCNrI44y2s1W3LWhWmpEjfZluP6udYg==}
+
+ '@zenfs/core@2.4.0':
+ resolution: {integrity: sha512-Ik1qM9xkP6lisNwR0zWaTXXuvM4Ef9yQRvYjJGqKGJv7fLsdwXS3tclbHkfvd9YkqlpxC6ac6am9oe7AWgepEA==}
+ engines: {node: '>= 18'}
+ hasBin: true
+
+ '@zenfs/dom@1.2.4':
+ resolution: {integrity: sha512-ftCviemTnU8W0yON8zKS1cUopCMRRq6+edWD9MwXR349h0wfeTsnXBhv7/ctLWpDorWe2nUXIHAvNAJvj32eqA==}
+ engines: {node: '>= 22'}
+ peerDependencies:
+ '@zenfs/core': ^2.3.11
+ kerium: ^1.3.4
+ utilium: ^2.5.0
+
+ abort-controller@3.0.0:
+ resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
+ engines: {node: '>=6.5'}
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn@8.14.0:
+ resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ agent-base@7.1.4:
+ resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
+ engines: {node: '>= 14'}
+
+ ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.2.0:
+ resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==}
+ engines: {node: '>=12'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ aria-hidden@1.2.6:
+ resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
+ engines: {node: '>=10'}
+
+ array-buffer-byte-length@1.0.2:
+ resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
+ engines: {node: '>= 0.4'}
+
+ array-includes@3.1.8:
+ resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.findlast@1.2.5:
+ resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.flat@1.3.3:
+ resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.flatmap@1.3.3:
+ resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.tosorted@1.1.4:
+ resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
+ engines: {node: '>= 0.4'}
+
+ arraybuffer.prototype.slice@1.0.4:
+ resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
+ engines: {node: '>= 0.4'}
+
+ audio-buffer@5.0.0:
+ resolution: {integrity: sha512-gsDyj1wwUp8u7NBB+eW6yhLb9ICf+0eBmDX8NGaAS00w8/fLqFdxUlL5Ge/U8kB64DlQhdonxYC59dXy1J7H/w==}
+
+ audio-decode@2.2.2:
+ resolution: {integrity: sha512-xyh7z6dpRT+5Ez4ggV2cEkSShkDvvIBBmVPR3kYY7uIBqRO1BGNjofip6JnjBnvezhrU3ypBGZjepyKFDZWnDw==}
+
+ audio-type@2.2.1:
+ resolution: {integrity: sha512-En9AY6EG1qYqEy5L/quryzbA4akBpJrnBZNxeKTqGHC2xT9Qc4aZ8b7CcbOMFTTc/MGdoNyp+SN4zInZNKxMYA==}
+ engines: {node: '>=14'}
+
+ available-typed-arrays@1.0.7:
+ resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
+ engines: {node: '>= 0.4'}
+
+ babel-plugin-macros@3.1.0:
+ resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
+ engines: {node: '>=10', npm: '>=6'}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ base64-js@1.5.1:
+ resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ brace-expansion@1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ buffer@6.0.3:
+ resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
+
+ bundle-n-require@1.1.2:
+ resolution: {integrity: sha512-bEk2jakVK1ytnZ9R2AAiZEeK/GxPUM8jvcRxHZXifZDMcjkI4EG/GlsJ2YGSVYT9y/p/gA9/0yDY8rCGsSU6Tg==}
+
+ call-bind-apply-helpers@1.0.1:
+ resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==}
+ engines: {node: '>= 0.4'}
+
+ call-bind@1.0.8:
+ resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
+ engines: {node: '>= 0.4'}
+
+ call-bound@1.0.3:
+ resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==}
+ engines: {node: '>= 0.4'}
+
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ camelize@1.0.1:
+ resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ cli-table@0.3.11:
+ resolution: {integrity: sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==}
+ engines: {node: '>= 0.2.0'}
+
+ codec-parser@2.5.0:
+ resolution: {integrity: sha512-Ru9t80fV8B0ZiixQl8xhMTLru+dzuis/KQld32/x5T/+3LwZb0/YvQdSKytX9JqCnRdiupvAvyYJINKrXieziQ==}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ colors@1.0.3:
+ resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==}
+ engines: {node: '>=0.1.90'}
+
+ commander@12.1.0:
+ resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
+ engines: {node: '>=18'}
+
+ commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
- constant-case@3.0.4:
- resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==}
+ convert-source-map@1.9.0:
+ resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
+
+ cookie-es@1.2.2:
+ resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
+
+ core-util-is@1.0.3:
+ resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+
+ cosmiconfig@7.1.0:
+ resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
+ engines: {node: '>=10'}
cross-fetch@4.0.0:
resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==}
@@ -884,9 +1835,23 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
+ crossws@0.3.5:
+ resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==}
+
+ css-color-keywords@1.0.0:
+ resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==}
+ engines: {node: '>=4'}
+
+ css-to-react-native@3.2.0:
+ resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==}
+
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+ data-uri-to-buffer@4.0.1:
+ resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
+ engines: {node: '>= 12'}
+
data-view-buffer@1.0.2:
resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
engines: {node: '>= 0.4'}
@@ -908,6 +1873,15 @@ packages:
supports-color:
optional: true
+ debug@4.4.1:
+ resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
@@ -919,18 +1893,26 @@ packages:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'}
- doctrine@2.1.0:
- resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
- engines: {node: '>=0.10.0'}
+ defu@6.1.4:
+ resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
+
+ destr@2.0.5:
+ resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
+
+ detect-node-es@1.1.0:
+ resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
- dom-align@1.12.4:
- resolution: {integrity: sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==}
+ dockview-core@4.7.1:
+ resolution: {integrity: sha512-Tia3vYHtqACMZTiZv86yQOabwKj5KrBhQqlSr7qXV0qmmRSZ8dNbaU63LIHYFprST7JgHupIm9JVES+OhqMoTQ==}
- dom-helpers@5.2.1:
- resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
+ dockview@4.7.1:
+ resolution: {integrity: sha512-DgMzSKNjDvZzIQjFfAV6I6EDkqe40Sjz1Qgyf88KG4U1Kgp/bIIEDSLpz65BsW5ZD9Qi3y18TCISYTgsNvU9TA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- dot-case@3.0.4:
- resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
+ doctrine@2.1.0:
+ resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+ engines: {node: '>=0.10.0'}
dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
@@ -939,6 +1921,18 @@ packages:
earcut@2.2.4:
resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==}
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ error-ex@1.3.2:
+ resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
+
es-abstract@1.23.9:
resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==}
engines: {node: '>= 0.4'}
@@ -975,6 +1969,11 @@ packages:
engines: {node: '>=18'}
hasBin: true
+ esbuild@0.25.9:
+ resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==}
+ engines: {node: '>=18'}
+ hasBin: true
+
escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
@@ -1038,9 +2037,17 @@ packages:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
+ event-target-shim@5.0.1:
+ resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
+ engines: {node: '>=6'}
+
eventemitter3@5.0.1:
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+ events@3.3.0:
+ resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
+ engines: {node: '>=0.8.x'}
+
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@@ -1048,15 +2055,26 @@ packages:
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
engines: {node: '>=8.6.0'}
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
+
fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+ fast-safe-stringify@2.1.1:
+ resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
+
fastq@1.18.0:
resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==}
+ fetch-blob@3.2.0:
+ resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
+ engines: {node: ^12.20 || >= 14.13}
+
file-entry-cache@8.0.0:
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
engines: {node: '>=16.0.0'}
@@ -1065,6 +2083,9 @@ packages:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
+ find-root@1.1.0:
+ resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==}
+
find-up@5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
@@ -1079,6 +2100,14 @@ packages:
for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+ foreground-child@3.3.1:
+ resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
+ engines: {node: '>=14'}
+
+ formdata-polyfill@4.0.10:
+ resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
+ engines: {node: '>=12.20.0'}
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -1098,6 +2127,10 @@ packages:
resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==}
engines: {node: '>= 0.4'}
+ get-nonce@1.0.1:
+ resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
+ engines: {node: '>=6'}
+
get-proto@1.0.1:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
@@ -1114,6 +2147,10 @@ packages:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
+ glob@10.4.5:
+ resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
+ hasBin: true
+
globals@14.0.0:
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
engines: {node: '>=18'}
@@ -1126,6 +2163,10 @@ packages:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'}
+ globby@14.1.0:
+ resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==}
+ engines: {node: '>=18'}
+
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
@@ -1133,6 +2174,9 @@ packages:
graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+ h3@1.15.4:
+ resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==}
+
has-bigints@1.1.0:
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
engines: {node: '>= 0.4'}
@@ -1160,15 +2204,16 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
- header-case@2.0.4:
- resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==}
-
- hotkeys-js@3.13.9:
- resolution: {integrity: sha512-3TRCj9u9KUH6cKo25w4KIdBfdBfNRjfUwrljCLDC2XhmPDG0SjAZFcFZekpUZFmXzfYoGhFDcdx2gX/vUVtztQ==}
+ hoist-non-react-statics@3.3.2:
+ resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
html-parse-stringify@3.0.1:
resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
+ https-proxy-agent@7.0.6:
+ resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
+ engines: {node: '>= 14'}
+
i18next-browser-languagedetector@8.0.4:
resolution: {integrity: sha512-f3frU3pIxD50/Tz20zx9TD9HobKYg47fmAETb117GKGPrhwcSSPJDoCposXlVycVebQ9GQohC3Efbpq7/nnJ5w==}
@@ -1189,10 +2234,23 @@ packages:
typescript:
optional: true
+ idb-keyval@6.2.2:
+ resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==}
+
+ ieee754@1.2.1:
+ resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+
ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'}
+ ignore@7.0.5:
+ resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
+ engines: {node: '>= 4'}
+
+ immediate@3.0.6:
+ resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
+
import-fresh@3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
@@ -1201,14 +2259,23 @@ packages:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
internal-slot@1.1.0:
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
engines: {node: '>= 0.4'}
+ iron-webcrypto@1.2.1:
+ resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
+
is-array-buffer@3.0.5:
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
engines: {node: '>= 0.4'}
+ is-arrayish@0.2.1:
+ resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+
is-async-function@2.1.0:
resolution: {integrity: sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==}
engines: {node: '>= 0.4'}
@@ -1217,6 +2284,10 @@ packages:
resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
engines: {node: '>= 0.4'}
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
is-boolean-object@1.2.1:
resolution: {integrity: sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==}
engines: {node: '>= 0.4'}
@@ -1245,6 +2316,10 @@ packages:
resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
engines: {node: '>= 0.4'}
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
is-generator-function@1.1.0:
resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
engines: {node: '>= 0.4'}
@@ -1301,6 +2376,9 @@ packages:
resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
engines: {node: '>= 0.4'}
+ isarray@1.0.0:
+ resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
+
isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
@@ -1319,6 +2397,9 @@ packages:
peerDependencies:
react: '>=18.0'
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -1326,9 +2407,17 @@ packages:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
+ jsesc@3.1.0:
+ resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
+ engines: {node: '>=6'}
+ hasBin: true
+
json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+ json-parse-even-better-errors@2.3.1:
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
@@ -1339,6 +2428,12 @@ packages:
resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
engines: {node: '>=4.0'}
+ jszip@3.10.1:
+ resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
+
+ kerium@1.3.6:
+ resolution: {integrity: sha512-TEMYweNOPW79LOGV9G26biypM2q96s4iJYxcWMg3IxUzRUIFGFfWIxS7Yx2eREKfhLINcNNXGUa0OR6ONS9Dgg==}
+
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -1346,6 +2441,12 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
+ lie@3.3.0:
+ resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
@@ -1353,20 +2454,23 @@ packages:
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
- lodash@4.17.21:
- resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+ look-it-up@2.1.0:
+ resolution: {integrity: sha512-nMoGWW2HurtuJf6XAL56FWTDCWLOTSsanrgwOyaR5Y4e3zfG5N/0cU5xWZSEU3tBxhQugRbV1xL9jb+ug7yZww==}
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
- lower-case@2.0.2:
- resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
+ lru-cache@10.4.3:
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
+ memium@0.3.8:
+ resolution: {integrity: sha512-spMrGHK7zNVBCZ2nhXxABC1yBtfe3HqUwEHD8j7oVMaLU+eqLrDoTZzMhx6bphw2/yA1EwOEdgeECtSfwRHk4w==}
+
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@@ -1382,22 +2486,70 @@ packages:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
- mpg123-decoder@1.0.0:
- resolution: {integrity: sha512-WV+pyuMUhRqv7s8S6p/Ii4KQHdBD1pb3yaABxcKJRsNp+HQ/Y6z2iIBIaOZu0JMHPTOoICYt0REDZ7XfLu+n/g==}
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
- ms@2.1.3:
- resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ mobx-react-lite@4.1.0:
+ resolution: {integrity: sha512-QEP10dpHHBeQNv1pks3WnHRCem2Zp636lq54M2nKO2Sarr13pL4u6diQXf65yzXUn0mkk18SyIDCm9UOJYTi1w==}
+ peerDependencies:
+ mobx: ^6.9.0
+ react: ^16.8.0 || ^17 || ^18 || ^19
+ react-dom: '*'
+ react-native: '*'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+
+ mobx-state-tree@7.0.2:
+ resolution: {integrity: sha512-Qmqgo2Ho1/JRTquo0EWw0ZA/k4wTUNPMIBg98ALGN1V/0Gupic7dg4GDYUhNbiLsYHpp48VgpaCDpDIKV+jNkQ==}
+ peerDependencies:
+ mobx: ^6.3.0
+
+ mobx@6.13.7:
+ resolution: {integrity: sha512-aChaVU/DO5aRPmk1GX8L+whocagUUpBQqoPtJk+cm7UOXUk87J4PeWCh6nNmTTIfEhiR9DI/+FnA8dln/hTK7g==}
+
+ mpg123-decoder@1.0.0:
+ resolution: {integrity: sha512-WV+pyuMUhRqv7s8S6p/Ii4KQHdBD1pb3yaABxcKJRsNp+HQ/Y6z2iIBIaOZu0JMHPTOoICYt0REDZ7XfLu+n/g==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
nanoid@3.3.8:
resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
+ nanoid@5.1.5:
+ resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==}
+ engines: {node: ^18 || >=20}
+ hasBin: true
+
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
- no-case@3.0.4:
- resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
+ next-themes@0.4.6:
+ resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
+ peerDependencies:
+ react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
+
+ node-domexception@1.0.0:
+ resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
+ engines: {node: '>=10.5.0'}
+ deprecated: Use your platform's native DOMException instead
+
+ node-eval@2.0.0:
+ resolution: {integrity: sha512-Ap+L9HznXAVeJj3TJ1op6M6bg5xtTq8L5CU/PJxtkhea/DrIxdTknGKIECKd/v/Lgql95iuMAYvIzBNd0pmcMg==}
+ engines: {node: '>= 4'}
+
+ node-fetch-native@1.6.7:
+ resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
@@ -1408,10 +2560,21 @@ packages:
encoding:
optional: true
+ node-fetch@3.3.2:
+ resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ node-mock-http@1.0.3:
+ resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==}
+
node-wav@0.0.2:
resolution: {integrity: sha512-M6Rm/bbG6De/gKGxOpeOobx/dnGuP0dz40adqx38boqHhlWssBJZgLCPBNtb9NkrmnKYiV04xELq+R6PFOnoLA==}
engines: {node: '>=4.4.0'}
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
normalize.css@8.0.1:
resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==}
@@ -1443,6 +2606,9 @@ packages:
resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==}
engines: {node: '>= 0.4'}
+ ofetch@1.4.1:
+ resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==}
+
ogg-opus-decoder@1.6.14:
resolution: {integrity: sha512-RQpk9yFl/mqXFwcgf1BrEYWL92HZk++aU1fOO8mPZ1+1DUYbJdpdUQEFfbPE1xcBkRGU3p75DjEO+EDMNeikFQ==}
@@ -1465,26 +2631,34 @@ packages:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
- param-case@3.0.4:
- resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
+ package-manager-detector@1.3.0:
+ resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==}
+
+ pako@1.0.11:
+ resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
+ parse-json@5.2.0:
+ resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
+ engines: {node: '>=8'}
+
parse-svg-path@0.1.2:
resolution: {integrity: sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==}
- pascal-case@3.1.2:
- resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
-
- path-case@3.0.4:
- resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==}
-
path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
+ path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
@@ -1492,6 +2666,21 @@ packages:
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
+ path-type@4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+
+ path-type@6.0.0:
+ resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==}
+ engines: {node: '>=18'}
+
+ perfect-freehand@1.2.2:
+ resolution: {integrity: sha512-eh31l019WICQ03pkF3FSzHxB8n07ItqIQ++G5UV8JX0zVOXzgTGCqnRR0jJ2h9U8/2uW4W4mtGJELt9kEV0CFQ==}
+
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -1499,6 +2688,10 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
+ pirates@4.0.7:
+ resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
+ engines: {node: '>= 6'}
+
pixi.js@8.6.6:
resolution: {integrity: sha512-o5pw7G2yuIrnBx0G4npBlmFp+XGNcapI/Ufs62rRj/4XKxc1Zo74YJr/BtEXcXTraTKd+pQvYOLvnfxRjxBMvQ==}
@@ -1506,6 +2699,13 @@ packages:
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
engines: {node: '>= 0.4'}
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.4.49:
+ resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==}
+ engines: {node: ^10 || ^12 || >=14}
+
postcss@8.5.2:
resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==}
engines: {node: ^10 || ^12 || >=14}
@@ -1514,9 +2714,27 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
+ prettier@3.6.2:
+ resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ process-nextick-args@2.0.1:
+ resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+
+ process@0.11.10:
+ resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
+ engines: {node: '>= 0.6.0'}
+
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+ proxy-compare@3.0.1:
+ resolution: {integrity: sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==}
+
+ proxy-memoize@3.0.1:
+ resolution: {integrity: sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g==}
+
punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
@@ -1527,88 +2745,18 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
- rc-align@4.0.15:
- resolution: {integrity: sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
-
- rc-dock@3.3.0:
- resolution: {integrity: sha512-9rQAzHSLAdQz1ZpPqQGkZKlAt4YI6gNYjuqqpY6hIWBFDhVPccs0jYr7L7PP3OpmliZ/R60LgHfLFbrL9l+Tlg==}
- peerDependencies:
- react: '>=17.0.0'
- react-dom: '>=17.0.0'
-
- rc-dropdown@4.0.1:
- resolution: {integrity: sha512-OdpXuOcme1rm45cR0Jzgfl1otzmU4vuBVb+etXM8vcaULGokAKVpKlw8p6xzspG7jGd/XxShvq+N3VNEfk/l5g==}
- peerDependencies:
- react: '>=16.11.0'
- react-dom: '>=16.11.0'
-
- rc-menu@9.6.4:
- resolution: {integrity: sha512-6DiNAjxjVIPLZXHffXxxcyE15d4isRL7iQ1ru4MqYDH2Cqc5bW96wZOdMydFtGLyDdnmEQ9jVvdCE9yliGvzkw==}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
-
- rc-menu@9.8.4:
- resolution: {integrity: sha512-lmw2j8I2fhdIzHmC9ajfImfckt0WDb2KVJJBBRIsxPEw2kGkEfjLMUoB1NgiNT/Q5cC8PdjGOGQjHJIJMwyNMw==}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
-
- rc-motion@2.9.5:
- resolution: {integrity: sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
-
- rc-new-window@0.1.13:
- resolution: {integrity: sha512-KqANLQVfgNcfs+R4ntpzV5ELyqXMlAUimdSfFHapk2VwsoZX3y+BK2RjFBFb7q865yqAshP87g0PbIPqblKVTg==}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
-
- rc-overflow@1.4.1:
- resolution: {integrity: sha512-3MoPQQPV1uKyOMVNd6SZfONi+f3st0r8PksexIdBTeIYbMX0Jr+k7pHEDvsXtR4BpCv90/Pv2MovVNhktKrwvw==}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
-
- rc-resize-observer@1.4.3:
- resolution: {integrity: sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
-
- rc-tabs@11.16.1:
- resolution: {integrity: sha512-bR7Dap23YyfzZQwtKomhiFEFzZuE7WaKWo+ypNRSGB9PDKSc6tM12VP8LWYkvmmQHthgwP0WRN8nFbSJWuqLYw==}
- engines: {node: '>=8.x'}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
-
- rc-trigger@5.3.4:
- resolution: {integrity: sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==}
- engines: {node: '>=8.x'}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
+ quick-lru@7.1.0:
+ resolution: {integrity: sha512-Pzd/4IFnTb8E+I1P5rbLQoqpUHcXKg48qTYKi4EANg+sTPwGFEMOcYGiiZz6xuQcOMZP7MPsrdAPx+16Q8qahg==}
+ engines: {node: '>=18'}
- rc-util@5.44.3:
- resolution: {integrity: sha512-q6KCcOFk3rv/zD3MckhJteZxb0VjAIFuf622B7ElK4vfrZdAzs16XR5p3VTdy3+U5jfJU5ACz4QnhLSuAGe5dA==}
- peerDependencies:
- react: '>=16.9.0'
- react-dom: '>=16.9.0'
+ radix3@1.1.2:
+ resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
react-dom@19.0.0:
resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
peerDependencies:
react: ^19.0.0
- react-fast-compare@3.2.2:
- resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==}
-
react-i18next@15.4.1:
resolution: {integrity: sha512-ahGab+IaSgZmNPYXdV1n+OYky95TGpFwnKRflX/16dY04DsYYKHtVLjeny7sBSCREEcoMbAgSkFiGLF5g5Oofw==}
peerDependencies:
@@ -1622,28 +2770,43 @@ packages:
react-native:
optional: true
+ react-icons@5.5.0:
+ resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==}
+ peerDependencies:
+ react: '*'
+
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
- react-is@18.3.1:
- resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
-
react-lifecycles-compat@3.0.4:
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
- react-popper@2.3.0:
- resolution: {integrity: sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==}
- peerDependencies:
- '@popperjs/core': ^2.0.0
- react: ^16.8.0 || ^17 || ^18
- react-dom: ^16.8.0 || ^17 || ^18
-
react-reconciler@0.31.0:
resolution: {integrity: sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ==}
engines: {node: '>=0.10.0'}
peerDependencies:
react: ^19.0.0
+ react-remove-scroll-bar@2.3.8:
+ resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-remove-scroll@2.7.1:
+ resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
react-split-pane@0.1.92:
resolution: {integrity: sha512-GfXP1xSzLMcLJI5BM36Vh7GgZBpy+U/X0no+VM3fxayv+p1Jly5HpMofZJraeaMl73b3hvlr+N9zJKvLB/uz9w==}
peerDependencies:
@@ -1653,18 +2816,12 @@ packages:
react-style-proptype@3.2.2:
resolution: {integrity: sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ==}
- react-transition-group@4.4.5:
- resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
- peerDependencies:
- react: '>=16.6.0'
- react-dom: '>=16.6.0'
-
- react-uid@2.4.0:
- resolution: {integrity: sha512-+MVs/25NrcZuGrmlVRWPOSsbS8y72GJOBsR7d68j3/wqOrRBF52U29XAw4+XSelw0Vm6s5VmGH5mCbTCPGVCVg==}
+ react-style-singleton@2.2.3:
+ resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
engines: {node: '>=10'}
peerDependencies:
- '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
@@ -1673,6 +2830,21 @@ packages:
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
engines: {node: '>=0.10.0'}
+ readable-stream@2.3.8:
+ resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
+
+ readable-stream@4.7.0:
+ resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
reflect.getprototypeof@1.0.10:
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
engines: {node: '>= 0.4'}
@@ -1684,13 +2856,15 @@ packages:
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
engines: {node: '>= 0.4'}
- resize-observer-polyfill@1.5.1:
- resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
-
resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
+ resolve@1.22.10:
+ resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
+ engines: {node: '>= 0.4'}
+ hasBin: true
+
resolve@2.0.0-next.5:
resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==}
hasBin: true
@@ -1711,6 +2885,12 @@ packages:
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
engines: {node: '>=0.4'}
+ safe-buffer@5.1.2:
+ resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
safe-push-apply@1.0.0:
resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
engines: {node: '>= 0.4'}
@@ -1722,6 +2902,9 @@ packages:
scheduler@0.25.0:
resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
+ scule@1.3.0:
+ resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
+
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@@ -1731,9 +2914,6 @@ packages:
engines: {node: '>=10'}
hasBin: true
- sentence-case@3.0.4:
- resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==}
-
set-function-length@1.2.2:
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
engines: {node: '>= 0.4'}
@@ -1746,6 +2926,9 @@ packages:
resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
engines: {node: '>= 0.4'}
+ setimmediate@1.0.5:
+ resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
+
shallowequal@1.1.0:
resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==}
@@ -1773,18 +2956,35 @@ packages:
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
engines: {node: '>= 0.4'}
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
simple-yenc@1.0.4:
resolution: {integrity: sha512-5gvxpSd79e9a3V4QDYUqnqxeD4HGlhCakVpb6gMnDD7lexJggSBJRBO5h52y/iJrdXRilX9UCuDaIJhSWm5OWw==}
- snake-case@3.0.4:
- resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
+ sisteransi@1.0.5:
+ resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
+
+ slash@5.1.0:
+ resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
+ engines: {node: '>=14.16'}
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
- spark-md5@3.0.2:
- resolution: {integrity: sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==}
+ source-map@0.5.7:
+ resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
+ engines: {node: '>=0.10.0'}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
string.prototype.matchall@4.0.12:
resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==}
@@ -1805,10 +3005,42 @@ packages:
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
engines: {node: '>= 0.4'}
+ string_decoder@1.1.1:
+ resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+
+ string_decoder@1.3.0:
+ resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
+ styled-components@6.1.19:
+ resolution: {integrity: sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==}
+ engines: {node: '>= 16'}
+ peerDependencies:
+ react: '>= 16.8.0'
+ react-dom: '>= 16.8.0'
+
+ stylis@4.2.0:
+ resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==}
+
+ stylis@4.3.2:
+ resolution: {integrity: sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==}
+
+ sucrase@3.35.0:
+ resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
@@ -1817,6 +3049,13 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -1830,8 +3069,22 @@ packages:
peerDependencies:
typescript: '>=4.2.0'
- tslib@2.6.3:
- resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
+ ts-essentials@9.4.2:
+ resolution: {integrity: sha512-mB/cDhOvD7pg3YCLk2rOtejHjjdSi9in/IBYE13S+8WA5FBSraYf4V/ws55uvs0IvQ/l0wBOlXy5yBNZ9Bl8ZQ==}
+ peerDependencies:
+ typescript: '>=4.1.0'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ tslib@2.6.2:
+ resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
@@ -1865,29 +3118,125 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
+ ufo@1.6.1:
+ resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
+
unbox-primitive@1.1.0:
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
engines: {node: '>= 0.4'}
+ uncrypto@0.1.3:
+ resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
+
undici-types@6.20.0:
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
- upper-case-first@2.0.2:
- resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==}
+ undici-types@7.10.0:
+ resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==}
- upper-case@2.0.2:
- resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==}
+ unicorn-magic@0.3.0:
+ resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
+ engines: {node: '>=18'}
+
+ unstorage@1.17.1:
+ resolution: {integrity: sha512-KKGwRTT0iVBCErKemkJCLs7JdxNVfqTPc/85ae1XES0+bsHbc/sFBfVi5kJp156cc51BHinIH2l3k0EZ24vOBQ==}
+ peerDependencies:
+ '@azure/app-configuration': ^1.8.0
+ '@azure/cosmos': ^4.2.0
+ '@azure/data-tables': ^13.3.0
+ '@azure/identity': ^4.6.0
+ '@azure/keyvault-secrets': ^4.9.0
+ '@azure/storage-blob': ^12.26.0
+ '@capacitor/preferences': ^6.0.3 || ^7.0.0
+ '@deno/kv': '>=0.9.0'
+ '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0
+ '@planetscale/database': ^1.19.0
+ '@upstash/redis': ^1.34.3
+ '@vercel/blob': '>=0.27.1'
+ '@vercel/functions': ^2.2.12 || ^3.0.0
+ '@vercel/kv': ^1.0.1
+ aws4fetch: ^1.0.20
+ db0: '>=0.2.1'
+ idb-keyval: ^6.2.1
+ ioredis: ^5.4.2
+ uploadthing: ^7.4.4
+ peerDependenciesMeta:
+ '@azure/app-configuration':
+ optional: true
+ '@azure/cosmos':
+ optional: true
+ '@azure/data-tables':
+ optional: true
+ '@azure/identity':
+ optional: true
+ '@azure/keyvault-secrets':
+ optional: true
+ '@azure/storage-blob':
+ optional: true
+ '@capacitor/preferences':
+ optional: true
+ '@deno/kv':
+ optional: true
+ '@netlify/blobs':
+ optional: true
+ '@planetscale/database':
+ optional: true
+ '@upstash/redis':
+ optional: true
+ '@vercel/blob':
+ optional: true
+ '@vercel/functions':
+ optional: true
+ '@vercel/kv':
+ optional: true
+ aws4fetch:
+ optional: true
+ db0:
+ optional: true
+ idb-keyval:
+ optional: true
+ ioredis:
+ optional: true
+ uploadthing:
+ optional: true
+
+ uqr@0.1.2:
+ resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==}
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ use-callback-ref@1.3.3:
+ resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-sidecar@1.1.3:
+ resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
use-sync-external-store@1.4.0:
resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- uuid@11.0.4:
- resolution: {integrity: sha512-IzL6VtTTYcAhA/oghbFJ1Dkmqev+FpQWnCBaKq/gUluLxliWvO8DPFWfIviRmYbtaavtSQe4WBL++rFjdcGWEg==}
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ utilium@2.5.4:
+ resolution: {integrity: sha512-JeuMqv+yc2AGo0A3vVIiEwrYQcE/8SXftnvUq0HK0wnAmHtPCMZ/vln7nmNF9G63Qw9egijnTx3TxzdWZKYBmA==}
+ engines: {node: '>=22.0.0'}
hasBin: true
vite@6.0.9:
@@ -1934,8 +3283,9 @@ packages:
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
engines: {node: '>=0.10.0'}
- warning@4.0.3:
- resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
+ web-streams-polyfill@3.3.3:
+ resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
+ engines: {node: '>= 8'}
webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
@@ -1968,12 +3318,142 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ yaml@1.10.2:
+ resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
+ engines: {node: '>= 6'}
+
yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
+ zod@3.25.76:
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+
+ zustand@5.0.8:
+ resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==}
+ engines: {node: '>=12.20.0'}
+ peerDependencies:
+ '@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
+
snapshots:
+ '@ark-ui/react@5.22.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@internationalized/date': 3.8.2
+ '@zag-js/accordion': 1.22.1
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/angle-slider': 1.22.1
+ '@zag-js/async-list': 1.22.1
+ '@zag-js/auto-resize': 1.22.1
+ '@zag-js/avatar': 1.22.1
+ '@zag-js/carousel': 1.22.1
+ '@zag-js/checkbox': 1.22.1
+ '@zag-js/clipboard': 1.22.1
+ '@zag-js/collapsible': 1.22.1
+ '@zag-js/collection': 1.22.1
+ '@zag-js/color-picker': 1.22.1
+ '@zag-js/color-utils': 1.22.1
+ '@zag-js/combobox': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/date-picker': 1.22.1(@internationalized/date@3.8.2)
+ '@zag-js/date-utils': 1.22.1(@internationalized/date@3.8.2)
+ '@zag-js/dialog': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/editable': 1.22.1
+ '@zag-js/file-upload': 1.22.1
+ '@zag-js/file-utils': 1.22.1
+ '@zag-js/floating-panel': 1.22.1
+ '@zag-js/focus-trap': 1.22.1
+ '@zag-js/highlight-word': 1.22.1
+ '@zag-js/hover-card': 1.22.1
+ '@zag-js/i18n-utils': 1.22.1
+ '@zag-js/json-tree-utils': 1.22.1
+ '@zag-js/listbox': 1.22.1
+ '@zag-js/menu': 1.22.1
+ '@zag-js/number-input': 1.22.1
+ '@zag-js/pagination': 1.22.1
+ '@zag-js/password-input': 1.22.1
+ '@zag-js/pin-input': 1.22.1
+ '@zag-js/popover': 1.22.1
+ '@zag-js/presence': 1.22.1
+ '@zag-js/progress': 1.22.1
+ '@zag-js/qr-code': 1.22.1
+ '@zag-js/radio-group': 1.22.1
+ '@zag-js/rating-group': 1.22.1
+ '@zag-js/react': 1.22.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@zag-js/scroll-area': 1.22.1
+ '@zag-js/select': 1.22.1
+ '@zag-js/signature-pad': 1.22.1
+ '@zag-js/slider': 1.22.1
+ '@zag-js/splitter': 1.22.1
+ '@zag-js/steps': 1.22.1
+ '@zag-js/switch': 1.22.1
+ '@zag-js/tabs': 1.22.1
+ '@zag-js/tags-input': 1.22.1
+ '@zag-js/time-picker': 1.22.1(@internationalized/date@3.8.2)
+ '@zag-js/timer': 1.22.1
+ '@zag-js/toast': 1.22.1
+ '@zag-js/toggle': 1.22.1
+ '@zag-js/toggle-group': 1.22.1
+ '@zag-js/tooltip': 1.22.1
+ '@zag-js/tour': 1.22.1
+ '@zag-js/tree-view': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+
+ '@babel/code-frame@7.27.1':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.27.1
+ js-tokens: 4.0.0
+ picocolors: 1.1.1
+
+ '@babel/generator@7.28.3':
+ dependencies:
+ '@babel/parser': 7.28.3
+ '@babel/types': 7.28.2
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.30
+ jsesc: 3.1.0
+
+ '@babel/helper-globals@7.28.0': {}
+
+ '@babel/helper-module-imports@7.27.1':
+ dependencies:
+ '@babel/traverse': 7.28.3
+ '@babel/types': 7.28.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-string-parser@7.27.1': {}
+
+ '@babel/helper-validator-identifier@7.27.1': {}
+
+ '@babel/parser@7.28.3':
+ dependencies:
+ '@babel/types': 7.28.2
+
'@babel/runtime@7.26.0':
dependencies:
regenerator-runtime: 0.14.1
@@ -1982,112 +3462,308 @@ snapshots:
dependencies:
regenerator-runtime: 0.14.1
- '@blueprintjs/colors@5.1.5':
+ '@babel/template@7.27.2':
+ dependencies:
+ '@babel/code-frame': 7.27.1
+ '@babel/parser': 7.28.3
+ '@babel/types': 7.28.2
+
+ '@babel/traverse@7.28.3':
dependencies:
- tslib: 2.6.3
+ '@babel/code-frame': 7.27.1
+ '@babel/generator': 7.28.3
+ '@babel/helper-globals': 7.28.0
+ '@babel/parser': 7.28.3
+ '@babel/template': 7.27.2
+ '@babel/types': 7.28.2
+ debug: 4.4.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/types@7.28.2':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.27.1
+
+ '@chakra-ui/cli@3.26.0(@chakra-ui/react@3.26.0(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))':
+ dependencies:
+ '@chakra-ui/react': 3.26.0(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@clack/prompts': 0.11.0
+ '@pandacss/is-valid-prop': 0.54.0
+ '@types/cli-table': 0.3.4
+ '@types/debug': 4.1.12
+ '@visulima/boxen': 2.0.2
+ bundle-n-require: 1.1.2
+ chokidar: 3.6.0
+ cli-table: 0.3.11
+ commander: 12.1.0
+ debug: 4.4.1
+ globby: 14.1.0
+ https-proxy-agent: 7.0.6
+ look-it-up: 2.1.0
+ node-fetch: 3.3.2
+ package-manager-detector: 1.3.0
+ prettier: 3.6.2
+ scule: 1.3.0
+ sucrase: 3.35.0
+ zod: 3.25.76
+ transitivePeerDependencies:
+ - supports-color
- '@blueprintjs/core@5.16.4(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ '@chakra-ui/react@3.26.0(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
- '@blueprintjs/colors': 5.1.5
- '@blueprintjs/icons': 5.17.1(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- '@popperjs/core': 2.11.8
- classnames: 2.5.1
- normalize.css: 8.0.1
+ '@ark-ui/react': 5.22.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@emotion/is-prop-valid': 1.4.0
+ '@emotion/react': 11.14.0(@types/react@19.0.7)(react@19.0.0)
+ '@emotion/serialize': 1.3.3
+ '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.0.0)
+ '@emotion/utils': 1.4.2
+ '@pandacss/is-valid-prop': 0.54.0
+ csstype: 3.1.3
+ fast-safe-stringify: 2.1.1
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
- react-popper: 2.3.0(@popperjs/core@2.11.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react-uid: 2.4.0(@types/react@19.0.7)(react@19.0.0)
- tslib: 2.6.3
- use-sync-external-store: 1.4.0(react@19.0.0)
- optionalDependencies:
- '@types/react': 19.0.7
- '@blueprintjs/icons@5.17.1(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ '@clack/core@0.5.0':
+ dependencies:
+ picocolors: 1.1.1
+ sisteransi: 1.0.5
+
+ '@clack/prompts@0.11.0':
+ dependencies:
+ '@clack/core': 0.5.0
+ picocolors: 1.1.1
+ sisteransi: 1.0.5
+
+ '@emotion/babel-plugin@11.13.5':
+ dependencies:
+ '@babel/helper-module-imports': 7.27.1
+ '@babel/runtime': 7.26.10
+ '@emotion/hash': 0.9.2
+ '@emotion/memoize': 0.9.0
+ '@emotion/serialize': 1.3.3
+ babel-plugin-macros: 3.1.0
+ convert-source-map: 1.9.0
+ escape-string-regexp: 4.0.0
+ find-root: 1.1.0
+ source-map: 0.5.7
+ stylis: 4.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@emotion/cache@11.14.0':
+ dependencies:
+ '@emotion/memoize': 0.9.0
+ '@emotion/sheet': 1.4.0
+ '@emotion/utils': 1.4.2
+ '@emotion/weak-memoize': 0.4.0
+ stylis: 4.2.0
+
+ '@emotion/hash@0.9.2': {}
+
+ '@emotion/is-prop-valid@1.2.2':
+ dependencies:
+ '@emotion/memoize': 0.8.1
+
+ '@emotion/is-prop-valid@1.4.0':
+ dependencies:
+ '@emotion/memoize': 0.9.0
+
+ '@emotion/memoize@0.8.1': {}
+
+ '@emotion/memoize@0.9.0': {}
+
+ '@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0)':
dependencies:
- change-case: 4.1.2
- classnames: 2.5.1
+ '@babel/runtime': 7.26.10
+ '@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(react@19.0.0)
+ '@emotion/utils': 1.4.2
+ '@emotion/weak-memoize': 0.4.0
+ hoist-non-react-statics: 3.3.2
react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
- tslib: 2.6.3
optionalDependencies:
'@types/react': 19.0.7
+ transitivePeerDependencies:
+ - supports-color
+
+ '@emotion/serialize@1.3.3':
+ dependencies:
+ '@emotion/hash': 0.9.2
+ '@emotion/memoize': 0.9.0
+ '@emotion/unitless': 0.10.0
+ '@emotion/utils': 1.4.2
+ csstype: 3.1.3
+
+ '@emotion/sheet@1.4.0': {}
+
+ '@emotion/unitless@0.10.0': {}
+
+ '@emotion/unitless@0.8.1': {}
+
+ '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+
+ '@emotion/utils@1.4.2': {}
+
+ '@emotion/weak-memoize@0.4.0': {}
'@esbuild/aix-ppc64@0.24.2':
optional: true
+ '@esbuild/aix-ppc64@0.25.9':
+ optional: true
+
'@esbuild/android-arm64@0.24.2':
optional: true
+ '@esbuild/android-arm64@0.25.9':
+ optional: true
+
'@esbuild/android-arm@0.24.2':
optional: true
+ '@esbuild/android-arm@0.25.9':
+ optional: true
+
'@esbuild/android-x64@0.24.2':
optional: true
+ '@esbuild/android-x64@0.25.9':
+ optional: true
+
'@esbuild/darwin-arm64@0.24.2':
optional: true
+ '@esbuild/darwin-arm64@0.25.9':
+ optional: true
+
'@esbuild/darwin-x64@0.24.2':
optional: true
+ '@esbuild/darwin-x64@0.25.9':
+ optional: true
+
'@esbuild/freebsd-arm64@0.24.2':
optional: true
+ '@esbuild/freebsd-arm64@0.25.9':
+ optional: true
+
'@esbuild/freebsd-x64@0.24.2':
optional: true
+ '@esbuild/freebsd-x64@0.25.9':
+ optional: true
+
'@esbuild/linux-arm64@0.24.2':
optional: true
+ '@esbuild/linux-arm64@0.25.9':
+ optional: true
+
'@esbuild/linux-arm@0.24.2':
optional: true
+ '@esbuild/linux-arm@0.25.9':
+ optional: true
+
'@esbuild/linux-ia32@0.24.2':
optional: true
+ '@esbuild/linux-ia32@0.25.9':
+ optional: true
+
'@esbuild/linux-loong64@0.24.2':
optional: true
+ '@esbuild/linux-loong64@0.25.9':
+ optional: true
+
'@esbuild/linux-mips64el@0.24.2':
optional: true
+ '@esbuild/linux-mips64el@0.25.9':
+ optional: true
+
'@esbuild/linux-ppc64@0.24.2':
optional: true
+ '@esbuild/linux-ppc64@0.25.9':
+ optional: true
+
'@esbuild/linux-riscv64@0.24.2':
optional: true
+ '@esbuild/linux-riscv64@0.25.9':
+ optional: true
+
'@esbuild/linux-s390x@0.24.2':
optional: true
+ '@esbuild/linux-s390x@0.25.9':
+ optional: true
+
'@esbuild/linux-x64@0.24.2':
optional: true
+ '@esbuild/linux-x64@0.25.9':
+ optional: true
+
'@esbuild/netbsd-arm64@0.24.2':
optional: true
+ '@esbuild/netbsd-arm64@0.25.9':
+ optional: true
+
'@esbuild/netbsd-x64@0.24.2':
optional: true
+ '@esbuild/netbsd-x64@0.25.9':
+ optional: true
+
'@esbuild/openbsd-arm64@0.24.2':
optional: true
+ '@esbuild/openbsd-arm64@0.25.9':
+ optional: true
+
'@esbuild/openbsd-x64@0.24.2':
optional: true
+ '@esbuild/openbsd-x64@0.25.9':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.25.9':
+ optional: true
+
'@esbuild/sunos-x64@0.24.2':
optional: true
+ '@esbuild/sunos-x64@0.25.9':
+ optional: true
+
'@esbuild/win32-arm64@0.24.2':
optional: true
+ '@esbuild/win32-arm64@0.25.9':
+ optional: true
+
'@esbuild/win32-ia32@0.24.2':
optional: true
+ '@esbuild/win32-ia32@0.25.9':
+ optional: true
+
'@esbuild/win32-x64@0.24.2':
optional: true
+ '@esbuild/win32-x64@0.25.9':
+ optional: true
+
'@eshaz/web-worker@1.2.2': {}
'@eslint-community/eslint-utils@4.4.1(eslint@9.17.0)':
@@ -2131,6 +3807,23 @@ snapshots:
dependencies:
levn: 0.4.1
+ '@floating-ui/core@1.7.3':
+ dependencies:
+ '@floating-ui/utils': 0.2.10
+
+ '@floating-ui/dom@1.7.4':
+ dependencies:
+ '@floating-ui/core': 1.7.3
+ '@floating-ui/utils': 0.2.10
+
+ '@floating-ui/react-dom@2.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@floating-ui/dom': 1.7.4
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+
+ '@floating-ui/utils@0.2.10': {}
+
'@fortawesome/fontawesome-common-types@6.7.2': {}
'@fortawesome/fontawesome-svg-core@6.7.2':
@@ -2160,30 +3853,313 @@ snapshots:
'@humanwhocodes/retry@0.4.1': {}
+ '@internationalized/date@3.8.2':
+ dependencies:
+ '@swc/helpers': 0.5.17
+
+ '@internationalized/number@3.6.4':
+ dependencies:
+ '@swc/helpers': 0.5.17
+
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.30
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.30':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
'@nodelib/fs.scandir@2.1.5':
dependencies:
- '@nodelib/fs.stat': 2.0.5
- run-parallel: 1.2.0
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.18.0
+
+ '@pandacss/is-valid-prop@0.54.0': {}
+
+ '@phifans/audio@0.0.7':
+ dependencies:
+ '@types/setimmediate': 1.0.4
+ audio-decode: 2.2.2
+ setimmediate: 1.0.5
+
+ '@pixi/colord@2.9.6': {}
+
+ '@pixi/react@8.0.0(@types/react@19.0.7)(pixi.js@8.6.6)(react@19.0.0)':
+ dependencies:
+ its-fine: 1.2.5(@types/react@19.0.7)(react@19.0.0)
+ pixi.js: 8.6.6
+ react: 19.0.0
+ react-reconciler: 0.31.0(react@19.0.0)
+ transitivePeerDependencies:
+ - '@types/react'
+
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
+ '@radix-ui/primitive@1.1.3': {}
+
+ '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-collection@1.1.7(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-compose-refs@1.1.2(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ '@radix-ui/react-context@1.1.2(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ '@radix-ui/react-direction@1.1.1(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-focus-guards@1.1.3(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-id@1.1.1(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ '@radix-ui/react-menu@2.1.16(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ aria-hidden: 1.2.6
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ react-remove-scroll: 2.7.1(@types/react@19.0.7)(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-popper@1.2.8(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@floating-ui/react-dom': 2.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-use-rect': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-use-size': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/rect': 1.1.1
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-portal@1.1.9(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-presence@1.1.5(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.3(@types/react@19.0.7))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ '@types/react-dom': 19.0.3(@types/react@19.0.7)
+
+ '@radix-ui/react-slot@1.2.3(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.0.7)(react@19.0.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
- '@nodelib/fs.stat@2.0.5': {}
+ '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.7)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
- '@nodelib/fs.walk@1.2.8':
+ '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.0.7)(react@19.0.0)':
dependencies:
- '@nodelib/fs.scandir': 2.1.5
- fastq: 1.18.0
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
- '@pixi/colord@2.9.6': {}
+ '@radix-ui/react-use-rect@1.1.1(@types/react@19.0.7)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/rect': 1.1.1
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.7
- '@pixi/react@8.0.0(@types/react@19.0.7)(pixi.js@8.6.6)(react@19.0.0)':
+ '@radix-ui/react-use-size@1.1.1(@types/react@19.0.7)(react@19.0.0)':
dependencies:
- its-fine: 1.2.5(@types/react@19.0.7)(react@19.0.0)
- pixi.js: 8.6.6
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.7)(react@19.0.0)
react: 19.0.0
- react-reconciler: 0.31.0(react@19.0.0)
- transitivePeerDependencies:
- - '@types/react'
+ optionalDependencies:
+ '@types/react': 19.0.7
- '@popperjs/core@2.11.8': {}
+ '@radix-ui/rect@1.1.1': {}
'@rollup/rollup-android-arm-eabi@4.34.7':
optional: true
@@ -2242,6 +4218,8 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.34.7':
optional: true
+ '@sindresorhus/merge-streams@2.3.0': {}
+
'@swc/core-darwin-arm64@1.10.3':
optional: true
@@ -2272,7 +4250,7 @@ snapshots:
'@swc/core-win32-x64-msvc@1.10.3':
optional: true
- '@swc/core@1.10.3':
+ '@swc/core@1.10.3(@swc/helpers@0.5.17)':
dependencies:
'@swc/counter': 0.1.3
'@swc/types': 0.1.17
@@ -2287,13 +4265,20 @@ snapshots:
'@swc/core-win32-arm64-msvc': 1.10.3
'@swc/core-win32-ia32-msvc': 1.10.3
'@swc/core-win32-x64-msvc': 1.10.3
+ '@swc/helpers': 0.5.17
'@swc/counter@0.1.3': {}
+ '@swc/helpers@0.5.17':
+ dependencies:
+ tslib: 2.8.1
+
'@swc/types@0.1.17':
dependencies:
'@swc/counter': 0.1.3
+ '@tauri-apps/api@2.8.0': {}
+
'@tauri-apps/cli-darwin-arm64@2.2.7':
optional: true
@@ -2337,24 +4322,46 @@ snapshots:
'@tauri-apps/cli-win32-ia32-msvc': 2.2.7
'@tauri-apps/cli-win32-x64-msvc': 2.2.7
+ '@tauri-apps/plugin-fs@2.4.2':
+ dependencies:
+ '@tauri-apps/api': 2.8.0
+
+ '@tauri-apps/plugin-sql@2.3.0':
+ dependencies:
+ '@tauri-apps/api': 2.8.0
+
'@thi.ng/bitstream@2.4.8':
dependencies:
'@thi.ng/errors': 2.5.22
'@thi.ng/errors@2.5.22': {}
+ '@types/cli-table@0.3.4': {}
+
'@types/css-font-loading-module@0.0.12': {}
+ '@types/debug@4.1.12':
+ dependencies:
+ '@types/ms': 2.1.0
+
'@types/earcut@2.1.4': {}
'@types/estree@1.0.6': {}
'@types/json-schema@7.0.15': {}
+ '@types/ms@2.1.0': {}
+
'@types/node@22.10.5':
dependencies:
undici-types: 6.20.0
+ '@types/node@24.3.1':
+ dependencies:
+ undici-types: 7.10.0
+
+ '@types/parse-json@4.0.2': {}
+
'@types/react-dom@19.0.3(@types/react@19.0.7)':
dependencies:
'@types/react': 19.0.7
@@ -2367,7 +4374,9 @@ snapshots:
dependencies:
csstype: 3.1.3
- '@types/spark-md5@3.0.5': {}
+ '@types/setimmediate@1.0.4': {}
+
+ '@types/stylis@4.2.5': {}
'@typescript-eslint/eslint-plugin@8.18.2(@typescript-eslint/parser@8.18.2(eslint@9.17.0)(typescript@5.6.3))(eslint@9.17.0)(typescript@5.6.3)':
dependencies:
@@ -2446,9 +4455,11 @@ snapshots:
'@typescript-eslint/types': 8.18.2
eslint-visitor-keys: 4.2.0
- '@vitejs/plugin-react-swc@3.7.2(vite@6.0.9(@types/node@22.10.5))':
+ '@visulima/boxen@2.0.2': {}
+
+ '@vitejs/plugin-react-swc@3.7.2(@swc/helpers@0.5.17)(vite@6.0.9(@types/node@22.10.5))':
dependencies:
- '@swc/core': 1.10.3
+ '@swc/core': 1.10.3(@swc/helpers@0.5.17)
vite: 6.0.9(@types/node@22.10.5)
transitivePeerDependencies:
- '@swc/helpers'
@@ -2472,12 +4483,550 @@ snapshots:
'@xmldom/xmldom@0.8.10': {}
+ '@xterm/xterm@5.5.0':
+ optional: true
+
+ '@zag-js/accordion@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/anatomy@1.22.1': {}
+
+ '@zag-js/angle-slider@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/rect-utils': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/aria-hidden@1.22.1': {}
+
+ '@zag-js/async-list@1.22.1':
+ dependencies:
+ '@zag-js/core': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/auto-resize@1.22.1':
+ dependencies:
+ '@zag-js/dom-query': 1.22.1
+
+ '@zag-js/avatar@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/carousel@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/scroll-snap': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/checkbox@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/focus-visible': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/clipboard@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/collapsible@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/collection@1.22.1':
+ dependencies:
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/color-picker@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/color-utils': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/color-utils@1.22.1':
+ dependencies:
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/combobox@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/aria-hidden': 1.22.1
+ '@zag-js/collection': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/core@1.22.1':
+ dependencies:
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/date-picker@1.22.1(@internationalized/date@3.8.2)':
+ dependencies:
+ '@internationalized/date': 3.8.2
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/date-utils': 1.22.1(@internationalized/date@3.8.2)
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/live-region': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/date-utils@1.22.1(@internationalized/date@3.8.2)':
+ dependencies:
+ '@internationalized/date': 3.8.2
+
+ '@zag-js/dialog@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/aria-hidden': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/focus-trap': 1.22.1
+ '@zag-js/remove-scroll': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/dismissable@1.22.1':
+ dependencies:
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/interact-outside': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/dom-query@1.22.1':
+ dependencies:
+ '@zag-js/types': 1.22.1
+
+ '@zag-js/editable@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/interact-outside': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/file-upload@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/file-utils': 1.22.1
+ '@zag-js/i18n-utils': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/file-utils@1.22.1':
+ dependencies:
+ '@zag-js/i18n-utils': 1.22.1
+
+ '@zag-js/floating-panel@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/rect-utils': 1.22.1
+ '@zag-js/store': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/focus-trap@1.22.1':
+ dependencies:
+ '@zag-js/dom-query': 1.22.1
+
+ '@zag-js/focus-visible@1.22.1':
+ dependencies:
+ '@zag-js/dom-query': 1.22.1
+
+ '@zag-js/highlight-word@1.22.1': {}
+
+ '@zag-js/hover-card@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/i18n-utils@1.22.1':
+ dependencies:
+ '@zag-js/dom-query': 1.22.1
+
+ '@zag-js/interact-outside@1.22.1':
+ dependencies:
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/json-tree-utils@1.22.1': {}
+
+ '@zag-js/listbox@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/collection': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/focus-visible': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/live-region@1.22.1': {}
+
+ '@zag-js/menu@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/rect-utils': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/number-input@1.22.1':
+ dependencies:
+ '@internationalized/number': 3.6.4
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/pagination@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/password-input@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/pin-input@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/popover@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/aria-hidden': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/focus-trap': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/remove-scroll': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/popper@1.22.1':
+ dependencies:
+ '@floating-ui/dom': 1.7.4
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/presence@1.22.1':
+ dependencies:
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+
+ '@zag-js/progress@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/qr-code@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+ proxy-memoize: 3.0.1
+ uqr: 0.1.2
+
+ '@zag-js/radio-group@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/focus-visible': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/rating-group@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/react@1.22.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@zag-js/core': 1.22.1
+ '@zag-js/store': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+
+ '@zag-js/rect-utils@1.22.1': {}
+
+ '@zag-js/remove-scroll@1.22.1':
+ dependencies:
+ '@zag-js/dom-query': 1.22.1
+
+ '@zag-js/scroll-area@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/scroll-snap@1.22.1':
+ dependencies:
+ '@zag-js/dom-query': 1.22.1
+
+ '@zag-js/select@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/collection': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/signature-pad@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+ perfect-freehand: 1.2.2
+
+ '@zag-js/slider@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/splitter@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/steps@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/store@1.22.1':
+ dependencies:
+ proxy-compare: 3.0.1
+
+ '@zag-js/switch@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/focus-visible': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/tabs@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/tags-input@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/auto-resize': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/interact-outside': 1.22.1
+ '@zag-js/live-region': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/time-picker@1.22.1(@internationalized/date@3.8.2)':
+ dependencies:
+ '@internationalized/date': 3.8.2
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/timer@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/toast@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/toggle-group@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/toggle@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/tooltip@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/focus-visible': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/tour@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dismissable': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/focus-trap': 1.22.1
+ '@zag-js/interact-outside': 1.22.1
+ '@zag-js/popper': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/tree-view@1.22.1':
+ dependencies:
+ '@zag-js/anatomy': 1.22.1
+ '@zag-js/collection': 1.22.1
+ '@zag-js/core': 1.22.1
+ '@zag-js/dom-query': 1.22.1
+ '@zag-js/types': 1.22.1
+ '@zag-js/utils': 1.22.1
+
+ '@zag-js/types@1.22.1':
+ dependencies:
+ csstype: 3.1.3
+
+ '@zag-js/utils@1.22.1': {}
+
+ '@zenfs/core@2.4.0':
+ dependencies:
+ '@types/node': 24.3.1
+ buffer: 6.0.3
+ eventemitter3: 5.0.1
+ kerium: 1.3.6
+ memium: 0.3.8
+ readable-stream: 4.7.0
+ utilium: 2.5.4
+
+ '@zenfs/dom@1.2.4(@zenfs/core@2.4.0)(kerium@1.3.6)(utilium@2.5.4)':
+ dependencies:
+ '@zenfs/core': 2.4.0
+ kerium: 1.3.6
+ utilium: 2.5.4
+
+ abort-controller@3.0.0:
+ dependencies:
+ event-target-shim: 5.0.1
+
acorn-jsx@5.3.2(acorn@8.14.0):
dependencies:
acorn: 8.14.0
acorn@8.14.0: {}
+ agent-base@7.1.4: {}
+
ajv@6.12.6:
dependencies:
fast-deep-equal: 3.1.3
@@ -2485,12 +5034,29 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
+ ansi-regex@5.0.1: {}
+
+ ansi-regex@6.2.0: {}
+
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
+ ansi-styles@6.2.1: {}
+
+ any-promise@1.3.0: {}
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
argparse@2.0.1: {}
+ aria-hidden@1.2.6:
+ dependencies:
+ tslib: 2.8.1
+
array-buffer-byte-length@1.0.2:
dependencies:
call-bound: 1.0.3
@@ -2565,9 +5131,17 @@ snapshots:
dependencies:
possible-typed-array-names: 1.0.0
+ babel-plugin-macros@3.1.0:
+ dependencies:
+ '@babel/runtime': 7.26.10
+ cosmiconfig: 7.1.0
+ resolve: 1.22.10
+
balanced-match@1.0.2: {}
- bowser@2.11.0: {}
+ base64-js@1.5.1: {}
+
+ binary-extensions@2.3.0: {}
brace-expansion@1.1.11:
dependencies:
@@ -2582,6 +5156,16 @@ snapshots:
dependencies:
fill-range: 7.1.1
+ buffer@6.0.3:
+ dependencies:
+ base64-js: 1.5.1
+ ieee754: 1.2.1
+
+ bundle-n-require@1.1.2:
+ dependencies:
+ esbuild: 0.25.9
+ node-eval: 2.0.0
+
call-bind-apply-helpers@1.0.1:
dependencies:
es-errors: 1.3.0
@@ -2601,38 +5185,32 @@ snapshots:
callsites@3.1.0: {}
- camel-case@4.1.2:
- dependencies:
- pascal-case: 3.1.2
- tslib: 2.6.3
-
- capital-case@1.0.4:
- dependencies:
- no-case: 3.0.4
- tslib: 2.6.3
- upper-case-first: 2.0.2
+ camelize@1.0.1: {}
chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
supports-color: 7.2.0
- change-case@4.1.2:
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ chokidar@4.0.3:
dependencies:
- camel-case: 4.1.2
- capital-case: 1.0.4
- constant-case: 3.0.4
- dot-case: 3.0.4
- header-case: 2.0.4
- no-case: 3.0.4
- param-case: 3.0.4
- pascal-case: 3.1.2
- path-case: 3.0.4
- sentence-case: 3.0.4
- snake-case: 3.0.4
- tslib: 2.6.3
+ readdirp: 4.1.2
- classnames@2.5.1: {}
+ cli-table@0.3.11:
+ dependencies:
+ colors: 1.0.3
codec-parser@2.5.0: {}
@@ -2642,13 +5220,27 @@ snapshots:
color-name@1.1.4: {}
+ colors@1.0.3: {}
+
+ commander@12.1.0: {}
+
+ commander@4.1.1: {}
+
concat-map@0.0.1: {}
- constant-case@3.0.4:
+ convert-source-map@1.9.0: {}
+
+ cookie-es@1.2.2: {}
+
+ core-util-is@1.0.3: {}
+
+ cosmiconfig@7.1.0:
dependencies:
- no-case: 3.0.4
- tslib: 2.6.3
- upper-case: 2.0.2
+ '@types/parse-json': 4.0.2
+ import-fresh: 3.3.0
+ parse-json: 5.2.0
+ path-type: 4.0.0
+ yaml: 1.10.2
cross-fetch@4.0.0:
dependencies:
@@ -2662,8 +5254,22 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
+ crossws@0.3.5:
+ dependencies:
+ uncrypto: 0.1.3
+
+ css-color-keywords@1.0.0: {}
+
+ css-to-react-native@3.2.0:
+ dependencies:
+ camelize: 1.0.1
+ css-color-keywords: 1.0.0
+ postcss-value-parser: 4.2.0
+
csstype@3.1.3: {}
+ data-uri-to-buffer@4.0.1: {}
+
data-view-buffer@1.0.2:
dependencies:
call-bound: 1.0.3
@@ -2686,6 +5292,10 @@ snapshots:
dependencies:
ms: 2.1.3
+ debug@4.4.1:
+ dependencies:
+ ms: 2.1.3
+
deep-is@0.1.4: {}
define-data-property@1.1.4:
@@ -2700,21 +5310,22 @@ snapshots:
has-property-descriptors: 1.0.2
object-keys: 1.1.1
- doctrine@2.1.0:
- dependencies:
- esutils: 2.0.3
+ defu@6.1.4: {}
+
+ destr@2.0.5: {}
- dom-align@1.12.4: {}
+ detect-node-es@1.1.0: {}
- dom-helpers@5.2.1:
+ dockview-core@4.7.1: {}
+
+ dockview@4.7.1(react@19.0.0):
dependencies:
- '@babel/runtime': 7.26.0
- csstype: 3.1.3
+ dockview-core: 4.7.1
+ react: 19.0.0
- dot-case@3.0.4:
+ doctrine@2.1.0:
dependencies:
- no-case: 3.0.4
- tslib: 2.6.3
+ esutils: 2.0.3
dunder-proto@1.0.1:
dependencies:
@@ -2724,6 +5335,16 @@ snapshots:
earcut@2.2.4: {}
+ eastasianwidth@0.2.0: {}
+
+ emoji-regex@8.0.0: {}
+
+ emoji-regex@9.2.2: {}
+
+ error-ex@1.3.2:
+ dependencies:
+ is-arrayish: 0.2.1
+
es-abstract@1.23.9:
dependencies:
array-buffer-byte-length: 1.0.2
@@ -2850,6 +5471,35 @@ snapshots:
'@esbuild/win32-ia32': 0.24.2
'@esbuild/win32-x64': 0.24.2
+ esbuild@0.25.9:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.25.9
+ '@esbuild/android-arm': 0.25.9
+ '@esbuild/android-arm64': 0.25.9
+ '@esbuild/android-x64': 0.25.9
+ '@esbuild/darwin-arm64': 0.25.9
+ '@esbuild/darwin-x64': 0.25.9
+ '@esbuild/freebsd-arm64': 0.25.9
+ '@esbuild/freebsd-x64': 0.25.9
+ '@esbuild/linux-arm': 0.25.9
+ '@esbuild/linux-arm64': 0.25.9
+ '@esbuild/linux-ia32': 0.25.9
+ '@esbuild/linux-loong64': 0.25.9
+ '@esbuild/linux-mips64el': 0.25.9
+ '@esbuild/linux-ppc64': 0.25.9
+ '@esbuild/linux-riscv64': 0.25.9
+ '@esbuild/linux-s390x': 0.25.9
+ '@esbuild/linux-x64': 0.25.9
+ '@esbuild/netbsd-arm64': 0.25.9
+ '@esbuild/netbsd-x64': 0.25.9
+ '@esbuild/openbsd-arm64': 0.25.9
+ '@esbuild/openbsd-x64': 0.25.9
+ '@esbuild/openharmony-arm64': 0.25.9
+ '@esbuild/sunos-x64': 0.25.9
+ '@esbuild/win32-arm64': 0.25.9
+ '@esbuild/win32-ia32': 0.25.9
+ '@esbuild/win32-x64': 0.25.9
+
escape-string-regexp@4.0.0: {}
eslint-plugin-react-hooks@5.1.0(eslint@9.17.0):
@@ -2948,8 +5598,12 @@ snapshots:
esutils@2.0.3: {}
+ event-target-shim@5.0.1: {}
+
eventemitter3@5.0.1: {}
+ events@3.3.0: {}
+
fast-deep-equal@3.1.3: {}
fast-glob@3.3.2:
@@ -2960,14 +5614,29 @@ snapshots:
merge2: 1.4.1
micromatch: 4.0.8
+ fast-glob@3.3.3:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
fast-json-stable-stringify@2.1.0: {}
fast-levenshtein@2.0.6: {}
+ fast-safe-stringify@2.1.1: {}
+
fastq@1.18.0:
dependencies:
reusify: 1.0.4
+ fetch-blob@3.2.0:
+ dependencies:
+ node-domexception: 1.0.0
+ web-streams-polyfill: 3.3.3
+
file-entry-cache@8.0.0:
dependencies:
flat-cache: 4.0.1
@@ -2976,6 +5645,8 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
+ find-root@1.1.0: {}
+
find-up@5.0.0:
dependencies:
locate-path: 6.0.0
@@ -2992,6 +5663,15 @@ snapshots:
dependencies:
is-callable: 1.2.7
+ foreground-child@3.3.1:
+ dependencies:
+ cross-spawn: 7.0.6
+ signal-exit: 4.1.0
+
+ formdata-polyfill@4.0.10:
+ dependencies:
+ fetch-blob: 3.2.0
+
fsevents@2.3.3:
optional: true
@@ -3021,6 +5701,8 @@ snapshots:
hasown: 2.0.2
math-intrinsics: 1.1.0
+ get-nonce@1.0.1: {}
+
get-proto@1.0.1:
dependencies:
dunder-proto: 1.0.1
@@ -3040,6 +5722,15 @@ snapshots:
dependencies:
is-glob: 4.0.3
+ glob@10.4.5:
+ dependencies:
+ foreground-child: 3.3.1
+ jackspeak: 3.4.3
+ minimatch: 9.0.5
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 1.11.1
+
globals@14.0.0: {}
globals@15.14.0: {}
@@ -3049,10 +5740,31 @@ snapshots:
define-properties: 1.2.1
gopd: 1.2.0
+ globby@14.1.0:
+ dependencies:
+ '@sindresorhus/merge-streams': 2.3.0
+ fast-glob: 3.3.3
+ ignore: 7.0.5
+ path-type: 6.0.0
+ slash: 5.1.0
+ unicorn-magic: 0.3.0
+
gopd@1.2.0: {}
graphemer@1.4.0: {}
+ h3@1.15.4:
+ dependencies:
+ cookie-es: 1.2.2
+ crossws: 0.3.5
+ defu: 6.1.4
+ destr: 2.0.5
+ iron-webcrypto: 1.2.1
+ node-mock-http: 1.0.3
+ radix3: 1.1.2
+ ufo: 1.6.1
+ uncrypto: 0.1.3
+
has-bigints@1.1.0: {}
has-flag@4.0.0: {}
@@ -3075,17 +5787,21 @@ snapshots:
dependencies:
function-bind: 1.1.2
- header-case@2.0.4:
+ hoist-non-react-statics@3.3.2:
dependencies:
- capital-case: 1.0.4
- tslib: 2.6.3
-
- hotkeys-js@3.13.9: {}
+ react-is: 16.13.1
html-parse-stringify@3.0.1:
dependencies:
void-elements: 3.1.0
+ https-proxy-agent@7.0.6:
+ dependencies:
+ agent-base: 7.1.4
+ debug: 4.4.1
+ transitivePeerDependencies:
+ - supports-color
+
i18next-browser-languagedetector@8.0.4:
dependencies:
'@babel/runtime': 7.26.0
@@ -3110,8 +5826,16 @@ snapshots:
optionalDependencies:
typescript: 5.6.3
+ idb-keyval@6.2.2: {}
+
+ ieee754@1.2.1: {}
+
ignore@5.3.2: {}
+ ignore@7.0.5: {}
+
+ immediate@3.0.6: {}
+
import-fresh@3.3.0:
dependencies:
parent-module: 1.0.1
@@ -3119,18 +5843,24 @@ snapshots:
imurmurhash@0.1.4: {}
+ inherits@2.0.4: {}
+
internal-slot@1.1.0:
dependencies:
es-errors: 1.3.0
hasown: 2.0.2
side-channel: 1.1.0
+ iron-webcrypto@1.2.1: {}
+
is-array-buffer@3.0.5:
dependencies:
call-bind: 1.0.8
call-bound: 1.0.3
get-intrinsic: 1.2.7
+ is-arrayish@0.2.1: {}
+
is-async-function@2.1.0:
dependencies:
call-bound: 1.0.3
@@ -3142,6 +5872,10 @@ snapshots:
dependencies:
has-bigints: 1.1.0
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
is-boolean-object@1.2.1:
dependencies:
call-bound: 1.0.3
@@ -3170,6 +5904,8 @@ snapshots:
dependencies:
call-bound: 1.0.3
+ is-fullwidth-code-point@3.0.0: {}
+
is-generator-function@1.1.0:
dependencies:
call-bound: 1.0.3
@@ -3229,6 +5965,8 @@ snapshots:
call-bound: 1.0.3
get-intrinsic: 1.2.7
+ isarray@1.0.0: {}
+
isarray@2.0.5: {}
isexe@2.0.0: {}
@@ -3251,14 +5989,24 @@ snapshots:
transitivePeerDependencies:
- '@types/react'
+ jackspeak@3.4.3:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
js-tokens@4.0.0: {}
js-yaml@4.1.0:
dependencies:
argparse: 2.0.1
+ jsesc@3.1.0: {}
+
json-buffer@3.0.1: {}
+ json-parse-even-better-errors@2.3.1: {}
+
json-schema-traverse@0.4.1: {}
json-stable-stringify-without-jsonify@1.0.1: {}
@@ -3270,6 +6018,17 @@ snapshots:
object.assign: 4.1.7
object.values: 1.2.1
+ jszip@3.10.1:
+ dependencies:
+ lie: 3.3.0
+ pako: 1.0.11
+ readable-stream: 2.3.8
+ setimmediate: 1.0.5
+
+ kerium@1.3.6:
+ dependencies:
+ utilium: 2.5.4
+
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@@ -3279,24 +6038,33 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
+ lie@3.3.0:
+ dependencies:
+ immediate: 3.0.6
+
+ lines-and-columns@1.2.4: {}
+
locate-path@6.0.0:
dependencies:
p-locate: 5.0.0
lodash.merge@4.6.2: {}
- lodash@4.17.21: {}
+ look-it-up@2.1.0: {}
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
- lower-case@2.0.2:
- dependencies:
- tslib: 2.6.3
+ lru-cache@10.4.3: {}
math-intrinsics@1.1.0: {}
+ memium@0.3.8:
+ dependencies:
+ kerium: 1.3.6
+ utilium: 2.5.4
+
merge2@1.4.1: {}
micromatch@4.0.8:
@@ -3312,27 +6080,72 @@ snapshots:
dependencies:
brace-expansion: 2.0.1
+ minipass@7.1.2: {}
+
+ mobx-react-lite@4.1.0(mobx@6.13.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
+ dependencies:
+ mobx: 6.13.7
+ react: 19.0.0
+ use-sync-external-store: 1.4.0(react@19.0.0)
+ optionalDependencies:
+ react-dom: 19.0.0(react@19.0.0)
+
+ mobx-state-tree@7.0.2(mobx@6.13.7)(typescript@5.6.3):
+ dependencies:
+ mobx: 6.13.7
+ ts-essentials: 9.4.2(typescript@5.6.3)
+ transitivePeerDependencies:
+ - typescript
+
+ mobx@6.13.7: {}
+
mpg123-decoder@1.0.0:
dependencies:
'@wasm-audio-decoders/common': 9.0.5
ms@2.1.3: {}
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
nanoid@3.3.8: {}
+ nanoid@5.1.5: {}
+
natural-compare@1.4.0: {}
- no-case@3.0.4:
+ next-themes@0.4.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
- lower-case: 2.0.2
- tslib: 2.6.3
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+
+ node-domexception@1.0.0: {}
+
+ node-eval@2.0.0:
+ dependencies:
+ path-is-absolute: 1.0.1
+
+ node-fetch-native@1.6.7: {}
node-fetch@2.7.0:
dependencies:
whatwg-url: 5.0.0
+ node-fetch@3.3.2:
+ dependencies:
+ data-uri-to-buffer: 4.0.1
+ fetch-blob: 3.2.0
+ formdata-polyfill: 4.0.10
+
+ node-mock-http@1.0.3: {}
+
node-wav@0.0.2: {}
+ normalize-path@3.0.0: {}
+
normalize.css@8.0.1: {}
object-assign@4.1.1: {}
@@ -3370,6 +6183,12 @@ snapshots:
define-properties: 1.2.1
es-object-atoms: 1.0.0
+ ofetch@1.4.1:
+ dependencies:
+ destr: 2.0.5
+ node-fetch-native: 1.6.7
+ ufo: 1.6.1
+
ogg-opus-decoder@1.6.14:
dependencies:
'@wasm-audio-decoders/common': 9.0.5
@@ -3403,37 +6222,50 @@ snapshots:
dependencies:
p-limit: 3.1.0
- param-case@3.0.4:
- dependencies:
- dot-case: 3.0.4
- tslib: 2.6.3
+ package-json-from-dist@1.0.1: {}
+
+ package-manager-detector@1.3.0: {}
+
+ pako@1.0.11: {}
parent-module@1.0.1:
dependencies:
callsites: 3.1.0
- parse-svg-path@0.1.2: {}
-
- pascal-case@3.1.2:
+ parse-json@5.2.0:
dependencies:
- no-case: 3.0.4
- tslib: 2.6.3
+ '@babel/code-frame': 7.27.1
+ error-ex: 1.3.2
+ json-parse-even-better-errors: 2.3.1
+ lines-and-columns: 1.2.4
- path-case@3.0.4:
- dependencies:
- dot-case: 3.0.4
- tslib: 2.6.3
+ parse-svg-path@0.1.2: {}
path-exists@4.0.0: {}
+ path-is-absolute@1.0.1: {}
+
path-key@3.1.1: {}
path-parse@1.0.7: {}
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.4.3
+ minipass: 7.1.2
+
+ path-type@4.0.0: {}
+
+ path-type@6.0.0: {}
+
+ perfect-freehand@1.2.2: {}
+
picocolors@1.1.1: {}
picomatch@2.3.1: {}
+ pirates@4.0.7: {}
+
pixi.js@8.6.6:
dependencies:
'@pixi/colord': 2.9.6
@@ -3448,6 +6280,14 @@ snapshots:
possible-typed-array-names@1.0.0: {}
+ postcss-value-parser@4.2.0: {}
+
+ postcss@8.4.49:
+ dependencies:
+ nanoid: 3.3.8
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
postcss@8.5.2:
dependencies:
nanoid: 3.3.8
@@ -3456,12 +6296,24 @@ snapshots:
prelude-ls@1.2.1: {}
+ prettier@3.6.2: {}
+
+ process-nextick-args@2.0.1: {}
+
+ process@0.11.10: {}
+
prop-types@15.8.1:
dependencies:
loose-envify: 1.4.0
object-assign: 4.1.1
react-is: 16.13.1
+ proxy-compare@3.0.1: {}
+
+ proxy-memoize@3.0.1:
+ dependencies:
+ proxy-compare: 3.0.1
+
punycode@2.3.1: {}
qoa-format@1.0.1:
@@ -3470,129 +6322,15 @@ snapshots:
queue-microtask@1.2.3: {}
- rc-align@4.0.15(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- classnames: 2.5.1
- dom-align: 1.12.4
- rc-util: 5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
- resize-observer-polyfill: 1.5.1
-
- rc-dock@3.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- classnames: 2.5.1
- lodash: 4.17.21
- rc-dropdown: 4.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-menu: 9.8.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-new-window: 0.1.13(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-tabs: 11.16.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
-
- rc-dropdown@4.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- classnames: 2.5.1
- rc-trigger: 5.3.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-util: 5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
-
- rc-menu@9.6.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- classnames: 2.5.1
- rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-overflow: 1.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-trigger: 5.3.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-util: 5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
- shallowequal: 1.1.0
-
- rc-menu@9.8.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- classnames: 2.5.1
- rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-overflow: 1.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-trigger: 5.3.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-util: 5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
-
- rc-motion@2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- classnames: 2.5.1
- rc-util: 5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
-
- rc-new-window@0.1.13(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- bowser: 2.11.0
- classnames: 2.5.1
- lodash: 4.17.21
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
-
- rc-overflow@1.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- classnames: 2.5.1
- rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-util: 5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
-
- rc-resize-observer@1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- classnames: 2.5.1
- rc-util: 5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
- resize-observer-polyfill: 1.5.1
-
- rc-tabs@11.16.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- classnames: 2.5.1
- rc-dropdown: 4.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-menu: 9.6.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-util: 5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
-
- rc-trigger@5.3.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- classnames: 2.5.1
- rc-align: 4.0.15(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- rc-util: 5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
+ quick-lru@7.1.0: {}
- rc-util@5.44.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
- react-is: 18.3.1
+ radix3@1.1.2: {}
react-dom@19.0.0(react@19.0.0):
dependencies:
react: 19.0.0
scheduler: 0.25.0
- react-fast-compare@3.2.2: {}
-
react-i18next@15.4.1(i18next@24.2.3(typescript@5.6.3))(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@babel/runtime': 7.26.0
@@ -3602,24 +6340,37 @@ snapshots:
optionalDependencies:
react-dom: 19.0.0(react@19.0.0)
- react-is@16.13.1: {}
+ react-icons@5.5.0(react@19.0.0):
+ dependencies:
+ react: 19.0.0
- react-is@18.3.1: {}
+ react-is@16.13.1: {}
react-lifecycles-compat@3.0.4: {}
- react-popper@2.3.0(@popperjs/core@2.11.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
+ react-reconciler@0.31.0(react@19.0.0):
dependencies:
- '@popperjs/core': 2.11.8
react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
- react-fast-compare: 3.2.2
- warning: 4.0.3
+ scheduler: 0.25.0
- react-reconciler@0.31.0(react@19.0.0):
+ react-remove-scroll-bar@2.3.8(@types/react@19.0.7)(react@19.0.0):
dependencies:
react: 19.0.0
- scheduler: 0.25.0
+ react-style-singleton: 2.2.3(@types/react@19.0.7)(react@19.0.0)
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ react-remove-scroll@2.7.1(@types/react@19.0.7)(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ react-remove-scroll-bar: 2.3.8(@types/react@19.0.7)(react@19.0.0)
+ react-style-singleton: 2.2.3(@types/react@19.0.7)(react@19.0.0)
+ tslib: 2.8.1
+ use-callback-ref: 1.3.3(@types/react@19.0.7)(react@19.0.0)
+ use-sidecar: 1.1.3(@types/react@19.0.7)(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
react-split-pane@0.1.92(patch_hash=15b3bc41b3c9ea6e7a5c245069978ef071c4655082c4e9b0e14eb5d4eb57da5c)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
@@ -3633,24 +6384,40 @@ snapshots:
dependencies:
prop-types: 15.8.1
- react-transition-group@4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
- dependencies:
- '@babel/runtime': 7.26.0
- dom-helpers: 5.2.1
- loose-envify: 1.4.0
- prop-types: 15.8.1
- react: 19.0.0
- react-dom: 19.0.0(react@19.0.0)
-
- react-uid@2.4.0(@types/react@19.0.7)(react@19.0.0):
+ react-style-singleton@2.2.3(@types/react@19.0.7)(react@19.0.0):
dependencies:
+ get-nonce: 1.0.1
react: 19.0.0
- tslib: 2.6.3
+ tslib: 2.8.1
optionalDependencies:
'@types/react': 19.0.7
react@19.0.0: {}
+ readable-stream@2.3.8:
+ dependencies:
+ core-util-is: 1.0.3
+ inherits: 2.0.4
+ isarray: 1.0.0
+ process-nextick-args: 2.0.1
+ safe-buffer: 5.1.2
+ string_decoder: 1.1.1
+ util-deprecate: 1.0.2
+
+ readable-stream@4.7.0:
+ dependencies:
+ abort-controller: 3.0.0
+ buffer: 6.0.3
+ events: 3.3.0
+ process: 0.11.10
+ string_decoder: 1.3.0
+
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.1
+
+ readdirp@4.1.2: {}
+
reflect.getprototypeof@1.0.10:
dependencies:
call-bind: 1.0.8
@@ -3673,10 +6440,14 @@ snapshots:
gopd: 1.2.0
set-function-name: 2.0.2
- resize-observer-polyfill@1.5.1: {}
-
resolve-from@4.0.0: {}
+ resolve@1.22.10:
+ dependencies:
+ is-core-module: 2.16.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
resolve@2.0.0-next.5:
dependencies:
is-core-module: 2.16.1
@@ -3722,6 +6493,10 @@ snapshots:
has-symbols: 1.1.0
isarray: 2.0.5
+ safe-buffer@5.1.2: {}
+
+ safe-buffer@5.2.1: {}
+
safe-push-apply@1.0.0:
dependencies:
es-errors: 1.3.0
@@ -3735,16 +6510,12 @@ snapshots:
scheduler@0.25.0: {}
+ scule@1.3.0: {}
+
semver@6.3.1: {}
semver@7.6.3: {}
- sentence-case@3.0.4:
- dependencies:
- no-case: 3.0.4
- tslib: 2.6.3
- upper-case-first: 2.0.2
-
set-function-length@1.2.2:
dependencies:
define-data-property: 1.1.4
@@ -3767,6 +6538,8 @@ snapshots:
es-errors: 1.3.0
es-object-atoms: 1.0.0
+ setimmediate@1.0.5: {}
+
shallowequal@1.1.0: {}
shebang-command@2.0.0:
@@ -3803,16 +6576,29 @@ snapshots:
side-channel-map: 1.0.1
side-channel-weakmap: 1.0.2
+ signal-exit@4.1.0: {}
+
simple-yenc@1.0.4: {}
- snake-case@3.0.4:
- dependencies:
- dot-case: 3.0.4
- tslib: 2.6.3
+ sisteransi@1.0.5: {}
+
+ slash@5.1.0: {}
source-map-js@1.2.1: {}
- spark-md5@3.0.2: {}
+ source-map@0.5.7: {}
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
string.prototype.matchall@4.0.12:
dependencies:
@@ -3858,14 +6644,66 @@ snapshots:
define-properties: 1.2.1
es-object-atoms: 1.0.0
+ string_decoder@1.1.1:
+ dependencies:
+ safe-buffer: 5.1.2
+
+ string_decoder@1.3.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.2.0
+
strip-json-comments@3.1.1: {}
+ styled-components@6.1.19(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
+ dependencies:
+ '@emotion/is-prop-valid': 1.2.2
+ '@emotion/unitless': 0.8.1
+ '@types/stylis': 4.2.5
+ css-to-react-native: 3.2.0
+ csstype: 3.1.3
+ postcss: 8.4.49
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ shallowequal: 1.1.0
+ stylis: 4.3.2
+ tslib: 2.6.2
+
+ stylis@4.2.0: {}
+
+ stylis@4.3.2: {}
+
+ sucrase@3.35.0:
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ commander: 4.1.1
+ glob: 10.4.5
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.7
+ ts-interface-checker: 0.1.13
+
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0
supports-preserve-symlinks-flag@1.0.0: {}
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
@@ -3876,7 +6714,15 @@ snapshots:
dependencies:
typescript: 5.6.3
- tslib@2.6.3: {}
+ ts-essentials@9.4.2(typescript@5.6.3):
+ optionalDependencies:
+ typescript: 5.6.3
+
+ ts-interface-checker@0.1.13: {}
+
+ tslib@2.6.2: {}
+
+ tslib@2.8.1: {}
type-check@0.4.0:
dependencies:
@@ -3927,6 +6773,8 @@ snapshots:
typescript@5.6.3: {}
+ ufo@1.6.1: {}
+
unbox-primitive@1.1.0:
dependencies:
call-bound: 1.0.3
@@ -3934,25 +6782,59 @@ snapshots:
has-symbols: 1.1.0
which-boxed-primitive: 1.1.1
+ uncrypto@0.1.3: {}
+
undici-types@6.20.0: {}
- upper-case-first@2.0.2:
- dependencies:
- tslib: 2.6.3
+ undici-types@7.10.0: {}
+
+ unicorn-magic@0.3.0: {}
- upper-case@2.0.2:
+ unstorage@1.17.1(idb-keyval@6.2.2):
dependencies:
- tslib: 2.6.3
+ anymatch: 3.1.3
+ chokidar: 4.0.3
+ destr: 2.0.5
+ h3: 1.15.4
+ lru-cache: 10.4.3
+ node-fetch-native: 1.6.7
+ ofetch: 1.4.1
+ ufo: 1.6.1
+ optionalDependencies:
+ idb-keyval: 6.2.2
+
+ uqr@0.1.2: {}
uri-js@4.4.1:
dependencies:
punycode: 2.3.1
+ use-callback-ref@1.3.3(@types/react@19.0.7)(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.0.7
+
+ use-sidecar@1.1.3(@types/react@19.0.7)(react@19.0.0):
+ dependencies:
+ detect-node-es: 1.1.0
+ react: 19.0.0
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.0.7
+
use-sync-external-store@1.4.0(react@19.0.0):
dependencies:
react: 19.0.0
- uuid@11.0.4: {}
+ util-deprecate@1.0.2: {}
+
+ utilium@2.5.4:
+ dependencies:
+ eventemitter3: 5.0.1
+ optionalDependencies:
+ '@xterm/xterm': 5.5.0
vite@6.0.9(@types/node@22.10.5):
dependencies:
@@ -3965,9 +6847,7 @@ snapshots:
void-elements@3.1.0: {}
- warning@4.0.3:
- dependencies:
- loose-envify: 1.4.0
+ web-streams-polyfill@3.3.3: {}
webidl-conversions@3.0.1: {}
@@ -4022,4 +6902,26 @@ snapshots:
word-wrap@1.2.5: {}
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
+
+ yaml@1.10.2: {}
+
yocto-queue@0.1.0: {}
+
+ zod@3.25.76: {}
+
+ zustand@5.0.8(@types/react@19.0.7)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)):
+ optionalDependencies:
+ '@types/react': 19.0.7
+ react: 19.0.0
+ use-sync-external-store: 1.4.0(react@19.0.0)
diff --git a/public/icon-black.svg b/public/icon-black.svg
new file mode 100644
index 0000000..0fca27f
--- /dev/null
+++ b/public/icon-black.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/public/icon.svg b/public/icon.svg
new file mode 100644
index 0000000..42912fe
--- /dev/null
+++ b/public/icon.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/public/logo.png b/public/logo.png
new file mode 100644
index 0000000..f71d353
Binary files /dev/null and b/public/logo.png differ
diff --git a/public/skin-default.zip b/public/skin-default.zip
new file mode 100644
index 0000000..d05fee0
Binary files /dev/null and b/public/skin-default.zip differ
diff --git a/public/skin/note-drag-highlight.png b/public/skin/note-drag-highlight.png
deleted file mode 100644
index 7b5772c..0000000
Binary files a/public/skin/note-drag-highlight.png and /dev/null differ
diff --git a/public/skin/note-drag.png b/public/skin/note-drag.png
deleted file mode 100644
index ffa0e06..0000000
Binary files a/public/skin/note-drag.png and /dev/null differ
diff --git a/public/skin/note-flick-highlight.png b/public/skin/note-flick-highlight.png
deleted file mode 100644
index 9786993..0000000
Binary files a/public/skin/note-flick-highlight.png and /dev/null differ
diff --git a/public/skin/note-flick.png b/public/skin/note-flick.png
deleted file mode 100644
index 323a3ba..0000000
Binary files a/public/skin/note-flick.png and /dev/null differ
diff --git a/public/skin/note-hold-body-highlight.png b/public/skin/note-hold-body-highlight.png
deleted file mode 100644
index fee0d9d..0000000
Binary files a/public/skin/note-hold-body-highlight.png and /dev/null differ
diff --git a/public/skin/note-hold-body.png b/public/skin/note-hold-body.png
deleted file mode 100644
index a39dcb3..0000000
Binary files a/public/skin/note-hold-body.png and /dev/null differ
diff --git a/public/skin/note-hold-end.png b/public/skin/note-hold-end.png
deleted file mode 100644
index d947aba..0000000
Binary files a/public/skin/note-hold-end.png and /dev/null differ
diff --git a/public/skin/note-hold-head-highlight.png b/public/skin/note-hold-head-highlight.png
deleted file mode 100644
index 3210e6c..0000000
Binary files a/public/skin/note-hold-head-highlight.png and /dev/null differ
diff --git a/public/skin/note-hold-head.png b/public/skin/note-hold-head.png
deleted file mode 100644
index 84d4e07..0000000
Binary files a/public/skin/note-hold-head.png and /dev/null differ
diff --git a/public/skin/note-tap-highlight.png b/public/skin/note-tap-highlight.png
deleted file mode 100644
index ee94efb..0000000
Binary files a/public/skin/note-tap-highlight.png and /dev/null differ
diff --git a/public/skin/note-tap.png b/public/skin/note-tap.png
deleted file mode 100644
index 74ce0b2..0000000
Binary files a/public/skin/note-tap.png and /dev/null differ
diff --git a/public/skin/skin-bundle.json b/public/skin/skin-bundle.json
deleted file mode 100644
index c29e4f8..0000000
--- a/public/skin/skin-bundle.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "skin-default",
- "assets": [
- {
- "alias": "note-tap",
- "src": "skin/note-tap.png"
- },
- {
- "alias": "note-tap-highlight",
- "src": "skin/note-tap-highlight.png"
- },
- {
- "alias": "note-drag",
- "src": "skin/note-drag.png"
- },
- {
- "alias": "note-drag-highlight",
- "src": "skin/note-drag-highlight.png"
- },
- {
- "alias": "note-hold-head",
- "src": "skin/note-hold-head.png"
- },
- {
- "alias": "note-hold-head-highlight",
- "src": "skin/note-hold-head-highlight.png"
- },
- {
- "alias": "note-hold-body",
- "src": "skin/note-hold-body.png"
- },
- {
- "alias": "note-hold-body-highlight",
- "src": "skin/note-hold-body-highlight.png"
- },
- {
- "alias": "note-hold-end",
- "src": "skin/note-hold-end.png"
- },
- {
- "alias": "note-flick",
- "src": "skin/note-flick.png"
- },
- {
- "alias": "note-flick-highlight",
- "src": "skin/note-flick-highlight.png"
- }
- ]
-}
\ No newline at end of file
diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index 8c67e03..b04a15c 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -52,6 +52,12 @@ dependencies = [
"alloc-no-stdlib",
]
+[[package]]
+name = "allocator-api2"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
+
[[package]]
name = "android-tzdata"
version = "0.1.1"
@@ -119,6 +125,15 @@ dependencies = [
"system-deps",
]
+[[package]]
+name = "atoi"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
+dependencies = [
+ "num-traits",
+]
+
[[package]]
name = "autocfg"
version = "1.4.0"
@@ -152,6 +167,12 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+[[package]]
+name = "base64ct"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
+
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -179,12 +200,6 @@ dependencies = [
"wyz",
]
-[[package]]
-name = "block"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
-
[[package]]
name = "block-buffer"
version = "0.10.4"
@@ -200,7 +215,16 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
dependencies = [
- "objc2",
+ "objc2 0.5.2",
+]
+
+[[package]]
+name = "block2"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2"
+dependencies = [
+ "objc2 0.6.2",
]
[[package]]
@@ -228,9 +252,9 @@ dependencies = [
[[package]]
name = "brotli"
-version = "7.0.0"
+version = "8.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd"
+checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
@@ -239,9 +263,9 @@ dependencies = [
[[package]]
name = "brotli-decompressor"
-version = "4.0.2"
+version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37"
+checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
@@ -366,12 +390,12 @@ dependencies = [
[[package]]
name = "cargo_toml"
-version = "0.21.0"
+version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fbd1fe9db3ebf71b89060adaf7b0504c2d6a425cf061313099547e382c2e472"
+checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77"
dependencies = [
"serde",
- "toml 0.8.20",
+ "toml 0.9.5",
]
[[package]]
@@ -436,44 +460,29 @@ dependencies = [
]
[[package]]
-name = "cocoa"
-version = "0.26.0"
+name = "combine"
+version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f79398230a6e2c08f5c9760610eb6924b52aa9e7950a619602baba59dcbbdbb2"
+checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
dependencies = [
- "bitflags 2.8.0",
- "block",
- "cocoa-foundation",
- "core-foundation",
- "core-graphics",
- "foreign-types",
- "libc",
- "objc",
+ "bytes",
+ "memchr",
]
[[package]]
-name = "cocoa-foundation"
-version = "0.2.0"
+name = "concurrent-queue"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e14045fb83be07b5acf1c0884b2180461635b433455fa35d1cd6f17f1450679d"
+checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
- "bitflags 2.8.0",
- "block",
- "core-foundation",
- "core-graphics-types",
- "libc",
- "objc",
+ "crossbeam-utils",
]
[[package]]
-name = "combine"
-version = "4.6.7"
+name = "const-oid"
+version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
-dependencies = [
- "bytes",
- "memchr",
-]
+checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "convert_case"
@@ -540,6 +549,21 @@ dependencies = [
"libc",
]
+[[package]]
+name = "crc"
+version = "3.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
+
[[package]]
name = "crc32fast"
version = "1.4.2"
@@ -558,6 +582,15 @@ dependencies = [
"crossbeam-utils",
]
+[[package]]
+name = "crossbeam-queue"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
+dependencies = [
+ "crossbeam-utils",
+]
+
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
@@ -576,15 +609,15 @@ dependencies = [
[[package]]
name = "cssparser"
-version = "0.27.2"
+version = "0.29.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a"
+checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa"
dependencies = [
"cssparser-macros",
"dtoa-short",
- "itoa 0.4.8",
+ "itoa",
"matches",
- "phf 0.8.0",
+ "phf 0.10.1",
"proc-macro2",
"quote",
"smallvec",
@@ -646,6 +679,17 @@ dependencies = [
"syn 2.0.98",
]
+[[package]]
+name = "der"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
+dependencies = [
+ "const-oid",
+ "pem-rfc7468",
+ "zeroize",
+]
+
[[package]]
name = "deranged"
version = "0.3.11"
@@ -676,16 +720,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
+ "const-oid",
"crypto-common",
-]
-
-[[package]]
-name = "dirs"
-version = "5.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
-dependencies = [
- "dirs-sys 0.4.1",
+ "subtle",
]
[[package]]
@@ -694,19 +731,7 @@ version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
dependencies = [
- "dirs-sys 0.5.0",
-]
-
-[[package]]
-name = "dirs-sys"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
-dependencies = [
- "libc",
- "option-ext",
- "redox_users 0.4.6",
- "windows-sys 0.48.0",
+ "dirs-sys",
]
[[package]]
@@ -717,8 +742,8 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
- "redox_users 0.5.0",
- "windows-sys 0.59.0",
+ "redox_users",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -727,6 +752,16 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
+[[package]]
+name = "dispatch2"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
+dependencies = [
+ "bitflags 2.8.0",
+ "objc2 0.6.2",
+]
+
[[package]]
name = "displaydoc"
version = "0.2.5"
@@ -740,9 +775,9 @@ dependencies = [
[[package]]
name = "dlopen2"
-version = "0.7.0"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e1297103d2bbaea85724fcee6294c2d50b1081f9ad47d0f6f6f61eda65315a6"
+checksum = "b54f373ccf864bf587a89e880fb7610f8d73f3045f13580948ccbcaff26febff"
dependencies = [
"dlopen2_derive",
"libc",
@@ -761,6 +796,12 @@ dependencies = [
"syn 2.0.98",
]
+[[package]]
+name = "dotenvy"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
+
[[package]]
name = "dpi"
version = "0.1.1"
@@ -797,16 +838,25 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "feeef44e73baff3a26d371801df019877a9866a8c493d315ab00177843314f35"
+[[package]]
+name = "either"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "embed-resource"
-version = "2.5.1"
+version = "3.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b68b6f9f63a0b6a38bc447d4ce84e2b388f3ec95c99c641c8ff0dd3ef89a6379"
+checksum = "4c6d81016d6c977deefb2ef8d8290da019e27cc26167e102185da528e6c0ab38"
dependencies = [
"cc",
"memchr",
"rustc_version",
- "toml 0.8.20",
+ "toml 0.9.5",
"vswhom",
"winreg",
]
@@ -843,6 +893,28 @@ dependencies = [
"typeid",
]
+[[package]]
+name = "etcetera"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
+dependencies = [
+ "cfg-if",
+ "home",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "event-listener"
+version = "5.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
+dependencies = [
+ "concurrent-queue",
+ "parking",
+ "pin-project-lite",
+]
+
[[package]]
name = "fdeflate"
version = "0.3.7"
@@ -881,12 +953,29 @@ dependencies = [
"miniz_oxide",
]
+[[package]]
+name = "flume"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+ "spin",
+]
+
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+[[package]]
+name = "foldhash"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
+
[[package]]
name = "foreign-types"
version = "0.5.0"
@@ -946,6 +1035,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
+ "futures-sink",
]
[[package]]
@@ -965,6 +1055,17 @@ dependencies = [
"futures-util",
]
+[[package]]
+name = "futures-intrusive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
+dependencies = [
+ "futures-core",
+ "lock_api",
+ "parking_lot",
+]
+
[[package]]
name = "futures-io"
version = "0.3.31"
@@ -1147,10 +1248,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
- "js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
- "wasm-bindgen",
]
[[package]]
@@ -1333,6 +1432,20 @@ name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash",
+]
+
+[[package]]
+name = "hashlink"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
+dependencies = [
+ "hashbrown 0.15.2",
+]
[[package]]
name = "heck"
@@ -1352,18 +1465,43 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+[[package]]
+name = "hkdf"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
+dependencies = [
+ "hmac",
+]
+
+[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest",
+]
+
+[[package]]
+name = "home"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
[[package]]
name = "html5ever"
-version = "0.26.0"
+version = "0.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7"
+checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c"
dependencies = [
"log",
"mac",
"markup5ever",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
+ "match_token",
]
[[package]]
@@ -1374,7 +1512,7 @@ checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
dependencies = [
"bytes",
"fnv",
- "itoa 1.0.14",
+ "itoa",
]
[[package]]
@@ -1418,31 +1556,13 @@ dependencies = [
"http",
"http-body",
"httparse",
- "itoa 1.0.14",
+ "itoa",
"pin-project-lite",
"smallvec",
"tokio",
"want",
]
-[[package]]
-name = "hyper-rustls"
-version = "0.27.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"
-dependencies = [
- "futures-util",
- "http",
- "hyper",
- "hyper-util",
- "rustls",
- "rustls-pki-types",
- "tokio",
- "tokio-rustls",
- "tower-service",
- "webpki-roots",
-]
-
[[package]]
name = "hyper-util"
version = "0.1.10"
@@ -1487,9 +1607,9 @@ dependencies = [
[[package]]
name = "ico"
-version = "0.3.0"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3804960be0bb5e4edb1e1ad67afd321a9ecfd875c3e65c099468fd2717d7cae"
+checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98"
dependencies = [
"byteorder",
"png",
@@ -1664,9 +1784,9 @@ dependencies = [
[[package]]
name = "infer"
-version = "0.16.0"
+version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847"
+checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7"
dependencies = [
"cfb",
]
@@ -1677,12 +1797,6 @@ version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
-[[package]]
-name = "itoa"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
-
[[package]]
name = "itoa"
version = "1.0.14"
@@ -1779,14 +1893,13 @@ dependencies = [
[[package]]
name = "kuchikiki"
-version = "0.8.2"
+version = "0.8.8-speedreader"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8"
+checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2"
dependencies = [
"cssparser",
"html5ever",
- "indexmap 1.9.3",
- "matches",
+ "indexmap 2.7.1",
"selectors",
]
@@ -1795,6 +1908,9 @@ name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+dependencies = [
+ "spin",
+]
[[package]]
name = "libappindicator"
@@ -1836,6 +1952,12 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "libm"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
+
[[package]]
name = "libredox"
version = "0.1.3"
@@ -1844,6 +1966,18 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.8.0",
"libc",
+ "redox_syscall",
+]
+
+[[package]]
+name = "libsqlite3-sys"
+version = "0.30.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
+dependencies = [
+ "cc",
+ "pkg-config",
+ "vcpkg",
]
[[package]]
@@ -1877,35 +2011,47 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
-[[package]]
-name = "malloc_buf"
-version = "0.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
-dependencies = [
- "libc",
-]
-
[[package]]
name = "markup5ever"
-version = "0.11.0"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016"
+checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18"
dependencies = [
"log",
- "phf 0.10.1",
- "phf_codegen 0.10.0",
+ "phf 0.11.3",
+ "phf_codegen 0.11.3",
"string_cache",
"string_cache_codegen",
"tendril",
]
+[[package]]
+name = "match_token"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.98",
+]
+
[[package]]
name = "matches"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
+[[package]]
+name = "md-5"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
+dependencies = [
+ "cfg-if",
+ "digest",
+]
+
[[package]]
name = "memchr"
version = "2.7.4"
@@ -1950,22 +2096,23 @@ dependencies = [
[[package]]
name = "muda"
-version = "0.15.3"
+version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdae9c00e61cc0579bcac625e8ad22104c60548a025bfc972dc83868a28e1484"
+checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a"
dependencies = [
"crossbeam-channel",
"dpi",
"gtk",
"keyboard-types",
- "objc2",
+ "objc2 0.6.2",
"objc2-app-kit",
- "objc2-foundation",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.1",
"once_cell",
"png",
"serde",
- "thiserror 1.0.69",
- "windows-sys 0.59.0",
+ "thiserror 2.0.11",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -2010,6 +2157,23 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
+[[package]]
+name = "num-bigint-dig"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
+dependencies = [
+ "byteorder",
+ "lazy_static",
+ "libm",
+ "num-integer",
+ "num-iter",
+ "num-traits",
+ "rand 0.8.5",
+ "smallvec",
+ "zeroize",
+]
+
[[package]]
name = "num-conv"
version = "0.1.0"
@@ -2017,12 +2181,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
-name = "num-traits"
-version = "0.2.19"
+name = "num-integer"
+version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
- "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-iter"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+ "libm",
]
[[package]]
@@ -2055,23 +2240,11 @@ dependencies = [
"libc",
]
-[[package]]
-name = "objc"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
-dependencies = [
- "malloc_buf",
-]
-
[[package]]
name = "objc-sys"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
-dependencies = [
- "cc",
-]
[[package]]
name = "objc2"
@@ -2083,80 +2256,89 @@ dependencies = [
"objc2-encode",
]
+[[package]]
+name = "objc2"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc"
+dependencies = [
+ "objc2-encode",
+ "objc2-exception-helper",
+]
+
[[package]]
name = "objc2-app-kit"
-version = "0.2.2"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
+checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc"
dependencies = [
"bitflags 2.8.0",
- "block2",
+ "block2 0.6.1",
"libc",
- "objc2",
+ "objc2 0.6.2",
+ "objc2-cloud-kit",
"objc2-core-data",
+ "objc2-core-foundation",
+ "objc2-core-graphics",
"objc2-core-image",
- "objc2-foundation",
- "objc2-quartz-core",
+ "objc2-foundation 0.3.1",
+ "objc2-quartz-core 0.3.1",
]
[[package]]
name = "objc2-cloud-kit"
-version = "0.2.2"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
+checksum = "17614fdcd9b411e6ff1117dfb1d0150f908ba83a7df81b1f118005fe0a8ea15d"
dependencies = [
"bitflags 2.8.0",
- "block2",
- "objc2",
- "objc2-core-location",
- "objc2-foundation",
+ "objc2 0.6.2",
+ "objc2-foundation 0.3.1",
]
[[package]]
-name = "objc2-contacts"
-version = "0.2.2"
+name = "objc2-core-data"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
+checksum = "291fbbf7d29287518e8686417cf7239c74700fd4b607623140a7d4a3c834329d"
dependencies = [
- "block2",
- "objc2",
- "objc2-foundation",
+ "bitflags 2.8.0",
+ "objc2 0.6.2",
+ "objc2-foundation 0.3.1",
]
[[package]]
-name = "objc2-core-data"
-version = "0.2.2"
+name = "objc2-core-foundation"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
+checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
dependencies = [
"bitflags 2.8.0",
- "block2",
- "objc2",
- "objc2-foundation",
+ "dispatch2",
+ "objc2 0.6.2",
]
[[package]]
-name = "objc2-core-image"
-version = "0.2.2"
+name = "objc2-core-graphics"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
+checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4"
dependencies = [
- "block2",
- "objc2",
- "objc2-foundation",
- "objc2-metal",
+ "bitflags 2.8.0",
+ "dispatch2",
+ "objc2 0.6.2",
+ "objc2-core-foundation",
+ "objc2-io-surface",
]
[[package]]
-name = "objc2-core-location"
-version = "0.2.2"
+name = "objc2-core-image"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
+checksum = "79b3dc0cc4386b6ccf21c157591b34a7f44c8e75b064f85502901ab2188c007e"
dependencies = [
- "block2",
- "objc2",
- "objc2-contacts",
- "objc2-foundation",
+ "objc2 0.6.2",
+ "objc2-foundation 0.3.1",
]
[[package]]
@@ -2165,6 +2347,15 @@ version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
+[[package]]
+name = "objc2-exception-helper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a"
+dependencies = [
+ "cc",
+]
+
[[package]]
name = "objc2-foundation"
version = "0.2.2"
@@ -2172,114 +2363,118 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.8.0",
- "block2",
+ "block2 0.5.1",
"libc",
- "objc2",
+ "objc2 0.5.2",
]
[[package]]
-name = "objc2-link-presentation"
-version = "0.2.2"
+name = "objc2-foundation"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
+checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c"
dependencies = [
- "block2",
- "objc2",
- "objc2-app-kit",
- "objc2-foundation",
+ "bitflags 2.8.0",
+ "block2 0.6.1",
+ "libc",
+ "objc2 0.6.2",
+ "objc2-core-foundation",
]
[[package]]
-name = "objc2-metal"
-version = "0.2.2"
+name = "objc2-io-surface"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
+checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c"
dependencies = [
"bitflags 2.8.0",
- "block2",
- "objc2",
- "objc2-foundation",
+ "objc2 0.6.2",
+ "objc2-core-foundation",
]
[[package]]
-name = "objc2-quartz-core"
+name = "objc2-javascript-core"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9052cb1bb50a4c161d934befcf879526fb87ae9a68858f241e693ca46225cf5a"
+dependencies = [
+ "objc2 0.6.2",
+ "objc2-core-foundation",
+]
+
+[[package]]
+name = "objc2-metal"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
+checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
dependencies = [
"bitflags 2.8.0",
- "block2",
- "objc2",
- "objc2-foundation",
- "objc2-metal",
+ "block2 0.5.1",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
]
[[package]]
-name = "objc2-symbols"
+name = "objc2-quartz-core"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc"
+checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
dependencies = [
- "objc2",
- "objc2-foundation",
+ "bitflags 2.8.0",
+ "block2 0.5.1",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
+ "objc2-metal",
]
[[package]]
-name = "objc2-ui-kit"
-version = "0.2.2"
+name = "objc2-quartz-core"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
+checksum = "90ffb6a0cd5f182dc964334388560b12a57f7b74b3e2dec5e2722aa2dfb2ccd5"
dependencies = [
"bitflags 2.8.0",
- "block2",
- "objc2",
- "objc2-cloud-kit",
- "objc2-core-data",
- "objc2-core-image",
- "objc2-core-location",
- "objc2-foundation",
- "objc2-link-presentation",
- "objc2-quartz-core",
- "objc2-symbols",
- "objc2-uniform-type-identifiers",
- "objc2-user-notifications",
+ "objc2 0.6.2",
+ "objc2-foundation 0.3.1",
]
[[package]]
-name = "objc2-uniform-type-identifiers"
-version = "0.2.2"
+name = "objc2-security"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
+checksum = "e1f8e0ef3ab66b08c42644dcb34dba6ec0a574bbd8adbb8bdbdc7a2779731a44"
dependencies = [
- "block2",
- "objc2",
- "objc2-foundation",
+ "bitflags 2.8.0",
+ "objc2 0.6.2",
+ "objc2-core-foundation",
]
[[package]]
-name = "objc2-user-notifications"
-version = "0.2.2"
+name = "objc2-ui-kit"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
+checksum = "25b1312ad7bc8a0e92adae17aa10f90aae1fb618832f9b993b022b591027daed"
dependencies = [
"bitflags 2.8.0",
- "block2",
- "objc2",
- "objc2-core-location",
- "objc2-foundation",
+ "objc2 0.6.2",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.1",
]
[[package]]
name = "objc2-web-kit"
-version = "0.2.2"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68bc69301064cebefc6c4c90ce9cba69225239e4b8ff99d445a2b5563797da65"
+checksum = "91672909de8b1ce1c2252e95bbee8c1649c9ad9d14b9248b3d7b4c47903c47ad"
dependencies = [
"bitflags 2.8.0",
- "block2",
- "objc2",
+ "block2 0.6.1",
+ "objc2 0.6.2",
"objc2-app-kit",
- "objc2-foundation",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.1",
+ "objc2-javascript-core",
+ "objc2-security",
]
[[package]]
@@ -2328,6 +2523,12 @@ dependencies = [
"system-deps",
]
+[[package]]
+name = "parking"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
+
[[package]]
name = "parking_lot"
version = "0.12.3"
@@ -2351,6 +2552,15 @@ dependencies = [
"windows-targets 0.52.6",
]
+[[package]]
+name = "pem-rfc7468"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
+dependencies = [
+ "base64ct",
+]
+
[[package]]
name = "percent-encoding"
version = "2.3.1"
@@ -2363,9 +2573,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
- "phf_macros 0.8.0",
"phf_shared 0.8.0",
- "proc-macro-hack",
]
[[package]]
@@ -2374,7 +2582,9 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
dependencies = [
+ "phf_macros 0.10.0",
"phf_shared 0.10.0",
+ "proc-macro-hack",
]
[[package]]
@@ -2399,12 +2609,12 @@ dependencies = [
[[package]]
name = "phf_codegen"
-version = "0.10.0"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
+checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
dependencies = [
- "phf_generator 0.10.0",
- "phf_shared 0.10.0",
+ "phf_generator 0.11.3",
+ "phf_shared 0.11.3",
]
[[package]]
@@ -2439,12 +2649,12 @@ dependencies = [
[[package]]
name = "phf_macros"
-version = "0.8.0"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
+checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0"
dependencies = [
- "phf_generator 0.8.0",
- "phf_shared 0.8.0",
+ "phf_generator 0.10.0",
+ "phf_shared 0.10.0",
"proc-macro-hack",
"proc-macro2",
"quote",
@@ -2500,7 +2710,9 @@ dependencies = [
"serde_json",
"tauri",
"tauri-build",
+ "tauri-plugin-fs",
"tauri-plugin-log",
+ "tauri-plugin-sql",
]
[[package]]
@@ -2515,6 +2727,27 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+[[package]]
+name = "pkcs1"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
+dependencies = [
+ "der",
+ "pkcs8",
+ "spki",
+]
+
+[[package]]
+name = "pkcs8"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
+dependencies = [
+ "der",
+ "spki",
+]
+
[[package]]
name = "pkg-config"
version = "0.3.31"
@@ -2664,58 +2897,6 @@ dependencies = [
"memchr",
]
-[[package]]
-name = "quinn"
-version = "0.11.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef"
-dependencies = [
- "bytes",
- "pin-project-lite",
- "quinn-proto",
- "quinn-udp",
- "rustc-hash",
- "rustls",
- "socket2",
- "thiserror 2.0.11",
- "tokio",
- "tracing",
-]
-
-[[package]]
-name = "quinn-proto"
-version = "0.11.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d"
-dependencies = [
- "bytes",
- "getrandom 0.2.15",
- "rand 0.8.5",
- "ring",
- "rustc-hash",
- "rustls",
- "rustls-pki-types",
- "slab",
- "thiserror 2.0.11",
- "tinyvec",
- "tracing",
- "web-time",
-]
-
-[[package]]
-name = "quinn-udp"
-version = "0.5.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944"
-dependencies = [
- "cfg_aliases",
- "libc",
- "once_cell",
- "socket2",
- "tracing",
- "windows-sys 0.59.0",
-]
-
[[package]]
name = "quote"
version = "1.0.38"
@@ -2827,17 +3008,6 @@ dependencies = [
"bitflags 2.8.0",
]
-[[package]]
-name = "redox_users"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
-dependencies = [
- "getrandom 0.2.15",
- "libredox",
- "thiserror 1.0.69",
-]
-
[[package]]
name = "redox_users"
version = "0.5.0"
@@ -2901,7 +3071,6 @@ dependencies = [
"http-body",
"http-body-util",
"hyper",
- "hyper-rustls",
"hyper-util",
"ipnet",
"js-sys",
@@ -2910,16 +3079,11 @@ dependencies = [
"once_cell",
"percent-encoding",
"pin-project-lite",
- "quinn",
- "rustls",
- "rustls-pemfile",
- "rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"tokio",
- "tokio-rustls",
"tokio-util",
"tower",
"tower-service",
@@ -2928,24 +3092,9 @@ dependencies = [
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
- "webpki-roots",
"windows-registry",
]
-[[package]]
-name = "ring"
-version = "0.17.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e75ec5e92c4d8aede845126adc388046234541629e76029599ed35a003c7ed24"
-dependencies = [
- "cc",
- "cfg-if",
- "getrandom 0.2.15",
- "libc",
- "untrusted",
- "windows-sys 0.52.0",
-]
-
[[package]]
name = "rkyv"
version = "0.7.45"
@@ -2975,6 +3124,26 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "rsa"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b"
+dependencies = [
+ "const-oid",
+ "digest",
+ "num-bigint-dig",
+ "num-integer",
+ "num-traits",
+ "pkcs1",
+ "pkcs8",
+ "rand_core 0.6.4",
+ "signature",
+ "spki",
+ "subtle",
+ "zeroize",
+]
+
[[package]]
name = "rust_decimal"
version = "1.36.0"
@@ -2997,12 +3166,6 @@ version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
-[[package]]
-name = "rustc-hash"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
-
[[package]]
name = "rustc_version"
version = "0.4.1"
@@ -3012,49 +3175,6 @@ dependencies = [
"semver",
]
-[[package]]
-name = "rustls"
-version = "0.23.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
-dependencies = [
- "once_cell",
- "ring",
- "rustls-pki-types",
- "rustls-webpki",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "rustls-pemfile"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
-dependencies = [
- "rustls-pki-types",
-]
-
-[[package]]
-name = "rustls-pki-types"
-version = "1.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
-dependencies = [
- "web-time",
-]
-
-[[package]]
-name = "rustls-webpki"
-version = "0.102.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
-dependencies = [
- "ring",
- "rustls-pki-types",
- "untrusted",
-]
-
[[package]]
name = "rustversion"
version = "1.0.19"
@@ -3117,22 +3237,20 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "selectors"
-version = "0.22.0"
+version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe"
+checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416"
dependencies = [
"bitflags 1.3.2",
"cssparser",
"derive_more",
"fxhash",
"log",
- "matches",
"phf 0.8.0",
"phf_codegen 0.8.0",
"precomputed-hash",
"servo_arc",
"smallvec",
- "thin-slice",
]
[[package]]
@@ -3146,9 +3264,9 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.217"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
@@ -3166,9 +3284,9 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.217"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
@@ -3192,7 +3310,7 @@ version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
dependencies = [
- "itoa 1.0.14",
+ "itoa",
"memchr",
"ryu",
"serde",
@@ -3218,6 +3336,15 @@ dependencies = [
"serde",
]
+[[package]]
+name = "serde_spanned"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@@ -3225,7 +3352,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
- "itoa 1.0.14",
+ "itoa",
"ryu",
"serde",
]
@@ -3262,9 +3389,9 @@ dependencies = [
[[package]]
name = "serialize-to-javascript"
-version = "0.1.1"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb"
+checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5"
dependencies = [
"serde",
"serde_json",
@@ -3273,25 +3400,36 @@ dependencies = [
[[package]]
name = "serialize-to-javascript-impl"
-version = "0.1.1"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763"
+checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.98",
]
[[package]]
name = "servo_arc"
-version = "0.1.1"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432"
+checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741"
dependencies = [
"nodrop",
"stable_deref_trait",
]
+[[package]]
+name = "sha1"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
[[package]]
name = "sha2"
version = "0.10.8"
@@ -3309,6 +3447,16 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+[[package]]
+name = "signature"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
+dependencies = [
+ "digest",
+ "rand_core 0.6.4",
+]
+
[[package]]
name = "simd-adler32"
version = "0.3.7"
@@ -3347,6 +3495,9 @@ name = "smallvec"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
+dependencies = [
+ "serde",
+]
[[package]]
name = "socket2"
@@ -3370,9 +3521,9 @@ dependencies = [
"foreign-types",
"js-sys",
"log",
- "objc2",
- "objc2-foundation",
- "objc2-quartz-core",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
+ "objc2-quartz-core 0.2.2",
"raw-window-handle",
"redox_syscall",
"wasm-bindgen",
@@ -3387,23 +3538,234 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f"
dependencies = [
"futures-channel",
- "gio",
- "glib",
- "libc",
- "soup3-sys",
+ "gio",
+ "glib",
+ "libc",
+ "soup3-sys",
+]
+
+[[package]]
+name = "soup3-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27"
+dependencies = [
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps",
+]
+
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "spki"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
+dependencies = [
+ "base64ct",
+ "der",
+]
+
+[[package]]
+name = "sqlx"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc"
+dependencies = [
+ "sqlx-core",
+ "sqlx-macros",
+ "sqlx-mysql",
+ "sqlx-postgres",
+ "sqlx-sqlite",
+]
+
+[[package]]
+name = "sqlx-core"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
+dependencies = [
+ "base64 0.22.1",
+ "bytes",
+ "crc",
+ "crossbeam-queue",
+ "either",
+ "event-listener",
+ "futures-core",
+ "futures-intrusive",
+ "futures-io",
+ "futures-util",
+ "hashbrown 0.15.2",
+ "hashlink",
+ "indexmap 2.7.1",
+ "log",
+ "memchr",
+ "once_cell",
+ "percent-encoding",
+ "serde",
+ "serde_json",
+ "sha2",
+ "smallvec",
+ "thiserror 2.0.11",
+ "time",
+ "tokio",
+ "tokio-stream",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "sqlx-macros"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "sqlx-core",
+ "sqlx-macros-core",
+ "syn 2.0.98",
+]
+
+[[package]]
+name = "sqlx-macros-core"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b"
+dependencies = [
+ "dotenvy",
+ "either",
+ "heck 0.5.0",
+ "hex",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_json",
+ "sha2",
+ "sqlx-core",
+ "sqlx-mysql",
+ "sqlx-postgres",
+ "sqlx-sqlite",
+ "syn 2.0.98",
+ "tokio",
+ "url",
+]
+
+[[package]]
+name = "sqlx-mysql"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526"
+dependencies = [
+ "atoi",
+ "base64 0.22.1",
+ "bitflags 2.8.0",
+ "byteorder",
+ "bytes",
+ "crc",
+ "digest",
+ "dotenvy",
+ "either",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-util",
+ "generic-array",
+ "hex",
+ "hkdf",
+ "hmac",
+ "itoa",
+ "log",
+ "md-5",
+ "memchr",
+ "once_cell",
+ "percent-encoding",
+ "rand 0.8.5",
+ "rsa",
+ "serde",
+ "sha1",
+ "sha2",
+ "smallvec",
+ "sqlx-core",
+ "stringprep",
+ "thiserror 2.0.11",
+ "time",
+ "tracing",
+ "whoami",
+]
+
+[[package]]
+name = "sqlx-postgres"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46"
+dependencies = [
+ "atoi",
+ "base64 0.22.1",
+ "bitflags 2.8.0",
+ "byteorder",
+ "crc",
+ "dotenvy",
+ "etcetera",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "hex",
+ "hkdf",
+ "hmac",
+ "home",
+ "itoa",
+ "log",
+ "md-5",
+ "memchr",
+ "once_cell",
+ "rand 0.8.5",
+ "serde",
+ "serde_json",
+ "sha2",
+ "smallvec",
+ "sqlx-core",
+ "stringprep",
+ "thiserror 2.0.11",
+ "time",
+ "tracing",
+ "whoami",
]
[[package]]
-name = "soup3-sys"
-version = "0.5.0"
+name = "sqlx-sqlite"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27"
+checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea"
dependencies = [
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
+ "atoi",
+ "flume",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-intrusive",
+ "futures-util",
+ "libsqlite3-sys",
+ "log",
+ "percent-encoding",
+ "serde",
+ "serde_urlencoded",
+ "sqlx-core",
+ "thiserror 2.0.11",
+ "time",
+ "tracing",
+ "url",
]
[[package]]
@@ -3437,6 +3799,17 @@ dependencies = [
"quote",
]
+[[package]]
+name = "stringprep"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+ "unicode-properties",
+]
+
[[package]]
name = "strsim"
version = "0.11.1"
@@ -3517,12 +3890,12 @@ dependencies = [
[[package]]
name = "tao"
-version = "0.31.1"
+version = "0.34.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3731d04d4ac210cd5f344087733943b9bfb1a32654387dad4d1c70de21aee2c9"
+checksum = "959469667dbcea91e5485fc48ba7dd6023face91bb0f1a14681a70f99847c3f7"
dependencies = [
"bitflags 2.8.0",
- "cocoa",
+ "block2 0.6.1",
"core-foundation",
"core-graphics",
"crossbeam-channel",
@@ -3539,7 +3912,9 @@ dependencies = [
"ndk",
"ndk-context",
"ndk-sys",
- "objc",
+ "objc2 0.6.2",
+ "objc2-app-kit",
+ "objc2-foundation 0.3.1",
"once_cell",
"parking_lot",
"raw-window-handle",
@@ -3548,7 +3923,7 @@ dependencies = [
"unicode-segmentation",
"url",
"windows",
- "windows-core 0.58.0",
+ "windows-core 0.61.2",
"windows-version",
"x11-dl",
]
@@ -3578,17 +3953,17 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "tauri"
-version = "2.2.5"
+version = "2.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58a998b6be84104ca05c7e9a21f2180ddec020c8b84ea59a8fc8530a2a19588d"
+checksum = "d4d1d3b3dc4c101ac989fd7db77e045cc6d91a25349cd410455cb5c57d510c1c"
dependencies = [
"anyhow",
"bytes",
- "dirs 6.0.0",
+ "cookie",
+ "dirs",
"dunce",
"embed_plist",
- "futures-util",
- "getrandom 0.2.15",
+ "getrandom 0.3.1",
"glob",
"gtk",
"heck 0.5.0",
@@ -3598,9 +3973,11 @@ dependencies = [
"log",
"mime",
"muda",
- "objc2",
+ "objc2 0.6.2",
"objc2-app-kit",
- "objc2-foundation",
+ "objc2-foundation 0.3.1",
+ "objc2-ui-kit",
+ "objc2-web-kit",
"percent-encoding",
"plist",
"raw-window-handle",
@@ -3628,13 +4005,13 @@ dependencies = [
[[package]]
name = "tauri-build"
-version = "2.0.5"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e950124f6779c6cf98e3260c7a6c8488a74aa6350dd54c6950fdaa349bca2df"
+checksum = "9c432ccc9ff661803dab74c6cd78de11026a578a9307610bbc39d3c55be7943f"
dependencies = [
"anyhow",
"cargo_toml",
- "dirs 5.0.1",
+ "dirs",
"glob",
"heck 0.5.0",
"json-patch",
@@ -3644,15 +4021,15 @@ dependencies = [
"serde_json",
"tauri-utils",
"tauri-winres",
- "toml 0.8.20",
+ "toml 0.9.5",
"walkdir",
]
[[package]]
name = "tauri-codegen"
-version = "2.0.4"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f77894f9ddb5cb6c04fcfe8c8869ebe0aded4dabf19917118d48be4a95599ab5"
+checksum = "1ab3a62cf2e6253936a8b267c2e95839674e7439f104fa96ad0025e149d54d8a"
dependencies = [
"base64 0.22.1",
"brotli",
@@ -3677,9 +4054,9 @@ dependencies = [
[[package]]
name = "tauri-macros"
-version = "2.0.4"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3240a5caed760a532e8f687be6f05b2c7d11a1d791fb53ccc08cfeb3e5308736"
+checksum = "4368ea8094e7045217edb690f493b55b30caf9f3e61f79b4c24b6db91f07995e"
dependencies = [
"heck 0.5.0",
"proc-macro2",
@@ -3691,9 +4068,9 @@ dependencies = [
[[package]]
name = "tauri-plugin"
-version = "2.0.4"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5841b9a0200e954ef7457f8d327091424328891e267a97b641dc246cc54d0dec"
+checksum = "9946a3cede302eac0c6eb6c6070ac47b1768e326092d32efbb91f21ed58d978f"
dependencies = [
"anyhow",
"glob",
@@ -3702,10 +4079,32 @@ dependencies = [
"serde",
"serde_json",
"tauri-utils",
- "toml 0.8.20",
+ "toml 0.9.5",
"walkdir",
]
+[[package]]
+name = "tauri-plugin-fs"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33ead0daec5d305adcefe05af9d970fc437bcc7996052d564e7393eb291252da"
+dependencies = [
+ "anyhow",
+ "dunce",
+ "glob",
+ "percent-encoding",
+ "schemars",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "tauri",
+ "tauri-plugin",
+ "tauri-utils",
+ "thiserror 2.0.11",
+ "toml 0.8.20",
+ "url",
+]
+
[[package]]
name = "tauri-plugin-log"
version = "2.2.1"
@@ -3716,8 +4115,8 @@ dependencies = [
"byte-unit",
"fern",
"log",
- "objc2",
- "objc2-foundation",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
"serde",
"serde_json",
"serde_repr",
@@ -3729,37 +4128,63 @@ dependencies = [
]
[[package]]
-name = "tauri-runtime"
+name = "tauri-plugin-sql"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2274ef891ccc0a8d318deffa9d70053f947664d12d58b9c0d1ae5e89237e01f7"
+checksum = "df059378695202fef1e274b8e7916fc3dffc44716ae4baf8c0226089b2f390ae"
+dependencies = [
+ "futures-core",
+ "indexmap 2.7.1",
+ "log",
+ "serde",
+ "serde_json",
+ "sqlx",
+ "tauri",
+ "tauri-plugin",
+ "thiserror 2.0.11",
+ "time",
+ "tokio",
+]
+
+[[package]]
+name = "tauri-runtime"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4cfc9ad45b487d3fded5a4731a567872a4812e9552e3964161b08edabf93846"
dependencies = [
+ "cookie",
"dpi",
"gtk",
"http",
"jni",
+ "objc2 0.6.2",
+ "objc2-ui-kit",
+ "objc2-web-kit",
"raw-window-handle",
"serde",
"serde_json",
"tauri-utils",
"thiserror 2.0.11",
"url",
+ "webkit2gtk",
+ "webview2-com",
"windows",
]
[[package]]
name = "tauri-runtime-wry"
-version = "2.3.0"
+version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3707b40711d3b9f6519150869e358ffbde7c57567fb9b5a8b51150606939b2a0"
+checksum = "c1fe9d48bd122ff002064e88cfcd7027090d789c4302714e68fcccba0f4b7807"
dependencies = [
"gtk",
"http",
"jni",
"log",
- "objc2",
+ "objc2 0.6.2",
"objc2-app-kit",
- "objc2-foundation",
+ "objc2-foundation 0.3.1",
+ "once_cell",
"percent-encoding",
"raw-window-handle",
"softbuffer",
@@ -3775,10 +4200,11 @@ dependencies = [
[[package]]
name = "tauri-utils"
-version = "2.1.1"
+version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96fb10e7cc97456b2d5b9c03e335b5de5da982039a303a20d10006885e4523a0"
+checksum = "41a3852fdf9a4f8fbeaa63dc3e9a85284dd6ef7200751f0bd66ceee30c93f212"
dependencies = [
+ "anyhow",
"brotli",
"cargo_metadata",
"ctor",
@@ -3803,7 +4229,7 @@ dependencies = [
"serde_with",
"swift-rs",
"thiserror 2.0.11",
- "toml 0.8.20",
+ "toml 0.9.5",
"url",
"urlpattern",
"uuid",
@@ -3812,12 +4238,12 @@ dependencies = [
[[package]]
name = "tauri-winres"
-version = "0.1.1"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb"
+checksum = "fd21509dd1fa9bd355dc29894a6ff10635880732396aa38c0066c1e6c1ab8074"
dependencies = [
"embed-resource",
- "toml 0.7.8",
+ "toml 0.9.5",
]
[[package]]
@@ -3831,12 +4257,6 @@ dependencies = [
"utf-8",
]
-[[package]]
-name = "thin-slice"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
-
[[package]]
name = "thiserror"
version = "1.0.69"
@@ -3884,7 +4304,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
dependencies = [
"deranged",
- "itoa 1.0.14",
+ "itoa",
"libc",
"num-conv",
"num_threads",
@@ -3951,12 +4371,13 @@ dependencies = [
]
[[package]]
-name = "tokio-rustls"
-version = "0.26.1"
+name = "tokio-stream"
+version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37"
+checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
dependencies = [
- "rustls",
+ "futures-core",
+ "pin-project-lite",
"tokio",
]
@@ -3975,26 +4396,29 @@ dependencies = [
[[package]]
name = "toml"
-version = "0.7.8"
+version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
+checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
dependencies = [
"serde",
- "serde_spanned",
- "toml_datetime",
- "toml_edit 0.19.15",
+ "serde_spanned 0.6.8",
+ "toml_datetime 0.6.8",
+ "toml_edit 0.22.24",
]
[[package]]
name = "toml"
-version = "0.8.20"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
+checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8"
dependencies = [
+ "indexmap 2.7.1",
"serde",
- "serde_spanned",
- "toml_datetime",
- "toml_edit 0.22.24",
+ "serde_spanned 1.0.0",
+ "toml_datetime 0.7.0",
+ "toml_parser",
+ "toml_writer",
+ "winnow 0.7.13",
]
[[package]]
@@ -4006,6 +4430,15 @@ dependencies = [
"serde",
]
+[[package]]
+name = "toml_datetime"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "toml_edit"
version = "0.19.15"
@@ -4013,9 +4446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap 2.7.1",
- "serde",
- "serde_spanned",
- "toml_datetime",
+ "toml_datetime 0.6.8",
"winnow 0.5.40",
]
@@ -4026,7 +4457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
dependencies = [
"indexmap 2.7.1",
- "toml_datetime",
+ "toml_datetime 0.6.8",
"winnow 0.5.40",
]
@@ -4038,11 +4469,26 @@ checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
dependencies = [
"indexmap 2.7.1",
"serde",
- "serde_spanned",
- "toml_datetime",
- "winnow 0.7.2",
+ "serde_spanned 0.6.8",
+ "toml_datetime 0.6.8",
+ "winnow 0.7.13",
+]
+
+[[package]]
+name = "toml_parser"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10"
+dependencies = [
+ "winnow 0.7.13",
]
+[[package]]
+name = "toml_writer"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
+
[[package]]
name = "tower"
version = "0.5.2"
@@ -4076,10 +4522,23 @@ version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
+ "log",
"pin-project-lite",
+ "tracing-attributes",
"tracing-core",
]
+[[package]]
+name = "tracing-attributes"
+version = "0.1.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.98",
+]
+
[[package]]
name = "tracing-core"
version = "0.1.33"
@@ -4091,22 +4550,23 @@ dependencies = [
[[package]]
name = "tray-icon"
-version = "0.19.2"
+version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d48a05076dd272615d03033bf04f480199f7d1b66a8ac64d75c625fc4a70c06b"
+checksum = "a0d92153331e7d02ec09137538996a7786fe679c629c279e82a6be762b7e6fe2"
dependencies = [
- "core-graphics",
"crossbeam-channel",
- "dirs 5.0.1",
+ "dirs",
"libappindicator",
"muda",
- "objc2",
+ "objc2 0.6.2",
"objc2-app-kit",
- "objc2-foundation",
+ "objc2-core-foundation",
+ "objc2-core-graphics",
+ "objc2-foundation 0.3.1",
"once_cell",
"png",
"serde",
- "thiserror 1.0.69",
+ "thiserror 2.0.11",
"windows-sys 0.59.0",
]
@@ -4169,6 +4629,12 @@ dependencies = [
"unic-common",
]
+[[package]]
+name = "unicode-bidi"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
+
[[package]]
name = "unicode-ident"
version = "1.0.16"
@@ -4176,16 +4642,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
[[package]]
-name = "unicode-segmentation"
-version = "1.12.0"
+name = "unicode-normalization"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
+checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
+dependencies = [
+ "tinyvec",
+]
[[package]]
-name = "untrusted"
-version = "0.9.0"
+name = "unicode-properties"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "url"
@@ -4251,6 +4726,12 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2"
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
[[package]]
name = "version-compare"
version = "0.2.0"
@@ -4323,6 +4804,12 @@ dependencies = [
"wit-bindgen-rt",
]
+[[package]]
+name = "wasite"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
+
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
@@ -4417,16 +4904,6 @@ dependencies = [
"wasm-bindgen",
]
-[[package]]
-name = "web-time"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
[[package]]
name = "webkit2gtk"
version = "2.0.1"
@@ -4471,25 +4948,16 @@ dependencies = [
"system-deps",
]
-[[package]]
-name = "webpki-roots"
-version = "0.26.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9"
-dependencies = [
- "rustls-pki-types",
-]
-
[[package]]
name = "webview2-com"
-version = "0.34.0"
+version = "0.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "823e7ebcfaea51e78f72c87fc3b65a1e602c321f407a0b36dbb327d7bb7cd921"
+checksum = "d4ba622a989277ef3886dd5afb3e280e3dd6d974b766118950a08f8f678ad6a4"
dependencies = [
"webview2-com-macros",
"webview2-com-sys",
"windows",
- "windows-core 0.58.0",
+ "windows-core 0.61.2",
"windows-implement",
"windows-interface",
]
@@ -4507,13 +4975,23 @@ dependencies = [
[[package]]
name = "webview2-com-sys"
-version = "0.34.0"
+version = "0.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a82bce72db6e5ee83c68b5de1e2cd6ea195b9fbff91cb37df5884cbe3222df4"
+checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c"
dependencies = [
- "thiserror 1.0.69",
+ "thiserror 2.0.11",
"windows",
- "windows-core 0.58.0",
+ "windows-core 0.61.2",
+]
+
+[[package]]
+name = "whoami"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d"
+dependencies = [
+ "libredox",
+ "wasite",
]
[[package]]
@@ -4549,13 +5027,14 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "window-vibrancy"
-version = "0.5.3"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "831ad7678290beae36be6f9fad9234139c7f00f3b536347de7745621716be82d"
+checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c"
dependencies = [
- "objc2",
+ "objc2 0.6.2",
"objc2-app-kit",
- "objc2-foundation",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.1",
"raw-window-handle",
"windows-sys 0.59.0",
"windows-version",
@@ -4563,12 +5042,24 @@ dependencies = [
[[package]]
name = "windows"
-version = "0.58.0"
+version = "0.61.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
+checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
dependencies = [
- "windows-core 0.58.0",
- "windows-targets 0.52.6",
+ "windows-collections",
+ "windows-core 0.61.2",
+ "windows-future",
+ "windows-link",
+ "windows-numerics",
+]
+
+[[package]]
+name = "windows-collections"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
+dependencies = [
+ "windows-core 0.61.2",
]
[[package]]
@@ -4582,22 +5073,33 @@ dependencies = [
[[package]]
name = "windows-core"
-version = "0.58.0"
+version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
+checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-interface",
- "windows-result",
- "windows-strings",
- "windows-targets 0.52.6",
+ "windows-link",
+ "windows-result 0.3.4",
+ "windows-strings 0.4.2",
+]
+
+[[package]]
+name = "windows-future"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
+dependencies = [
+ "windows-core 0.61.2",
+ "windows-link",
+ "windows-threading",
]
[[package]]
name = "windows-implement"
-version = "0.58.0"
+version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
+checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
@@ -4606,23 +5108,39 @@ dependencies = [
[[package]]
name = "windows-interface"
-version = "0.58.0"
+version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
+checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
+[[package]]
+name = "windows-link"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
+
+[[package]]
+name = "windows-numerics"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
+dependencies = [
+ "windows-core 0.61.2",
+ "windows-link",
+]
+
[[package]]
name = "windows-registry"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
dependencies = [
- "windows-result",
- "windows-strings",
+ "windows-result 0.2.0",
+ "windows-strings 0.1.0",
"windows-targets 0.52.6",
]
@@ -4635,16 +5153,34 @@ dependencies = [
"windows-targets 0.52.6",
]
+[[package]]
+name = "windows-result"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
+dependencies = [
+ "windows-link",
+]
+
[[package]]
name = "windows-strings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
- "windows-result",
+ "windows-result 0.2.0",
"windows-targets 0.52.6",
]
+[[package]]
+name = "windows-strings"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
+dependencies = [
+ "windows-link",
+]
+
[[package]]
name = "windows-sys"
version = "0.45.0"
@@ -4681,6 +5217,15 @@ dependencies = [
"windows-targets 0.52.6",
]
+[[package]]
+name = "windows-sys"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+dependencies = [
+ "windows-targets 0.53.3",
+]
+
[[package]]
name = "windows-targets"
version = "0.42.2"
@@ -4729,10 +5274,11 @@ dependencies = [
[[package]]
name = "windows-targets"
-version = "0.53.0"
+version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
+checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
dependencies = [
+ "windows-link",
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
@@ -4743,13 +5289,22 @@ dependencies = [
"windows_x86_64_msvc 0.53.0",
]
+[[package]]
+name = "windows-threading"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
+dependencies = [
+ "windows-link",
+]
+
[[package]]
name = "windows-version"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c12476c23a74725c539b24eae8bfc0dac4029c39cdb561d9f23616accd4ae26d"
dependencies = [
- "windows-targets 0.53.0",
+ "windows-targets 0.53.3",
]
[[package]]
@@ -4943,21 +5498,21 @@ dependencies = [
[[package]]
name = "winnow"
-version = "0.7.2"
+version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603"
+checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
-version = "0.52.0"
+version = "0.55.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
+checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97"
dependencies = [
"cfg-if",
- "windows-sys 0.48.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -4983,14 +5538,15 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "wry"
-version = "0.48.1"
+version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2e33c08b174442ff80d5c791020696f9f8b4e4a87b8cfc7494aad6167ec44e1"
+checksum = "31f0e9642a0d061f6236c54ccae64c2722a7879ad4ec7dff59bd376d446d8e90"
dependencies = [
"base64 0.22.1",
- "block2",
+ "block2 0.6.1",
"cookie",
"crossbeam-channel",
+ "dirs",
"dpi",
"dunce",
"gdkx11",
@@ -5002,9 +5558,10 @@ dependencies = [
"kuchikiki",
"libc",
"ndk",
- "objc2",
+ "objc2 0.6.2",
"objc2-app-kit",
- "objc2-foundation",
+ "objc2-core-foundation",
+ "objc2-foundation 0.3.1",
"objc2-ui-kit",
"objc2-web-kit",
"once_cell",
@@ -5019,7 +5576,7 @@ dependencies = [
"webkit2gtk-sys",
"webview2-com",
"windows",
- "windows-core 0.58.0",
+ "windows-core 0.61.2",
"windows-version",
"x11-dl",
]
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index 10a3cdb..f6a979c 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -23,3 +23,5 @@ serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri = { version = "2.2.4", features = [] }
tauri-plugin-log = "2.0.0-rc"
+tauri-plugin-fs = "2"
+tauri-plugin-sql = { version = "2", features = ["sqlite"] }
diff --git a/src-tauri/build.rs b/src-tauri/build.rs
index 795b9b7..d860e1e 100644
--- a/src-tauri/build.rs
+++ b/src-tauri/build.rs
@@ -1,3 +1,3 @@
fn main() {
- tauri_build::build()
+ tauri_build::build()
}
diff --git a/src-tauri/capabilities/database.json b/src-tauri/capabilities/database.json
new file mode 100644
index 0000000..700b253
--- /dev/null
+++ b/src-tauri/capabilities/database.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "../gen/schemas/desktop-schema.json",
+ "identifier": "database",
+ "description": "enables database permissions",
+ "windows": [
+ "*"
+ ],
+ "permissions": [
+ "sql:default",
+ "sql:allow-execute"
+ ]
+}
\ No newline at end of file
diff --git a/src-tauri/capabilities/fs.json b/src-tauri/capabilities/fs.json
new file mode 100644
index 0000000..347632e
--- /dev/null
+++ b/src-tauri/capabilities/fs.json
@@ -0,0 +1,16 @@
+{
+ "$schema": "../gen/schemas/desktop-schema.json",
+ "identifier": "fs",
+ "description": "enables fs permissions on certain path",
+ "windows": [
+ "*"
+ ],
+ "permissions": [
+ "fs:default",
+ "fs:scope-appconfig-recursive",
+ "fs:scope-appconfig-index",
+ "fs:allow-appconfig-read-recursive",
+ "fs:allow-appconfig-write-recursive",
+ "fs:allow-appconfig-meta-recursive"
+ ]
+}
\ No newline at end of file
diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs
index 9c3118c..42a0394 100644
--- a/src-tauri/src/lib.rs
+++ b/src-tauri/src/lib.rs
@@ -1,16 +1,18 @@
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
- tauri::Builder::default()
- .setup(|app| {
- if cfg!(debug_assertions) {
- app.handle().plugin(
- tauri_plugin_log::Builder::default()
- .level(log::LevelFilter::Info)
- .build(),
- )?;
- }
- Ok(())
- })
- .run(tauri::generate_context!())
- .expect("error while running tauri application");
+ tauri::Builder::default()
+ .plugin(tauri_plugin_sql::Builder::new().build())
+ .plugin(tauri_plugin_fs::init())
+ .setup(|app| {
+ if cfg!(debug_assertions) {
+ app.handle().plugin(
+ tauri_plugin_log::Builder::default()
+ .level(log::LevelFilter::Info)
+ .build(),
+ )?;
+ }
+ Ok(())
+ })
+ .run(tauri::generate_context!())
+ .expect("error while running tauri application");
}
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index ad5fe83..69c3a72 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -2,5 +2,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
- app_lib::run();
+ app_lib::run();
}
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index 1f5e382..d9f6414 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -6,8 +6,8 @@
"build": {
"frontendDist": "../dist",
"devUrl": "http://localhost:5173/",
- "beforeDevCommand": "pnpm dev --config vite.config.tauri.ts",
- "beforeBuildCommand": "pnpm build --config vite.config.tauri.ts"
+ "beforeDevCommand": "pnpm dev --config vite/config.tauri.ts",
+ "beforeBuildCommand": "pnpm build --config vite/config.tauri.ts"
},
"app": {
"windows": [
@@ -20,6 +20,7 @@
}
],
"security": {
+ "capabilities": ["database", "fs", "default"],
"csp": null
}
},
diff --git a/src/App/App.ts b/src/App/App.ts
deleted file mode 100644
index c8d4a38..0000000
--- a/src/App/App.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { EventEmitter } from "eventemitter3";
-import Audio, { Audio as AudioClass } from "@/Audio/Audio";
-import Chart, { ChartExported } from "@/Chart/Chart";
-import Assets, { AssetsManager } from '@/Assets/Assets';
-import { Hotkeys } from './Hotkeys';
-import { ChartInfo } from "@/Chart/types";
-import { Nullable } from "@/utils/types";
-import { Ticker } from "pixi.js";
-import { ImportChart } from "@/utils/file";
-
-export class App {
- readonly audio: AudioClass = Audio;
- readonly assets: AssetsManager = Assets;
- readonly events = new EventEmitter();
- readonly hotkeys = new Hotkeys(this.events);
- private currentChart: Nullable = null;
-}
-
-const app = new App();
-export default app;
-
-console.log(app);
diff --git a/src/App/Hotkeys.ts b/src/App/Hotkeys.ts
deleted file mode 100644
index 297c1b7..0000000
--- a/src/App/Hotkeys.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { EventEmitter } from 'eventemitter3';
-import hotkeys from 'hotkeys-js';
-
-export class Hotkeys {
- keymap: { [key: string]: string };
- event: EventEmitter;
-
- constructor(e: EventEmitter) {
- this.keymap = {};
- this.event = e;
- }
-
- add(key: string, id: string) {
- this.keymap[key] = id;
- hotkeys(key, (event: KeyboardEvent,) => {
- event.preventDefault();
- this.event.emit(id);
- });
- }
-
- remove(key: string) {
- hotkeys.unbind(key);
- delete this.keymap[key];
- }
-
- on(id: string, callback: () => void) {
- this.event.on(id, callback);
- }
-}
\ No newline at end of file
diff --git a/src/Assets/Assets.ts b/src/Assets/Assets.ts
deleted file mode 100644
index 5b3d813..0000000
--- a/src/Assets/Assets.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import { Assets } from 'pixi.js';
-import AudioClip from '@/Audio/Clip';
-import { AssetsBundle, Texture, UnresolvedAsset } from 'pixi.js';
-
-const loadDefaultAssetsTexture = (): Promise> => new Promise(async (res, rej) => {
- try {
- const result: Record = {};
- const defaultBundle = (await (await fetch('skin/skin-bundle.json')).json()) as AssetsBundle;
- await Assets.init({ manifest: { bundles: [ defaultBundle ] } });
- const bundleResult = await Assets.loadBundle('skin-default') as Record;
-
- for (const asset of (defaultBundle.assets as UnresolvedAsset[])) {
- if (!asset.alias) continue;
- result[asset.alias as string] = bundleResult[asset.alias as string];
- }
-
- res(result);
- } catch (e) {
- rej(e);
- }
-});
-
-class AssetsManager {
- readonly textures: Record = {};
- readonly sounds: Record = {};
-
- constructor() {
- loadDefaultAssetsTexture()
- .then((e) => {
- for (const name in e) {
- this.textures[name] = e[name];
- }
- })
- .catch(e => {throw e});
- }
-}
-
-const assets = new AssetsManager();
-export default assets;
-export { AssetsManager };
diff --git a/src/Audio/Audio.ts b/src/Audio/Audio.ts
deleted file mode 100644
index 93aedba..0000000
--- a/src/Audio/Audio.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { Ticker } from 'pixi.js';
-import AudioClock from './Clock';
-import AudioChannel from './Channel';
-import AudioClip from './Clip';
-import { resumeAudioCtx } from './utils';
-
-const AudioCtx = window.AudioContext;
-const GlobalAudioCtx = new AudioCtx({ latencyHint: 'interactive' });
-const GlobalAudioTicker = new Ticker();
-const GlobalAudioClock = new AudioClock(GlobalAudioCtx, GlobalAudioTicker, GlobalAudioCtx.baseLatency);
-
-export class Audio {
- readonly audioCtx: AudioContext;
- readonly clock: AudioClock;
-
- readonly masterGain: GainNode;
- readonly channels: {
- music: AudioChannel,
- effect: AudioChannel,
- };
-
- constructor() {
- this.audioCtx = GlobalAudioCtx;
- this.clock = GlobalAudioClock;
-
- this.masterGain = this.audioCtx.createGain();
- this.masterGain.connect(this.audioCtx.destination);
- this.channels = {
- music: new AudioChannel(this, GlobalAudioTicker),
- effect: new AudioChannel(this, GlobalAudioTicker),
- };
- }
-
- static from(buffer: AudioBuffer) {
- return new AudioClip(GlobalAudioCtx, GlobalAudioClock, buffer);
- }
-
- get masterVolume() {
- return this.masterGain.gain.value;
- }
-
- set masterVolume(volume: number) {
- this.masterGain.gain.value = volume;
- }
-}
-
-const audio = new Audio();
-export default audio;
-
-// Automatically resume AudioContext
-const _resumeAudio = () => {
- resumeAudioCtx(GlobalAudioCtx).catch(() => void 0);
-};
-const handleWindowLoaded = () => {
- window.removeEventListener('load', handleWindowLoaded);
-
- if (GlobalAudioCtx.state === 'running') return;
- window.addEventListener('pointerdown', _resumeAudio);
- window.addEventListener('pointerover', _resumeAudio);
- window.addEventListener('pointerleave', _resumeAudio);
-};
-
-GlobalAudioCtx.addEventListener('statechange', () => {
- if (GlobalAudioCtx.state !== 'running') return;
-
- console.info('[Audio]', 'Resume audio success');
- window.removeEventListener('pointerdown', _resumeAudio);
- window.removeEventListener('pointerover', _resumeAudio);
- window.removeEventListener('pointerleave', _resumeAudio);
-});
-window.addEventListener('load', handleWindowLoaded);
diff --git a/src/Audio/Channel.ts b/src/Audio/Channel.ts
deleted file mode 100644
index 54e70dd..0000000
--- a/src/Audio/Channel.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { Ticker } from 'pixi.js';
-import { Audio } from './Audio';
-import AudioClip from './Clip';
-
-export default class AudioChannel {
- private readonly audioCtx: AudioContext;
- private readonly ticker: Ticker;
- readonly gain: GainNode;
- readonly playlist: Array = [];
-
- private isTickerStarted = false;
-
- constructor(audio: Audio, ticker: Ticker) {
- this.audioCtx = audio.audioCtx;
- this.ticker = ticker;
-
- this.gain = this.audioCtx.createGain();
- this.gain.connect(audio.masterGain);
-
- this.calcTick = this.calcTick.bind(this);
- }
-
- startTicker() {
- if (this.isTickerStarted) return;
- // eslint-disable-next-line @typescript-eslint/unbound-method
- this.ticker.add(this.calcTick);
- this.isTickerStarted = true;
- }
-
- stopTicker() {
- if (!this.isTickerStarted) return;
- // eslint-disable-next-line @typescript-eslint/unbound-method
- this.ticker.remove(this.calcTick);
- this.isTickerStarted = false;
- }
-
- private calcTick() {
- while(this.playlist.length > 0) {
- const audio = this.playlist.shift()!;
- const buffer = this.audioCtx.createBufferSource();
-
- buffer.buffer = audio.source;
- buffer.connect(this.gain);
- buffer.start();
- }
- }
-
- get volume() {
- return this.gain.gain.value;
- }
-
- set volume(value: number) {
- this.gain.gain.value = value;
- }
-}
diff --git a/src/Audio/Clip.ts b/src/Audio/Clip.ts
deleted file mode 100644
index 7c0d7d0..0000000
--- a/src/Audio/Clip.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-import { Nullable } from '@/utils/types';
-import AudioChannel from './Channel';
-import AudioClock from './Clock';
-import Audio from './Audio';
-import { ReadFileAsAudioBuffer } from '@/utils/file';
-
-export enum EAudioClipStatus {
- STOP = 0,
- PLAY = 1,
- PAUSE = 2,
-}
-
-export default class AudioClip {
- readonly source: AudioBuffer;
-
- private _timeOffset: number = 0;
- private _channel: Nullable = null;
- private buffer?: AudioBufferSourceNode;
- private readonly audioCtx: AudioContext;
- readonly clock: AudioClock;
-
- status: EAudioClipStatus = EAudioClipStatus.STOP;
- startTime: number = NaN;
- pauseTime: number = NaN;
-
- constructor(audioCtx: AudioContext, clock: AudioClock, audioBuffer: AudioBuffer, channel: Nullable = null) {
- this.source = audioBuffer;
- this._channel = channel;
-
- this.audioCtx = audioCtx;
- this.clock = clock;
- }
-
- static from(file: Blob, channel?: AudioChannel): Promise {return new Promise((res, rej) => {
- ReadFileAsAudioBuffer(file)
- .then((buffer) => res(new AudioClip(Audio.audioCtx, Audio.clock, buffer, channel)))
- .catch((e) => rej(e));
- })}
-
- play() {
- if (!this._channel) throw new Error('Cannot play a clip directly without any channel');
- if (this.status === EAudioClipStatus.PLAY) return;
-
- this.buffer = this.audioCtx.createBufferSource();
- this.buffer.buffer = this.source;
- this.buffer.connect(this._channel.gain);
-
- if (isNaN(this.pauseTime)) {
- this.startTime = this.clock.time;
- this.buffer.start(0, 0);
- } else {
- const pausedTime = this.pauseTime - this.startTime;
- this.startTime = this.clock.time - pausedTime;
- this.buffer.start(0, pausedTime);
- }
-
- this.pauseTime = NaN;
- this.status = EAudioClipStatus.PLAY;
- this.buffer.onended = () => this.stop();
- }
-
- pause() {
- if (this.status !== EAudioClipStatus.PLAY) return;
-
- this.disconnectBuffer();
- this.pauseTime = this.clock.time;
- this.status = EAudioClipStatus.PAUSE;
- }
-
- stop() {
- if (this.status === EAudioClipStatus.STOP) return;
-
- this.disconnectBuffer();
- this.startTime = NaN;
- this.pauseTime = NaN;
- this.status = EAudioClipStatus.STOP;
- }
-
- /**
- *
- * @param {number} time Seek seconds
- */
- seek(time: number) {
- let _time = time + this._timeOffset;
- if (_time < 0) _time = 0;
-
- if (this.status === EAudioClipStatus.STOP) {
- const currentTime = this.clock.time;
- this.startTime = currentTime - _time;
- this.pauseTime = currentTime;
- return;
- }
-
- const isPlayingBefore = this.status === EAudioClipStatus.PLAY;
- this.pause();
- this.startTime = this.pauseTime - _time;
-
- if (this.startTime > this.pauseTime) this.startTime = this.pauseTime;
- if (isPlayingBefore) this.play();
- }
-
- destroy() {
- if (!this._channel) return;
- this.stop();
- }
-
- get channel() {
- return this._channel;
- }
-
- set channel(channel: Nullable) {
- this._channel = channel;
- }
-
- get time() {
- if (isNaN(this.startTime)) return -this._timeOffset;
- else if (isNaN(this.pauseTime)) return this.clock.time - this.startTime - this._timeOffset;
- else return this.pauseTime - this.startTime - this._timeOffset;
- }
-
- get duration() {
- return this.source.duration - this._timeOffset;
- }
-
- get timeOffset() {
- return this._timeOffset;
- }
-
- set timeOffset(offset: number) {
- this._timeOffset = offset;
- }
-
- get speed() {
- return this.buffer ? this.buffer.playbackRate.value : 1;
- }
-
- set speed(value: number) {
- if (this.buffer) this.buffer.playbackRate.value = value;
- }
-
- private disconnectBuffer() {
- if (!this.buffer) return;
-
- this.buffer.stop();
- this.buffer.disconnect();
- this.buffer.onended = null;
- this.buffer = (void 0);
- }
-}
diff --git a/src/Audio/Clock.ts b/src/Audio/Clock.ts
deleted file mode 100644
index 202b0bc..0000000
--- a/src/Audio/Clock.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Ticker } from 'pixi.js';
-import { resumeAudioCtx } from './utils';
-
-export default class AudioClock {
- /**
- * The current audio time.
- */
- public time: number = 0;
-
- private offsets: number[] = [];
- private sum: number = 0;
-
- private readonly audioCtx: AudioContext;
- private readonly ticker: Ticker;
- private readonly baseOffset;
-
- constructor(audioCtx: AudioContext, ticker: Ticker, baseOffset: number = 0) {
- this.audioCtx = audioCtx;
- this.ticker = ticker;
- this.baseOffset = baseOffset;
-
- this.calcTick = this.calcTick.bind(this);
- this.init().catch(() => void 0);
- }
-
- private async init() {
- this.audioCtx.addEventListener('statechange', () => {
- // eslint-disable-next-line @typescript-eslint/unbound-method
- if (this.audioCtx.state === 'running') this.ticker.add(this.calcTick);
- });
-
- await resumeAudioCtx(this.audioCtx);
- this.ticker.start();
- }
-
- private calcTick() {
- const { audioCtx, baseOffset, offsets } = this;
- const realTime = performance.now() / 1000;
- const delta = realTime - audioCtx.currentTime - baseOffset;
-
- offsets.push(delta);
- this.sum += delta;
-
- while(offsets.length > 60) {
- this.sum -= offsets.shift()!;
- }
-
- this.time = realTime - this.sum / offsets.length;
- }
-}
diff --git a/src/Audio/utils.ts b/src/Audio/utils.ts
deleted file mode 100644
index 822f030..0000000
--- a/src/Audio/utils.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-
-/**
- * Resume an AudioContext.
- * @link https://github.com/bemusic/bemuse/blob/master/bemuse/src/sampling-master/index.js#L276
- * @param audioCtx
- * @returns {Promise} Return false if resume failed
- */
-export const resumeAudioCtx = (audioCtx: AudioContext): Promise => {
- if (audioCtx.state === 'running') return new Promise((res) => res(true));
-
- console.info('[Audio]', 'Try resuming audio...');
-
- const gain = audioCtx.createGain();
- const osc = audioCtx.createOscillator();
-
- osc.frequency.value = 440;
-
- osc.start(audioCtx.currentTime + 0.1);
- osc.stop(audioCtx.currentTime + 0.1);
-
- gain.connect(audioCtx.destination);
- gain.disconnect();
-
- return new Promise((res) => {
- audioCtx.resume()
- .then(() => res(true))
- .catch((e) => {
- res(false);
- console.error('[Audio]', 'Failed to resume audio');
- console.error(e);
- });
- });
-};
diff --git a/src/Chart/BPM.ts b/src/Chart/BPM.ts
deleted file mode 100644
index d3e5aa6..0000000
--- a/src/Chart/BPM.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { v4 as uuid } from 'uuid';
-import { BeatArrayToNumber, parseDoublePrecist } from '@/utils/math';
-import { BeatArray } from '@/utils/types';
-
-export type ChartBPMExported = {
- beat: BeatArray,
- bpm: number,
-};
-
-export default class ChartBPM {
- /** Internal property */
- readonly id: string;
-
- beat: BeatArray;
- beatNum: number;
- bpm: number;
-
- time: number ;
- timePerBeat: number;
- endBeat: BeatArray;
- endBeatNum: number;
- endTime: number;
-
- constructor(beat: BeatArray, bpm: number, id = uuid()) {
- if (BeatArrayToNumber(beat) < 0) throw new Error('Cannot set a negative beat to BPM!');
- if (bpm <= 0) throw new Error('Cannot set a zero/negative BPM!');
-
- this.id = id;
- this.beat = beat;
- this.beatNum = BeatArrayToNumber(this.beat);
- this.bpm = bpm;
-
- /**
- * NOTE: These will be generated by BPMList automatically,
- * please do not edit them manually!
- */
- this.time = NaN;
- this.timePerBeat = parseDoublePrecist(60 / this.bpm, 6, -1);
- this.endBeat = [ Infinity, 0, 1 ];
- this.endBeatNum = Infinity;
- this.endTime = Infinity;
- }
-
- update() {
- this.beatNum = BeatArrayToNumber(this.beat);
- this.timePerBeat = parseDoublePrecist(60 / this.bpm, 6, -1);
- }
-
- get json(): ChartBPMExported {
- return {
- beat: this.beat,
- bpm: this.bpm,
- };
- }
-}
diff --git a/src/Chart/BPMList.ts b/src/Chart/BPMList.ts
deleted file mode 100644
index 8384a2a..0000000
--- a/src/Chart/BPMList.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { BeatArrayToNumber, parseDoublePrecist } from '@/utils/math';
-import ChartBPM, { ChartBPMExported } from './BPM';
-import { BeatArray } from '@/utils/types';
-
-const BPMSortFn = (a: ChartBPM, b: ChartBPM) => BeatArrayToNumber(a.beat) - BeatArrayToNumber(b.beat);
-
-export default class ChartBPMList extends Array {
- add(beat: BeatArray, bpm: number) {
- const newBPM = new ChartBPM(beat, bpm);
- this.push(newBPM);
- this.calcRealTime();
- return newBPM;
- }
-
- remove(id: string) {
- if (this.length === 1) return;
-
- const bpmIndex = this.findIndex((e) => e.id === id);
- if (bpmIndex === -1) return;
- const oldBPM = this[bpmIndex];
-
- this.splice(bpmIndex, 1);
- this.calcRealTime();
- return oldBPM;
- }
-
- edit(id: string, newBPM?: number, newBeat?: BeatArray) {
- const bpm = this.findByID(id);
- if (!bpm) return;
-
- if (newBPM) bpm.bpm = newBPM;
- if (newBeat) bpm.beat = newBeat;
-
- bpm.update();
- this.calcRealTime();
- return bpm;
- }
-
- findByID(id: string) {
- const bpm = this.find((e) => e.id === id);
- return bpm;
- }
-
- findByTime(beat: BeatArray) {
- const beatNum = BeatArrayToNumber(beat);
- const bpm = this.find((e) => e.beatNum === beatNum);
- return bpm;
- }
-
- getRealTime(beat: BeatArray | number) {
- if (typeof beat === 'number') return this.getRealTimeByBeatNum(beat);
- else return this.getRealTimeByBeatNum(BeatArrayToNumber(beat));
- }
-
- timeToBeatNum(time: number) {
- if (this.length === 1 || time < 0) return parseDoublePrecist(time / this[0].timePerBeat, 6, -1);
-
- for (const bpm of this) {
- if (bpm.endTime <= time) continue;
- if (bpm.time > time) break;
-
- return parseDoublePrecist(bpm.beatNum + (time - bpm.time) / bpm.timePerBeat, 6, -1);
- }
-
- throw new Error(`Cannot found beat number for time ${time}`);
- }
-
- private calcRealTime() {
- this.sort(BPMSortFn);
- if (BeatArrayToNumber(this[0].beat) !== 0) {
- this[0].beat = [ 0, 0, 1 ];
- this[0].beatNum = 0;
- }
-
- let currentTimePerBeat = this[0].timePerBeat;
- let bpmChangedBeat = 0;
- let bpmChangedTime = 0;
-
- for (let i = 0; i < this.length; i++) {
- const bpm = this[i];
- const bpmNext = this[i + 1];
-
- bpmChangedTime = parseDoublePrecist(bpmChangedTime + (
- currentTimePerBeat * (bpm.beatNum - bpmChangedBeat)
- ), 6, -1);
- bpmChangedBeat = parseDoublePrecist(bpmChangedBeat + (
- bpm.beatNum - bpmChangedBeat
- ), 6, -1);
- currentTimePerBeat = bpm.timePerBeat;
-
- bpm.time = bpmChangedTime;
- bpm.endBeat = bpmNext ? bpmNext.beat : [ Infinity, 0, 1 ];
- bpm.endBeatNum = bpmNext ? BeatArrayToNumber(bpmNext.beat) : Infinity;
- bpm.endTime = bpmNext ? parseDoublePrecist(bpm.time + (
- bpm.timePerBeat * (bpm.endBeatNum - bpm.beatNum)
- ), 6, -1) : Infinity;
- }
- }
-
- get json(): ChartBPMExported[] {
- return this.map((e) => e.json);
- }
-
- private getRealTimeByBeatNum(beat: number) {
- if (!isFinite(beat)) return beat;
- if (this.length <= 0) return parseDoublePrecist(beat * 0.5, 6, -1);
- if (this.length === 1 || beat < 0) return parseDoublePrecist((beat - this[0].beatNum) * this[0].timePerBeat, 6, -1);
-
- for (const bpm of this) {
- if (bpm.endBeatNum <= beat) continue;
- if (bpm.beatNum > beat) break;
-
- return parseDoublePrecist(bpm.time + (beat - bpm.beatNum) * bpm.timePerBeat, 6, -1);
- }
-
- throw new Error(`Cannot found BPM for beat ${JSON.stringify(beat)}`);
- }
-}
diff --git a/src/Chart/Chart.ts b/src/Chart/Chart.ts
deleted file mode 100644
index 1c8db70..0000000
--- a/src/Chart/Chart.ts
+++ /dev/null
@@ -1,482 +0,0 @@
-import { Container, Sprite, Texture, Ticker } from 'pixi.js';
-import { EventEmitter } from 'eventemitter3';
-import { v4 as uuid } from 'uuid';
-import Audio from '@/Audio/Audio';
-import AudioClip, { EAudioClipStatus } from '@/Audio/Clip';
-import Database from '@/Database/Database';
-import StorageFile from '@/Storage/File';
-import ChartBPMList from './BPMList';
-import ChartJudgeline, { ChartJudgelineExported } from './Judgeline';
-import ChartNote from './Note';
-import ChartTick from './Tick';
-import { ChartBookmark, ChartInfo, ChartInfoWithFile } from './types';
-import { BeatArray, Nullable, RendererSize } from '@/utils/types';
-import { CalculateRendererSize } from '@/utils/renderer';
-import { ChartBPMExported } from './BPM';
-import ChartHistory from './History/History';
-import { TChartJudgelineProps } from './JudgelineProps';
-import { ChartKeyframeExported } from './Keyframe';
-import { TProject } from '@/Database/types';
-import { ReadFileAsText } from '@/utils/file';
-import { TStorageFile } from '@/Storage/types';
-
-type $ChartInfo = ChartInfoWithFile & {
- id: string,
-};
-
-export type ChartExported = {
- info: ChartInfo,
- offset: number,
- bpm: ChartBPMExported[],
- lines: ChartJudgelineExported[],
-};
-
-class Chart {
- // Chart data
- bpm: ChartBPMList = new ChartBPMList();
- lines: ChartJudgeline[] = [];
- notes: ChartNote[] = [];
-
- _offset: number = 0;
- offsetBeat: number = 0;
-
- bookmarks: ChartBookmark[] = [];
- histories: ChartHistory = new ChartHistory(this);
-
- rendererSize = CalculateRendererSize(1, 1);
- readonly container = new Container();
-
- readonly events = new EventEmitter();
- readonly ticker: Ticker;
- readonly tick = ChartTick.bind(this);
-
- // Resources
- private _info: Nullable<$ChartInfo> = null;
- private _id: Nullable = null;
- private _music: Nullable = null;
- private _background: Nullable = null;
-
- constructor() {
- // Init ticker
- this.ticker = new Ticker();
- this.ticker.stop();
- this.ticker.add(this.tick);
- }
-
- create(infoWithFile: ChartInfoWithFile) {
- if (this._info !== null) return;
-
- this._info = {
- ...infoWithFile,
- id: uuid(),
- };
- this._id = null;
-
- this.addBPM([ 0, 0, 1 ], 120, false, false);
- this.addLine(true, false);
-
- this.loadFiles();
- this.events.emit('loaded', this);
- }
-
- load(infoWithFile: ChartInfoWithFile, chartJson: ChartExported, projectID = uuid(), chartID = uuid()) {
- if (this._info !== null) return;
-
- const addKeyframesToLine = (line: ChartJudgeline, type: keyof TChartJudgelineProps, keyframes: ChartKeyframeExported[]) => {
- for (const keyframe of keyframes) {
- line.addKeyframe(type, keyframe.beat, keyframe.value, keyframe.continuous, keyframe.easing);
- }
- };
-
- this._info = {
- ...infoWithFile,
- id: projectID,
- };
- this._id = chartID;
- this._offset = chartJson.offset / 1000;
-
- for (const bpm of chartJson.bpm) {
- this.addBPM(bpm.beat, bpm.bpm, false, false);
- }
-
- for (const line of chartJson.lines) {
- const newLine = this.addLine(false, false)!;
-
- for (const _name in line.props) {
- const name = _name as keyof TChartJudgelineProps;
- addKeyframesToLine(newLine, name, line.props[name]);
- newLine.updateProp(name, true);
- }
-
- newLine.calcFloorPositions();
-
- for (const note of line.notes) {
- newLine.addNote({
- ...note
- });
- }
- }
-
- this.loadFiles();
- this.events.emit('loaded', this);
- }
-
- saveToDatabase(): Promise> {return new Promise(async (res) => {
- if (!this._info) return res(null);
-
- const oldProject = await Database.project.get(this._info.id);
- if (oldProject) {
- const projectInfo: ChartInfo & Partial<$ChartInfo> & Partial = {
- ...oldProject,
- ...this._info,
- };
-
- delete projectInfo.music;
- delete projectInfo.background;
-
- await StorageFile.update(this._id!, new Blob([ JSON.stringify(this.json) ]));
- await Database.project.update(projectInfo.id!, projectInfo as TProject);
-
- return res(projectInfo as TProject);
- } else {
- const { id: musicID } = await StorageFile.add(this._info.music);
- const { id: backgroundID } = await StorageFile.add(this._info.background);
- const { id: chartID } = await StorageFile.add(new Blob([ JSON.stringify(this.json) ]));
-
- this._id = chartID;
-
- const projectInfo: ChartInfo & Partial<$ChartInfo> & Partial = { ...this._info };
-
- delete projectInfo.music;
- delete projectInfo.background;
-
- projectInfo.chartID = chartID;
- projectInfo.musicID = musicID;
- projectInfo.backgroundID = backgroundID;
- projectInfo.filesID = uuid(); // TODO
-
- await Database.project.add(projectInfo as TProject);
- return res(projectInfo as TProject);
- }
- })}
-
- clear() {
- if (!this._info) return;
-
- this.ticker.stop();
-
- this._music?.destroy();
- this._background?.destroy();
-
- this._music = null;
- this._background = null;
- this._info = null;
- this._id = null;
-
- this.bpm.length = 0;
- this.lines.length = 0;
-
- this.events.emit('clear', null);
- }
-
- loadFromDatabase(projectID: string) {return new Promise(async (res, rej) => {
- if (this._info !== null) return res(null);
-
- const projectMeta = await Database.project.get(projectID);
- if (!projectMeta) return rej(`No project found: ${projectID}`);
-
- const musicFile = await StorageFile.get(projectMeta.musicID) as Nullable;
- if (!musicFile) return rej(`No file found: ${projectMeta.musicID}`);
-
- const backgroundFile = await StorageFile.get(projectMeta.backgroundID) as Nullable;
- if (!backgroundFile) return rej(`No file found: ${projectMeta.backgroundID}`);
-
- const chartFile = await StorageFile.get(projectMeta.chartID) as Nullable;
- if (!chartFile) return rej(`No file found: ${projectMeta.chartID}`);
-
- // TODO: Extra files
-
- const chartText = await ReadFileAsText(chartFile.blob);
- const chartJson = JSON.parse(chartText) as ChartExported;
-
- this.load({
- name: projectMeta.name,
- artist: projectMeta.artist,
- illustration: projectMeta.illustration,
- level: projectMeta.level,
- designer: projectMeta.designer,
- music: musicFile.blob,
- background: backgroundFile.blob,
- }, chartJson, projectMeta.id, projectMeta.chartID);
- res(this);
- })}
-
- async play() {
- if (!this._info) return;
- await this.waitAudio();
- this._music!.play();
- }
-
- async pause() {
- if (!this._info) return;
- await this.waitAudio();
- this._music!.pause();
- }
-
- async playOrPause() {
- if (!this._info) return;
- await this.waitAudio();
- if (this._music!.status === EAudioClipStatus.PLAY) this._music!.pause();
- else this._music!.play();
- }
-
- async stop() {
- if (!this._info) return;
- await this.waitAudio();
- this._music!.stop();
- }
-
- addLine(addDefaultKeyframes = true, addToHistory = true) {
- if (!this._info) return;
- const newLine = new ChartJudgeline(this, addDefaultKeyframes);
- this.lines.push(newLine);
- this.container.addChild(newLine.sprite);
- if (addToHistory) this.histories.add({
- name: 'line',
- action: 'add',
- id: newLine.id,
- after: newLine.json,
- });
-
- this.events.emit('lines.added', newLine);
- this.events.emit('lines.updated', this.lines);
-
- return newLine;
- }
-
- removeLine(id: string, emit = true, addToHistory = true) {
- if (!this._info) return;
- const lineIndex = this.lines.findIndex((e) => e.id === id);
- if (lineIndex === -1) return;
-
- const line = this.lines[lineIndex];
- line.destroy();
- this.lines.splice(lineIndex, 1);
- if (addToHistory) this.histories.add({
- name: 'line',
- action: 'delete',
- id: line.id,
- before: line.json,
- });
-
- if (emit) {
- this.events.emit('lines.removed', line);
- this.events.emit('lines.updated', [ ...this.lines ]);
- }
- }
-
- addBPM(time: BeatArray, bpm: number, emit = true, addToHistory = true) {
- if (!this._info) return;
- const newBPM = this.bpm.add(time, bpm);
- if (addToHistory) this.histories.add({
- name: 'bpm',
- action: 'add',
- id: newBPM.id,
- after: newBPM.json,
- });
-
- this.updateLinesTime();
- this.updateOffsetBeat();
- if (emit) this.events.emit('bpms.updated', [ ...this.bpm ]);
- }
-
- editBPM(id: string, newBeat?: BeatArray, newBPM?: number, emit = true) {
- if (!this._info) return;
- this.bpm.edit(id, newBPM, newBeat);
- this.updateLinesTime();
- this.updateOffsetBeat();
- if (emit) this.events.emit('bpms.updated', [ ...this.bpm ]);
- }
-
- removeBPM(id: string, emit = true, addToHistory = true) {
- if (!this._info) return;
- const oldBPM = this.bpm.remove(id);
- if (!oldBPM) return;
- if (addToHistory) this.histories.add({
- name: 'bpm',
- action: 'delete',
- id: oldBPM.id,
- before: oldBPM.json,
- })
-
- this.updateLinesTime();
- this.updateOffsetBeat();
- if (emit) this.events.emit('bpms.updated', [ ...this.bpm ]);
- }
-
- resize(size: RendererSize) {
- this.rendererSize = size;
-
- this.container.position.set(
- size.widthRealHalf,
- size.heightHalf
- );
-
- for (const line of this.lines) {
- line.resize(size);
- }
- }
-
- updateOffsetBeat() {
- if (!this._info) return;
- if (this.bpm.length <= 0) return;
-
- const offsetBeat = this.bpm.timeToBeatNum(this._offset);
- if (this.offsetBeat === offsetBeat) return;
-
- this.offsetBeat = offsetBeat;
- this.events.emit('offset.updated', { offset: this.offset, offsetBeat: offsetBeat });
- }
-
- get info(): Nullable {
- if (!this._info) return null;
-
- const chartInfo: Partial & ChartInfo = { ...this._info };
-
- delete chartInfo.music;
- delete chartInfo.background;
-
- return chartInfo;
- }
-
- get files() {
- if (!this._info) return null;
-
- return {
- music: this._info.music,
- background: this._info.background,
- chart: new Blob([ JSON.stringify(this.json) ]),
- };
- }
-
- get json(): Nullable {
- if (this._info === null) return null;
-
- return {
- info: this.info!,
- offset: this.offset,
- bpm: this.bpm.json,
- lines: this.lines.map((e) => e.json),
- };
- }
-
- get status() {
- if (!this._info) return EAudioClipStatus.STOP;
- return this._music ? this._music.status : EAudioClipStatus.STOP;
- }
-
- get time() {
- if (!this._info) return 0;
- return this._music ? this._music.time : 0;
- }
-
- set time(time: number) {
- if (!this._info) return;
- this.waitAudio()
- .then(() => this._music!.seek(time))
- .catch(() => void 0);
- }
-
- get duration() {
- if (!this._info) return 0;
- return this._music ? this._music.duration : 0;
- }
-
- get beatNum() {
- if (!this._info) return 0;
- return this.bpm.timeToBeatNum(this.time);
- }
-
- set beatNum(beatNum: number) {
- if (!this._info) return;
- this.waitAudio()
- .then(() => this._music!.seek(this.bpm.getRealTime(beatNum)))
- .catch(() => void 0);
- }
-
- get beatDuration() {
- if (!this._info) return 0;
- return this.bpm.timeToBeatNum(this.duration);
- }
-
- get offset() {
- if (!this._info) return 0;
- return this._offset * 1000;
- }
-
- set offset(offset: number) {
- const _offset = offset / 1000;
- this._offset = _offset;
-
- this.updateOffsetBeat();
- this.waitAudio()
- .then((clip) => {
- clip.timeOffset = _offset;
- })
- .catch(() => void 0);
- }
-
- private loadFiles() {
- if (!this._info) return;
-
- AudioClip.from(this._info.music, Audio.channels.music)
- .then((clip) => {
- clip.timeOffset = this._offset;
- this._music = clip;
-
- this.updateOffsetBeat();
- this.ticker.start();
- this.events.emit('music.loaded', this._music);
- })
- .catch((e) => { throw e });
-
- createImageBitmap(this._info.background)
- .then((bitmap) => {
- this._background = Sprite.from(Texture.from(bitmap));
- this._background.anchor.set(0.5);
-
- this.events.emit('background.loaded', this._background);
- })
- .catch((e) => { throw e });
- }
-
- private waitAudio(): Promise {return new Promise((res) => {
- if (this._music) return res(this._music);
- const clockId = setInterval(() => {
- if (!this._music) return;
- res(this._music);
- clearInterval(clockId);
- }, 200);
- })}
-
- private updateLinesTime() {
- for (const line of this.lines) {
- line.updateProp('speed', true);
- line.updateProp('positionX', true);
- line.updateProp('positionY', true);
- line.updateProp('rotate', true);
- line.updateProp('alpha', true);
-
- line.calcFloorPositions();
- for (const note of line.notes) {
- line.calcNoteTime(note);
- }
- }
- }
-}
-
-const chart = new Chart();
-console.log(chart);
-
-export default chart;
-export { Chart };
diff --git a/src/Chart/History/History.ts b/src/Chart/History/History.ts
deleted file mode 100644
index 6af3e73..0000000
--- a/src/Chart/History/History.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import Chart from '../Chart';
-import { HistoryType } from './types';
-
-class ChartHistory extends Array {
- readonly chart: Chart;
- currentIndex = 0;
-
- constructor(chart: Chart, histories?: HistoryType[]) {
- super();
-
- this.chart = chart;
- if (histories) this.push(...histories);
- }
-
- add(action: HistoryType) {
- this.unshift(action);
- this.currentIndex = 0;
- // TODO: History count in settings
- if (this.length > 20) this.length = 20;
- }
-
-
-}
-
-export default ChartHistory;
diff --git a/src/Chart/History/types.ts b/src/Chart/History/types.ts
deleted file mode 100644
index ddaff85..0000000
--- a/src/Chart/History/types.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { ChartBPMExported } from "../BPM";
-import { ChartJudgelineExported } from "../Judgeline";
-import { TChartJudgelineProps } from "../JudgelineProps";
-import { ChartKeyframeExported } from "../Keyframe";
-import { ChartNoteExported } from "../Note";
-
-
-export type HistoryBaseAdd = {
- id: string,
- action: 'add',
- after: Partial,
-};
-
-export type HistoryBaseEdit = {
- id: string,
- action: 'edit',
- before: Partial,
- after: Partial,
-};
-
-export type HistoryBaseDelete = {
- id: string,
- action: 'delete',
- before: Partial,
-};
-
-export type HistoryBase = HistoryBaseAdd | HistoryBaseEdit | HistoryBaseDelete;
-
-
-export type HistoryBPM = HistoryBase & {
- name: 'bpm',
-};
-
-export type HistoryLine = HistoryBase & {
- name: 'line',
-};
-
-export type HistoryKeyframe = HistoryBase & {
- name: 'keyframe',
- type: keyof TChartJudgelineProps,
- lineID: string,
-};
-
-export type HistoryNote = HistoryBase & {
- name: 'note',
- lineID: string,
-};
-
-export type HistoryType = HistoryBPM | HistoryLine | HistoryKeyframe | HistoryNote;
diff --git a/src/Chart/Judgeline.ts b/src/Chart/Judgeline.ts
deleted file mode 100644
index 0525b72..0000000
--- a/src/Chart/Judgeline.ts
+++ /dev/null
@@ -1,388 +0,0 @@
-import { v4 as uuid } from 'uuid';
-import { EventEmitter } from 'eventemitter3';
-import { BeatArray, RendererSize } from '@/utils/types';
-import JudgelineProps, { ChartJudgelinePropsExported, TChartJudgelineProps } from './JudgelineProps';
-import ChartKeyframe, { TChartKeyframe } from './Keyframe';
-import Note, { ChartNoteExported, ChartNoteProps } from './Note';
-import { BeatArrayToNumber, parseDoublePrecist } from '@/utils/math';
-import { getLinePropValue } from '@/utils/chart';
-import { Container, Sprite, Texture } from 'pixi.js';
-import Chart from './Chart';
-import { FloorPosition, NoteType } from './types';
-
-const PropsSortFn = (a: ChartKeyframe, b: ChartKeyframe) => a.beatNum - b.beatNum;
-
-export type ChartJudgelineExported = {
- props: ChartJudgelinePropsExported,
- notes: ChartNoteExported[],
-};
-
-export default class ChartJudgeline {
- /** Internal property */
- readonly id: string;
- readonly chart: Chart;
-
- props: JudgelineProps;
- floorPositions: FloorPosition[] = [];
- notes: Note[] = [];
-
- // Used for live preview
- _speed: number = 1;
- _posX: number = 0;
- _posY: number = 0;
- _alpha: number = 1;
- _rotate: number = 0;
-
- _fPos: number = 0;
- _realPosX: number = 0;
- _realPosY: number = 0;
- _radian: number = 0;
- _cosr: number = 0;
- _sinr: number = 0;
-
- readonly events: EventEmitter = new EventEmitter();
- sprite!: Sprite;
-
- constructor(chart: Chart, addDefaultKeyframes = true, id = uuid()) {
- this.id = id;
- this.chart = chart;
-
- this.props = new JudgelineProps(addDefaultKeyframes);
-
- if (addDefaultKeyframes) {
- this.updateProp('speed', true);
- this.updateProp('positionX', true);
- this.updateProp('positionY', true);
- this.updateProp('rotate', true);
- this.updateProp('alpha', true);
-
- this.calcFloorPositions();
- }
-
- this.createSprite();
- }
-
- addKeyframe(
- type: keyof TChartJudgelineProps,
- beat: BeatArray,
- value: number,
- continuous: boolean,
- easing: number
- ) {
- const keyframeArr = this.props[type];
- if (!keyframeArr || !(keyframeArr instanceof Array)) throw new Error(`No such type: ${type}`);
- if (this.findKeyframeByBeat(type, beat)) return;
-
- const newKeyframe = new ChartKeyframe(type, beat, value, continuous, easing);
- keyframeArr.push(newKeyframe);
-
- this.updateProp(type);
- if (type === 'speed') {
- this.calcFloorPositions();
- this.updateNotesFloorPosition();
- }
-
- this.events.emit('props.updated', { type, keyframes: [ ...keyframeArr ] });
- }
-
- editKeyframe(
- type: keyof TChartJudgelineProps,
- id: string,
- newProps: Partial = {}
- ) {
- const keyframeArr = this.props[type];
- if (!keyframeArr || !(keyframeArr instanceof Array)) throw new Error(`No such type: ${type}`);
-
- const keyframe = this.findKeyframeById(type, id);
- if (!keyframe) throw new Error(`Cannot find keyframe ID: "${id}" for props ${type}`);
- if (newProps.beat && this.findKeyframeByBeat(type, newProps.beat)) return;
-
- const prevKeyframe = keyframeArr.find((e) => e.nextKeyframe && e.nextKeyframe.id === keyframe.id);
- if (prevKeyframe) prevKeyframe.nextKeyframe = null;
-
- for (const name in newProps) {
- // XXX: This sucks
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-expect-error
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- keyframe[name] = newProps[name];
- }
-
- keyframe.beatNum = BeatArrayToNumber(keyframe.beat);
- keyframe.time = this.chart.bpm.getRealTime(keyframe.beat);
-
- this.updateProp(type);
- if (type === 'speed') {
- this.calcFloorPositions();
- this.updateNotesFloorPosition();
- }
-
- this.events.emit('props.updated', { type, keyframes: [ ...keyframeArr ] });
- }
-
- deleteKeyframe(type: keyof TChartJudgelineProps, id: string) {
- const keyframeArr = this.props[type];
- if (!keyframeArr || !(keyframeArr instanceof Array)) throw new Error(`No such type: ${type}`);
- if (keyframeArr.length === 1) return;
-
- const keyframeIndex = keyframeArr.findIndex((e) => e.id === id);
- if (keyframeIndex === -1) throw new Error(`Cannot find keyframe ID: "${id}" for props ${type}`);
-
- const prevKeyframe = keyframeArr.find((e) => e.nextKeyframe && e.nextKeyframe.id === id);
- if (prevKeyframe) prevKeyframe.nextKeyframe = null;
-
- // const keyframe = keyframeArr[keyframeIndex];
- keyframeArr.splice(keyframeIndex, 1);
-
- this.updateProp(type);
- if (type === 'speed') {
- this.calcFloorPositions();
- this.updateNotesFloorPosition();
- }
-
- this.events.emit('props.updated', { type, keyframes: [ ...keyframeArr ] });
- }
-
- findKeyframeByBeat(type: keyof TChartJudgelineProps, beat: BeatArray) {
- const keyframeArr = this.props[type];
- if (!keyframeArr || !(keyframeArr instanceof Array)) throw new Error(`No such type: ${type}`);
-
- const beatNum = BeatArrayToNumber(beat);
- return keyframeArr.find((e) => e.beatNum === beatNum);
- }
-
- findKeyframeById(type: keyof TChartJudgelineProps, id: string) {
- const keyframeArr = this.props[type];
- if (!keyframeArr || !(keyframeArr instanceof Array)) throw new Error(`No such type: ${type}`);
-
- return keyframeArr.find((e) => e.id === id);
- }
-
- addNote(props: Omit, id = uuid()) {
- const note = this.calcNoteTime(new Note({
- ...props,
- line: this,
- }, id));
- this.notes.push(note);
- this.sortNotes();
-
- note.resize(this.chart.rendererSize);
- this.sprite.parent.addChild(note.sprite!);
-
- this.events.emit('note.added', note);
- this.events.emit('notes.updated', [ ...this.notes ]);
-
- return note;
- }
-
- editNote(id: string, newProps: Partial>) {
- const note = this.findNoteById(id);
- if (!note) throw new Error(`Cannot find note ID: "${id}" for line "${this.id}"`);
-
- for (const name in newProps) {
- // XXX: This sucks
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-expect-error
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- note[name] = newProps[name];
- }
-
- note.beatNum = BeatArrayToNumber(note.beat);
- note.updateHoldProps();
- this.calcNoteTime(note);
- this.sortNotes();
-
- if (newProps['type'] !== (void 0)) note.createSprite(this.sprite.parent);
- note.resize(this.chart.rendererSize);
-
- this.events.emit('notes.updated', [ ...this.notes ]);
- }
-
- deleteNote(id: string) {
- const noteIndex = this.notes.findIndex((e) => e.id === id);
- if (noteIndex === -1) throw new Error(`Cannot find note ID: "${id}" for line "${this.id}"`);
-
- const note = this.notes[noteIndex];
- this.notes.splice(noteIndex, 1);
- note.sprite!.removeFromParent();
- note.sprite!.destroy();
-
- this.events.emit('note.removed', note);
- this.events.emit('notes.updated', [ ...this.notes ]);
- }
-
- findNoteById(id: string) {
- return this.notes.find((e) => e.id === id);
- }
-
- getFloorPosition(time: number) {
- const getFloorPosition = (time: number) => {
- for (const event of this.floorPositions) {
- if (event.endTime <= time) continue;
- if (event.time > time) break;
-
- return event;
- }
-
- return {
- time,
- endTime: Infinity,
- value: time,
- };
- };
-
- const speed = getLinePropValue(time, this.props.speed, 1);
- const floorPosition = getFloorPosition(time);
-
- return parseDoublePrecist(floorPosition.value + (speed * (time - floorPosition.time)), 3, 1);
- }
-
- createSprite(container?: Container) {
- this.sprite = new Sprite(Texture.WHITE);
-
- this.sprite.width = 1920;
- this.sprite.height = 3;
- this.sprite.anchor.set(0.5);
-
- if (container) container.addChild(this.sprite);
- return this.sprite;
- }
-
- resize(size: RendererSize) {
- const scaleX = Math.round((4000 / 1920) * (size.width / 1350) * 1920);
- const scaleY = Math.round(size.lineScale * 18.75 * 0.008);
-
- this.sprite.scale.set(scaleX, scaleY);
-
- for (const note of this.notes) {
- note.resize(size);
- }
- }
-
- updateProp(type: keyof TChartJudgelineProps, forceUpdateTime = false) {
- this.props[type].sort(PropsSortFn);
- this.props[type] = this.calcPropTime(this.props[type], forceUpdateTime);
- return this.props[type];
- }
-
- destroy() {
- this.sprite.removeFromParent();
- this.sprite.destroy();
-
- for (const note of this.notes) {
- if (!note.sprite) continue;
- note.sprite.removeFromParent();
- note.sprite.destroy();
- }
- }
-
- get json(): ChartJudgelineExported {
- return {
- props: this.props.json,
- notes: this.notes.map((e) => e.json),
- };
- }
-
- private calcPropTime(keyframes: ChartKeyframe[], forceUpdateTime = false) {
- for (let i = 0; i < keyframes.length; i++) {
- const keyframe = keyframes[i];
- const keyframeNext = keyframes[i + 1];
-
- if (isNaN(keyframe.time) || forceUpdateTime) keyframe.time = this.chart.bpm.getRealTime(keyframe.beat);
-
- if (!keyframeNext) continue;
- if (keyframeNext.continuous) {
- keyframe.nextKeyframe = keyframeNext
- } else {
- keyframe.nextKeyframe = null;
- }
- }
-
- return keyframes;
- }
-
- private sortNotes() {
- this.notes.sort((a, b) => BeatArrayToNumber(a.beat) - BeatArrayToNumber(b.beat));
- }
-
- calcNoteTime(note: Note) {
- note.time = this.chart.bpm.getRealTime(note.beat);
- note.holdEndTime = this.chart.bpm.getRealTime(note.holdEndBeat);
- this.updateNoteFloorPosition(note);
-
- return note;
- }
-
- calcFloorPositions() {
- this.floorPositions.length = 0;
-
- for (const keyframe of this.props.speed) {
- const { nextKeyframe } = keyframe;
- if (!nextKeyframe || nextKeyframe.value === keyframe.value) {
- this.floorPositions.push({
- time: keyframe.time,
- endTime: NaN,
- value: NaN,
- });
- continue;
- }
-
- const beatBetween = nextKeyframe.beatNum - keyframe.beatNum;
- for (let i = 0, count = Math.ceil(beatBetween / 0.125); i < count; i++) {
- const beatPercent = i / count;
- const beatPercentNext = i < count - 1 ? (i + 1) / count : 1;
- const currentTime = keyframe.time * (1 - beatPercent) + nextKeyframe.time * beatPercent;
- const nextTime = keyframe.time * (1 - beatPercentNext) + nextKeyframe.time * beatPercentNext;
-
- this.floorPositions.push({
- time: currentTime,
- endTime: nextTime,
- value: NaN,
- });
- }
-
- this.floorPositions.push({
- time: nextKeyframe.time,
- endTime: NaN,
- value: NaN,
- });
- }
-
- this.floorPositions.sort((a, b) => a.time - b.time);
- if (this.floorPositions[0].time !== 0) {
- this.floorPositions.unshift({
- time: 0,
- endTime: this.floorPositions[0].time,
- value: 0,
- });
- }
-
- let currentFloorPosition = 0;
- for (let i = 0; i < this.floorPositions.length; i++) {
- const event = this.floorPositions[i];
- const eventNext = this.floorPositions[i + 1];
-
- event.value = currentFloorPosition;
- event.endTime = eventNext ? eventNext.time : Infinity;
-
- if (eventNext) currentFloorPosition = parseDoublePrecist(currentFloorPosition +
- (eventNext.time - event.time) * getLinePropValue(event.time, this.props.speed, 1)
- , 3, -1);
- }
- }
-
- private updateNoteFloorPosition(note: Note) {
- note.floorPosition = this.getFloorPosition(note.time);
- if (note.type === NoteType.HOLD) note.holdEndPosition = this.getFloorPosition(note.holdEndTime);
- else note.holdEndPosition = note.floorPosition;
-
- note.updateHoldProps();
- }
-
- updateNotesFloorPosition() {
- for (const note of this.notes) {
- this.updateNoteFloorPosition(note);
- note.resize(this.chart.rendererSize);
- }
- }
-}
diff --git a/src/Chart/JudgelineProps.ts b/src/Chart/JudgelineProps.ts
deleted file mode 100644
index c040fe0..0000000
--- a/src/Chart/JudgelineProps.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import ChartKeyframe, { ChartKeyframeExported } from './Keyframe';
-
-export type TChartJudgelineProps = {
- speed: ChartKeyframe[],
- positionX: ChartKeyframe[],
- positionY: ChartKeyframe[],
- alpha: ChartKeyframe[],
- rotate: ChartKeyframe[],
-};
-
-export type ChartJudgelinePropsExported = {
- speed: ChartKeyframeExported[],
- positionX: ChartKeyframeExported[],
- positionY: ChartKeyframeExported[],
- rotate: ChartKeyframeExported[],
- alpha: ChartKeyframeExported[],
-};
-
-export default class ChartJudgelineProps implements TChartJudgelineProps {
- speed: ChartKeyframe[] = [];
- /**
- * Center: half of the screen width
- * Unit: Percent
- * Value: half of the screen width
- */
- positionX: ChartKeyframe[] = [];
- /**
- * Center: half of the screen height
- * Unit: Percent
- * Value: half of the screen height
- */
- positionY: ChartKeyframe[] = [];
- /**
- * Range: 0-255
- */
- alpha: ChartKeyframe[] = [];
- /**
- * Unit: Angle
- */
- rotate: ChartKeyframe[] = [];
-
- constructor(addDefaultKeyframes = true) {
- if (addDefaultKeyframes) {
- this.speed.push(new ChartKeyframe('speed', [ 0, 0, 1 ], 1, false, 0));
- this.positionX.push(new ChartKeyframe('positionX', [ 0, 0, 1 ], 0, false, 0));
- this.positionY.push(new ChartKeyframe('positionY', [ 0, 0, 1 ], 0, false, 0));
- this.alpha.push(new ChartKeyframe('alpha', [ 0, 0, 1 ], 255, false, 0));
- this.rotate.push(new ChartKeyframe('rotate', [ 0, 0, 1 ], 0, false, 0));
- }
- }
-
- get json(): ChartJudgelinePropsExported {
- return {
- speed: this.speed.map((e) => e.json),
- positionX: this.positionX.map((e) => e.json),
- positionY: this.positionY.map((e) => e.json),
- rotate: this.rotate.map((e) => e.json),
- alpha: this.alpha.map((e) => e.json),
- };
- }
-}
diff --git a/src/Chart/Keyframe.ts b/src/Chart/Keyframe.ts
deleted file mode 100644
index e7a75eb..0000000
--- a/src/Chart/Keyframe.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { v4 as uuid } from 'uuid';
-import { BeatArrayToNumber } from '@/utils/math';
-import { BeatArray, Nullable } from '@/utils/types';
-import ChartJudgelineProps from './JudgelineProps';
-
-export type TChartKeyframe = {
- beat: BeatArray;
- beatNum: number;
- value: number;
- continuous: boolean;
- easing: number;
-};
-
-export type ChartKeyframeExported = Omit;
-
-export default class ChartKeyframe implements TChartKeyframe {
- /** Internal property */
- readonly id: string;
- readonly type: keyof ChartJudgelineProps;
-
- beat: BeatArray;
- beatNum: number;
- value: number;
- continuous: boolean;
- easing: number;
-
- time: number;
- nextKeyframe: Nullable = null;
-
- constructor(
- type: keyof ChartJudgelineProps,
- beat: BeatArray,
- value: number,
- continuous: boolean,
- easing: number,
- id = uuid()
- ) {
- if (BeatArrayToNumber(beat) < 0) throw new Error('Cannot set a negative beat to keyframe!');
- this.type = type;
- this.id = id;
-
- this.beat = beat;
- this.beatNum = BeatArrayToNumber(this.beat);
- this.value = value;
- this.continuous = continuous;
- this.easing = easing;
-
- // TODO: Auto-generating these
- this.time = NaN;
- }
-
- get json(): ChartKeyframeExported {
- return {
- beat: this.beat,
- value: this.value,
- continuous: this.continuous,
- easing: this.easing,
- };
- }
-}
diff --git a/src/Chart/Note.ts b/src/Chart/Note.ts
deleted file mode 100644
index a01c902..0000000
--- a/src/Chart/Note.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-import { v4 as uuid } from 'uuid';
-import ChartJudgeline from './Judgeline';
-import { BeatArrayToNumber } from '@/utils/math';
-import { NoteType } from './types';
-import { BeatArray, RendererSize } from '@/utils/types';
-import { Sprite, Container, Texture } from 'pixi.js';
-
-const getNoteTexture = (type: NoteType) => {
- if (type === NoteType.DRAG) return 'note-drag';
- else if (type === NoteType.FLICK) return 'note-flick';
- else return 'note-tap';
-};
-
-export type ChartNoteProps = {
- line: ChartJudgeline,
- type: NoteType,
- beat: BeatArray,
- positionX: number,
- speed: number,
- isAbove: boolean,
-
- holdEndBeat?: BeatArray
-};
-
-export type ChartNotePropsNoLine = Omit;
-
-export type ChartNoteExported = ChartNotePropsNoLine & { holdEndBeat: BeatArray };
-
-export default class ChartNote {
- /** Internal property */
- readonly id: string;
-
- line: ChartJudgeline;
- type: NoteType;
- beat: BeatArray;
- positionX: number;
- speed: number;
- isAbove: boolean;
-
- holdEndBeat: BeatArray;
-
- beatNum: number;
- time: number;
- holdEndBeatNum!: number;
- holdEndTime: number;
- holdLengthBeatNum!: number;
- holdLengthTime!: number;
-
- floorPosition: number;
- holdLength!: number;
- holdEndPosition!: number;
-
- sprite?: Sprite | Container;
-
- _realLinePosX: number = 0;
- _realLinePosY: number = 0;
- _realPosX: number = 0;
- _realPosY: number = 0;
-
- constructor({
- line,
- type,
- beat,
- positionX,
- speed,
- isAbove,
-
- holdEndBeat
- }: ChartNoteProps, id = uuid()) {
- this.id = id;
-
- this.line = line;
- this.type = type;
- this.beat = beat;
- this.positionX = positionX;
- this.speed = speed;
- this.isAbove = isAbove;
-
- this.beatNum = BeatArrayToNumber(this.beat);
- this.holdEndBeat = this.type === NoteType.HOLD && holdEndBeat ? holdEndBeat : this.beat;
-
- // TODO: Auto-generating these
- this.time = 0;
- this.holdEndTime = 0;
- this.floorPosition = 0;
- this.holdEndPosition = 0;
-
- this.updateHoldProps();
- this.createSprite();
- }
-
- updateHoldProps() {
- this.holdEndBeatNum = this.type === NoteType.HOLD ? BeatArrayToNumber(this.holdEndBeat) : this.beatNum;
- if (this.holdEndBeatNum < this.beatNum) {
- this.holdEndBeat = this.beat;
- this.holdEndBeatNum = this.beatNum;
- }
-
- this.holdLengthBeatNum = this.type === NoteType.HOLD ? this.holdEndBeatNum - this.beatNum : 0;
- this.holdLengthTime = this.type === NoteType.HOLD ? this.holdEndTime - this.time : 0;
- this.holdLength = this.type === NoteType.HOLD ? this.holdEndPosition - this.floorPosition : 0;
- }
-
- createSprite(container?: Container) {
- if (this.sprite) {
- if (this.sprite.parent) this.sprite.parent.removeChild(this.sprite);
- this.sprite.destroy();
- this.sprite = (void 0);
- }
-
- if (this.type !== NoteType.HOLD) this.sprite = this.createSpriteNonHold();
- else this.sprite = this.createSpriteHold();
-
- if (container) container.addChild(this.sprite);
- return this.sprite;
- }
-
- resize(size: RendererSize) {
- if (!this.sprite) return;
-
- if (this.type === NoteType.HOLD) {
- const holdLength = this.holdLength * this.speed * size.noteSpeed / size.noteScale;
- this.sprite.children[1].height = holdLength;
- this.sprite.children[2].position.y = -holdLength;
- }
-
- this.sprite.scale.set(size.noteScale);
- }
-
- get json(): ChartNoteExported {
- return {
- type: this.type,
- beat: this.beat,
- positionX: this.positionX,
- speed: this.speed,
- isAbove: this.isAbove,
- holdEndBeat: this.holdEndBeat || this.beat,
- };
- }
-
- private createSpriteNonHold() {
- const sprite = new Sprite(Texture.from(getNoteTexture(this.type)));
- sprite.anchor.set(0.5);
- return sprite;
- }
-
- private createSpriteHold() {
- const container = new Container();
- const holdHead = new Sprite(Texture.from('note-hold-head'));
- const holdBody = new Sprite(Texture.from('note-hold-body'));
- const holdEnd = new Sprite(Texture.from('note-hold-end'));
-
- holdHead.anchor.set(0.5, 0);
- holdBody.anchor.set(0.5, 1);
- holdEnd.anchor.set(0.5, 1);
-
- container.addChild(
- holdHead,
- holdBody,
- holdEnd
- );
- return container;
- }
-}
diff --git a/src/Chart/Tick.ts b/src/Chart/Tick.ts
deleted file mode 100644
index ddd0628..0000000
--- a/src/Chart/Tick.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import { Chart } from './Chart';
-import { getLinePropValue } from '@/utils/chart';
-import { NoteType } from './types';
-
-function ChartTick(this: Chart) {
- const {
- rendererSize,
- lines,
- time,
- container,
- } = this;
-
- const {
- widthHalf,
- heightHalf,
- noteSpeed,
- noteScale,
- } = rendererSize;
- for (const line of lines) {
- const { props, floorPositions, sprite, notes } = line;
-
- line._speed = getLinePropValue(time, props.speed, line._speed);
- line._posX = getLinePropValue(time, props.positionX, line._posX);
- line._posY = getLinePropValue(time, props.positionY, line._posY);
- line._rotate = getLinePropValue(time, props.rotate, line._rotate);
- line._alpha = getLinePropValue(time, props.alpha, line._alpha);
-
- for (let i = 0, l = floorPositions.length; i < l; i++) {
- const event = floorPositions[i];
-
- if (event.endTime < time) continue;
- if (event.time > time) break;
-
- line._fPos = event.value + (time - event.time) * line._speed;
- }
-
- line._realPosX = line._posX / 100 * widthHalf;
- line._realPosY = line._posY / -100 * heightHalf;
-
- line._radian = line._rotate * (Math.PI / 180);
- line._cosr = Math.cos(line._radian);
- line._sinr = Math.sin(line._radian);
-
- sprite.position.set(line._realPosX, line._realPosY);
- sprite.angle = line._rotate;
- sprite.alpha = line._alpha / 255;
-
- for (const note of notes) {
- const {
- type,
- time: noteTime,
- holdEndTime,
- positionX,
- speed,
- isAbove,
- floorPosition,
- holdLength,
- holdEndPosition,
- sprite,
- } = note;
- if (!sprite) continue;
-
- if (
- (noteTime <= time) &&
- (type !== NoteType.HOLD || holdEndTime <= time)
- ) {
- if (sprite.parent) sprite.removeFromParent();
- continue;
- }
-
- const floorPositionDiff = (floorPosition - line._fPos) * speed;
- if (
- floorPositionDiff > 2 ||
- (floorPositionDiff < 0 && noteTime > time)
- ) {
- if (sprite.parent) sprite.removeFromParent();
- continue;
- }
-
- const posX = widthHalf * positionX / 100;
- const posY = floorPositionDiff * noteSpeed * (isAbove ? -1 : 1);
- const realXSin = posY * line._sinr * -1;
- const realYCos = posY * line._cosr;
-
- note._realLinePosX = posX * line._cosr + line._realPosX;
- note._realLinePosY = posX * line._sinr + line._realPosY;
-
- note._realPosX = note._realLinePosX + realXSin;
- note._realPosY = note._realLinePosY + realYCos;
-
- if (type === NoteType.HOLD) {
- const [ spriteHead, spriteBody, spriteEnd ] = sprite.children;
- let realHoldLength = holdLength * speed * noteSpeed / noteScale;
-
- spriteHead.visible = true;
- if (noteTime <= time) {
- realHoldLength = (holdEndPosition - line._fPos) * speed * noteSpeed / noteScale;
-
- note._realPosX -= realXSin;
- note._realPosY -= realYCos;
-
- spriteHead.visible = false;
- }
-
- spriteBody.height = realHoldLength;
- spriteEnd.position.y = -realHoldLength;
- }
-
- sprite.position.set(note._realPosX, note._realPosY);
- sprite.angle = line._rotate + (isAbove ? 0 : 180);
- if (!sprite.parent) container.addChild(sprite);
- }
- }
-}
-
-export default ChartTick;
diff --git a/src/Chart/types.ts b/src/Chart/types.ts
deleted file mode 100644
index 62f13bd..0000000
--- a/src/Chart/types.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Nullable } from '@/utils/types';
-
-export type ChartInfo = {
- name: string,
- artist: string,
- illustration: string,
- level: string,
- designer: string,
-};
-
-export type ChartInfoWithFile = ChartInfo & {
- music: Blob,
- background: Blob,
-};
-
-export type ChartBookmark = {
- id: string;
- beatNum: number;
- label: string;
- color: Nullable;
-};
-
-export enum NoteType {
- TAP = 1,
- DRAG = 2,
- HOLD = 3,
- FLICK = 4,
-};
-
-export type FloorPosition = {
- time: number,
- endTime: number,
- value: number,
-};
diff --git a/src/Database/Database.ts b/src/Database/Database.ts
deleted file mode 100644
index 6c45395..0000000
--- a/src/Database/Database.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import DatabaseEngine from './Engine';
-import { TProject } from './types';
-
-class Database {
- readonly project = new DatabaseEngine('editor_db_project', 1, {
- structures: [
- { name: 'id', options: { key: true, unique: true } },
- { name: 'filesID', options: { unique: true } },
- { name: 'chartID', options: { unique: true } },
- ],
- });
-};
-
-const database = new Database();
-export default database;
-export { Database };
diff --git a/src/Database/Engine.ts b/src/Database/Engine.ts
deleted file mode 100644
index 50ffc89..0000000
--- a/src/Database/Engine.ts
+++ /dev/null
@@ -1,182 +0,0 @@
-
-export type TDatabaseDataType = string | boolean | number | Blob;
-
-export type TDatabaseStructure = {
- name: string,
- options?: Partial<{
- key: boolean,
- index: boolean,
- unique: boolean,
- multiEntry: boolean,
- }>,
-};
-
-export type TDatabase = {
- structures: TDatabaseStructure[],
- autoIncrement?: boolean,
-};
-
-export type TDatabaseData = {
- [x: string]: TDatabaseDataType | TDatabaseDataType[],
-};
-
-export default class DatabaseEngine {
- readonly name: string;
- readonly version: number;
-
- private db!: IDBDatabase;
- private isReady = false;
-
- constructor(name: string, version: number, options: TDatabase) {
- this.name = name;
- this.version = version;
-
- const request = window.indexedDB.open(this.name, this.version);
-
- request.onsuccess = () => {
- const { result } = request;
- if (!result) return;
-
- this.db = result;
- if (this.db.version === version) this.isReady = true;
- };
-
- request.onerror = (e) => {
- throw (e as unknown as Error);
- };
-
- request.onupgradeneeded = () => {
- this.db = request.result;
-
- const indexes: TDatabaseStructure[] = [];
- let keyPath = null;
-
- for (const structure of options.structures) {
- const { options } = structure;
- if (!options) continue;
-
- if (options.key) keyPath = structure.name;
- else if (options.index) indexes.push(structure);
- }
-
- const objectOptions = { keyPath: keyPath, autoIncrement: options.autoIncrement };
- const store = this.db.createObjectStore(this.name, objectOptions);
-
- for (const index of indexes) {
- store.createIndex(index.name, index.name, {
- unique: index.options!.unique,
- multiEntry: index.options!.multiEntry,
- });
- }
-
- this.isReady = true;
- };
- }
-
- add(data: TData) {return new Promise(async (res, rej) => {
- await this.waitReady();
- const { db } = this;
-
- const transaction = db.transaction([ this.name ], 'readwrite');
- const store = transaction.objectStore(this.name);
-
- transaction.oncomplete = () => {
- res(transaction);
- };
- transaction.onerror = (e) => {
- rej(e);
- };
-
- store.add(data);
- })}
-
- delete(index: string | number): Promise {return new Promise(async (res, rej) => {
- await this.waitReady();
- const { db } = this;
-
- const transaction = db.transaction([ this.name ], 'readwrite');
- const store = transaction.objectStore(this.name);
- const request = store.delete(index);
-
- request.onsuccess = () => {
- res(request.result);
- };
- request.onerror = (e) => {
- rej(e);
- };
- })}
-
- get(index: string | number, key?: string): Promise {return new Promise(async (res, rej) => {
- await this.waitReady();
- const { db } = this;
-
- const transaction = db.transaction([ this.name ], 'readonly');
- const store = transaction.objectStore(this.name);
- const request = key ? store.index(key).get(index) : store.get(index);
-
- request.onsuccess = () => {
- res((request.result as TData) || null);
- };
- request.onerror = (e) => {
- rej(e);
- };
- })}
-
- getAll(): Promise {return new Promise(async (res, rej) => {
- await this.waitReady();
- const { db } = this;
- const result: TData[] = [];
-
- const transaction = db.transaction([ this.name ], 'readonly');
- const store = transaction.objectStore(this.name);
- const cursor = store.openCursor();
-
- cursor.onsuccess = (e) => {
- const _cur = (e.target as IDBRequest).result as (IDBCursorWithValue | null);
- if (_cur) {
- result.push((_cur.value as TData));
- _cur.continue();
- } else {
- res(result);
- }
- };
-
- cursor.onerror = (e) => {
- rej(e);
- };
- })}
-
- update(index: string | number, data: TData): Promise {return new Promise(async (res, rej) => {
- await this.waitReady();
- const { db } = this;
-
- const transaction = db.transaction([ this.name ], 'readwrite');
- const store = transaction.objectStore(this.name);
- const request = store.get(index);
-
- request.onsuccess = () => {
- const oldData = request.result as TData;
- const newData = { ...oldData, ...data };
-
- const reqUpdate = store.put(newData);
- reqUpdate.onsuccess = () => {
- res(newData);
- };
- reqUpdate.onerror = (e) => {
- rej(e);
- };
- };
- request.onerror = (e) => {
- rej(e);
- };
- })}
-
- private waitReady() {return new Promise((res) => {
- if (this.isReady) return res(this.isReady);
- const clockId = setInterval(() => {
- if (!this.isReady) return;
- res(this.isReady);
- clearInterval(clockId);
- }, 200);
- })}
-}
diff --git a/src/Database/types.ts b/src/Database/types.ts
deleted file mode 100644
index 59efc73..0000000
--- a/src/Database/types.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { ChartInfo } from '@/Chart/types';
-
-export type TProject = ChartInfo & {
- id: string,
- filesID: string,
- chartID: string,
- musicID: string,
- backgroundID: string,
-};
diff --git a/src/Settings/Settings.ts b/src/Settings/Settings.ts
deleted file mode 100644
index bf06482..0000000
--- a/src/Settings/Settings.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import EventEmitter from 'eventemitter3';
-import { TSettings } from './types';
-
-const STORAGE_KEY_NAME = 'editor-settings';
-
-class Settings {
- readonly storage = window.localStorage;
- readonly event = new EventEmitter();
- private _current: TSettings = {
- // Default settings goes here
- noteScale: 8000,
- };
-
- constructor() {
- const storagedSettings = JSON.parse(this.storage.getItem(STORAGE_KEY_NAME) ?? '{}') as TSettings;
-
- this._current = {
- ...this._current,
- ...storagedSettings,
- };
- this.storage.setItem(STORAGE_KEY_NAME, JSON.stringify(this._current));
- this.event.emit('settings.updated', { ...this._current });
- }
-
- /**
- * Get single setting's value
- */
- get(name: keyof TSettings): TSettings[keyof TSettings] {
- return this._current[name];
- }
-
- set(name: keyof TSettings, value: TSettings[keyof TSettings]) {
- this._current[name] = value;
- this.storage.setItem(STORAGE_KEY_NAME, JSON.stringify(this._current));
-
- this.event.emit('settings.updated', { ...this._current });
- return this._current;
- }
-
- get current() {
- return this._current;
- }
-}
-
-const settings = new Settings();
-export default settings;
-export { Settings };
diff --git a/src/Settings/types.tsx b/src/Settings/types.tsx
deleted file mode 100644
index ec58d58..0000000
--- a/src/Settings/types.tsx
+++ /dev/null
@@ -1,4 +0,0 @@
-
-export type TSettings = {
- noteScale: number,
-};
diff --git a/src/Storage/File.ts b/src/Storage/File.ts
deleted file mode 100644
index c84e028..0000000
--- a/src/Storage/File.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { v4 as uuid } from 'uuid';
-import DatabaseEngine from '@/Database/Engine';
-import { GetFileMD5 } from '@/utils/file';
-import { TStorageFile } from './types';
-import { Nullable } from '@/utils/types';
-
-class StorageFile {
- readonly db = new DatabaseEngine('editor_storage_files', 1, {
- structures: [
- { name: 'id', options: { key: true, unique: true } },
- { name: 'md5', options: { unique: true, index: true } },
- ]
- });
-
- add(blob: Blob): Promise<{ md5: string, id: string }> {return new Promise(async (res, rej) => {
- const id = uuid();
- const md5 = await GetFileMD5(blob);
- const fileData = await this.db.get(md5);
- if (fileData) return res(fileData);
-
- this.db.add({
- id, md5, blob
- }).then(() => res({ md5, id }))
- .catch(e => rej(e));
- })}
-
- remove(md5: string) {
- return this.db.delete(md5);
- }
-
- get(id: string | string[]): Promise> {
- if (typeof id === 'string') return this.db.get(id);
- return new Promise(async (res) => {
- const allFiles = await this.db.getAll();
- res(allFiles.filter((e) => id.includes(e.id)));
- });
- }
-
- getByMD5(md5: string | string[]): Promise> {
- if (typeof md5 === 'string') return this.db.get(md5, 'md5');
- return new Promise(async (res) => {
- const allFiles = await this.db.getAll();
- res(allFiles.filter((e) => md5.includes(e.md5)));
- });
- }
-
- update(id: string, file: Blob): Promise<{ md5: string }> {return new Promise(async (res, rej) => {
- const md5 = await GetFileMD5(file);
-
- this.db.update(id, {
- id, md5, blob: file,
- }).then(() => res({ md5 }))
- .catch((e) => rej(e));
- })}
-}
-
-const file = new StorageFile;
-export default file;
-export { StorageFile };
diff --git a/src/Storage/Storage.ts b/src/Storage/Storage.ts
deleted file mode 100644
index a21837b..0000000
--- a/src/Storage/Storage.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import DatabaseEngine from '@/Database/Engine';
-import StorageFile from './File';
-import { TStorage, TStorageStructure } from './types';
-
-class Storage {
- readonly file = StorageFile;
- readonly db = new DatabaseEngine('editor_storage_structure', 1, {
- structures: [
- { name: 'id', options: { key: true, unique: true } },
- { name: 'structure' }
- ],
- });
-
- add(id: string, structure: TStorageStructure) {
- return this.db.add({
- id, structure
- });
- }
-
- remove(id: string) {
- return this.db.delete(id);
- }
-
- get(id: string) {
- return this.db.get(id);
- }
-
- getAll() {
- return this.db.getAll();
- }
-
- update(id: string, structure: TStorageStructure) {
- return this.db.update(id, {
- id, structure
- });
- }
-}
-
-const storage = new Storage();
-export default storage;
-export { Storage };
diff --git a/src/Storage/types.ts b/src/Storage/types.ts
deleted file mode 100644
index 3b23eb2..0000000
--- a/src/Storage/types.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-
-export type TStorageItemBase = {
- // UUID?
- id: string,
- name: string,
- isPath: boolean,
-};
-
-export type TStorageItemFile = TStorageItemBase & {
- isPath: false,
- md5: string,
-};
-
-export type TStorageItemPath = TStorageItemBase & {
- isPath: true,
- files: TStorageItem[],
-};
-
-export type TStorageItem = TStorageItemFile | TStorageItemPath;
-
-export type TStorageStructure = Record;
-
-export type TStorage = {
- id: string,
- structure: TStorageStructure,
-};
-
-export type TStorageFile = {
- id: string,
- md5: string,
- blob: Blob,
-};
diff --git a/src/core/command/bpm/add.ts b/src/core/command/bpm/add.ts
new file mode 100644
index 0000000..79da1a7
--- /dev/null
+++ b/src/core/command/bpm/add.ts
@@ -0,0 +1,24 @@
+import { getRelativePath, SnapshotIn } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { BPM } from '@/core/models/BPM';
+import { BeatArray } from '@/utils/types';
+import { Command } from '../command';
+
+type AddBPMPayload = Omit, 'id'>;
+
+export class AddBPMCommand extends Command {
+ type: string = 'bpm.add';
+ propName = (void 0);
+
+ getState(project: IChart) {
+ return project;
+ }
+
+ getStatePath(project: IChart) {
+ return getRelativePath(project, project.bpm);
+ }
+
+ edit(payload: AddBPMPayload) {
+ this.state!.addBPM(payload.beat as BeatArray, payload.bpm);
+ }
+}
diff --git a/src/core/command/bpm/change.ts b/src/core/command/bpm/change.ts
new file mode 100644
index 0000000..3cee266
--- /dev/null
+++ b/src/core/command/bpm/change.ts
@@ -0,0 +1,18 @@
+import { resolveIdentifier } from 'mobx-state-tree';
+import { SnapshotIn } from 'mobx-state-tree';
+import { BPM, IBPM } from '@/core/models/BPM';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+
+export class ChangeBPMCommand extends Command {
+ type: string = 'bpm.change';
+ propName: keyof SnapshotIn & string = 'bpm';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(BPM, project.bpm, id);
+ }
+
+ edit(payload: number) {
+ this.state!.updateProps({ bpm: payload });
+ }
+}
diff --git a/src/core/command/bpm/move.ts b/src/core/command/bpm/move.ts
new file mode 100644
index 0000000..22bd2ec
--- /dev/null
+++ b/src/core/command/bpm/move.ts
@@ -0,0 +1,19 @@
+import { resolveIdentifier } from 'mobx-state-tree';
+import { SnapshotIn } from 'mobx-state-tree';
+import { BPM, IBPM } from '@/core/models/BPM';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+import { BeatArray } from '@/utils/types';
+
+export class MoveBPMCommand extends Command {
+ type: string = 'bpm.move';
+ propName: keyof SnapshotIn & string = 'beat';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(BPM, project.bpm, id);
+ }
+
+ edit(payload: BeatArray) {
+ this.state!.updateProps({ beat: payload });
+ }
+}
diff --git a/src/core/command/bpm/remove.ts b/src/core/command/bpm/remove.ts
new file mode 100644
index 0000000..fc28f42
--- /dev/null
+++ b/src/core/command/bpm/remove.ts
@@ -0,0 +1,21 @@
+import { getRelativePath, resolveIdentifier, getParent } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { BPM, IBPM } from '@/core/models/BPM';
+import { Command } from '../command';
+
+export class RemoveBPMCommand extends Command {
+ type: string = 'bpm.remove';
+ propName = (void 0);
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(BPM, project.bpm, id);
+ }
+
+ getStatePath(project: IChart) {
+ return getRelativePath(project, project.bpm);
+ }
+
+ edit() {
+ (getParent(this.state!, 2) as IChart).removeBPM(this.state!.id);
+ }
+}
diff --git a/src/core/command/bus.ts b/src/core/command/bus.ts
new file mode 100644
index 0000000..8cb5958
--- /dev/null
+++ b/src/core/command/bus.ts
@@ -0,0 +1,51 @@
+import { store as ChartStore } from '../state/chartStore';
+import { commandBusStore } from './state';
+import { CommandExecutor } from './types';
+
+export class CommandBus {
+ readonly history: CommandExecutor[] = [];
+ readonly redoStack: CommandExecutor[] = [];
+
+ dispatch(executor: CommandExecutor) {
+ this.history.unshift(executor);
+ this.redoStack.length = 0;
+
+ this.updateStore();
+ }
+
+ undo() {
+ const executor = this.history.shift();
+ if (!executor) return;
+
+ executor.undo(ChartStore);
+ this.redoStack.unshift(executor);
+
+ this.updateStore();
+ }
+
+ redo() {
+ const executor = this.redoStack.shift();
+ if (!executor) return;
+
+ executor.redo(ChartStore);
+ this.history.unshift(executor);
+
+ this.updateStore();
+ }
+
+ reset() {
+ this.history.length = 0;
+ this.redoStack.length = 0;
+
+ this.updateStore();
+ }
+
+ private updateStore() {
+ commandBusStore.setState({
+ history: this.history.map((e) => e.meta),
+ redoStack: this.redoStack.map((e) => e.meta),
+ });
+ }
+}
+
+export const commandBus = new CommandBus();
diff --git a/src/core/command/command.ts b/src/core/command/command.ts
new file mode 100644
index 0000000..7d1a828
--- /dev/null
+++ b/src/core/command/command.ts
@@ -0,0 +1,98 @@
+import { applyPatch, getRelativePath, onPatch } from 'mobx-state-tree';
+import { IAnyStateTreeNode, IJsonPatch, IDisposer, SnapshotIn } from 'mobx-state-tree';
+import { CommandExecutor } from './types';
+import { IChart } from '../models/Chart';
+import { Nullable } from '@/utils/types';
+
+const dedup = (patches: IJsonPatch[]) => {
+ const seen = new Set();
+ const result: IJsonPatch[] = [];
+
+ for (let i = patches.length - 1; i >= 0; i--) {
+ const p = patches[i];
+ if (p.op === 'replace' && !seen.has(p.path)) {
+ seen.add(p.path);
+ result.unshift(p);
+ } else if (p.op !== 'replace') {
+ result.unshift(p);
+ }
+ }
+
+ return result;
+};
+
+const apply = (target: IChart, patches: IJsonPatch[]) => applyPatch(target, patches);
+
+export abstract class Command {
+ // TODO: types
+ abstract readonly type: string;
+ timestamp: number = Date.now();
+ abstract readonly propName?: keyof SnapshotIn & string;
+
+ state: Nullable = null;
+ patchDisposer: Nullable = null;
+
+ isRecording = true;
+
+ patches: IJsonPatch[] = [];
+ inverse: IJsonPatch[] = [];
+
+ abstract getState(project: IChart, id: string): T | undefined;
+
+ getStatePath(project: IChart): string {
+ return this.state ? getRelativePath(project, this.state) : '/';
+ }
+
+ start(project: IChart, id: string) {
+ if (project.metadata === null)
+ throw new Error('Cannot start command before project initialized');
+ if (this.patchDisposer)
+ throw new Error('Command already started');
+
+ this.state = this.getState(project, id) ?? null;
+ if (!this.state) throw new Error(`No such state found: ${id}`);
+
+ const statePath = `${this.getStatePath(project)}${this.propName ? '/' + this.propName : ''}`;
+ this.patchDisposer = onPatch(project, (p, r) => {
+ if (!this.isRecording) return;
+ if (!p.path.startsWith(statePath)) return;
+
+ this.patches.push(p);
+ this.inverse.push(r);
+ });
+ }
+
+ abstract edit(payload: P): void;
+
+ end(merge: boolean = true) {
+ if (!this.patchDisposer)
+ throw new Error('Cannot call end() before calling start()');
+
+ this.patchDisposer();
+ this.patchDisposer = null;
+
+ if (merge) {
+ this.patches = dedup(this.patches);
+ this.inverse = dedup(this.inverse.reverse());
+ }
+
+ return this.executor;
+ }
+
+ execute(project: IChart, id: string, payload: P, merge = true) {
+ this.start(project, id);
+ this.edit(payload)
+ return this.end(merge);
+ };
+
+ get executor(): CommandExecutor {
+ return {
+ meta: {
+ type: this.type,
+ timestamp: this.timestamp,
+ },
+ undo: (target) => apply(target, this.inverse),
+ redo: (target) => apply(target, this.patches),
+ };
+ }
+}
diff --git a/src/core/command/keyframe/add.ts b/src/core/command/keyframe/add.ts
new file mode 100644
index 0000000..8456751
--- /dev/null
+++ b/src/core/command/keyframe/add.ts
@@ -0,0 +1,32 @@
+import { getRelativePath, resolveIdentifier, SnapshotIn } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { IKeyframeRecord } from '@/core/models/KeyframeRecord';
+import { JudgeLine } from '@/core/models/JudgeLine';
+import { Keyframe } from '@/core/models/Keyframe';
+import { BeatArray } from '@/utils/types';
+import { Command } from '../command';
+
+type AddKeyframePayload = Omit, 'id'>;
+
+export class AddKeyframeCommand extends Command {
+ type: string = 'keyframe.add';
+ propName = (void 0);
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(JudgeLine, project.judgelines, id)?.keyframes;
+ }
+
+ getStatePath(project: IChart) {
+ return getRelativePath(project, this.state);
+ }
+
+ edit(payload: AddKeyframePayload) {
+ this.state!.add(
+ payload.type,
+ payload.beat as BeatArray,
+ payload.value,
+ payload.continuous,
+ payload.easing
+ );
+ }
+}
diff --git a/src/core/command/keyframe/changeEasing.ts b/src/core/command/keyframe/changeEasing.ts
new file mode 100644
index 0000000..40e24ed
--- /dev/null
+++ b/src/core/command/keyframe/changeEasing.ts
@@ -0,0 +1,19 @@
+import { resolveIdentifier, SnapshotIn } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { IKeyframe, Keyframe } from '@/core/models/Keyframe';
+import { Command } from '../command';
+
+export class ChangeKeyframeEasingCommand extends Command {
+ type: string = 'keyframe.easing';
+ propName: keyof SnapshotIn = 'easing';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Keyframe, project.judgelines, id);
+ }
+
+ edit(payload: number) {
+ this.state!.updateProps({
+ easing: payload,
+ });
+ }
+}
diff --git a/src/core/command/keyframe/changeValue.ts b/src/core/command/keyframe/changeValue.ts
new file mode 100644
index 0000000..a17c38b
--- /dev/null
+++ b/src/core/command/keyframe/changeValue.ts
@@ -0,0 +1,19 @@
+import { resolveIdentifier, SnapshotIn } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { IKeyframe, Keyframe } from '@/core/models/Keyframe';
+import { Command } from '../command';
+
+export class ChangeKeyframeValueCommand extends Command {
+ type: string = 'keyframe.value';
+ propName: keyof SnapshotIn = 'value';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Keyframe, project.judgelines, id);
+ }
+
+ edit(payload: number) {
+ this.state!.updateProps({
+ value: payload,
+ });
+ }
+}
diff --git a/src/core/command/keyframe/move.ts b/src/core/command/keyframe/move.ts
new file mode 100644
index 0000000..b350baa
--- /dev/null
+++ b/src/core/command/keyframe/move.ts
@@ -0,0 +1,19 @@
+import { resolveIdentifier } from 'mobx-state-tree';
+import { SnapshotIn } from 'mobx-state-tree';
+import { Keyframe, IKeyframe } from '@/core/models/Keyframe';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+import { BeatArray } from '@/utils/types';
+
+export class MoveKeyframeCommand extends Command {
+ type: string = 'keyframe.move';
+ propName: keyof SnapshotIn & string = 'beat';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Keyframe, project.judgelines, id);
+ }
+
+ edit(payload: BeatArray) {
+ this.state!.updateProps({ beat: payload });
+ }
+}
diff --git a/src/core/command/keyframe/remove.ts b/src/core/command/keyframe/remove.ts
new file mode 100644
index 0000000..9e0fc90
--- /dev/null
+++ b/src/core/command/keyframe/remove.ts
@@ -0,0 +1,22 @@
+import { getRelativePath, resolveIdentifier, getParent } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+import { IKeyframe, Keyframe } from '@/core/models/Keyframe';
+import { IKeyframeRecord } from '@/core/models/KeyframeRecord';
+
+export class RemoveKeyframeCommand extends Command {
+ type: string = 'keyframe.remove';
+ propName = (void 0);
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Keyframe, project.judgelines, id);
+ }
+
+ getStatePath(project: IChart) {
+ return getRelativePath(project, getParent(this.state!, 2));
+ }
+
+ edit() {
+ (getParent(this.state!, 2) as IKeyframeRecord).remove(this.state!.type, this.state!.id);
+ }
+}
diff --git a/src/core/command/keyframe/setContinuous.ts b/src/core/command/keyframe/setContinuous.ts
new file mode 100644
index 0000000..978c2e8
--- /dev/null
+++ b/src/core/command/keyframe/setContinuous.ts
@@ -0,0 +1,19 @@
+import { resolveIdentifier, SnapshotIn } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { IKeyframe, Keyframe } from '@/core/models/Keyframe';
+import { Command } from '../command';
+
+export class SetKeyframeContinuousCommand extends Command {
+ type: string = 'keyframe.continuous';
+ propName: keyof SnapshotIn = 'continuous';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Keyframe, project.judgelines, id);
+ }
+
+ edit(payload: boolean) {
+ this.state!.updateProps({
+ continuous: payload,
+ });
+ }
+}
diff --git a/src/core/command/line/add.ts b/src/core/command/line/add.ts
new file mode 100644
index 0000000..5402290
--- /dev/null
+++ b/src/core/command/line/add.ts
@@ -0,0 +1,20 @@
+import { getRelativePath } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+
+export class AddLineCommand extends Command {
+ type: string = 'line.add';
+ propName = (void 0);
+
+ getState(project: IChart) {
+ return project;
+ }
+
+ getStatePath(project: IChart) {
+ return getRelativePath(project, project.judgelines);
+ }
+
+ edit() {
+ this.state!.addJudgeLine();
+ }
+}
diff --git a/src/core/command/line/remove.ts b/src/core/command/line/remove.ts
new file mode 100644
index 0000000..93d65c1
--- /dev/null
+++ b/src/core/command/line/remove.ts
@@ -0,0 +1,21 @@
+import { getRelativePath, resolveIdentifier, getParent } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { JudgeLine, IJudgeLine } from '@/core/models/JudgeLine';
+import { Command } from '../command';
+
+export class RemoveLineCommand extends Command {
+ type: string = 'line.remove';
+ propName = (void 0);
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(JudgeLine, project.judgelines, id);
+ }
+
+ getStatePath(project: IChart) {
+ return getRelativePath(project, project.judgelines);
+ }
+
+ edit() {
+ (getParent(this.state!, 2) as IChart).removeJudgeLine(this.state!.id);
+ }
+}
diff --git a/src/core/command/note/add.ts b/src/core/command/note/add.ts
new file mode 100644
index 0000000..0c7b216
--- /dev/null
+++ b/src/core/command/note/add.ts
@@ -0,0 +1,25 @@
+import { getRelativePath, resolveIdentifier } from 'mobx-state-tree';
+import { SnapshotIn } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { IJudgeLine, JudgeLine } from '@/core/models/JudgeLine';
+import { Note } from '@/core/models/Note';
+import { Command } from '../command';
+
+type AddNotePayload = Omit, 'id'>;
+
+export class AddNoteCommand extends Command {
+ type: string = 'note.add';
+ propName = (void 0);
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(JudgeLine, project.judgelines, id);
+ }
+
+ getStatePath(project: IChart) {
+ return getRelativePath(project, this.state!.notes);
+ }
+
+ edit(payload: AddNotePayload) {
+ this.state!.addNote(payload);
+ }
+}
diff --git a/src/core/command/note/changeHoldEnd.ts b/src/core/command/note/changeHoldEnd.ts
new file mode 100644
index 0000000..45e83f2
--- /dev/null
+++ b/src/core/command/note/changeHoldEnd.ts
@@ -0,0 +1,20 @@
+import { resolveIdentifier, SnapshotIn } from 'mobx-state-tree';
+import { Note, INote } from '@/core/models/Note';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+import { BeatArray } from '@/utils/types';
+
+export class ChangeNoteHoldEndCommand extends Command {
+ type: string = 'note.holdEndBeat';
+ propName: keyof SnapshotIn = 'holdEndBeat';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Note, project.judgelines, id);
+ }
+
+ edit(payload: BeatArray) {
+ this.state!.updateProps({
+ holdEndBeat: payload,
+ });
+ }
+}
diff --git a/src/core/command/note/changePositionX.ts b/src/core/command/note/changePositionX.ts
new file mode 100644
index 0000000..5d2c71f
--- /dev/null
+++ b/src/core/command/note/changePositionX.ts
@@ -0,0 +1,19 @@
+import { resolveIdentifier, SnapshotIn } from 'mobx-state-tree';
+import { Note, INote } from '@/core/models/Note';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+
+export class ChangeNotePositionXCommand extends Command {
+ type: string = 'note.positionX';
+ propName: keyof SnapshotIn = 'positionX';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Note, project.judgelines, id);
+ }
+
+ edit(payload: number) {
+ this.state!.updateProps({
+ positionX: payload,
+ });
+ }
+}
diff --git a/src/core/command/note/changeSpeed.ts b/src/core/command/note/changeSpeed.ts
new file mode 100644
index 0000000..c6e97b3
--- /dev/null
+++ b/src/core/command/note/changeSpeed.ts
@@ -0,0 +1,19 @@
+import { resolveIdentifier, SnapshotIn } from 'mobx-state-tree';
+import { Note, INote } from '@/core/models/Note';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+
+export class ChangeNoteSpeedCommand extends Command {
+ type: string = 'note.speed';
+ propName: keyof SnapshotIn = 'speed';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Note, project.judgelines, id);
+ }
+
+ edit(payload: number) {
+ this.state!.updateProps({
+ speed: payload,
+ });
+ }
+}
diff --git a/src/core/command/note/changeType.ts b/src/core/command/note/changeType.ts
new file mode 100644
index 0000000..6e4369f
--- /dev/null
+++ b/src/core/command/note/changeType.ts
@@ -0,0 +1,20 @@
+import { resolveIdentifier, SnapshotIn } from 'mobx-state-tree';
+import { Note, INote } from '@/core/models/Note';
+import { IChart } from '@/core/models/Chart';
+import { NoteType } from '@/core/types';
+import { Command } from '../command';
+
+export class ChangeNoteTypeCommand extends Command {
+ type: string = 'note.type';
+ propName: keyof SnapshotIn = 'type';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Note, project.judgelines, id);
+ }
+
+ edit(payload: NoteType) {
+ this.state!.updateProps({
+ type: payload,
+ });
+ }
+}
diff --git a/src/core/command/note/move.ts b/src/core/command/note/move.ts
new file mode 100644
index 0000000..acf91e3
--- /dev/null
+++ b/src/core/command/note/move.ts
@@ -0,0 +1,30 @@
+import { resolveIdentifier } from 'mobx-state-tree';
+import { Note, INote } from '@/core/models/Note';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+import { BeatArray } from '@/utils/types';
+import { BeatArrayToNumber, BeatNumberToArray } from '@/utils/math';
+
+export class MoveNoteCommand extends Command {
+ type: string = 'note.move';
+ propName = (void 0);
+
+ isRecording = false;
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Note, project.judgelines, id);
+ }
+
+ edit(payload: BeatArray) {
+ const newBeatNum = BeatArrayToNumber(payload);
+ let newHoldEndBeatNum = this.state!.holdEndBeatNum + (newBeatNum - this.state!.beatNum);
+ if (newHoldEndBeatNum < newBeatNum) newHoldEndBeatNum = newBeatNum;
+
+ this.isRecording = true;
+ this.state!.updateProps({
+ beat: payload,
+ holdEndBeat: BeatNumberToArray(newHoldEndBeatNum, payload[2]),
+ });
+ this.isRecording = false;
+ }
+}
diff --git a/src/core/command/note/remove.ts b/src/core/command/note/remove.ts
new file mode 100644
index 0000000..c1bffea
--- /dev/null
+++ b/src/core/command/note/remove.ts
@@ -0,0 +1,22 @@
+import { getParent, getRelativePath, resolveIdentifier } from 'mobx-state-tree';
+import { IChart } from '@/core/models/Chart';
+import { INote, Note } from '@/core/models/Note';
+import { Command } from '../command';
+import { IJudgeLine } from '@/core/models/JudgeLine';
+
+export class RemoveNoteCommand extends Command {
+ type: string = 'note.remove';
+ propName = (void 0);
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Note, project.judgelines, id);
+ }
+
+ getStatePath(project: IChart) {
+ return getRelativePath(project, getParent(this.state!, 1));
+ }
+
+ edit() {
+ (getParent(this.state!, 2) as IJudgeLine).removeNote(this.state!.id);
+ }
+}
diff --git a/src/core/command/note/setAbove.ts b/src/core/command/note/setAbove.ts
new file mode 100644
index 0000000..97b20bc
--- /dev/null
+++ b/src/core/command/note/setAbove.ts
@@ -0,0 +1,19 @@
+import { resolveIdentifier, SnapshotIn } from 'mobx-state-tree';
+import { Note, INote } from '@/core/models/Note';
+import { IChart } from '@/core/models/Chart';
+import { Command } from '../command';
+
+export class SetNoteAboveCommand extends Command {
+ type: string = 'note.isAbove';
+ propName: keyof SnapshotIn = 'isAbove';
+
+ getState(project: IChart, id: string) {
+ return resolveIdentifier(Note, project.judgelines, id);
+ }
+
+ edit(payload: boolean) {
+ this.state!.updateProps({
+ isAbove: payload,
+ });
+ }
+}
diff --git a/src/core/command/state.ts b/src/core/command/state.ts
new file mode 100644
index 0000000..36f04c2
--- /dev/null
+++ b/src/core/command/state.ts
@@ -0,0 +1,17 @@
+import { createStore } from 'zustand/vanilla';
+import { useStore } from 'zustand';
+import { CommandMeta } from './types';
+
+type CommandBusStore = {
+ history: CommandMeta[],
+ redoStack: CommandMeta[],
+};
+
+export const commandBusStore = createStore(() => ({
+ history: [],
+ redoStack: [],
+}));
+
+export const useCommandBusStore = (
+ selector: (state: CommandBusStore) => U
+) => useStore(commandBusStore, selector);
diff --git a/src/core/command/types.ts b/src/core/command/types.ts
new file mode 100644
index 0000000..ea53518
--- /dev/null
+++ b/src/core/command/types.ts
@@ -0,0 +1,12 @@
+import { IAnyStateTreeNode } from 'mobx-state-tree';
+
+export type CommandMeta = {
+ type: string, // TODO: Types
+ timestamp: number,
+};
+
+export type CommandExecutor = {
+ meta: CommandMeta;
+ undo: (target: IAnyStateTreeNode) => void;
+ redo: (target: IAnyStateTreeNode) => void;
+};
diff --git a/src/core/models/BPM.ts b/src/core/models/BPM.ts
new file mode 100644
index 0000000..8319e7c
--- /dev/null
+++ b/src/core/models/BPM.ts
@@ -0,0 +1,48 @@
+import { nanoid } from 'nanoid';
+import { types, getParent, Instance, SnapshotIn } from 'mobx-state-tree';
+import { IChart } from './Chart';
+import { BeatArray } from '@/core/utils/model';
+import { BeatArrayToNumber } from '@/utils/math';
+
+const BPMNumber = types.custom({
+ name: 'BPMNumber',
+
+ fromSnapshot: (value) => value,
+ toSnapshot: (value) => value,
+
+ isTargetType(value) {
+ return !isNaN(value) && value > 0;
+ },
+
+ getValidationMessage(snapshot) {
+ if (isNaN(snapshot)) return '\'NaN\' BPM is not allowed';
+ if (snapshot <= 0) return 'BPM cannot smaller than 1';
+ return '';
+ },
+});
+
+export const BPM = types.model('BPM', {
+ id: types.optional(types.identifier, nanoid),
+ beat: BeatArray,
+ bpm: BPMNumber,
+}).views((self) => ({
+ get beatNum() {
+ return BeatArrayToNumber(self.beat);
+ }
+})).actions((self) => ({
+ afterCreate() {
+ this.updateParentBPMCache();
+ },
+
+ updateProps(props: Partial, 'id'>>) {
+ Object.assign(self, props);
+ this.updateParentBPMCache();
+ },
+
+ updateParentBPMCache() {
+ const chart = getParent(self, 2) as IChart;
+ chart.updateBPMCache();
+ },
+}));
+
+export type IBPM = Instance;
diff --git a/src/core/models/Chart.ts b/src/core/models/Chart.ts
new file mode 100644
index 0000000..9999255
--- /dev/null
+++ b/src/core/models/Chart.ts
@@ -0,0 +1,73 @@
+import { types, Instance, SnapshotIn, destroy } from 'mobx-state-tree';
+import { calculateBPMCache } from '../timeline/bpm';
+import { Metadata } from './Metadata';
+import { BPM } from './BPM';
+import { JudgeLine } from './JudgeLine';
+import { BeatArray } from '@/utils/types';
+import { BPMCache } from '../types';
+
+export const Chart = types.model('Chart', {
+ // TODO: remove `maybeNull`?
+ metadata: types.maybeNull(Metadata),
+ offset: types.number,
+ bpm: types.optional(types.array(BPM), [{
+ beat: [ 0, 0, 1 ],
+ bpm: 120,
+ }]),
+ judgelines: types.array(JudgeLine),
+}).volatile(() => ({
+ bpmCache: [] as BPMCache[],
+})).actions((self) => ({
+ afterCreate() {
+ this.updateBPMCache();
+ },
+
+ updateMetadata(metadata: SnapshotIn) {
+ if (self.metadata === null) self.metadata = Metadata.create(metadata);
+ else self.metadata.updateProps(metadata);
+ },
+
+ removeMetadata() {
+ self.metadata = null;
+ },
+
+ updateOffset(offset: number) {
+ self.offset = offset;
+ },
+
+ addBPM(beat: BeatArray, bpm: number) {
+ self.bpm.push({
+ beat, bpm,
+ });
+ },
+
+ removeBPM(id: string) {
+ if (self.bpm.length === 1) {
+ throw new Error('Must have at least 1 bpm exists');
+ }
+
+ const index = self.bpm.findIndex(e => e.id === id);
+ if (index >= 0) destroy(self.bpm[index]);
+ this.updateBPMCache();
+ },
+
+ addJudgeLine() {
+ self.judgelines.push({});
+ },
+
+ removeJudgeLine(id: string) {
+ const index = self.judgelines.findIndex(e => e.id === id);
+ if (index >= 0) destroy(self.judgelines[index]);
+ },
+
+ updateBPMCache() {
+ self.bpmCache = calculateBPMCache(self.bpm);
+ this.updateTimeCache();
+ },
+
+ updateTimeCache() {
+ for (const line of self.judgelines) line.updateTimeCache();
+ }
+}));
+
+export type IChart = Instance;
diff --git a/src/core/models/JudgeLine.ts b/src/core/models/JudgeLine.ts
new file mode 100644
index 0000000..432a2d4
--- /dev/null
+++ b/src/core/models/JudgeLine.ts
@@ -0,0 +1,34 @@
+import { nanoid } from 'nanoid';
+import { types, Instance, destroy } from 'mobx-state-tree';
+import { KeyframeRecord } from './KeyframeRecord';
+import { Note } from './Note';
+import { SnapshotIn } from 'mobx-state-tree';
+
+export const JudgeLine = types.model('JudgeLine', {
+ id: types.optional(types.identifier, nanoid),
+ keyframes: types.optional(KeyframeRecord, {}),
+ notes: types.optional(types.array(Note), []),
+}).actions((self) => ({
+ addNote(props: SnapshotIn) {
+ self.notes.push(props);
+ },
+
+ editNote(id: string, props: Partial, 'id'>>) {
+ const note = self.notes.find(e => e.id === id);
+ if (!note) return;
+
+ note.updateProps(props);
+ },
+
+ removeNote(id: string) {
+ const index = self.notes.findIndex(e => e.id === id);
+ if (index >= 0) destroy(self.notes[index]);
+ },
+
+ updateTimeCache() {
+ self.keyframes.updateTimeCache();
+ for (const n of self.notes) n.updateTimeCache();
+ }
+}));
+
+export type IJudgeLine = Instance;
diff --git a/src/core/models/Keyframe.ts b/src/core/models/Keyframe.ts
new file mode 100644
index 0000000..8ae97e1
--- /dev/null
+++ b/src/core/models/Keyframe.ts
@@ -0,0 +1,43 @@
+import { nanoid } from 'nanoid';
+import { types, getParent, Instance, SnapshotIn } from 'mobx-state-tree';
+import { BeatArray } from '@/core/utils/model';
+import { getTimeByBeat } from '../timeline/bpm';
+import { BeatArrayToNumber } from '@/utils/math';
+import { KeyframeType } from '../types';
+
+export const Keyframe = types.model('Keyframe', {
+ id: types.optional(types.identifier, nanoid),
+ type: types.enumeration('KeyframeType', Object.values(KeyframeType)),
+ beat: BeatArray,
+ value: types.number,
+ continuous: types.boolean,
+ easing: types.number,
+ hasEndValue: types.optional(types.boolean, false),
+ endValue: types.optional(types.number, 0),
+}).views((self) => ({
+ get line() {
+ // TODO: types
+ return getParent(self, 3);
+ },
+
+ get beatNum() {
+ return BeatArrayToNumber(self.beat);
+ }
+})).volatile(() => ({
+ time: 0,
+})).actions((self) => ({
+ afterCreate() {
+ this.updateTimeCache();
+ },
+
+ updateProps(props: Partial, 'id' | 'type'>>) {
+ Object.assign(self, props);
+ if (props.beat !== (void 0)) this.updateTimeCache();
+ },
+
+ updateTimeCache() {
+ self.time = getTimeByBeat(self.beatNum);
+ }
+}));
+
+export type IKeyframe = Instance;
diff --git a/src/core/models/KeyframeRecord.ts b/src/core/models/KeyframeRecord.ts
new file mode 100644
index 0000000..43fb3a0
--- /dev/null
+++ b/src/core/models/KeyframeRecord.ts
@@ -0,0 +1,69 @@
+import { types, Instance, destroy } from 'mobx-state-tree';
+import { Keyframe } from './Keyframe';
+import { KeyframeType } from '../types';
+import { BeatArray } from '@/utils/types';
+
+export const KeyframeRecord = types.model('KeyframeRecord', {
+ positionX: types.optional(types.array(Keyframe), [{
+ type: KeyframeType.PositionX,
+ beat: [ 0, 0, 1 ],
+ value: 0,
+ continuous: false,
+ easing: 0,
+ }]),
+ positionY: types.optional(types.array(Keyframe), [{
+ type: KeyframeType.PositionY,
+ beat: [ 0, 0, 1 ],
+ value: 0,
+ continuous: false,
+ easing: 0,
+ }]),
+ rotate: types.optional(types.array(Keyframe), [{
+ type: KeyframeType.Rotate,
+ beat: [ 0, 0, 1 ],
+ value: 0,
+ continuous: false,
+ easing: 0,
+ }]),
+ alpha: types.optional(types.array(Keyframe), [{
+ type: KeyframeType.Alpha,
+ beat: [ 0, 0, 1 ],
+ value: 255,
+ continuous: false,
+ easing: 0,
+ }]),
+ speed: types.optional(types.array(Keyframe), [{
+ type: KeyframeType.Speed,
+ beat: [ 0, 0, 1 ],
+ value: 1,
+ continuous: false,
+ easing: 0,
+ }]),
+}).actions((self) => ({
+ add(
+ type: KeyframeType,
+ beat: BeatArray,
+ value: number,
+ continuous: boolean,
+ easing: number,
+ ) {
+ self[type].push({
+ type, beat, value, continuous, easing
+ });
+ },
+
+ remove(type: KeyframeType, id: string) {
+ const index = self[type].findIndex(e => e.id === id);
+ if (index >= 0) destroy(self[type][index]);
+ },
+
+ updateTimeCache() {
+ for (const k of self.positionX) k.updateTimeCache();
+ for (const k of self.positionY) k.updateTimeCache();
+ for (const k of self.rotate) k.updateTimeCache();
+ for (const k of self.alpha) k.updateTimeCache();
+ for (const k of self.speed) k.updateTimeCache();
+ },
+}));
+
+export type IKeyframeRecord = Instance;
diff --git a/src/core/models/Metadata.ts b/src/core/models/Metadata.ts
new file mode 100644
index 0000000..baba832
--- /dev/null
+++ b/src/core/models/Metadata.ts
@@ -0,0 +1,17 @@
+import { types, Instance, SnapshotIn } from 'mobx-state-tree';
+
+export const Metadata = types.model('Metadata', {
+ name: types.optional(types.string, 'Untitled'),
+ artist: types.optional(types.string, 'Unknown'),
+ illustration: types.optional(types.string, 'Unknown'),
+ level: types.optional(types.string, 'SP Lv.?'),
+ designer: types.optional(types.string, 'Unknown'),
+ musicFile: types.string,
+ backgroundFile: types.string,
+}).actions((self) => ({
+ updateProps(props: Partial>) {
+ Object.assign(self, props);
+ }
+}));
+
+export type IMetadata = Instance;
diff --git a/src/core/models/Note.ts b/src/core/models/Note.ts
new file mode 100644
index 0000000..83a78d2
--- /dev/null
+++ b/src/core/models/Note.ts
@@ -0,0 +1,68 @@
+import { nanoid } from 'nanoid';
+import { types, getParent, Instance, SnapshotIn } from 'mobx-state-tree';
+import { BeatArray } from '@/core/utils/model';
+import { getTimeByBeat } from '../timeline/bpm';
+import { BeatArrayToNumber, parseDoublePrecist } from '@/utils/math';
+import { NoteType } from '../types';
+import { BeatArray as TBeatArray } from '@/utils/types';
+
+export const Note = types.model('Note', {
+ id: types.optional(types.identifier, nanoid),
+ type: types.enumeration('NoteType', Object.values(NoteType)),
+ beat: BeatArray,
+ positionX: types.number,
+ speed: types.number,
+ isAbove: types.boolean,
+
+ holdEndBeat: types.optional(BeatArray, [ 0, 0, 1 ]),
+}).volatile(() => ({
+ time: 0,
+ holdEndTime: 0,
+ holdLengthTime: 0,
+})).postProcessSnapshot((self) => {
+ if (
+ self.holdEndBeat &&
+ BeatArrayToNumber(self.beat as TBeatArray) > BeatArrayToNumber(self.holdEndBeat as TBeatArray)
+ ) {
+ self.holdEndBeat = self.beat;
+ }
+}).views((self) => ({
+ get line() {
+ // TODO: types
+ return getParent(self, 2);
+ },
+
+ get beatNum() {
+ return BeatArrayToNumber(self.beat);
+ },
+
+ get holdEndBeatNum() {
+ if (self.type !== NoteType.Hold || !self.holdEndBeat) return BeatArrayToNumber(self.beat);
+ return BeatArrayToNumber(self.holdEndBeat);
+ },
+
+ get holdLengthBeatNum() {
+ if (self.type !== NoteType.Hold || !self.holdEndBeat) return 0;
+ return BeatArrayToNumber(self.holdEndBeat) - BeatArrayToNumber(self.beat);
+ }
+})).actions((self) => ({
+ afterCreate() {
+ this.updateTimeCache();
+ },
+
+ updateProps(props: Omit>, 'id'>) {
+ if (
+ props.beat !== (void 0) ||
+ props.holdEndBeat !== (void 0)
+ ) this.updateTimeCache(props.beat as TBeatArray | undefined, props.holdEndBeat as TBeatArray | undefined);
+ Object.assign(self, props);
+ },
+
+ updateTimeCache(beat?: TBeatArray, holdEndBeat?: TBeatArray) {
+ self.time = getTimeByBeat(beat ? BeatArrayToNumber(beat) : self.beatNum);
+ self.holdEndTime = self.type === NoteType.Hold ? getTimeByBeat(holdEndBeat ? BeatArrayToNumber(holdEndBeat) : self.holdEndBeatNum) : self.time;
+ self.holdLengthTime = parseDoublePrecist(self.holdEndTime - self.time, 6, -1);
+ }
+}));
+
+export type INote = Instance;
diff --git a/src/core/project/create.ts b/src/core/project/create.ts
new file mode 100644
index 0000000..474d07b
--- /dev/null
+++ b/src/core/project/create.ts
@@ -0,0 +1,41 @@
+import { applySnapshot } from 'mobx-state-tree';
+import { runtimeCache } from '@/runtime/resources/cache';
+import { store as ChartStore } from '../state/chartStore';
+import { SnapshotIn } from 'mobx-state-tree';
+import { Chart } from '../models/Chart';
+import { Metadata } from '../models/Metadata';
+
+const NewChartData: SnapshotIn = {
+ offset: 0,
+ bpm: [{
+ beat: [ 0, 0, 1 ],
+ bpm: 120,
+ }],
+ judgelines: [{
+ notes: [],
+ }],
+};
+
+export const createNewProject = (metadata: SnapshotIn) => {
+ if (!runtimeCache.has(metadata.musicFile)) {
+ throw new Error(`Music file ${metadata.musicFile} not found or not loaded`);
+ }
+
+ if (!runtimeCache.has(metadata.backgroundFile)) {
+ throw new Error(`Background file ${metadata.backgroundFile} not found or not loaded`);
+ }
+
+ const _chart: SnapshotIn = {
+ ...NewChartData,
+ metadata: {
+ name: `Untitled ${Date.now()}`,
+ artist: 'Unknown',
+ illustration: 'Unknown',
+ level: 'SP Lv.?',
+ designer: 'Unknown',
+ ...metadata,
+ },
+ };
+
+ return applySnapshot(ChartStore, _chart);
+};
diff --git a/src/core/state/chartStore.ts b/src/core/state/chartStore.ts
new file mode 100644
index 0000000..ea75006
--- /dev/null
+++ b/src/core/state/chartStore.ts
@@ -0,0 +1,7 @@
+import { Chart, IChart } from '@/core/models/Chart';
+
+export const store: IChart = Chart.create({
+ metadata: null,
+ offset: 0,
+ judgelines: [],
+});
diff --git a/src/core/timeline/bpm.ts b/src/core/timeline/bpm.ts
new file mode 100644
index 0000000..54fd80c
--- /dev/null
+++ b/src/core/timeline/bpm.ts
@@ -0,0 +1,65 @@
+import { store as ChartStore } from '../state/chartStore';
+import { sortByBeat, parseDoublePrecist } from '@/utils/math';
+import { IBPM } from '../models/BPM';
+import { BPMCache } from '../types';
+
+export const calculateBPMCache = (bpms: IBPM[]): BPMCache[] => {
+ const _bpms = bpms.slice().sort(sortByBeat);
+ const result: BPMCache[] = [];
+
+ for (const bpm of _bpms) {
+ const timePerBeat = parseDoublePrecist(60 / bpm.bpm, 6, -1);
+
+ if (result.length === 0) {
+ result.push({
+ time: 0,
+ beat: 0,
+ timePerBeat,
+ });
+ continue;
+ }
+
+ const lastBpmCache = result[result.length - 1]!;
+ result.push({
+ time: parseDoublePrecist((
+ lastBpmCache.beat + (lastBpmCache.timePerBeat * (bpm.beatNum - lastBpmCache.beat))
+ ), 6, -1),
+ beat: bpm.beatNum,
+ timePerBeat,
+ });
+ }
+
+ return result;
+};
+
+export const getBeatByTime = (time: number) => {
+ const bpms = ChartStore.bpmCache;
+ let min = 0, max = bpms.length - 1;
+
+ while (min <= max) {
+ const mid = (min + max) >> 1;
+ if (bpms[mid].time <= time) min = mid + 1;
+ else max = mid - 1;
+ }
+
+ const result = bpms[Math.max(0, min - 1)];
+ return parseDoublePrecist((
+ result.beat + (time - result.time) / result.timePerBeat
+ ), 6, -1);
+};
+
+export const getTimeByBeat = (beat: number) => {
+ const bpms = ChartStore.bpmCache;
+ let min = 0, max = bpms.length - 1;
+
+ while (min <= max) {
+ const mid = (min + max) >> 1;
+ if (bpms[mid].beat <= beat) min = mid + 1;
+ else max = mid - 1;
+ }
+
+ const result = bpms[Math.max(0, min - 1)];
+ return parseDoublePrecist((
+ result.time + (beat - result.beat) * result.timePerBeat
+ ), 6, -1);
+};
diff --git a/src/core/types.ts b/src/core/types.ts
new file mode 100644
index 0000000..0dd4fb6
--- /dev/null
+++ b/src/core/types.ts
@@ -0,0 +1,21 @@
+
+export type BPMCache = {
+ time: number,
+ beat: number,
+ timePerBeat: number,
+};
+
+export enum KeyframeType {
+ PositionX = 'positionX',
+ PositionY = 'positionY',
+ Rotate = 'rotate',
+ Alpha = 'alpha',
+ Speed = 'speed',
+};
+
+export enum NoteType {
+ Tap = 'tap',
+ Drag = 'drag',
+ Hold = 'hold',
+ Flick = 'flick',
+};
diff --git a/src/core/utils/easings.ts b/src/core/utils/easings.ts
new file mode 100644
index 0000000..1e01be6
--- /dev/null
+++ b/src/core/utils/easings.ts
@@ -0,0 +1,174 @@
+
+type EasingFn = (x: number) => number;
+
+/**
+ * All these easings comes from https://easings.net/
+ * @see https://easings.net/
+ */
+const Easings: EasingFn[] = [
+ /** 0: Linear */
+ (x) => x,
+ /** 1: In Sine */
+ (x) => 1 - Math.cos((x * Math.PI) / 2),
+ /** 2: Out Sine */
+ (x) => Math.sin((x * Math.PI) / 2),
+ /** 3: In Out Sine */
+ (x) => -(Math.cos(Math.PI * x) - 1) / 2,
+ /** 4: In Quad */
+ (x) => x * x,
+ /** 5: Out Quad */
+ (x) => 1 - (1 - x) * (1 - x),
+ /** 6: In Out Quad */
+ (x) => x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2,
+ /** 7: In Cubic */
+ (x) => x * x * x,
+ /** 8: Out Cubic */
+ (x) => 1 - Math.pow(1 - x, 3),
+ /** 9: In Out Cubic */
+ (x) => x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2,
+ /** 10: In Quart */
+ (x) => x * x * x * x,
+ /** 11: Out Quart */
+ (x) => 1 - Math.pow(1 - x, 4),
+ /** 12: In Out Quart */
+ (x) => x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2,
+ /** 13: In Quint */
+ (x) => x * x * x * x * x,
+ /** 14: Out Quint */
+ (x) => 1 - Math.pow(1 - x, 5),
+ /** 15: In Out Quint */
+ (x) => x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2,
+ /** 16: In Expo */
+ (x) => x === 0 ? 0 : Math.pow(2, 10 * x - 10),
+ /** 17: Out Expo */
+ (x) => x === 1 ? 1 : 1 - Math.pow(2, -10 * x),
+ /** 18: In Out Expo */
+ (x) => (x === 0
+ ? 0
+ : x === 1
+ ? 1
+ : x < 0.5 ? Math.pow(2, 20 * x - 10) / 2
+ : (2 - Math.pow(2, -20 * x + 10)) / 2),
+ /** 19: In Circ */
+ (x) => 1 - Math.sqrt(1 - Math.pow(x, 2)),
+ /** 20: Out Circ */
+ (x) => Math.sqrt(1 - Math.pow(x - 1, 2)),
+ /** 21: In Out Circ */
+ (x) => (x < 0.5
+ ? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2
+ : (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2),
+ /** 22: In Back */
+ (x) => {
+ const c1 = 1.70158;
+ const c3 = c1 + 1;
+
+ return c3 * x * x * x - c1 * x * x
+ },
+ /** 23: Out Back */
+ (x) => {
+ const c1 = 1.70158;
+ const c3 = c1 + 1;
+
+ return 1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2);
+ },
+ /** 24: In Out Back */
+ (x) => {
+ const c1 = 1.70158;
+ const c2 = c1 * 1.525;
+
+ return x < 0.5
+ ? (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
+ : (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
+ },
+ /** 25: In Elastic */
+ (x) => {
+ const c4 = (2 * Math.PI) / 3;
+
+ return x === 0
+ ? 0
+ : x === 1
+ ? 1
+ : -Math.pow(2, 10 * x - 10) * Math.sin((x * 10 - 10.75) * c4);
+ },
+ /** 26: Out Elastic */
+ (x) => {
+ const c4 = (2 * Math.PI) / 3;
+
+ return x === 0
+ ? 0
+ : x === 1
+ ? 1
+ : Math.pow(2, -10 * x) * Math.sin((x * 10 - 0.75) * c4) + 1;
+ },
+ /** 27: In Out Elastic */
+ (x) => {
+ const c5 = (2 * Math.PI) / 4.5;
+
+ return x === 0
+ ? 0
+ : x === 1
+ ? 1
+ : x < 0.5
+ ? -(Math.pow(2, 20 * x - 10) * Math.sin((20 * x - 11.125) * c5)) / 2
+ : (Math.pow(2, -20 * x + 10) * Math.sin((20 * x - 11.125) * c5)) / 2 + 1;
+ },
+ /** 28: In Bounce */
+ (x) => 1 - Easings[29](1 - x),
+ /** 29: Out Bounce */
+ (x) => {
+ const n1 = 7.5625;
+ const d1 = 2.75;
+
+ if (x < 1 / d1) {
+ return n1 * x * x;
+ } else if (x < 2 / d1) {
+ return n1 * (x -= 1.5 / d1) * x + 0.75;
+ } else if (x < 2.5 / d1) {
+ return n1 * (x -= 2.25 / d1) * x + 0.9375;
+ } else {
+ return n1 * (x -= 2.625 / d1) * x + 0.984375;
+ }
+ },
+ /** 30: In Out Bounce */
+ (x) => (x < 0.5
+ ? (1 - Easings[29](1 - 2 * x)) / 2
+ : (1 + Easings[29](2 * x - 1)) / 2)
+];
+
+const EasingNames: string[] = [
+ 'Linear',
+ 'In Sine',
+ 'Out Sine',
+ 'In Out Sine',
+ 'In Quad',
+ 'Out Quad',
+ 'In Out Quad',
+ 'In Cubic',
+ 'Out Cubic',
+ 'In Out Cubic',
+ 'In Quart',
+ 'Out Quart',
+ 'In Out Quart',
+ 'In Quint',
+ 'Out Quint',
+ 'In Out Quint',
+ 'In Expo',
+ 'Out Expo',
+ 'In Out Expo',
+ 'In Circ',
+ 'Out Circ',
+ 'In Out Circ',
+ 'In Back',
+ 'Out Back',
+ 'In Out Back',
+ 'In Elastic',
+ 'Out Elastic',
+ 'In Out Elastic',
+ 'In Bounce',
+ 'Out Bounce',
+ 'In Out Bounce',
+];
+
+export default Easings;
+export { EasingNames };
+export type { Easings };
diff --git a/src/core/utils/model.ts b/src/core/utils/model.ts
new file mode 100644
index 0000000..44ae18f
--- /dev/null
+++ b/src/core/utils/model.ts
@@ -0,0 +1,33 @@
+import { types } from 'mobx-state-tree';
+import { normalizeBeatArray, BeatArrayToNumber } from '@/utils/math';
+import { BeatArray as TBeatArray } from '../../utils/types';
+
+export const BeatArray = types.custom({
+ name: 'BeatArray',
+
+ fromSnapshot(value: number[]) {
+ return normalizeBeatArray([ value[0], value[1], value[2] ]);
+ },
+
+ toSnapshot(value: TBeatArray) {
+ return [ ...value ];
+ },
+
+ isTargetType(value: TBeatArray | number[]) {
+ return (
+ value.length === 3 &&
+ !isNaN(BeatArrayToNumber(value as TBeatArray))
+ );
+ },
+
+ getValidationMessage(snapshot: number[]) {
+ if (snapshot.length !== 3) return 'Invalid array length';
+ if (isNaN(BeatArrayToNumber(snapshot as TBeatArray))) return 'Array contains NaN';
+ if (
+ snapshot[0] < 0 ||
+ snapshot[1] < 0 ||
+ snapshot[2] < 1
+ ) return 'Array contains invaild number';
+ return '';
+ }
+});
diff --git a/src/main.ts b/src/main.ts
index 6e2214d..314f228 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,2 +1,4 @@
-import './App/App';
+import 'setimmediate'; // TODO: This is a workaround for upstream @phifans/audio
+import '@/storage/init';
+import '@/runtime/init';
import './ui';
diff --git a/src/renderer/preview/app.ts b/src/renderer/preview/app.ts
new file mode 100644
index 0000000..65a7ef0
--- /dev/null
+++ b/src/renderer/preview/app.ts
@@ -0,0 +1,3 @@
+import { PreviewApplication } from './classes/Application';
+
+export const app = new PreviewApplication();
diff --git a/src/renderer/preview/classes/Application.ts b/src/renderer/preview/classes/Application.ts
new file mode 100644
index 0000000..bc9fe1c
--- /dev/null
+++ b/src/renderer/preview/classes/Application.ts
@@ -0,0 +1,136 @@
+import { Application, Container } from 'pixi.js';
+import { onPatch } from 'mobx-state-tree';
+import { store as ChartStore } from '@/core/state/chartStore';
+import { runtimeAudioStore } from '@/runtime/audio/state';
+import { skinStore } from '@/runtime/skin/state';
+import { settingsStore } from '@/runtime/settings/state';
+import { UpdateRendererTick } from '../ticker';
+import { JudgeLineSprite } from './JudgeLine';
+import { ApplicationOptions } from 'pixi.js';
+import { IJsonPatch } from 'mobx-state-tree';
+import { Clip } from '@phifans/audio';
+import { PreviewSize } from '@/renderer/types';
+import { Nullable } from '@/utils/types';
+
+const JudgeLinePathReg = /^\/judgelines\/(\d+)$/;
+
+export class PreviewApplication extends Application {
+ readonly containerGame = new Container();
+ readonly containerUI = new Container();
+
+ readonly size: PreviewSize = {
+ width: 0,
+ height: 0,
+ widthHalf: 0,
+ heightHalf: 0,
+ noteScale: 0,
+ lineScale: 0,
+ heightPercent: 0,
+ };
+
+ private musicClip: Nullable = null;
+ private lines: JudgeLineSprite[] = [];
+ private onInitCallbacks: (() => void)[] = [];
+
+ constructor(rendererOptions: Partial = {}) {
+ super();
+
+ this.init({
+ hello: true,
+ ...rendererOptions,
+ }).then(() => {
+ this.triggerInitCallback();
+
+ this.stage.addChild(this.containerGame);
+ this.stage.addChild(this.containerUI);
+
+ this.ticker.add(() => {
+ UpdateRendererTick(
+ this.size,
+ this.lines,
+ this.musicClip,
+ this.containerGame,
+ );
+ });
+ });
+
+ onPatch(ChartStore, (patch) => this.handleChartPatch(patch));
+ runtimeAudioStore.subscribe((s) => this.musicClip = s.musicClip);
+ skinStore.subscribe((s) => {
+ if (s.skinCount === (void 0)) return;
+ this.updateTexture();
+ });
+ settingsStore.subscribe(() => {
+ this.$resize(this.size.width, this.size.height);
+ });
+ }
+
+ $resize(width: number, height: number) {
+ if (!this.renderer) return;
+
+ this.renderer.resize(width, height);
+ this.calculatePreviewSize(width, height);
+ this.render();
+ }
+
+ addOnInitCallback(callback: () => void) {
+ this.onInitCallbacks.push(callback);
+
+ return (() => {
+ this.onInitCallbacks = this.onInitCallbacks.filter(e => e !== callback);
+ });
+ }
+
+ private handleChartPatch(patch: IJsonPatch) {
+ if (!patch.path.startsWith('/judgelines')) return;
+
+ if (JudgeLinePathReg.test(patch.path)) {
+ const [ , idStr ] = JudgeLinePathReg.exec(patch.path)!;
+ const id = parseInt(idStr);
+ const lineState = ChartStore.judgelines[id];
+
+ if (patch.op === 'add') {
+ const lineSprite = new JudgeLineSprite(lineState, this);
+ lineSprite.resize(this.size);
+ this.containerGame.addChild(lineSprite);
+ this.lines[id] = lineSprite;
+ }
+ return;
+ }
+ }
+
+ private updateTexture() {
+ for (const l of this.lines) l.updateTexture();
+ }
+
+ private triggerInitCallback() {
+ for (const cb of this.onInitCallbacks) {
+ cb();
+ }
+ }
+
+ private calculatePreviewSize(width: number, height: number) {
+ const settings = settingsStore.getState();
+ const { size } = this;
+
+ size.width = width;
+ size.height = height;
+
+ size.widthHalf = size.width / 2;
+ size.heightHalf = size.height / 2;
+
+ size.noteScale = size.width / settings['renderer.noteScale'];
+ size.lineScale = size.width > size.height * 0.75 ? size.height / 18.75 : size.width / 14.0625
+
+ size.heightPercent = size.height / 1080;
+
+ // Apply size to containers
+ this.containerGame.x = size.widthHalf;
+ this.containerGame.y = size.heightHalf;
+
+ // Apply size to lines
+ for (const line of this.lines) {
+ line.resize(size);
+ }
+ }
+};
diff --git a/src/renderer/preview/classes/JudgeLine.ts b/src/renderer/preview/classes/JudgeLine.ts
new file mode 100644
index 0000000..b46e6c4
--- /dev/null
+++ b/src/renderer/preview/classes/JudgeLine.ts
@@ -0,0 +1,215 @@
+import { Sprite, Texture } from 'pixi.js';
+import { onPatch } from 'mobx-state-tree';
+import { PreviewApplication } from './Application';
+import { PlainNoteSprite } from './PlainNote';
+import { LongNoteSprite } from './LongNote';
+import { SnapshotOut } from 'mobx-state-tree';
+import { IDisposer, IJsonPatch } from 'mobx-state-tree';
+import { IJudgeLine } from '@/core/models/JudgeLine';
+import { Keyframe, IKeyframe } from '@/core/models/Keyframe';
+import { FloorPosition, PreviewSize } from '@/renderer/types';
+import { KeyframeType, NoteType } from '@/core/types';
+import { calculateLineValue } from '@/renderer/utils';
+import { parseDoublePrecist } from '@/utils/math';
+import { INote, Note } from '@/core/models/Note';
+
+type NoteSprite = PlainNoteSprite | LongNoteSprite;
+
+type $KeyframeCaches = {
+ [K in KeyframeType]: IKeyframe[];
+}
+
+const LineWidthBase = 4000;
+const LineHeightBase = 18.75 * 0.008;
+
+const KeyframeTypeReg = /^\/keyframes\/([a-zA-Z]+)(?:\/(\d+))?(?:\/([a-zA-Z]+))?$/;
+const NotePatchReg = /^\/notes(?:\/(\d+))?(?:\/([a-zA-Z]+))?$/;
+
+const createNoteSprite = (state: INote, line: JudgeLineSprite) => {
+ if (state.type !== NoteType.Hold) return new PlainNoteSprite(state, line);
+ else return new LongNoteSprite(state, line);
+};
+
+export class JudgeLineSprite extends Sprite {
+ private readonly state: IJudgeLine;
+ readonly app: PreviewApplication;
+ private readonly patchDisposer: IDisposer;
+
+ readonly floorPositions: FloorPosition[] = [];
+ readonly keyframes: $KeyframeCaches = {
+ [KeyframeType.PositionX]: [],
+ [KeyframeType.PositionY]: [],
+ [KeyframeType.Rotate]: [],
+ [KeyframeType.Alpha]: [],
+ [KeyframeType.Speed]: []
+ };
+ readonly notes: NoteSprite[] = [];
+
+ constructor(state: IJudgeLine, app: PreviewApplication) {
+ super(Texture.WHITE);
+
+ this.state = state;
+ this.app = app;
+ this.updateAllKeyframesCache();
+
+ this.anchor.set(0.5);
+
+ this.patchDisposer = onPatch(this.state, (p, r) => this.handlePatch(p, r));
+ }
+
+ updateTexture() {
+ for (const n of this.notes) n.updateTexture();
+ }
+
+ resize(size: PreviewSize) {
+ this.scale.x = Math.round(LineWidthBase * (size.width / 1350));
+ this.scale.y = Math.round(size.lineScale * LineHeightBase);
+
+ for (const n of this.notes) n.resize(size);
+ }
+
+ $destroy() {
+ this.patchDisposer();
+ this.destroy();
+ }
+
+ private handlePatch(patch: IJsonPatch, revPatch: IJsonPatch) {
+ if (KeyframeTypeReg.test(patch.path)) {
+ const matches = patch.path.match(KeyframeTypeReg)!;
+ const type = matches[1] as KeyframeType;
+ const keyframeIndex = matches[2] as string | undefined;
+ const prop = matches[3] as keyof SnapshotOut | undefined;
+
+ if (
+ (patch.op !== 'replace' || keyframeIndex === (void 0)) ||
+ type === KeyframeType.Speed ||
+ prop === 'beat'
+ ) {
+ this.updateKeyframesCache(type);
+ }
+ return;
+ }
+
+ if (NotePatchReg.test(patch.path)) {
+ const matches = patch.path.match(NotePatchReg)!;
+ const noteIndex = matches[1] as string | undefined;
+ const prop = matches[2] as unknown as keyof SnapshotOut | undefined;
+
+ if (!noteIndex) {
+ if (patch.op === 'replace') {
+ for (const note of this.notes) note.$destroy();
+ this.notes.length = 0;
+
+ const newNoteStates = patch.value as INote[];
+ for (const noteState of newNoteStates) {
+ const noteSprite = createNoteSprite(noteState, this);
+ noteSprite.resize(this.app.size);
+ this.notes.push(noteSprite);
+ }
+ }
+ return;
+ }
+
+ const index = parseInt(noteIndex);
+
+ if (!!prop) {
+ if (prop === 'type') {
+ const newType = patch.value! as NoteType;
+ const prevType = revPatch.value! as NoteType;
+
+ if (newType === NoteType.Hold || prevType === NoteType.Hold) {
+ this.notes[index].$destroy();
+ this.notes[index] = createNoteSprite(this.state.notes[index], this);
+ this.notes[index].resize(this.app.size);
+ }
+ }
+ return;
+ }
+
+ if (patch.op === 'add') {
+ const noteState = this.state.notes[index];
+ const noteSprite = createNoteSprite(noteState, this);
+ noteSprite.resize(this.app.size);
+ this.notes[index] = noteSprite;
+ }
+ else if (patch.op === 'remove') {
+ const noteSprite = this.notes[index];
+ if (!noteSprite) return;
+ noteSprite.$destroy();
+ this.notes.splice(index, 1);
+ }
+ return;
+ }
+ }
+
+ private updateFloorPositions() {
+ const keyframes = this.keyframes.speed;
+ this.floorPositions.length = 0;
+
+ for (let i = 0; i < keyframes.length; i++) {
+ const keyframe = keyframes[i];
+ const nextKeyframe = keyframes[i + 1];
+
+ if (!nextKeyframe || !nextKeyframe.continuous || nextKeyframe.value === keyframe.value) {
+ this.floorPositions.push({
+ time: keyframe.time,
+ value: NaN,
+ });
+ continue;
+ }
+
+ const beatBetween = nextKeyframe.beatNum - keyframe.beatNum;
+ for (let i = 0, count = Math.ceil(beatBetween / 0.125); i < count; i++) {
+ const beatPercent = i / count;
+ const currentTime = keyframe.time * (1 - beatPercent) + nextKeyframe.time * beatPercent;
+
+ this.floorPositions.push({
+ time: currentTime,
+ value: NaN,
+ });
+ }
+
+ this.floorPositions.push({
+ time: nextKeyframe.time,
+ value: NaN,
+ });
+ }
+
+ this.floorPositions.sort((a, b) => a.time - b.time);
+ if (this.floorPositions[0].time > 0) {
+ this.floorPositions.unshift({
+ time: 0,
+ value: NaN,
+ });
+ }
+
+ let currentFloorPosition = parseDoublePrecist((
+ this.floorPositions[0].time * calculateLineValue(this.floorPositions[0].time, keyframes)
+ ), 3, -1);
+ for (let i = 0; i < this.floorPositions.length; i++) {
+ const event = this.floorPositions[i];
+ const eventNext = this.floorPositions[i + 1];
+
+ event.value = currentFloorPosition;
+
+ if (eventNext) currentFloorPosition = parseDoublePrecist(currentFloorPosition + (
+ (eventNext.time - event.time) + calculateLineValue(event.time, keyframes)
+ ), 3, -1);
+ }
+
+ for (const n of this.notes) n.updateFloorPosition();
+ }
+
+ private updateKeyframesCache(type: KeyframeType) {
+ this.keyframes[type] = this.state.keyframes[type].slice().sort((a, b) => a.time - b.time);
+ if (type === KeyframeType.Speed) this.updateFloorPositions();
+ }
+
+ private updateAllKeyframesCache() {
+ this.updateKeyframesCache(KeyframeType.PositionX);
+ this.updateKeyframesCache(KeyframeType.PositionY);
+ this.updateKeyframesCache(KeyframeType.Rotate);
+ this.updateKeyframesCache(KeyframeType.Alpha);
+ this.updateKeyframesCache(KeyframeType.Speed);
+ }
+}
diff --git a/src/renderer/preview/classes/LongNote.ts b/src/renderer/preview/classes/LongNote.ts
new file mode 100644
index 0000000..24dd6ba
--- /dev/null
+++ b/src/renderer/preview/classes/LongNote.ts
@@ -0,0 +1,97 @@
+import { Container, Sprite, Texture } from 'pixi.js';
+import { onPatch } from 'mobx-state-tree';
+import { skinStore } from '@/runtime/skin/state';
+import { calculateFloorPosition, calculateLineValue } from '@/renderer/utils';
+import { INote, Note } from '@/core/models/Note';
+import { JudgeLineSprite } from './JudgeLine';
+import { PreviewSize } from '@/renderer/types';
+import { runtimeCache } from '@/runtime/resources/cache';
+import { IDisposer, IJsonPatch, SnapshotIn } from 'mobx-state-tree';
+
+const PatchPathReg = /^\/([a-zA-Z]+)$/;
+
+export class LongNoteSprite extends Container {
+ readonly state: INote;
+ readonly line: JudgeLineSprite;
+ private readonly patchDisposer: IDisposer;
+
+ readonly head = new Sprite();
+ readonly body = new Sprite();
+ readonly end = new Sprite();
+
+ floorPosition: number = 0;
+ endFloorPosition: number = 0;
+ holdLength: number = 0;
+
+ onLinePosX: number = 0;
+ onLinePosY: number = 0;
+
+ constructor(state: INote, line: JudgeLineSprite) {
+ super();
+
+ this.state = state;
+ this.line = line;
+
+ this.head.anchor.set(0.5, 0);
+ this.body.anchor.set(0.5, 1);
+ this.end.anchor.set(0.5, 1);
+ this.addChild(this.head, this.body, this.end);
+
+ this.zIndex = 100;
+
+ this.updateFloorPosition();
+ this.updateTexture();
+ this.patchDisposer = onPatch(this.state, (p) => this.handlePatch(p));
+ }
+
+ resize(size: PreviewSize) {
+ const realLength = this.holdLength * this.state.speed * size.height / size.noteScale;
+
+ this.head.visible = true;
+ this.body.scale.y = 1;
+ this.body.height = realLength;
+ this.end.position.y = -realLength;
+
+ this.scale.set(size.noteScale);
+ }
+
+ updateFloorPosition() {
+ this.floorPosition = calculateFloorPosition(
+ this.state.time,
+ this.line.floorPositions,
+ calculateLineValue(this.state.time, this.line.keyframes.speed)
+ );
+ this.endFloorPosition = calculateFloorPosition(
+ this.state.holdEndTime,
+ this.line.floorPositions,
+ calculateLineValue(this.state.holdEndTime, this.line.keyframes.speed)
+ );
+ this.holdLength = this.endFloorPosition - this.floorPosition;
+ this.resize(this.line.app.size);
+ }
+
+ updateTexture() {
+ const { skinCount } = skinStore.getState();
+
+ this.head.texture = runtimeCache.get(`skin${skinCount}:HoldHead.png`) as Texture;
+ this.body.texture = runtimeCache.get(`skin${skinCount}:HoldBody.png`) as Texture;
+ this.end.texture = runtimeCache.get(`skin${skinCount}:HoldEnd.png`) as Texture;
+ }
+
+ $destroy() {
+ this.patchDisposer();
+ this.destroy({ children: true, texture: false });
+ }
+
+ private handlePatch(patch: IJsonPatch) {
+ const matches = patch.path.match(PatchPathReg);
+ if (!matches || matches.length <= 1) return;
+
+ const prop = matches[1] as keyof SnapshotIn;
+
+ if (prop === 'beat' || prop === 'holdEndBeat')
+ this.updateFloorPosition();
+ if (prop === 'speed')
+ this.resize(this.line.app.size);
+ }
+}
diff --git a/src/renderer/preview/classes/PlainNote.ts b/src/renderer/preview/classes/PlainNote.ts
new file mode 100644
index 0000000..b82e9be
--- /dev/null
+++ b/src/renderer/preview/classes/PlainNote.ts
@@ -0,0 +1,80 @@
+import { Sprite, Texture } from 'pixi.js';
+import { onPatch } from 'mobx-state-tree';
+import { runtimeCache } from '@/runtime/resources/cache';
+import { skinStore } from '@/runtime/skin/state';
+import { calculateLineValue, calculateFloorPosition } from '@/renderer/utils';
+import { IDisposer, IJsonPatch, SnapshotOut } from 'mobx-state-tree';
+import { INote, Note } from '@/core/models/Note';
+import { NoteType } from '@/core/types';
+import { PreviewSize } from '@/renderer/types';
+import { JudgeLineSprite } from './JudgeLine';
+
+const PatchPathReg = /^\/([a-zA-Z]+)$/;
+
+export class PlainNoteSprite extends Sprite {
+ readonly state: INote;
+ readonly line: JudgeLineSprite;
+ private readonly patchDisposer: IDisposer;
+
+ floorPosition: number = 0;
+
+ onLinePosX: number = 0;
+ onLinePosY: number = 0;
+
+ constructor(state: INote, line: JudgeLineSprite) {
+ super();
+
+ this.state = state;
+ this.line = line;
+
+ this.anchor.set(0.5);
+ this.zIndex = 100;
+
+ this.updateFloorPosition();
+ this.updateTexture();
+ this.patchDisposer = onPatch(this.state, (p) => this.handlePatch(p));
+ }
+
+ resize(size: PreviewSize) {
+ this.scale.set(size.noteScale);
+ }
+
+ updateFloorPosition() {
+ this.floorPosition = calculateFloorPosition(
+ this.state.time,
+ this.line.floorPositions,
+ calculateLineValue(this.state.time, this.line.keyframes.speed)
+ );
+ }
+
+ updateTexture() {
+ const { skinCount } = skinStore.getState();
+
+ let skinName = `skin${skinCount}:Tap.png`;
+ if (this.state.type === NoteType.Drag) skinName = `skin${skinCount}:Drag.png`;
+ if (this.state.type === NoteType.Flick) skinName = `skin${skinCount}:Flick.png`;
+
+ const texture = runtimeCache.get(skinName) as Texture | undefined;
+ if (!texture) return;
+
+ this.texture = texture;
+ }
+
+ $destroy() {
+ this.patchDisposer();
+ this.destroy(false);
+ }
+
+ private handlePatch(patch: IJsonPatch) {
+ const matches = patch.path.match(PatchPathReg);
+ if (!matches || matches.length <= 1) return;
+
+ const prop = matches[1] as keyof SnapshotOut;
+ const value = patch.value as SnapshotOut[typeof prop] | undefined;
+
+ if (prop === 'beat')
+ this.updateFloorPosition();
+ if (prop === 'type' && value !== NoteType.Hold)
+ this.updateTexture();
+ }
+}
diff --git a/src/renderer/preview/ticker.ts b/src/renderer/preview/ticker.ts
new file mode 100644
index 0000000..c8d6437
--- /dev/null
+++ b/src/renderer/preview/ticker.ts
@@ -0,0 +1,102 @@
+import { Clip } from '@phifans/audio';
+import { calculateFloorPosition, calculateLineValue } from '../utils';
+import { Container } from 'pixi.js';
+import { Nullable } from '@/utils/types';
+import { JudgeLineSprite } from './classes/JudgeLine';
+import { LongNoteSprite } from './classes/LongNote';
+import { PreviewSize } from '../types';
+import { NoteType } from '@/core/types';
+
+const RADIAN = Math.PI / 180;
+
+export const UpdateRendererTick = (
+ size: PreviewSize,
+ lines: JudgeLineSprite[],
+ clip: Nullable,
+ container: Container
+) => {
+ if (lines.length === 0) return;
+ if (clip === null) return;
+
+ const {
+ widthHalf,
+ heightHalf,
+ } = size;
+ const { currentTime } = clip;
+
+ for (const line of lines) {
+ const {
+ keyframes,
+ floorPositions,
+ notes,
+ } = line;
+
+ const lineSpeed = calculateLineValue(currentTime, keyframes.speed);
+ const linePosX = calculateLineValue(currentTime, keyframes.positionX) / 100 * widthHalf;
+ const linePosY = calculateLineValue(currentTime, keyframes.positionY) / -100 * heightHalf;
+ const lineRotate = calculateLineValue(currentTime, keyframes.rotate);
+ const lineAlpha = calculateLineValue(currentTime, keyframes.alpha) / 255;
+ const lineFloorPosition = calculateFloorPosition(currentTime, floorPositions, lineSpeed);
+
+ const lineRadian = lineRotate * RADIAN;
+ const lineSinr = Math.sin(lineRadian);
+ const lineCosr = Math.cos(lineRadian);
+
+ line.x = linePosX;
+ line.y = linePosY;
+ line.angle = lineRotate;
+ line.alpha = lineAlpha;
+
+ for (const note of notes) {
+ const { state } = note;
+
+ if (
+ (state.time <= currentTime) &&
+ (state.type !== NoteType.Hold || state.holdEndTime <= currentTime)
+ ) {
+ if (note.parent) note.removeFromParent();
+ continue;
+ }
+
+ const floorPositionDiff = (note.floorPosition - lineFloorPosition) * state.speed;
+ if (floorPositionDiff > 2 || (floorPositionDiff < 0 && currentTime < state.time)) {
+ if (note.parent) note.removeFromParent();
+ continue;
+ }
+
+ const posX = widthHalf * (state.positionX / 100);
+ const posY = floorPositionDiff * size.height * (state.isAbove ? -1 : 1);
+ const realXSin = posY * lineSinr * -1;
+ const realYCos = posY * lineCosr;
+
+ note.onLinePosX = posX * lineCosr + linePosX;
+ note.onLinePosY = posX * lineSinr + linePosY;
+
+ if (state.type === NoteType.Hold && floorPositionDiff <= 0) {
+ const _n = note as LongNoteSprite;
+ const currentLength = (_n.holdLength + floorPositionDiff) * state.speed * size.height / size.noteScale;
+
+ if (_n.head.visible) _n.head.visible = false;
+ _n.body.height = currentLength;
+ _n.end.position.y = -currentLength;
+
+ _n.position.set(
+ _n.onLinePosX,
+ _n.onLinePosY,
+ );
+ } else {
+ note.position.set(
+ note.onLinePosX + realXSin,
+ note.onLinePosY + realYCos,
+ );
+
+ if (state.type === NoteType.Hold && !(note as LongNoteSprite).head.visible)
+ (note as LongNoteSprite).head.visible = true;
+ }
+
+ note.angle = lineRotate + (state.isAbove ? 0 : 180);
+
+ if (!note.parent) container.addChild(note);
+ }
+ }
+};
diff --git a/src/renderer/types.ts b/src/renderer/types.ts
new file mode 100644
index 0000000..40d762d
--- /dev/null
+++ b/src/renderer/types.ts
@@ -0,0 +1,17 @@
+
+export type PreviewSize = {
+ width: number,
+ height: number,
+ widthHalf: number,
+ heightHalf: number,
+
+ noteScale: number,
+ lineScale: number,
+
+ heightPercent: number,
+};
+
+export type FloorPosition = {
+ time: number,
+ value: number,
+};
diff --git a/src/renderer/utils.ts b/src/renderer/utils.ts
new file mode 100644
index 0000000..3d62735
--- /dev/null
+++ b/src/renderer/utils.ts
@@ -0,0 +1,41 @@
+import Easings from '@/utils/easings';
+import { IKeyframe } from '@/core/models/Keyframe';
+import { FloorPosition } from './types';
+
+export const calculateLineValue = (time: number, keyframes: IKeyframe[]) => {
+ let min = 0, max = keyframes.length - 1;
+
+ while (min <= max) {
+ const mid = (min + max) >> 1;
+ if (keyframes[mid].time <= time) min = mid + 1;
+ else max = mid - 1;
+ }
+
+ const index = Math.max(0, min - 1);
+ const keyframe = keyframes[index];
+ const keyframeNext = keyframes[index + 1];
+ const startValue = keyframe.hasEndValue ? keyframe.endValue : keyframe.value;
+
+ if (!keyframeNext || !keyframeNext.continuous || keyframeNext.value === startValue) {
+ return keyframe.value;
+ }
+
+ const timePercentEnd = Easings[keyframeNext.easing](
+ (time - keyframe.time) / (keyframeNext.time - keyframe.time)
+ );
+
+ return startValue * (1 - timePercentEnd) + keyframeNext.value * timePercentEnd;
+};
+
+export const calculateFloorPosition = (time: number, floorPositions: FloorPosition[], speed: number = 1) => {
+ let min = 0, max = floorPositions.length - 1;
+
+ while (min <= max) {
+ const mid = (min + max) >> 1;
+ if (floorPositions[mid].time <= time) min = mid + 1;
+ else max = mid - 1;
+ }
+
+ const fPos = floorPositions[Math.max(0, min - 1)];
+ return fPos.value + (time - fPos.time) * speed;
+};
diff --git a/src/runtime/audio/bindChart.ts b/src/runtime/audio/bindChart.ts
new file mode 100644
index 0000000..d7c2399
--- /dev/null
+++ b/src/runtime/audio/bindChart.ts
@@ -0,0 +1,65 @@
+import { onPatch } from 'mobx-state-tree';
+import { channelMusic } from './bus';
+import { runtimeAudioStore, runtimeAudioTimeStore } from './state';
+import { ticker } from './ticker';
+import { store as ChartStore } from '@/core/state/chartStore';
+import { getBeatByTime } from '@/core/timeline/bpm';
+import { runtimeCache } from '@/runtime/resources/cache';
+import { SnapshotIn } from 'mobx-state-tree';
+import { Clip } from '@phifans/audio';
+import { Metadata } from '@/core/models/Metadata';
+import { Nullable } from '@/utils/types';
+
+const applyNewClip = (clip?: Clip) => {
+ if (!clip) {
+ console.error('You must load audio file(s) before loading a chart file!');
+ return;
+ }
+
+ const {
+ musicClip: oldClip
+ } = runtimeAudioStore.getState();
+
+ if (oldClip) {
+ oldClip.stop();
+ oldClip.channel = null;
+ }
+ clip.channel = channelMusic;
+
+ runtimeAudioStore.setState({
+ musicClip: clip,
+ status: -1,
+ duration: clip.duration,
+ durationBeat: getBeatByTime(clip.duration),
+ });
+ runtimeAudioTimeStore.setState({
+ currentTime: 0,
+ currentBeat: 0,
+ });
+ if (!ticker.started) ticker.start();
+};
+
+// Listen to chart metadata changes
+onPatch(ChartStore, (patch) => {
+ if (patch.path === '/metadata' && patch.op === 'replace') {
+ const value = patch.value as Nullable>>;
+
+ if (!value) return;
+ if (!value.musicFile) return;
+
+ return applyNewClip(runtimeCache.get(value.musicFile) as Clip | undefined);
+ }
+
+ if (patch.path === '/metadata/musicFile' && patch.op === 'replace') {
+ const value = patch.value as string | undefined;
+ if (!value) return;
+
+ return applyNewClip(runtimeCache.get(value) as Clip | undefined);
+ }
+
+ if (patch.path.startsWith('/bpm')) {
+ const { musicClip } = runtimeAudioStore.getState();
+ if (!musicClip) return;
+ return runtimeAudioStore.setState({ durationBeat: getBeatByTime(musicClip.duration) });
+ }
+});
diff --git a/src/runtime/audio/bus.ts b/src/runtime/audio/bus.ts
new file mode 100644
index 0000000..06f1b4f
--- /dev/null
+++ b/src/runtime/audio/bus.ts
@@ -0,0 +1,8 @@
+import { Bus } from '@phifans/audio';
+
+export const bus = new Bus();
+
+export const channelMusic = bus.createChannel('music');
+
+export const channelEffect = bus.createChannel('effect');
+channelEffect.startTick();
diff --git a/src/runtime/audio/state.ts b/src/runtime/audio/state.ts
new file mode 100644
index 0000000..c06fa6e
--- /dev/null
+++ b/src/runtime/audio/state.ts
@@ -0,0 +1,74 @@
+/**
+ * XXX: Should this state be seperated?
+ */
+import { createStore } from 'zustand/vanilla';
+import { useStore } from 'zustand';
+import { Clip } from '@phifans/audio';
+import { Nullable } from '@/utils/types';
+import './bindChart';
+
+type RuntimeAudioStore = {
+ musicClip: Nullable,
+ status: -1 | 0 | 1,
+ duration: number,
+ durationBeat: number,
+
+ play: () => void,
+ pause: () => void,
+ stop: () => void,
+ seek: (seconds: number) => void,
+};
+
+export const runtimeAudioStore = createStore((set, get) => ({
+ musicClip: null,
+ status: -1,
+ duration: 0,
+ durationBeat: 0,
+
+ play() {
+ const { musicClip } = get();
+ if (!musicClip) return;
+ if (musicClip.status !== 1) musicClip.play();
+ else musicClip.pause();
+ setImmediate(() => set({ status: musicClip.status })); // TODO: This is a workaround for upstream @phifans/audio
+ },
+
+ pause() {
+ const { musicClip } = get();
+ if (!musicClip) return;
+ if (musicClip.status === 1) musicClip.pause();
+ else musicClip.play();
+ setImmediate(() => set({ status: musicClip.status })); // TODO: This is a workaround for upstream @phifans/audio
+ },
+
+ stop() {
+ const { musicClip } = get();
+ if (!musicClip) return;
+ musicClip.stop();
+ setImmediate(() => set({ status: musicClip.status })); // TODO: This is a workaround for upstream @phifans/audio
+ },
+
+ seek(seconds: number) {
+ const { musicClip } = get();
+ if (!musicClip) return;
+ musicClip.seek(seconds);
+ },
+}));
+
+export const runtimeAudioTimeStore = createStore<{
+ currentTime: number,
+ currentBeat: number,
+}>(() => ({
+ currentTime: 0,
+ currentBeat: 0,
+}));
+
+export const useRuntimeAudioStore = (
+ selector: (state: RuntimeAudioStore) => U
+) => useStore(runtimeAudioStore, selector);
+
+export const useRuntimeAudioTime = () =>
+ useStore(runtimeAudioTimeStore, (s) => s.currentTime);
+
+export const useRuntimeAudioBeat = () =>
+ useStore(runtimeAudioTimeStore, (s) => s.currentBeat);
diff --git a/src/runtime/audio/ticker.ts b/src/runtime/audio/ticker.ts
new file mode 100644
index 0000000..4d38461
--- /dev/null
+++ b/src/runtime/audio/ticker.ts
@@ -0,0 +1,20 @@
+import { Ticker } from 'pixi.js';
+import { getBeatByTime } from '@/core/timeline/bpm';
+import { runtimeAudioStore, runtimeAudioTimeStore } from './state';
+export const ticker = new Ticker();
+
+ticker.stop();
+ticker.autoStart = false;
+ticker.minFPS = ticker.maxFPS = 30;
+
+ticker.add(() => {
+ const {
+ musicClip
+ } = runtimeAudioStore.getState();
+ if (!musicClip) return;
+
+ runtimeAudioTimeStore.setState({
+ currentTime: musicClip.currentTime,
+ currentBeat: getBeatByTime(musicClip.currentTime),
+ });
+});
diff --git a/src/runtime/database/adatpers/indexeddb.ts b/src/runtime/database/adatpers/indexeddb.ts
new file mode 100644
index 0000000..d2d8d8f
--- /dev/null
+++ b/src/runtime/database/adatpers/indexeddb.ts
@@ -0,0 +1,7 @@
+import indexedDBDriver from 'unstorage/drivers/indexedb';
+
+export const IndexedDB = () =>
+ indexedDBDriver({
+ dbName: 'phifans-editor-database',
+ storeName: 'database',
+ });
diff --git a/src/runtime/database/adatpers/tauri.ts b/src/runtime/database/adatpers/tauri.ts
new file mode 100644
index 0000000..f23c248
--- /dev/null
+++ b/src/runtime/database/adatpers/tauri.ts
@@ -0,0 +1,146 @@
+// Reference: https://github.com/unjs/unstorage/blob/main/src/drivers/db0.ts
+import Database from '@tauri-apps/plugin-sql';
+import { defineDriver } from 'unstorage';
+import { Nullable } from '@/utils/types';
+
+type RowSchema = Array<{
+ key: string;
+ value: V;
+ created_at: string;
+ updated_at: string;
+}>;
+
+interface TauriDBOptions {
+ filename?: string,
+ tableName?: string,
+};
+
+const setupTable = (db: Database, tableName: string = 'unstorage') => {
+ return db.execute(`CREATE TABLE IF NOT EXISTS "${tableName}" (
+ key TEXT PRIMARY KEY,
+ value TEXT,
+ blob BLOB,
+ created_at TEXT DEFAULT CURRENT_TIMESTAMP,
+ updated_at TEXT DEFAULT CURRENT_TIMESTAMP
+ );
+ `);
+};
+
+const DRIVER_NAME = 'tauri';
+
+const tauriDBDriver = defineDriver>((opts) => {
+ const tableName = opts.tableName ?? 'unstorage';
+
+ let db: Nullable = null;
+ let setupPromise: Nullable> = null;
+ let setupDone = false;
+ const ensureTable = () => {
+ if (setupDone) return;
+
+ if (!setupPromise) {
+ setupPromise = Database.load(`sqlite:${opts.filename ?? 'database.db'}`)
+ .then((_db) => {
+ db = _db;
+ return setupTable(db, tableName);
+ })
+ .then(() => {
+ setupPromise = null;
+ setupDone = true;
+ });
+ }
+
+ return setupPromise;
+ };
+
+ return {
+ name: DRIVER_NAME,
+ options: opts,
+ getInstance: () => db,
+
+ async hasItem(key) {
+ await ensureTable();
+ const result = await db!.select>(
+ `SELECT EXISTS (SELECT 1 FROM "${tableName}" WHERE key = $1) AS value`,
+ [ key ]
+ );
+ return (result[0]?.value ?? 0) === 1;
+ },
+
+ async getItem(key) {
+ await ensureTable();
+ const result = await db!.select(
+ `SELECT value FROM "${tableName}" WHERE key = $1`,
+ [ key ]
+ );
+ return result[0]?.value ?? null;
+ },
+
+ async getItemRaw(key) {
+ await ensureTable();
+ const result = await db!.select(
+ `SELECT blob AS value FROM "${tableName}" WHERE key = $1`,
+ [ key ]
+ );
+ return result[0]?.value ?? null;
+ },
+
+ async setItem(key, value) {
+ await ensureTable();
+ await db!.execute(
+ `INSERT INTO "${tableName}" (key, value, created_at, updated_at) VALUES ($1, $2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) ON CONFLICT(key) DO UPDATE SET value = $2, updated_at = CURRENT_TIMESTAMP`,
+ [ key, value ]
+ );
+ },
+
+ async setItemRaw(key, value) {
+ await ensureTable();
+ await db!.execute(
+ `INSERT INTO "${tableName}" (key, blob, created_at, updated_at) VALUES ($1, $2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) ON CONFLICT(key) DO UPDATE SET blob = $2, updated_at = CURRENT_TIMESTAMP`,
+ [ key, value ]
+ );
+ },
+
+ async removeItem(key) {
+ await ensureTable();
+ await db!.execute(
+ `DELETE FROM "${tableName}" WHERE key = $1`,
+ [ key ]
+ );
+ },
+
+ async getMeta(key) {
+ await ensureTable();
+ const result = await db!.select(
+ `SELECT created_at, updated_at FROM "${tableName}" WHERE key = $1`,
+ [ key ]
+ );
+ if (result.length <= 0 || !result[0]) return null;
+ return {
+ atime: new Date(result[0].created_at),
+ mtime: new Date(result[0].updated_at),
+ };
+ },
+
+ async getKeys(base = "") {
+ await ensureTable();
+ const result = await db!.select(
+ `SELECT key FROM "${tableName}" WHERE key LIKE $1`,
+ [ `${base + '%'}` ]
+ );
+ return result.map((e) => e.key);
+ },
+
+ async clear() {
+ await ensureTable();
+ await db!.execute(
+ `DELETE FROM "${tableName}"`
+ );
+ },
+ };
+});
+
+export const Tauri = () =>
+ tauriDBDriver({
+ filename: 'database.db',
+ tableName: 'database',
+ });
diff --git a/src/runtime/database/index.ts b/src/runtime/database/index.ts
new file mode 100644
index 0000000..4d15d0d
--- /dev/null
+++ b/src/runtime/database/index.ts
@@ -0,0 +1,20 @@
+import { isTauri } from '@tauri-apps/api/core';
+import { createStorage } from 'unstorage';
+import { Tauri } from './adatpers/tauri';
+import { IndexedDB } from './adatpers/indexeddb';
+import { SkinMeta } from '../skin/types';
+
+type DatabaseStructure = {
+ items: {
+ skins: SkinMeta[],
+ }
+};
+
+const Driver = (() => {
+ if (isTauri()) return Tauri;
+ return IndexedDB;
+})()
+
+export const db = createStorage({
+ driver: Driver(),
+});
diff --git a/src/runtime/init.ts b/src/runtime/init.ts
new file mode 100644
index 0000000..4578e26
--- /dev/null
+++ b/src/runtime/init.ts
@@ -0,0 +1,25 @@
+import { db } from './database';
+import { SettingEngine } from './settings/engine';
+import { settingsStore, updateSettings } from './settings/state';
+import { skinStore } from './skin/state';
+import { importFromZip } from './skin/importer';
+import { DefaultSettings } from './settings/defaults';
+
+(async () => {
+ // Init settings
+ const settings = await SettingEngine.getAll();
+ if (!settings) updateSettings(DefaultSettings);
+ else settingsStore.setState(settings);
+
+ // Init skins
+ const skins = await db.get('skins');
+ const { selectSkin } = skinStore.getState();
+ if (!skins || skins.length <= 0) {
+ await fetch('./skin-default.zip')
+ .then(e => e.blob())
+ .then((e) => importFromZip(e));
+ } else {
+ skinStore.setState({ skins });
+ await selectSkin(skins[0].name, skins[0].author);
+ }
+})();
diff --git a/src/runtime/resources/cache.ts b/src/runtime/resources/cache.ts
new file mode 100644
index 0000000..ad7bf9b
--- /dev/null
+++ b/src/runtime/resources/cache.ts
@@ -0,0 +1,16 @@
+import { Clip } from '@phifans/audio';
+import { Texture } from 'pixi.js';
+import { LRUCache } from './class';
+
+type CacheItem = Texture | Clip;
+
+export const runtimeCache = new LRUCache({
+ maxSize: 100,
+ onEviction(_key, item) {
+ if (item instanceof Texture) {
+ return item.destroy(true);
+ } else {
+ return item.destroy();
+ }
+ }
+});
diff --git a/src/runtime/resources/class.ts b/src/runtime/resources/class.ts
new file mode 100644
index 0000000..5dac254
--- /dev/null
+++ b/src/runtime/resources/class.ts
@@ -0,0 +1,57 @@
+import QuickLRU, { Options } from 'quick-lru';
+
+const SkinKeyReg = /^skin\d+:/;
+
+export class LRUCache extends QuickLRU {
+ private readonly _onEviction?: (key: KeyType, value: ValueType) => void;
+
+ constructor(options: Options) {
+ super(options);
+
+ this._onEviction = options.onEviction;
+ }
+
+ /**
+ * Destroy an item. This will also call `onEviction` if set.
+ */
+ destroy(key: KeyType) {
+ const item = this.get(key);
+ if (!item) return false;
+
+ if (typeof this._onEviction === 'function') {
+ this._onEviction(key, item);
+ }
+
+ return this.delete(key);
+ }
+
+ /**
+ * Destroy all items. This will also call `onEviction` if set.
+ */
+ destroyAll() {
+ for (const [ key, item ] of this.entriesAscending()) {
+ if (typeof this._onEviction === 'function') {
+ this._onEviction(key, item);
+ }
+ }
+
+ return this.clear();
+ }
+
+ /**
+ * Destroy all items except `skin\d+:`. This will also call `onEviction` if set.
+ */
+ destroyAllWithoutSkin() {
+ for (const [ key ] of this.entriesAscending()) {
+ if (SkinKeyReg.test(key)) return;
+ this.destroy(key);
+ }
+ }
+
+ destroySkins() {
+ for (const [ key ] of this.entriesAscending()) {
+ if (!SkinKeyReg.test(key)) return;
+ this.destroy(key);
+ }
+ }
+}
diff --git a/src/runtime/resources/loader/audio.ts b/src/runtime/resources/loader/audio.ts
new file mode 100644
index 0000000..d4543ff
--- /dev/null
+++ b/src/runtime/resources/loader/audio.ts
@@ -0,0 +1,14 @@
+import { Clip } from '@phifans/audio';
+import { runtimeCache } from '../cache';
+
+export const loadAudio = (file: File | Blob, filename?: string) => new Promise((res, rej) => {
+ Clip.from(file)
+ .then((clip) => {
+ const _filename = (file as File).name ?? filename;
+
+ if (runtimeCache.has(_filename)) runtimeCache.destroy(_filename);
+ runtimeCache.set(_filename, clip);
+ res(clip);
+ })
+ .catch(e => rej(e));
+});
diff --git a/src/runtime/resources/loader/image.ts b/src/runtime/resources/loader/image.ts
new file mode 100644
index 0000000..e3819db
--- /dev/null
+++ b/src/runtime/resources/loader/image.ts
@@ -0,0 +1,15 @@
+import { Texture } from 'pixi.js';
+import { runtimeCache } from '../cache';
+
+export const loadImage = (file: Blob | File, filename?: string) => new Promise((res, rej) => {
+ window.createImageBitmap(file)
+ .then((bitmap) => {
+ const texture = Texture.from(bitmap);
+ const _filename = (file as File).name ?? filename;
+
+ if (runtimeCache.has(_filename)) runtimeCache.destroy(_filename);
+ runtimeCache.set(_filename, texture);
+ res(texture);
+ })
+ .catch(e => rej(e));
+});
diff --git a/src/runtime/resources/loader/index.ts b/src/runtime/resources/loader/index.ts
new file mode 100644
index 0000000..f2a0352
--- /dev/null
+++ b/src/runtime/resources/loader/index.ts
@@ -0,0 +1,29 @@
+import { loadImage } from './image';
+import { loadAudio } from './audio';
+
+export const loadFiles = (files: File[]) => new Promise<{
+ successed: string[], failed: string[]
+}>(async (res) => {
+ const filesSuccessed: string[] = [];
+ const filesFailed: string[] = [];
+
+ for (const file of files) {
+ (await new Promise(() => {
+ throw new Error('Promice chain');
+ }).catch(async () => {
+ await loadImage(file);
+ filesSuccessed.push(file.name);
+ }).catch(async () => {
+ await loadAudio(file);
+ filesSuccessed.push(file.name);
+ }).catch(() => {
+ console.warn(`Unsupported file: ${file.name}`);
+ filesFailed.push(file.name);
+ }));
+ }
+
+ res({
+ successed: filesSuccessed,
+ failed: filesFailed,
+ });
+});
diff --git a/src/runtime/settings/defaults.ts b/src/runtime/settings/defaults.ts
new file mode 100644
index 0000000..4608862
--- /dev/null
+++ b/src/runtime/settings/defaults.ts
@@ -0,0 +1,5 @@
+import { Settings } from './types';
+
+export const DefaultSettings: Readonly = Object.freeze({
+ 'renderer.noteScale': 8080,
+});
diff --git a/src/runtime/settings/engine/index.ts b/src/runtime/settings/engine/index.ts
new file mode 100644
index 0000000..e905268
--- /dev/null
+++ b/src/runtime/settings/engine/index.ts
@@ -0,0 +1,9 @@
+import { isTauri } from '@tauri-apps/api/core';
+import { LocalStorageEngine } from './localstorage';
+import { TauriFSEngine } from './tauri';
+import { SettingEngine as TSettingEngine, Settings } from '../types';
+
+export const SettingEngine = (() => {
+ if (isTauri()) return new TauriFSEngine();
+ return new LocalStorageEngine();
+})() as TSettingEngine;
diff --git a/src/runtime/settings/engine/localstorage.ts b/src/runtime/settings/engine/localstorage.ts
new file mode 100644
index 0000000..deca778
--- /dev/null
+++ b/src/runtime/settings/engine/localstorage.ts
@@ -0,0 +1,65 @@
+import { SettingEngine, TSettings } from '../types';
+import { Nullable } from '@/utils/types';
+
+type LocalStorageOptions = {
+ keyName: string,
+};
+
+export class LocalStorageEngine extends SettingEngine {
+ private readonly opts: LocalStorageOptions;
+
+ constructor(options: Partial = {}) {
+ super();
+
+ this.opts = {
+ keyName: 'settings',
+ ...options,
+ };
+ }
+
+ private getStore(): Nullable {
+ try {
+ const storeRaw = window.localStorage.getItem(this.opts.keyName);
+ if (!storeRaw) return null;
+ return JSON.parse(storeRaw) as T;
+ } catch {
+ return null;
+ }
+ }
+
+ private setStore(store: T) {
+ const storeRaw = JSON.stringify(store);
+ window.localStorage.setItem(this.opts.keyName, storeRaw);
+ }
+
+ public get(key: K, defaultValue?: T[K]): Promise> {
+ return new Promise((res) => {
+ const store = this.getStore();
+ if (!store) return res(null);
+ res(store[key] ?? defaultValue ?? null);
+ });
+ }
+
+ public set(key: K, value: T[K]): Promise {
+ return new Promise((res) => {
+ const store = this.getStore() ?? {} as T;
+ store[key] = value;
+ this.setStore(store);
+ res();
+ });
+ }
+
+ public getAll(defaultValue?: T): Promise> {
+ return new Promise((res) => {
+ const store = this.getStore();
+ res(store ?? defaultValue ?? null);
+ });
+ }
+
+ public setAll(settings: T): Promise {
+ return new Promise((res) => {
+ this.setStore(settings);
+ res();
+ });
+ }
+}
diff --git a/src/runtime/settings/engine/tauri.ts b/src/runtime/settings/engine/tauri.ts
new file mode 100644
index 0000000..573c4ac
--- /dev/null
+++ b/src/runtime/settings/engine/tauri.ts
@@ -0,0 +1,61 @@
+import * as fs from '@tauri-apps/plugin-fs';
+import * as path from '@tauri-apps/api/path';
+import { SettingEngine, TSettings } from '../types';
+import { Nullable } from '@/utils/types';
+
+type TauriFSOptions = {
+ filename: string,
+};
+
+export class TauriFSEngine extends SettingEngine {
+ private readonly opts: TauriFSOptions;
+
+ constructor(options: Partial = {}) {
+ super();
+
+ this.opts = {
+ filename: 'settings.json',
+ ...options,
+ };
+ }
+
+ private async path(...paths: string[]) {
+ return path.join(await path.appConfigDir(), ...paths);
+ }
+
+ private async getStore(): Promise> {
+ try {
+ const storeRaw = await fs.readTextFile(await this.path(this.opts.filename));
+ if (!storeRaw) return null;
+ return JSON.parse(storeRaw) as T;
+ } catch {
+ return null;
+ }
+ }
+
+ private async setStore(store: T) {
+ const storeRaw = JSON.stringify(store, null, 4);
+ await fs.writeTextFile(await this.path(this.opts.filename), storeRaw);
+ }
+
+ public async get(key: K, defaultValue?: T[K] | undefined): Promise> {
+ const store = await this.getStore();
+ if (!store) return null;
+ return store[key] ?? defaultValue ?? null;
+ }
+
+ public async set(key: K, value: T[K]): Promise {
+ const store = (await this.getStore()) ?? {} as T;
+ store[key] = value;
+ await this.setStore(store);
+ }
+
+ public async getAll(defaultValue?: T): Promise> {
+ const store = await this.getStore();
+ return store ?? defaultValue ?? null;
+ }
+
+ public async setAll(settings: T): Promise {
+ this.setStore(settings);
+ }
+}
diff --git a/src/runtime/settings/state.ts b/src/runtime/settings/state.ts
new file mode 100644
index 0000000..b7f2f45
--- /dev/null
+++ b/src/runtime/settings/state.ts
@@ -0,0 +1,37 @@
+import { createStore } from 'zustand/vanilla';
+import { useStore } from 'zustand';
+import { SettingEngine } from './engine';
+import { DefaultSettings } from './defaults';
+import { Settings } from './types';
+
+type SettingsStore = Settings & {};
+
+export const settingsStore = createStore(() => ({
+ ...DefaultSettings,
+}));
+
+export const useSettingsStore = (
+ selector: (state: SettingsStore) => U
+) => useStore(settingsStore, selector);
+
+export const updateSettings = (settings: Partial) => {
+ (new Promise(async (res) => {
+ settingsStore.setState(() => ({
+ ...settings,
+ }));
+
+ await SettingEngine.setAll(settingsStore.getState());
+ res(void 0);
+ })).then();
+};
+
+export const updateSettingsByKey = (key: K, value: Settings[K]) => {
+ (new Promise(async (res) => {
+ settingsStore.setState(() => ({
+ [key]: value,
+ }));
+
+ await SettingEngine.set(key, value);
+ res(void 0);
+ })).then();
+};
diff --git a/src/runtime/settings/types.ts b/src/runtime/settings/types.ts
new file mode 100644
index 0000000..c1f0945
--- /dev/null
+++ b/src/runtime/settings/types.ts
@@ -0,0 +1,19 @@
+import { Nullable } from '@/utils/types';
+
+export type SettingValue = Nullable;
+
+export type TSettings = Record;
+
+export abstract class SettingEngine {
+ public abstract get(key: K, defaultValue?: T[K]): Promise>;
+
+ public abstract set(key: K, value: T[K]): Promise;
+
+ public abstract getAll(defaultValue?: T): Promise>;
+
+ public abstract setAll(settings: T): Promise;
+};
+
+export type Settings = {
+ 'renderer.noteScale': number,
+};
diff --git a/src/runtime/skin/consts.ts b/src/runtime/skin/consts.ts
new file mode 100644
index 0000000..cb138ab
--- /dev/null
+++ b/src/runtime/skin/consts.ts
@@ -0,0 +1,14 @@
+
+export const SkinFiles = Object.freeze([
+ 'Tap.png',
+ 'TapHL.png',
+ 'Drag.png',
+ 'DragHL.png',
+ 'HoldHead.png',
+ 'HoldHeadHL.png',
+ 'HoldBody.png',
+ 'HoldBodyHL.png',
+ 'HoldEnd.png',
+ 'Flick.png',
+ 'FlickHL.png',
+]);
diff --git a/src/runtime/skin/importer.ts b/src/runtime/skin/importer.ts
new file mode 100644
index 0000000..0265633
--- /dev/null
+++ b/src/runtime/skin/importer.ts
@@ -0,0 +1,57 @@
+import JSZip from 'jszip';
+import * as fs from '@zenfs/core/promises';
+import { db } from '../database';
+import { skinStore } from './state';
+import { checkMetaValidation, getSkinFolderName } from './utils';
+import { SkinFiles } from './consts';
+import { SkinMeta } from './types';
+
+/**
+ * Import a skin from a zip file and save them to storage.
+ * @param zipFile {Blob | string}
+ * @returns {Promise}
+ */
+export const importFromZip = (zipFile: Blob, loadAfterImport = true): Promise =>
+ new Promise(async (res, rej) => {
+ const { skins, selectSkin } = skinStore.getState();
+ const zip = await JSZip.loadAsync(zipFile);
+
+ const metaFile = zip.file('skin.json');
+ if (!metaFile) return rej('Not a valid skin file');
+
+ const metaString = await metaFile.async('string');
+ if (!checkMetaValidation(metaString)) return rej('Not a valid skin file');
+
+ const metaJson = JSON.parse(metaString) as SkinMeta;
+ const folderName = getSkinFolderName(metaJson);
+ if (!folderName) return rej('Invalid skin name');
+
+ const pendingBuffers = await Promise.all(
+ SkinFiles.map((filename) => {
+ const file = zip.file(filename);
+ if (!file) return null;
+ return file.async('uint8array').then(b => ({ filename, buffer: b }));
+ }).filter(e => e !== null)
+ );
+ if (pendingBuffers.length <= 0) return rej('No skin file(s) found');
+
+ if (!(await fs.exists(`/skins/${folderName}`))) await fs.mkdir(`/skins/${folderName}`);
+ if (!(await db.has('skins'))) await db.setItem('skins', []);
+
+ await Promise.all(
+ pendingBuffers.map((e) => (
+ fs.writeFile(`/skins/${folderName}/${e.filename}`, e.buffer)
+ ))
+ );
+
+ const oldIndex = skins.findIndex(e => e.name === metaJson.name && e.author === metaJson.author);
+ if (oldIndex >= 0)
+ Object.assign(skins[oldIndex], metaJson);
+ else
+ skins.push(metaJson);
+ await db.set('skins', skins);
+ skinStore.setState({ skins });
+
+ if (loadAfterImport) await selectSkin(metaJson.name, metaJson.author);
+ res(metaJson);
+ });
diff --git a/src/runtime/skin/state.ts b/src/runtime/skin/state.ts
new file mode 100644
index 0000000..0ffca5d
--- /dev/null
+++ b/src/runtime/skin/state.ts
@@ -0,0 +1,69 @@
+import { createStore } from 'zustand/vanilla';
+import { useStore } from 'zustand';
+import * as fs from '@zenfs/core/promises';
+import { getSkinFolderName } from './utils';
+import { loadFiles } from '../resources/loader';
+import { SkinFiles } from './consts';
+import { SkinMeta } from './types';
+import { Nullable } from '@/utils/types';
+import { runtimeCache } from '../resources/cache';
+
+type SkinStore = {
+ skins: SkinMeta[],
+ currentSkin: Nullable,
+ skinCount: number,
+
+ selectSkin: (name: string, author?: string) => Promise,
+};
+
+export const skinStore = createStore((set, get) => ({
+ skins: [],
+ currentSkin: null,
+ skinCount: -1,
+
+ selectSkin(name: string, author?: string) {
+ return new Promise(async (res, rej) => {
+ const { skins, skinCount } = get();
+ if (!skins || skins.length <= 0) return rej('No skin stored');
+
+ const skinIndex = skins.findIndex(e => e.name === name && (author === (void 0) || e.author === author));
+ if (skinIndex === -1) return rej('No such skin found');
+
+ const folderName = getSkinFolderName(skins[skinIndex]);
+ const pendingBuffers = await Promise.all(
+ SkinFiles.map((filename) =>
+ fs.readFile(`/skins/${folderName}/${filename}`)
+ .then((b) => ({ filename, buffer: b }))
+ )
+ );
+
+ const missingFiles = SkinFiles.filter((e) => pendingBuffers.findIndex(h => h.filename === e) === -1);
+ if (skinCount < 0 && missingFiles.length > 0) return rej('Missing files in default skin');
+
+ missingFiles.forEach((filename) => {
+ const file = runtimeCache.peek(`skin${skinCount}:${filename}`);
+ if (!file) return;
+
+ runtimeCache.set(`skin${skinCount + 1}:${filename}`, file);
+ runtimeCache.delete(`skin${skinCount}:${filename}`);
+ });
+
+ await loadFiles(pendingBuffers.map((e) => new File([e.buffer as unknown as ArrayBuffer], `skin${skinCount + 1}:${e.filename}`)));
+
+ set({
+ currentSkin: skins[skinIndex],
+ skinCount: (skinCount + 1),
+ });
+
+ for (const [ name ] of runtimeCache.entriesAscending()) {
+ if (name.startsWith(`skin${skinCount}:`)) runtimeCache.destroy(name);
+ }
+
+ res(skins[skinIndex]);
+ });
+ },
+}));
+
+export const useSkinStore = (
+ selector: (state: SkinStore) => U
+) => useStore(skinStore, selector);
diff --git a/src/runtime/skin/types.ts b/src/runtime/skin/types.ts
new file mode 100644
index 0000000..7d48968
--- /dev/null
+++ b/src/runtime/skin/types.ts
@@ -0,0 +1,7 @@
+
+export type SkinMeta = {
+ name: string,
+ author: string,
+ version: string,
+ homepage?: string,
+};
diff --git a/src/runtime/skin/utils.ts b/src/runtime/skin/utils.ts
new file mode 100644
index 0000000..742f763
--- /dev/null
+++ b/src/runtime/skin/utils.ts
@@ -0,0 +1,20 @@
+import { SkinMeta } from './types';
+
+export const checkMetaValidation = (metaString: string) => {
+ try {
+ const json = JSON.parse(metaString) as SkinMeta;
+ return (
+ json.name !== (void 0) &&
+ json.author !== (void 0) &&
+ json.version !== (void 0)
+ );
+ } catch (_) {
+ return false;
+ }
+};
+
+export const getSkinFolderName = (meta: SkinMeta) =>
+ `${meta.author} - ${meta.name}`
+ .replace(/[\/\\?%*:|"<>]/g, '')
+ .replace(/[\x00-\x1F\x7F]/g, '')
+ .trim();
diff --git a/src/runtime/state/index.ts b/src/runtime/state/index.ts
new file mode 100644
index 0000000..d23a8e2
--- /dev/null
+++ b/src/runtime/state/index.ts
@@ -0,0 +1,18 @@
+
+import { createStore } from 'zustand/vanilla';
+import { useStore } from 'zustand';
+import { createProjectState, ProjectState } from './project';
+import { createPropertyState, PropertyState } from './property';
+import { createSelectionState, SelectionState } from './selection';
+
+type RuntimeStore = ProjectState & PropertyState & SelectionState;
+
+export const runtimeStore = createStore((set, get, state) => ({
+ ...createProjectState(set, get, state),
+ ...createPropertyState(set, get, state),
+ ...createSelectionState(set, get, state),
+}));
+
+export const useRuntimeStore = (
+ selector: (state: RuntimeStore) => U
+) => useStore(runtimeStore, selector);
diff --git a/src/runtime/state/project.ts b/src/runtime/state/project.ts
new file mode 100644
index 0000000..d4ce26e
--- /dev/null
+++ b/src/runtime/state/project.ts
@@ -0,0 +1,15 @@
+import { StateCreator } from 'zustand';
+
+export interface ProjectState {
+ isEditable: boolean;
+
+ setIsEditable: (isEditable: boolean) => void;
+};
+
+export const createProjectState: StateCreator = (set) => ({
+ isEditable: false,
+
+ setIsEditable: (isEditable) => set(({
+ isEditable
+ })),
+});
diff --git a/src/runtime/state/property.ts b/src/runtime/state/property.ts
new file mode 100644
index 0000000..5e75e5c
--- /dev/null
+++ b/src/runtime/state/property.ts
@@ -0,0 +1,15 @@
+import { StateCreator } from 'zustand';
+
+export interface PropertyState {
+ tempo: number;
+
+ setTempo: (tempo: number) => void;
+};
+
+export const createPropertyState: StateCreator = (set) => ({
+ tempo: 4,
+
+ setTempo: (tempo) => set(({
+ tempo,
+ })),
+});
diff --git a/src/runtime/state/selection.ts b/src/runtime/state/selection.ts
new file mode 100644
index 0000000..490c460
--- /dev/null
+++ b/src/runtime/state/selection.ts
@@ -0,0 +1,34 @@
+import { StateCreator } from 'zustand';
+import { Nullable } from '@/utils/types';
+
+export interface SelectionState {
+ selectedLineId: Nullable;
+ selectedKeyframeId: Nullable;
+ selectedNoteId: Nullable;
+
+ setSelectedLine: (lineId: Nullable) => void;
+ setSelectedKeyframe: (keyframeId: Nullable) => void;
+ setSelectedNote: (noteId: Nullable) => void;
+};
+
+export const createSelectionState: StateCreator = (set) => ({
+ selectedLineId: null,
+ selectedKeyframeId: null,
+ selectedNoteId: null,
+
+ setSelectedLine: (lineId) => set(() => ({
+ selectedLineId: lineId,
+ selectedKeyframeId: null,
+ selectedNoteId: null,
+ })),
+
+ setSelectedKeyframe: (keyframeId) => set(() => ({
+ selectedKeyframeId: keyframeId,
+ selectedNoteId: null,
+ })),
+
+ setSelectedNote: (noteId) => set(() => ({
+ selectedNoteId: noteId,
+ selectedKeyframeId: null,
+ })),
+});
diff --git a/src/storage/adapters/indexeddb.ts b/src/storage/adapters/indexeddb.ts
new file mode 100644
index 0000000..ed4de1d
--- /dev/null
+++ b/src/storage/adapters/indexeddb.ts
@@ -0,0 +1,7 @@
+import { IndexedDB as Engine } from '@zenfs/dom';
+import { MountConfiguration } from '@zenfs/core';
+
+export const IndexedDB: MountConfiguration = {
+ backend: Engine,
+ storeName: 'phifans-editor-storage',
+};
diff --git a/src/storage/adapters/tauri.ts b/src/storage/adapters/tauri.ts
new file mode 100644
index 0000000..cf2a02a
--- /dev/null
+++ b/src/storage/adapters/tauri.ts
@@ -0,0 +1,151 @@
+import { isTauri } from '@tauri-apps/api/core';
+import * as $TauriFS from '@tauri-apps/plugin-fs';
+import * as TauriPath from '@tauri-apps/api/path';
+import {
+ CreationOptions,
+ Async,
+ FileSystem,
+ InodeLike,
+ Backend,
+ MountConfiguration
+} from '@zenfs/core';
+
+class ErrorWithCode extends Error {
+ readonly code: string;
+
+ constructor(code: string, message: string) {
+ super(message);
+
+ this.code = code;
+ this.name = code;
+ }
+}
+
+class TauriFSEngine extends Async(FileSystem) {
+ private async path(...paths: string[]) {
+ return TauriPath.join(await TauriPath.appConfigDir(), ...paths);
+ }
+
+ public async ready() { return; }
+
+ public async rename(oldPath: string, newPath: string): Promise {
+ return $TauriFS.rename(await this.path(oldPath), await this.path(newPath));
+ }
+
+ public async stat(path: string): Promise {
+ if (!await ($TauriFS.exists(await this.path(path)))) {
+ throw new ErrorWithCode('ENOENT', `No such enrty: ${path}`);
+ }
+
+ const info = await $TauriFS.stat(await this.path(path));
+ return {
+ size: info.size,
+ mode: info.mode ?? 0o755,
+ atimeMs: (info.atime ?? new Date()).getTime(),
+ mtimeMs: (info.mtime ?? new Date()).getTime(),
+ ctimeMs: Date.now(),
+ birthtimeMs: (info.birthtime ?? new Date()).getTime(),
+ uid: info.uid ?? 1000,
+ gid: info.gid ?? 1000,
+ ino: info.ino ?? -1,
+ nlink: info.nlink ?? 0,
+ };
+ }
+
+ public async createFile(path: string): Promise {
+ await $TauriFS.create(await this.path(path));
+ return await this.stat(path);
+ }
+
+ public async unlink(path: string): Promise {
+ return $TauriFS.remove(await this.path(path));
+ }
+
+ public async rmdir(path: string): Promise {
+ return $TauriFS.remove(await this.path(path));
+ }
+
+ public async mkdir(path: string, options: CreationOptions): Promise {
+ const _options: $TauriFS.MkdirOptions = { recursive: true };
+ if (options && options.mode) _options.mode = options.mode;
+
+ await $TauriFS.mkdir(await this.path(path), _options);
+ return await this.stat(path);
+ }
+
+ public async readdir(path: string): Promise {
+ const result = await $TauriFS.readDir(await this.path(path));
+ throw result.map((e) => e.name);
+ }
+
+ public async exists(path: string): Promise {
+ return $TauriFS.exists(await this.path(path));
+ }
+
+ public async read(path: string, buffer: Uint8Array, start: number, end: number): Promise {
+ const file = await $TauriFS.open(await this.path(path), { read: true });
+ if ((await file.stat()).size <= 0) return;
+
+ const _buffer = new Uint8Array(end);
+ await file.read(_buffer);
+
+ const _result = _buffer.subarray(start, end);
+ buffer.set(_result);
+ }
+
+ public async write(path: string, buffer: Uint8Array, offset: number): Promise {
+ const file = await $TauriFS.open(await this.path(path), { write: true, create: true });
+
+ const _offsetData = new Uint8Array(offset);
+ await file.read(_offsetData);
+
+ const _result = new Uint8Array(buffer.length + offset);
+ _result.set(_offsetData, 0);
+ _result.set(buffer, offset);
+
+ await file.write(_result);
+ }
+
+ // These are unsupported APIs from Tauri
+ public async touch(): Promise { return void 0; }
+
+ public async link() {
+ throw new Error('Tauri does not support symlink');
+ }
+}
+
+const _TauriFS = {
+ name: 'TauriFS',
+
+ options: {},
+
+ async isAvailable() {
+ if (!(isTauri() ?? false)) return false;
+
+ try {
+ const BasePath = await TauriPath.appConfigDir();
+ if (!(await $TauriFS.exists(BasePath))) {
+ await $TauriFS.mkdir(BasePath);
+ }
+
+ const file = await $TauriFS.create(await TauriPath.join(BasePath, '__zenfs-test'));
+ return !isNaN(file.rid);
+ } catch {
+ return false;
+ } finally {
+ await $TauriFS.remove(await TauriPath.join(await TauriPath.appConfigDir(), '__zenfs-test'));
+ }
+ },
+
+ create() {
+ const fs = new TauriFSEngine(7421, 'tauri');
+ return fs;
+ },
+} as const satisfies Backend;
+type _TauriFS = typeof _TauriFS;
+interface TauriFS extends _TauriFS {};
+const TauriFS: TauriFS = _TauriFS;
+
+export const Tauri: MountConfiguration = {
+ backend: TauriFS,
+};
diff --git a/src/storage/init.ts b/src/storage/init.ts
new file mode 100644
index 0000000..b06115b
--- /dev/null
+++ b/src/storage/init.ts
@@ -0,0 +1,20 @@
+import { isTauri } from '@tauri-apps/api/core';
+import { configureSingle } from '@zenfs/core';
+import * as fs from '@zenfs/core/promises';
+import { IndexedDB } from './adapters/indexeddb';
+import { Tauri } from './adapters/tauri';
+
+const Engine = (() => {
+ if (isTauri()) return Tauri;
+ return IndexedDB;
+})();
+
+await configureSingle(Engine).then(async () => {
+ if (!(await fs.exists('/charts'))) {
+ await fs.mkdir('/charts');
+ }
+
+ if (!(await fs.exists('/skins'))) {
+ await fs.mkdir('/skins');
+ }
+});
diff --git a/src/ui/App.tsx b/src/ui/App.tsx
index ac3dfcd..235915c 100644
--- a/src/ui/App.tsx
+++ b/src/ui/App.tsx
@@ -1,137 +1,150 @@
-import TempoContext from './contexts/Tempo';
-import Chart from '@/Chart/Chart';
import PanelDock from './Panel/PanelDock';
import { PopupReadFiles, ReadFileAsText } from '@/utils/file';
+import { Clip } from '@phifans/audio';
import { Nullable } from '@/utils/types';
-import { useCallback, useRef, useState } from 'react';
-import AppBar from './Bar/AppBar';
-import SettingsProvider from './contexts/Settings/Provider';
-import DockLayout from 'rc-dock';
-import SettingsPanel from './Panel/SettingsPanel/SettingsPanel';
-import { ChartExported } from '@/Chart/Chart';
-import NumberInput from './components/NumberInput';
-import TopBar from './Bar/TopBar/TopBar';
-import DialogProvider from './contexts/Dialog/Provider';
+import { useCallback, useState } from 'react';
+import { importFromZip } from '@/runtime/skin/importer';
+import { DockviewApi } from 'dockview';
+import { showCreateProjectDialog } from './dialogs/createProject';
+import { loadFiles } from '@/runtime/resources/loader';
+import { store as ChartStore } from '@/core/state/chartStore';
+import { runtimeCache } from '@/runtime/resources/cache';
+import { MenuBar } from './Bar/MenuBar/MenuBar';
+import { StatusBar } from './Bar/StatusBar/StatusBar';
+import ActivityBar from './Bar/ActivityBar';
+import '@/runtime/audio/state';
function App() {
- const dockRef = useRef>(null);
- const [ tempo, setTempo ] = useState(4);
+ const [dockviewApi, setDockviewApi] = useState();
+ const [tempo, setTempo] = useState(4);
let importedMusic: Nullable = null;
- const onImportAudio = () => {
- PopupReadFiles(false)
+ const onImportFiles = () => {
+ PopupReadFiles(true)
.then((files) => {
if (!files || files.length === 0) return;
- importedMusic = files[0];
+ return loadFiles([...files]);
+ })
+ .then((result) => {
+ console.log(result);
})
.catch((e) => console.error(e));
};
- const onCreateChart = () => {
- if (!importedMusic) return;
- if (Chart.info) return;
+ const onApplyTestMetadata = () => {
+ let audioFile: string = '';
+
+ for (const [name, item] of runtimeCache.entriesDescending()) {
+ if (!audioFile && item instanceof Clip) {
+ audioFile = name;
+ break;
+ }
+ }
- Chart.create({
- name: 'test',
- artist: 'test',
- illustration: 'test',
- level: 'test',
- designer: 'test',
- music: importedMusic,
- background: importedMusic
+ ChartStore.updateMetadata({
+ musicFile: audioFile,
+ backgroundFile: 'tHisIsATestFileNamePleaseRemove'
});
};
- const onLoadChart = () => {
- if (!importedMusic) return;
- if (Chart.info) return;
-
- PopupReadFiles(false)
- .then(async (files) => {
+ const onImportSkin = () => {
+ PopupReadFiles(true)
+ .then((files) => {
if (!files || files.length === 0) return;
- const chartRaw = JSON.parse(await ReadFileAsText(files[0])) as ChartExported;
- Chart.load({
- ...chartRaw.info,
- music: importedMusic!,
- background: importedMusic!,
- }, chartRaw);
+ return importFromZip(files[0]);
+ })
+ .then((result) => {
+ console.log(result);
})
.catch((e) => console.error(e));
};
- const onExportChart = () => {
- if (!Chart.info) return;
-
- const chartJson = Chart.json!;
- const chartText = JSON.stringify(chartJson, null, 4);
- const chartBlob = new Blob([ chartText ], { type: 'text/json' });
- const chartUrl = URL.createObjectURL(chartBlob);
-
- const downloadDom = document.createElement('a');
- downloadDom.href = chartUrl;
- downloadDom.download = 'exported.json';
- downloadDom.click();
- };
-
const handleTempoUpdate = useCallback((tempo: number) => {
setTempo(tempo);
}, []);
const showSettingsPanel = () => {
- const dock = dockRef.current;
- if (!dock) return;
- if (dock.find('settings-panel')) return;
-
- dock.dockMove({
- id: 'settings-panel',
- title: 'Settings',
- cached: true,
- closable: true,
- content: (),
- }, null, 'float');
+ if (!dockviewApi) return;
+ const panel = dockviewApi.addPanel({
+ id: 'settings',
+ component: 'settingsPanel',
+ title: 'Settings'
+ });
+ if (panel) {
+ dockviewApi.addFloatingGroup(panel);
+ }
};
return (
<>
-
-
-
-
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ showCreateProjectDialog(),
+ },
+ {
+ key: 'file.open',
+ label: 'Open',
+ },
+ {
+ key: 'file.save',
+ label: 'Save',
+ },
+ {
+ key: 'file.save_as',
+ label: 'Save as...',
+ items: [
+ {
+ key: 'file.save_as.plain',
+ label: 'Plain text',
+ },
+ {
+ key: 'file.save_as.csv',
+ label: 'CSV',
+ },
+ {
+ key: 'file.save_as.test',
+ label: 'Click me',
+ onClick() {
+ alert('Clicked!');
+ },
+ }
+ ]
+ },
+ {
+ key: 'file.settings',
+ label: 'Settings',
+ onClick: () => showSettingsPanel(),
+ }
+ ]
+ },
+ {
+ key: 'edit',
+ label: 'Edit',
+ items: [
+ {
+ key: 'edit.undo',
+ label: 'Undo',
+ },
+ {
+ key: 'edit.redo',
+ label: 'Redo',
+ },
+ ]
+ }
+ ]}
+ />
+
+
>
);
}
diff --git a/src/ui/Bar/ActivityBar.tsx b/src/ui/Bar/ActivityBar.tsx
new file mode 100644
index 0000000..1963d77
--- /dev/null
+++ b/src/ui/Bar/ActivityBar.tsx
@@ -0,0 +1,26 @@
+import NumberInput from '@/ui/components/NumberInput';
+import { HStack, Text } from '@chakra-ui/react';
+
+type ActivityBarProps = {
+ handleTempoUpdate: (tempo: number) => void,
+};
+
+const ActivityBar = ({ handleTempoUpdate }: ActivityBarProps) => {
+ return (
+
+ Set tempo: 1/
+
+
+ );
+};
+
+export default ActivityBar;
\ No newline at end of file
diff --git a/src/ui/Bar/AppBar.tsx b/src/ui/Bar/AppBar.tsx
deleted file mode 100644
index e60f8a3..0000000
--- a/src/ui/Bar/AppBar.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import './styles.css';
-
-type AppBarProps = {
- className?: string,
- children?: React.ReactNode,
-};
-
-const AppBar = ({
- className,
- children
-}: AppBarProps) => {
- return (
-
- {children}
-
- );
-};
-
-export default AppBar;
diff --git a/src/ui/Bar/MenuBar/Entry.tsx b/src/ui/Bar/MenuBar/Entry.tsx
new file mode 100644
index 0000000..4ce8a20
--- /dev/null
+++ b/src/ui/Bar/MenuBar/Entry.tsx
@@ -0,0 +1,30 @@
+import styled from 'styled-components';
+import { Trigger, Menu } from '@radix-ui/react-menubar';
+import { menuItem } from './style';
+import { MenuBarList } from './List';
+import { MenuItem } from './types';
+
+const TriggerWrapper = styled(Trigger)(menuItem);
+
+// TODO: Hotkey
+type MenuBarEntryProps = {
+ label: string,
+ items: MenuItem[],
+};
+
+export const MenuBarEntry: React.FC = ({
+ label,
+ items,
+}) => {
+ return (
+
+ );
+};
diff --git a/src/ui/Bar/MenuBar/Item.tsx b/src/ui/Bar/MenuBar/Item.tsx
new file mode 100644
index 0000000..766a1f8
--- /dev/null
+++ b/src/ui/Bar/MenuBar/Item.tsx
@@ -0,0 +1,52 @@
+import styled from 'styled-components';
+import { Item, Sub, SubTrigger } from '@radix-ui/react-menubar';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faCaretRight } from '@fortawesome/free-solid-svg-icons';
+import { menuItem } from './style';
+import { themeSystem } from '@/ui/theme/system';
+import { MenuBarList } from './List';
+import { MenuItemProps } from '@chakra-ui/react';
+import { MenuItem } from './types';
+
+const ItemWrapper = styled(Item)(menuItem);
+const SubTriggerWrapper = styled(SubTrigger)(menuItem);
+
+const RightSlotIcon = styled(FontAwesomeIcon)(themeSystem.css({
+ marginLeft: 'auto',
+ paddingLeft: '2',
+ color: 'text',
+}));
+
+// TODO: Hotkey
+type MenuBarItemProps = MenuItemProps & {
+ depth: number,
+ items?: MenuItem[],
+};
+
+export const MenuBarItem: React.FC = ({
+ children,
+ depth,
+ items,
+ ...rest
+}) => {
+ if (items) {
+ return (
+
+
+ {children}
+
+
+
+
+ );
+ } else {
+ return (
+
+ {children}
+
+ );
+ }
+};
diff --git a/src/ui/Bar/MenuBar/List.tsx b/src/ui/Bar/MenuBar/List.tsx
new file mode 100644
index 0000000..89aff63
--- /dev/null
+++ b/src/ui/Bar/MenuBar/List.tsx
@@ -0,0 +1,60 @@
+import { Portal, Content, SubContent } from '@radix-ui/react-menubar';
+import styled from 'styled-components';
+import { themeSystem } from '@/ui/theme/system';
+import { MenuBarItem } from './Item';
+import { MenuItem } from './types';
+import { MenubarContentProps } from '@radix-ui/react-menubar';
+import { MenuSeparator } from './Separator';
+
+const menuContentStyle = themeSystem.css({
+ minW: '40',
+ layerStyle: 'fill.subtle',
+ p: '3',
+});
+
+type MenuBarListProps = {
+ items: MenuItem[],
+ depth: number,
+};
+
+const ContentWrapper = styled(Content)(menuContentStyle);
+const SubContentWrapper = styled(SubContent)(menuContentStyle);
+
+export const MenuBarList: React.FC = ({
+ items,
+ depth,
+}) => {
+ const ContentDom = depth === 0 ? ContentWrapper : SubContentWrapper;
+
+ const contentProps: MenubarContentProps = {};
+ if (depth === 0) {
+ contentProps.align = 'start';
+ contentProps.sideOffset = 5;
+ contentProps.alignOffset = -3;
+ } else {
+ contentProps.alignOffset = -5;
+ }
+
+ return (
+
+
+ {items.map((item, index) => (
+ item.type && item.type === 'separator' ? (
+
+ ) : (
+
+ )
+ ))}
+
+
+ );
+};
diff --git a/src/ui/Bar/MenuBar/MenuBar.tsx b/src/ui/Bar/MenuBar/MenuBar.tsx
new file mode 100644
index 0000000..dddfedd
--- /dev/null
+++ b/src/ui/Bar/MenuBar/MenuBar.tsx
@@ -0,0 +1,40 @@
+import styled from 'styled-components';
+import { Root } from '@radix-ui/react-menubar';
+import { themeSystem } from '@/ui/theme/system';
+import { MenuBarEntry } from './Entry';
+import { MenuEntry } from './types';
+
+const RootWraper = styled(Root)(themeSystem.css({
+ display: 'flex',
+ layerStyle: 'fill.subtle',
+}));
+
+const Icon = styled.img(themeSystem.css({
+ width: '0.7rem',
+ mx: '4',
+ my: 'auto',
+ alignSelf: 'center',
+ justifySelf: 'center',
+ borderRadius: '50%',
+}));
+
+type MenuBarProps = {
+ entries: MenuEntry[],
+};
+
+export const MenuBar: React.FC = ({
+ entries
+}) => {
+ return (
+
+
+ {entries.map((entry) => (
+
+ ))}
+
+ );
+};
diff --git a/src/ui/Bar/MenuBar/Separator.tsx b/src/ui/Bar/MenuBar/Separator.tsx
new file mode 100644
index 0000000..c04fa88
--- /dev/null
+++ b/src/ui/Bar/MenuBar/Separator.tsx
@@ -0,0 +1,15 @@
+import styled from 'styled-components';
+import { Separator } from '@radix-ui/react-menubar';
+import { themeSystem } from '@/ui/theme/system';
+
+const SeparatorWrapper = styled(Separator)(themeSystem.css({
+ height: '1px',
+ backgroundColor: 'border',
+ margin: '2',
+}));
+
+export const MenuSeparator = () => {
+ return (
+
+ );
+};
diff --git a/src/ui/Bar/MenuBar/style.ts b/src/ui/Bar/MenuBar/style.ts
new file mode 100644
index 0000000..a15b164
--- /dev/null
+++ b/src/ui/Bar/MenuBar/style.ts
@@ -0,0 +1,18 @@
+import { themeSystem } from '@/ui/theme/system';
+
+export const menuItem = themeSystem.css({
+ layerStyle: 'fill.subtle',
+ textStyle: 'sm',
+ px: '3',
+ py: '1',
+ gap: '2',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ display: 'flex',
+ lineHeight: '1.5',
+ outline: 'none',
+ userSelect: 'none',
+ '&[data-highlighted]': { layerStyle: 'fill.muted' },
+ '&[data-state="open"]': { layerStyle: 'fill.muted' },
+ '&:hover': { layerStyle: 'fill.muted' }
+});
diff --git a/src/ui/Bar/MenuBar/types.ts b/src/ui/Bar/MenuBar/types.ts
new file mode 100644
index 0000000..5e87b3d
--- /dev/null
+++ b/src/ui/Bar/MenuBar/types.ts
@@ -0,0 +1,13 @@
+
+export type MenuItem = {
+ type?: string,
+ key: string,
+ label: string,
+ hotkey?: string, // TODO
+ onClick?: () => void, // XXX
+ items?: MenuItem[], // XXX
+} & { type?: 'separator' };
+
+export type MenuEntry = Partial> & Omit