init
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
node_modules
|
||||||
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"bun.runtime": "~/.bun/bin/bun",
|
||||||
|
"bun.debugTerminal.enabled": true,
|
||||||
|
"bun.debugTerminal.stopOnEntry": false,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.defaultFormatter": "biomejs.biome",
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.organizeImports.biome": "explicit",
|
||||||
|
"source.fixAll.biome": "explicit"
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"linter": {
|
||||||
|
"rules": {
|
||||||
|
"a11y": "off",
|
||||||
|
"style": {
|
||||||
|
"noNonNullAssertion": "off"
|
||||||
|
},
|
||||||
|
"suspicious": {
|
||||||
|
"noAssignInExpressions": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
{
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"configVersion": 0,
|
||||||
|
"workspaces": {
|
||||||
|
"": {
|
||||||
|
"name": "nage",
|
||||||
|
"devDependencies": {
|
||||||
|
"@biomejs/biome": "latest",
|
||||||
|
"@types/bun": "latest",
|
||||||
|
"lz-string": "latest",
|
||||||
|
"solid-js": "latest",
|
||||||
|
"vite": "latest",
|
||||||
|
"vite-plugin-solid": "latest",
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "latest",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
|
||||||
|
|
||||||
|
"@babel/compat-data": ["@babel/compat-data@7.28.4", "", {}, "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw=="],
|
||||||
|
|
||||||
|
"@babel/core": ["@babel/core@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.4", "@babel/types": "^7.28.4", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA=="],
|
||||||
|
|
||||||
|
"@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="],
|
||||||
|
|
||||||
|
"@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="],
|
||||||
|
|
||||||
|
"@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
|
||||||
|
|
||||||
|
"@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="],
|
||||||
|
|
||||||
|
"@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
|
||||||
|
|
||||||
|
"@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="],
|
||||||
|
|
||||||
|
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
|
||||||
|
|
||||||
|
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="],
|
||||||
|
|
||||||
|
"@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
|
||||||
|
|
||||||
|
"@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="],
|
||||||
|
|
||||||
|
"@babel/parser": ["@babel/parser@7.28.4", "", { "dependencies": { "@babel/types": "^7.28.4" }, "bin": "./bin/babel-parser.js" }, "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg=="],
|
||||||
|
|
||||||
|
"@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w=="],
|
||||||
|
|
||||||
|
"@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
|
||||||
|
|
||||||
|
"@babel/traverse": ["@babel/traverse@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/types": "^7.28.4", "debug": "^4.3.1" } }, "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ=="],
|
||||||
|
|
||||||
|
"@babel/types": ["@babel/types@7.28.4", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q=="],
|
||||||
|
|
||||||
|
"@biomejs/biome": ["@biomejs/biome@2.3.7", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.7", "@biomejs/cli-darwin-x64": "2.3.7", "@biomejs/cli-linux-arm64": "2.3.7", "@biomejs/cli-linux-arm64-musl": "2.3.7", "@biomejs/cli-linux-x64": "2.3.7", "@biomejs/cli-linux-x64-musl": "2.3.7", "@biomejs/cli-win32-arm64": "2.3.7", "@biomejs/cli-win32-x64": "2.3.7" }, "bin": { "biome": "bin/biome" } }, "sha512-CTbAS/jNAiUc6rcq94BrTB8z83O9+BsgWj2sBCQg9rD6Wkh2gjfR87usjx0Ncx0zGXP1NKgT7JNglay5Zfs9jw=="],
|
||||||
|
|
||||||
|
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LirkamEwzIUULhXcf2D5b+NatXKeqhOwilM+5eRkbrnr6daKz9rsBL0kNZ16Hcy4b8RFq22SG4tcLwM+yx/wFA=="],
|
||||||
|
|
||||||
|
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-Q4TO633kvrMQkKIV7wmf8HXwF0dhdTD9S458LGE24TYgBjSRbuhvio4D5eOQzirEYg6eqxfs53ga/rbdd8nBKg=="],
|
||||||
|
|
||||||
|
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-inHOTdlstUBzgjDcx0ge71U4SVTbwAljmkfi3MC5WzsYCRhancqfeL+sa4Ke6v2ND53WIwCFD5hGsYExoI3EZQ=="],
|
||||||
|
|
||||||
|
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-/afy8lto4CB8scWfMdt+NoCZtatBUF62Tk3ilWH2w8ENd5spLhM77zKlFZEvsKJv9AFNHknMl03zO67CiklL2Q=="],
|
||||||
|
|
||||||
|
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-fJMc3ZEuo/NaMYo5rvoWjdSS5/uVSW+HPRQujucpZqm2ZCq71b8MKJ9U4th9yrv2L5+5NjPF0nqqILCl8HY/fg=="],
|
||||||
|
|
||||||
|
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-CQUtgH1tIN6e5wiYSJqzSwJumHYolNtaj1dwZGCnZXm2PZU1jOJof9TsyiP3bXNDb+VOR7oo7ZvY01If0W3iFQ=="],
|
||||||
|
|
||||||
|
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJAE8eCNyRpcfx2JJAtsPtISnELJ0H4xVVSwnxm13bzI8RwbXMyVtxy2r5DV1xT3WiSP+7LxORcApWw0LM8HiA=="],
|
||||||
|
|
||||||
|
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.7", "", { "os": "win32", "cpu": "x64" }, "sha512-pulzUshqv9Ed//MiE8MOUeeEkbkSHVDVY5Cz5wVAnH1DUqliCQG3j6s1POaITTFqFfo7AVIx2sWdKpx/GS+Nqw=="],
|
||||||
|
|
||||||
|
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.10", "", { "os": "aix", "cpu": "ppc64" }, "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.10", "", { "os": "android", "cpu": "arm" }, "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.10", "", { "os": "android", "cpu": "arm64" }, "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg=="],
|
||||||
|
|
||||||
|
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.10", "", { "os": "android", "cpu": "x64" }, "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.10", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.10", "", { "os": "freebsd", "cpu": "x64" }, "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.10", "", { "os": "linux", "cpu": "arm" }, "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.10", "", { "os": "linux", "cpu": "ia32" }, "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.10", "", { "os": "linux", "cpu": "none" }, "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.10", "", { "os": "linux", "cpu": "none" }, "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.10", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.10", "", { "os": "linux", "cpu": "none" }, "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.10", "", { "os": "linux", "cpu": "s390x" }, "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.10", "", { "os": "linux", "cpu": "x64" }, "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.10", "", { "os": "none", "cpu": "arm64" }, "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.10", "", { "os": "none", "cpu": "x64" }, "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.10", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.10", "", { "os": "openbsd", "cpu": "x64" }, "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw=="],
|
||||||
|
|
||||||
|
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.10", "", { "os": "none", "cpu": "arm64" }, "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag=="],
|
||||||
|
|
||||||
|
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.10", "", { "os": "sunos", "cpu": "x64" }, "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.10", "", { "os": "win32", "cpu": "ia32" }, "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.10", "", { "os": "win32", "cpu": "x64" }, "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw=="],
|
||||||
|
|
||||||
|
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
||||||
|
|
||||||
|
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
|
||||||
|
|
||||||
|
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||||
|
|
||||||
|
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||||
|
|
||||||
|
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.52.0", "", { "os": "android", "cpu": "arm" }, "sha512-VxDYCDqOaR7NXzAtvRx7G1u54d2kEHopb28YH/pKzY6y0qmogP3gG7CSiWsq9WvDFxOQMpNEyjVAHZFXfH3o/A=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.52.0", "", { "os": "android", "cpu": "arm64" }, "sha512-pqDirm8koABIKvzL59YI9W9DWbRlTX7RWhN+auR8HXJxo89m4mjqbah7nJZjeKNTNYopqL+yGg+0mhCpf3xZtQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.52.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YCdWlY/8ltN6H78HnMsRHYlPiKvqKagBP1r+D7SSylxX+HnsgXGCmLiV3Y4nSyY9hW8qr8U9LDUx/Lo7M6MfmQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.52.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-z4nw6y1j+OOSGzuVbSWdIp1IUks9qNw4dc7z7lWuWDKojY38VMWBlEN7F9jk5UXOkUcp97vA1N213DF+Lz8BRg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.52.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-Q/dv9Yvyr5rKlK8WQJZVrp5g2SOYeZUs9u/t2f9cQ2E0gJjYB/BWoedXfUT0EcDJefi2zzVfhcOj8drWCzTviw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.52.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kdBsLs4Uile/fbjZVvCRcKB4q64R+1mUq0Yd7oU1CMm1Av336ajIFqNFovByipciuUQjBCPMxwJhCgfG2re3rg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.52.0", "", { "os": "linux", "cpu": "arm" }, "sha512-aL6hRwu0k7MTUESgkg7QHY6CoqPgr6gdQXRJI1/VbFlUMwsSzPGSR7sG5d+MCbYnJmJwThc2ol3nixj1fvI/zQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.52.0", "", { "os": "linux", "cpu": "arm" }, "sha512-BTs0M5s1EJejgIBJhCeiFo7GZZ2IXWkFGcyZhxX4+8usnIo5Mti57108vjXFIQmmJaRyDwmV59Tw64Ap1dkwMw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.52.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-uj672IVOU9m08DBGvoPKPi/J8jlVgjh12C9GmjjBxCTQc3XtVmRkRKyeHSmIKQpvJ7fIm1EJieBUcnGSzDVFyw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.52.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-/+IVbeDMDCtB/HP/wiWsSzduD10SEGzIZX2945KSgZRNi4TSkjHqRJtNTVtVb8IRwhJ65ssI56krlLik+zFWkw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.52.0", "", { "os": "linux", "cpu": "none" }, "sha512-U1vVzvSWtSMWKKrGoROPBXMh3Vwn93TA9V35PldokHGqiUbF6erSzox/5qrSMKp6SzakvyjcPiVF8yB1xKr9Pg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.52.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-X/4WfuBAdQRH8cK3DYl8zC00XEE6aM472W+QCycpQJeLWVnHfkv7RyBFVaTqNUMsTgIX8ihMjCvFF9OUgeABzw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.52.0", "", { "os": "linux", "cpu": "none" }, "sha512-xIRYc58HfWDBZoLmWfWXg2Sq8VCa2iJ32B7mqfWnkx5mekekl0tMe7FHpY8I72RXEcUkaWawRvl3qA55og+cwQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.52.0", "", { "os": "linux", "cpu": "none" }, "sha512-mbsoUey05WJIOz8U1WzNdf+6UMYGwE3fZZnQqsM22FZ3wh1N887HT6jAOjXs6CNEK3Ntu2OBsyQDXfIjouI4dw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.52.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-qP6aP970bucEi5KKKR4AuPFd8aTx9EF6BvutvYxmZuWLJHmnq4LvBfp0U+yFDMGwJ+AIJEH5sIP+SNypauMWzg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.52.0", "", { "os": "linux", "cpu": "x64" }, "sha512-nmSVN+F2i1yKZ7rJNKO3G7ZzmxJgoQBQZ/6c4MuS553Grmr7WqR7LLDcYG53Z2m9409z3JLt4sCOhLdbKQ3HmA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.52.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2d0qRo33G6TfQVjaMR71P+yJVGODrt5V6+T0BDYH4EMfGgdC/2HWDVjSSFw888GSzAZUwuska3+zxNUCDco6rQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.52.0", "", { "os": "none", "cpu": "arm64" }, "sha512-A1JalX4MOaFAAyGgpO7XP5khquv/7xKzLIyLmhNrbiCxWpMlnsTYr8dnsWM7sEeotNmxvSOEL7F65j0HXFcFsw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.52.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-YQugafP/rH0eOOHGjmNgDURrpYHrIX0yuojOI8bwCyXwxC9ZdTd3vYkmddPX0oHONLXu9Rb1dDmT0VNpjkzGGw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.52.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-zYdUYhi3Qe2fndujBqL5FjAFzvNeLxtIqfzNEVKD1I7C37/chv1VxhscWSQHTNfjPCrBFQMnynwA3kpZpZ8w4A=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.52.0", "", { "os": "win32", "cpu": "x64" }, "sha512-fGk03kQylNaCOQ96HDMeT7E2n91EqvCDd3RwvT5k+xNdFCeMGnj5b5hEgTGrQuyidqSsD3zJDQ21QIaxXqTBJw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.52.0", "", { "os": "win32", "cpu": "x64" }, "sha512-6iKDCVSIUQ8jPMoIV0OytRKniaYyy5EbY/RRydmLW8ZR3cEBhxbWl5ro0rkUNe0ef6sScvhbY79HrjRm8i3vDQ=="],
|
||||||
|
|
||||||
|
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
|
||||||
|
|
||||||
|
"@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
|
||||||
|
|
||||||
|
"@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="],
|
||||||
|
|
||||||
|
"@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
|
||||||
|
|
||||||
|
"@types/bun": ["@types/bun@1.3.3", "", { "dependencies": { "bun-types": "1.3.3" } }, "sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g=="],
|
||||||
|
|
||||||
|
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||||
|
|
||||||
|
"@types/node": ["@types/node@24.5.2", "", { "dependencies": { "undici-types": "~7.12.0" } }, "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ=="],
|
||||||
|
|
||||||
|
"babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.1", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2", "validate-html-nesting": "^1.2.1" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-b4iHuirqK7RgaMzB2Lsl7MqrlDgQtVRSSazyrmx7wB3T759ggGjod5Rkok5MfHjQXhR7tRPmdwoeGPqBnW2KfA=="],
|
||||||
|
|
||||||
|
"babel-preset-solid": ["babel-preset-solid@1.9.9", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.1" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.8" }, "optionalPeers": ["solid-js"] }, "sha512-pCnxWrciluXCeli/dj5PIEHgbNzim3evtTn12snjqqg8QZWJNMjH1AWIp4iG/tbVjqQ72aBEymMSagvmgxubXw=="],
|
||||||
|
|
||||||
|
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.6", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw=="],
|
||||||
|
|
||||||
|
"browserslist": ["browserslist@4.26.2", "", { "dependencies": { "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001741", "electron-to-chromium": "^1.5.218", "node-releases": "^2.0.21", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A=="],
|
||||||
|
|
||||||
|
"bun-types": ["bun-types@1.3.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ=="],
|
||||||
|
|
||||||
|
"caniuse-lite": ["caniuse-lite@1.0.30001743", "", {}, "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw=="],
|
||||||
|
|
||||||
|
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||||
|
|
||||||
|
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||||
|
|
||||||
|
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||||
|
|
||||||
|
"electron-to-chromium": ["electron-to-chromium@1.5.222", "", {}, "sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w=="],
|
||||||
|
|
||||||
|
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||||
|
|
||||||
|
"esbuild": ["esbuild@0.25.10", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.10", "@esbuild/android-arm": "0.25.10", "@esbuild/android-arm64": "0.25.10", "@esbuild/android-x64": "0.25.10", "@esbuild/darwin-arm64": "0.25.10", "@esbuild/darwin-x64": "0.25.10", "@esbuild/freebsd-arm64": "0.25.10", "@esbuild/freebsd-x64": "0.25.10", "@esbuild/linux-arm": "0.25.10", "@esbuild/linux-arm64": "0.25.10", "@esbuild/linux-ia32": "0.25.10", "@esbuild/linux-loong64": "0.25.10", "@esbuild/linux-mips64el": "0.25.10", "@esbuild/linux-ppc64": "0.25.10", "@esbuild/linux-riscv64": "0.25.10", "@esbuild/linux-s390x": "0.25.10", "@esbuild/linux-x64": "0.25.10", "@esbuild/netbsd-arm64": "0.25.10", "@esbuild/netbsd-x64": "0.25.10", "@esbuild/openbsd-arm64": "0.25.10", "@esbuild/openbsd-x64": "0.25.10", "@esbuild/openharmony-arm64": "0.25.10", "@esbuild/sunos-x64": "0.25.10", "@esbuild/win32-arm64": "0.25.10", "@esbuild/win32-ia32": "0.25.10", "@esbuild/win32-x64": "0.25.10" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ=="],
|
||||||
|
|
||||||
|
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
||||||
|
|
||||||
|
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||||
|
|
||||||
|
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
|
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
||||||
|
|
||||||
|
"html-entities": ["html-entities@2.3.3", "", {}, "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA=="],
|
||||||
|
|
||||||
|
"is-what": ["is-what@4.1.16", "", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="],
|
||||||
|
|
||||||
|
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||||
|
|
||||||
|
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
|
||||||
|
|
||||||
|
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
|
||||||
|
|
||||||
|
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||||
|
|
||||||
|
"lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="],
|
||||||
|
|
||||||
|
"merge-anything": ["merge-anything@5.1.7", "", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ=="],
|
||||||
|
|
||||||
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
|
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|
||||||
|
"node-releases": ["node-releases@2.0.21", "", {}, "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw=="],
|
||||||
|
|
||||||
|
"parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="],
|
||||||
|
|
||||||
|
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
|
|
||||||
|
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||||
|
|
||||||
|
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||||
|
|
||||||
|
"rollup": ["rollup@4.52.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.0", "@rollup/rollup-android-arm64": "4.52.0", "@rollup/rollup-darwin-arm64": "4.52.0", "@rollup/rollup-darwin-x64": "4.52.0", "@rollup/rollup-freebsd-arm64": "4.52.0", "@rollup/rollup-freebsd-x64": "4.52.0", "@rollup/rollup-linux-arm-gnueabihf": "4.52.0", "@rollup/rollup-linux-arm-musleabihf": "4.52.0", "@rollup/rollup-linux-arm64-gnu": "4.52.0", "@rollup/rollup-linux-arm64-musl": "4.52.0", "@rollup/rollup-linux-loong64-gnu": "4.52.0", "@rollup/rollup-linux-ppc64-gnu": "4.52.0", "@rollup/rollup-linux-riscv64-gnu": "4.52.0", "@rollup/rollup-linux-riscv64-musl": "4.52.0", "@rollup/rollup-linux-s390x-gnu": "4.52.0", "@rollup/rollup-linux-x64-gnu": "4.52.0", "@rollup/rollup-linux-x64-musl": "4.52.0", "@rollup/rollup-openharmony-arm64": "4.52.0", "@rollup/rollup-win32-arm64-msvc": "4.52.0", "@rollup/rollup-win32-ia32-msvc": "4.52.0", "@rollup/rollup-win32-x64-gnu": "4.52.0", "@rollup/rollup-win32-x64-msvc": "4.52.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g=="],
|
||||||
|
|
||||||
|
"semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||||
|
|
||||||
|
"seroval": ["seroval@1.3.2", "", {}, "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ=="],
|
||||||
|
|
||||||
|
"seroval-plugins": ["seroval-plugins@1.3.3", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w=="],
|
||||||
|
|
||||||
|
"solid-js": ["solid-js@1.9.10", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew=="],
|
||||||
|
|
||||||
|
"solid-refresh": ["solid-refresh@0.6.3", "", { "dependencies": { "@babel/generator": "^7.23.6", "@babel/helper-module-imports": "^7.22.15", "@babel/types": "^7.23.6" }, "peerDependencies": { "solid-js": "^1.3" } }, "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA=="],
|
||||||
|
|
||||||
|
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
|
|
||||||
|
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
||||||
|
|
||||||
|
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||||
|
|
||||||
|
"undici-types": ["undici-types@7.12.0", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="],
|
||||||
|
|
||||||
|
"update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="],
|
||||||
|
|
||||||
|
"validate-html-nesting": ["validate-html-nesting@1.2.3", "", {}, "sha512-kdkWdCl6eCeLlRShJKbjVOU2kFKxMF8Ghu50n+crEoyx+VKm3FxAxF9z4DCy6+bbTOqNW0+jcIYRnjoIRzigRw=="],
|
||||||
|
|
||||||
|
"vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="],
|
||||||
|
|
||||||
|
"vite-plugin-solid": ["vite-plugin-solid@2.11.10", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-Yr1dQybmtDtDAHkii6hXuc1oVH9CPcS/Zb2jN/P36qqcrkNnVPsMTzQ06jyzFPFjj3U1IYKMVt/9ZqcwGCEbjw=="],
|
||||||
|
|
||||||
|
"vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
|
||||||
|
|
||||||
|
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||||
|
|
||||||
|
"babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="],
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { loadImage } from "#/lib/loadImage.ts";
|
||||||
|
import { createSprite, type Sprite } from "#/lib/Sprite.ts";
|
||||||
|
import { createVector, type Vector } from "#/lib/Vector.ts";
|
||||||
|
|
||||||
|
export type Entity = {
|
||||||
|
id: string;
|
||||||
|
src: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EntityInstance = {
|
||||||
|
position: Vector;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
sprite: Sprite;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createEntity(
|
||||||
|
id: string,
|
||||||
|
src: string,
|
||||||
|
width: number = 16,
|
||||||
|
height: number = 16,
|
||||||
|
): Entity {
|
||||||
|
return { id, width, height, src };
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadEntity(name: string): Promise<EntityInstance> {
|
||||||
|
const entity = (await import(`#/entities/${name}/index.ts`)).default;
|
||||||
|
|
||||||
|
const { width, height } = entity;
|
||||||
|
const sprite = createSprite(await loadImage(entity.src), 2, 4);
|
||||||
|
const position = createVector();
|
||||||
|
|
||||||
|
return { position, width, height, sprite };
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
export type SceneData = {
|
||||||
|
id: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
entities: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Scene = {
|
||||||
|
data: SceneData;
|
||||||
|
process: Process;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Process = (ctx: CanvasRenderingContext2D, delta: number) => void;
|
||||||
|
|
||||||
|
export type SceneChangeCallback = (from: Scene, to: Scene) => void;
|
||||||
|
|
||||||
|
let sceneChangeCallback: SceneChangeCallback = (): void => {};
|
||||||
|
|
||||||
|
const sceneDataMap = new Map<string, SceneData>();
|
||||||
|
const sceneProcessMap = new Map<string, Process>();
|
||||||
|
|
||||||
|
export const currentScene: Scene = {
|
||||||
|
data: {
|
||||||
|
id: "",
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
entities: [],
|
||||||
|
},
|
||||||
|
process: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useScene(data: SceneData): {
|
||||||
|
process: (fn: Process) => void;
|
||||||
|
} {
|
||||||
|
sceneDataMap.set(data.id, data);
|
||||||
|
|
||||||
|
return {
|
||||||
|
process(fn: Process): void {
|
||||||
|
sceneProcessMap.set(data.id, fn);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setSceneChangeCallback(callback: SceneChangeCallback) {
|
||||||
|
sceneChangeCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function changeScene(scene: Scene): void {
|
||||||
|
sceneChangeCallback(currentScene, scene);
|
||||||
|
currentScene.data = scene.data;
|
||||||
|
currentScene.process = scene.process;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadScene(name: string): Promise<void> {
|
||||||
|
await import(`#/scenes/${name}/index.ts`);
|
||||||
|
|
||||||
|
const data = sceneDataMap.get(name)!;
|
||||||
|
currentScene.data = data;
|
||||||
|
|
||||||
|
const process = sceneProcessMap.get(name)!;
|
||||||
|
currentScene.process = process;
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
import { createVector, type Vector } from "#/lib/Vector.ts";
|
||||||
|
|
||||||
|
export type Viewport = {
|
||||||
|
initialScale: number;
|
||||||
|
imageSmoothing: CanvasImageSmoothing;
|
||||||
|
translation: Vector;
|
||||||
|
ctx: CanvasRenderingContext2D;
|
||||||
|
canvas: HTMLCanvasElement;
|
||||||
|
gameContainer: HTMLElement;
|
||||||
|
canvasContainer: HTMLElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const viewport: Viewport = {
|
||||||
|
initialScale: 4,
|
||||||
|
imageSmoothing: {
|
||||||
|
imageSmoothingEnabled: false,
|
||||||
|
imageSmoothingQuality: "low",
|
||||||
|
},
|
||||||
|
translation: createVector(),
|
||||||
|
ctx: null as unknown as CanvasRenderingContext2D,
|
||||||
|
canvas: null as unknown as HTMLCanvasElement,
|
||||||
|
gameContainer: null as unknown as HTMLElement,
|
||||||
|
canvasContainer: null as unknown as HTMLElement,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function initViewport(): void {
|
||||||
|
const gameContainer = document.createElement("div");
|
||||||
|
gameContainer.id = "gameContainer";
|
||||||
|
|
||||||
|
const canvasContainer = document.createElement("div");
|
||||||
|
canvasContainer.id = "canvasContainer";
|
||||||
|
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
viewport.ctx = canvas.getContext("2d", {
|
||||||
|
alpha: false,
|
||||||
|
}) as CanvasRenderingContext2D;
|
||||||
|
|
||||||
|
viewport.canvas = canvas;
|
||||||
|
viewport.canvasContainer = canvasContainer;
|
||||||
|
viewport.gameContainer = gameContainer;
|
||||||
|
|
||||||
|
canvasContainer.appendChild(canvas);
|
||||||
|
gameContainer.appendChild(canvasContainer);
|
||||||
|
document.body.appendChild(gameContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setScale(scale: number): void {
|
||||||
|
viewport.initialScale = scale;
|
||||||
|
self.dispatchEvent(new Event("resize"));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resizeCanvas(width: number, height: number): void {
|
||||||
|
const {
|
||||||
|
initialScale,
|
||||||
|
imageSmoothing,
|
||||||
|
ctx,
|
||||||
|
canvas,
|
||||||
|
canvasContainer,
|
||||||
|
gameContainer,
|
||||||
|
} = viewport;
|
||||||
|
|
||||||
|
const containerWidth = (gameContainer.offsetWidth / initialScale) | 0;
|
||||||
|
const containerHeight = (gameContainer.offsetHeight / initialScale) | 0;
|
||||||
|
|
||||||
|
canvas.width = Math.min(width, containerWidth);
|
||||||
|
canvas.height = Math.min(height, containerHeight);
|
||||||
|
|
||||||
|
ctx.imageSmoothingEnabled = imageSmoothing.imageSmoothingEnabled;
|
||||||
|
ctx.imageSmoothingQuality = imageSmoothing.imageSmoothingQuality;
|
||||||
|
|
||||||
|
const canvasWidth =
|
||||||
|
canvas.width * initialScale - (containerWidth % initialScale);
|
||||||
|
const canvasHeight =
|
||||||
|
canvas.height * initialScale - (containerHeight % initialScale);
|
||||||
|
|
||||||
|
canvasContainer.style = `width: ${canvasWidth}px; height: ${canvasHeight}px;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetCtx() {
|
||||||
|
const { ctx, canvas, translation } = viewport;
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(-(translation.x | 0), -(translation.y | 0));
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"id": "testEntity",
|
||||||
|
"src": "/assets/char-idle.png",
|
||||||
|
"width": 16,
|
||||||
|
"height": 16
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { createEntity } from "#/engine/Entity.ts";
|
||||||
|
import data from "./data.json";
|
||||||
|
|
||||||
|
export default createEntity(data.id, data.src, data.width, data.height);
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<script type="module" src="main.ts"></script>
|
||||||
|
<link rel="stylesheet" href="styles.css" />
|
||||||
|
<link rel="icon" href="/favicon.png" />
|
||||||
|
<title>nage</title>
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
||||||
+119
@@ -0,0 +1,119 @@
|
|||||||
|
import type { Vector } from "./Vector.ts";
|
||||||
|
|
||||||
|
export type Node<T> = T;
|
||||||
|
export type Edge<T> = [Node<T>, Node<T>];
|
||||||
|
export type Graph<T> = Map<Node<T>, Array<Node<T>>>;
|
||||||
|
|
||||||
|
type PositionPartial = {
|
||||||
|
position: Vector;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function drawNode(
|
||||||
|
node: Node<PositionPartial>,
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
color: string,
|
||||||
|
): void {
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.strokeStyle = color;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(node.position.x, node.position.y, 8, 0, 2 * Math.PI);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNodeByPosition(
|
||||||
|
nodes: Array<Node<PositionPartial>>,
|
||||||
|
position: Vector,
|
||||||
|
): Node<PositionPartial> | null {
|
||||||
|
for (const node of nodes) {
|
||||||
|
if (
|
||||||
|
node.position.x <= position.x + 16 &&
|
||||||
|
node.position.x >= position.x - 16 &&
|
||||||
|
node.position.y <= position.y + 16 &&
|
||||||
|
node.position.y >= position.y - 16
|
||||||
|
) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function drawEdge(
|
||||||
|
edge: Edge<PositionPartial>,
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
color: string,
|
||||||
|
): void {
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.strokeStyle = color;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(edge[0].position.x, edge[0].position.y);
|
||||||
|
ctx.lineTo(edge[1].position.x, edge[1].position.y);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createGraph<T>(
|
||||||
|
nodes: Array<Node<T>>,
|
||||||
|
edges: Array<Edge<T>>,
|
||||||
|
): Graph<T> {
|
||||||
|
const graph: Graph<T> = new Map();
|
||||||
|
|
||||||
|
for (const node of nodes) {
|
||||||
|
const neighbours = edges.reduce(
|
||||||
|
(acc, edge) => {
|
||||||
|
if (edge[0] === node) {
|
||||||
|
acc.push(edge[1]);
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge[1] === node) {
|
||||||
|
acc.push(edge[0]);
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
[] as Array<Node<T>>,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (neighbours.length > 0) {
|
||||||
|
graph.set(node, neighbours);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function originDFS<T>(origin: Node<T>, graph: Graph<T>): Array<Node<T>> {
|
||||||
|
const visited: Array<Node<T>> = [origin];
|
||||||
|
|
||||||
|
if (!graph.has(origin)) {
|
||||||
|
return visited;
|
||||||
|
}
|
||||||
|
|
||||||
|
innerDFS(origin, graph, visited);
|
||||||
|
|
||||||
|
return visited;
|
||||||
|
}
|
||||||
|
|
||||||
|
function innerDFS<T>(
|
||||||
|
node: Node<T>,
|
||||||
|
graph: Graph<T>,
|
||||||
|
visited: Array<Node<T>>,
|
||||||
|
): void {
|
||||||
|
const neighbours = graph.get(node)!;
|
||||||
|
for (const node of neighbours) {
|
||||||
|
if (visited.includes(node)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
visited.push(node);
|
||||||
|
innerDFS(node, graph, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNeighbours<T>(
|
||||||
|
graph: Graph<T>,
|
||||||
|
node: Node<T>,
|
||||||
|
): Array<Node<T>> {
|
||||||
|
return graph.has(node) ? graph.get(node)! : [];
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import { lerp } from "./lerp.ts";
|
||||||
|
import type { Vector } from "./Vector.ts";
|
||||||
|
|
||||||
|
export type Segment = [Vector, Vector];
|
||||||
|
|
||||||
|
export type SegmentIntersection = {
|
||||||
|
position: Vector;
|
||||||
|
offset: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createSegmentIntersection(): SegmentIntersection {
|
||||||
|
return {
|
||||||
|
position: {
|
||||||
|
x: Number.NaN,
|
||||||
|
y: Number.NaN,
|
||||||
|
},
|
||||||
|
offset: Number.NaN,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setSegmentIntersection(
|
||||||
|
segmentIntersection: SegmentIntersection,
|
||||||
|
a: Segment,
|
||||||
|
b: Segment,
|
||||||
|
): void {
|
||||||
|
const bottom =
|
||||||
|
(b[1].y - b[0].y) * (a[1].x - a[0].x) -
|
||||||
|
(b[1].x - b[0].x) * (a[1].y - a[0].y);
|
||||||
|
|
||||||
|
if (bottom === 0) {
|
||||||
|
segmentIntersection.position.x = Number.NaN;
|
||||||
|
segmentIntersection.position.y = Number.NaN;
|
||||||
|
segmentIntersection.offset = Number.NaN;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tTop =
|
||||||
|
(b[1].x - b[0].x) * (a[0].y - b[0].y) -
|
||||||
|
(b[1].y - b[0].y) * (a[0].x - b[0].x);
|
||||||
|
const uTop =
|
||||||
|
(b[0].y - a[0].y) * (a[0].x - a[1].x) -
|
||||||
|
(b[0].x - a[0].x) * (a[0].y - a[1].y);
|
||||||
|
|
||||||
|
const t = tTop / bottom;
|
||||||
|
const u = uTop / bottom;
|
||||||
|
|
||||||
|
if (t < 0 || t > 1 || u < 0 || u > 1) {
|
||||||
|
segmentIntersection.position.x = Number.NaN;
|
||||||
|
segmentIntersection.position.y = Number.NaN;
|
||||||
|
segmentIntersection.offset = Number.NaN;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
segmentIntersection.position.x = lerp(a[0].x, a[1].x, t);
|
||||||
|
segmentIntersection.position.y = lerp(a[0].y, a[1].y, t);
|
||||||
|
segmentIntersection.offset = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function drawSegment(
|
||||||
|
segment: Segment,
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
color: string,
|
||||||
|
): void {
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.strokeStyle = color;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(segment[0].x, segment[0].y);
|
||||||
|
ctx.lineTo(segment[1].x, segment[1].y);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
export type Sprite = {
|
||||||
|
image: HTMLImageElement;
|
||||||
|
xFrames: number;
|
||||||
|
yFrames: number;
|
||||||
|
frameWidth: number;
|
||||||
|
frameHeight: number;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createSprite(
|
||||||
|
image: HTMLImageElement,
|
||||||
|
xFrames: number,
|
||||||
|
yFrames: number,
|
||||||
|
): Sprite {
|
||||||
|
return {
|
||||||
|
image,
|
||||||
|
xFrames,
|
||||||
|
yFrames,
|
||||||
|
frameWidth: image.width / xFrames,
|
||||||
|
frameHeight: image.height / yFrames,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function drawSprite(
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
sprite: Sprite,
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
): void {
|
||||||
|
ctx.drawImage(
|
||||||
|
sprite.image,
|
||||||
|
sprite.x,
|
||||||
|
sprite.y,
|
||||||
|
sprite.frameWidth,
|
||||||
|
sprite.frameHeight,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
export type Vector = {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createVector(x: number = 0, y: number = 0): Vector {
|
||||||
|
return { x, y };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fromPolar(direction: number, magnitude: number): Vector {
|
||||||
|
return {
|
||||||
|
x: Math.cos(direction) * magnitude,
|
||||||
|
y: Math.sin(direction) * magnitude,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDirection(vector: Vector): number {
|
||||||
|
return Math.atan2(vector.y, vector.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMagnitude(vector: Vector): number {
|
||||||
|
return Math.sqrt(vector.x * vector.x + vector.y * vector.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDistance(a: Vector, b: Vector): number {
|
||||||
|
const dx = a.x - b.x;
|
||||||
|
const dy = a.y - b.y;
|
||||||
|
|
||||||
|
return Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSquared(vector: Vector): number {
|
||||||
|
return vector.x * vector.x + vector.y * vector.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setDistanceNormal(normal: Vector, a: Vector, b: Vector): void {
|
||||||
|
const dx = a.x - b.x;
|
||||||
|
const dy = a.y - b.y;
|
||||||
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
|
if (distance > 0) {
|
||||||
|
normal.x = dx / distance;
|
||||||
|
normal.y = dy / distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDotProduct(a: Vector, b: Vector): number {
|
||||||
|
return a.x * b.x + a.y * b.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPerpDotProduct(a: Vector, b: Vector): number {
|
||||||
|
return a.x * b.x - a.y * b.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function scale(vector: Vector, scalar: number): void {
|
||||||
|
vector.x *= scalar;
|
||||||
|
vector.y *= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalize(vector: Vector): void {
|
||||||
|
const magnitude = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
|
||||||
|
|
||||||
|
if (magnitude > 0) {
|
||||||
|
const scalar = 1 / magnitude;
|
||||||
|
vector.x *= scalar;
|
||||||
|
vector.y *= scalar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isZero(vector: Vector): boolean {
|
||||||
|
return vector.x === 0 && vector.y === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isBelowThreshold(vector: Vector, threshold: number): boolean {
|
||||||
|
return Math.abs(vector.x) < threshold && Math.abs(vector.y) < threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function equals(a: Vector, b: Vector): boolean {
|
||||||
|
return a.x === b.x && a.y === b.y;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export function lerp(a: number, b: number, t: number): number {
|
||||||
|
return a + (b - a) * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function lerpPrecice(a: number, b: number, t: number): number {
|
||||||
|
return a * (1 - t) + b * t;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export function loadImage(src: string): Promise<HTMLImageElement> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const image = new Image();
|
||||||
|
image.onload = () => resolve(image);
|
||||||
|
image.onerror = () => {
|
||||||
|
console.error(image.src);
|
||||||
|
return resolve(image);
|
||||||
|
};
|
||||||
|
|
||||||
|
image.src = src;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { currentScene, loadScene } from "#/engine/Scene.ts";
|
||||||
|
import {
|
||||||
|
initViewport,
|
||||||
|
resetCtx,
|
||||||
|
resizeCanvas,
|
||||||
|
viewport,
|
||||||
|
} from "#/engine/Viewport.ts";
|
||||||
|
|
||||||
|
let then = self.performance.now();
|
||||||
|
let delta = 0;
|
||||||
|
function animate(timestamp: number): void {
|
||||||
|
delta = timestamp - then;
|
||||||
|
then = timestamp;
|
||||||
|
|
||||||
|
resetCtx();
|
||||||
|
currentScene.process(viewport.ctx, delta);
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
import("#/tools/main.tsx").then((m) => m.use(viewport.gameContainer));
|
||||||
|
}
|
||||||
|
|
||||||
|
initViewport();
|
||||||
|
await loadScene("testScene");
|
||||||
|
|
||||||
|
resizeCanvas(currentScene.data.width, currentScene.data.height);
|
||||||
|
self.addEventListener("resize", () => {
|
||||||
|
resizeCanvas(currentScene.data.width, currentScene.data.height);
|
||||||
|
});
|
||||||
|
|
||||||
|
animate(delta);
|
||||||
|
})();
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "nage",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@biomejs/biome": "2.3.7",
|
||||||
|
"@types/bun": "1.3.3",
|
||||||
|
"lz-string": "1.5.0",
|
||||||
|
"solid-js": "1.9.10",
|
||||||
|
"vite": "7.2.4",
|
||||||
|
"vite-plugin-solid": "2.11.10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "5.9.3"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 551 B |
Binary file not shown.
|
After Width: | Height: | Size: 700 B |
Binary file not shown.
|
After Width: | Height: | Size: 324 B |
Binary file not shown.
|
After Width: | Height: | Size: 331 B |
Binary file not shown.
|
After Width: | Height: | Size: 815 B |
Binary file not shown.
|
After Width: | Height: | Size: 242 B |
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"id": "testScene",
|
||||||
|
"width": 48,
|
||||||
|
"height": 48,
|
||||||
|
"entities": ["testEntity"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { type EntityInstance, loadEntity } from "#/engine/Entity.ts";
|
||||||
|
import { useScene } from "#/engine/Scene.ts";
|
||||||
|
import { drawSprite } from "#/lib/Sprite.ts";
|
||||||
|
import data from "./data.json";
|
||||||
|
|
||||||
|
const { process } = useScene(data);
|
||||||
|
|
||||||
|
const entities: Array<EntityInstance> = [];
|
||||||
|
for (const entity of data.entities) {
|
||||||
|
const instance = await loadEntity(entity);
|
||||||
|
entities.push(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
process((ctx, _delta) => {
|
||||||
|
for (const instance of entities) {
|
||||||
|
drawSprite(ctx, instance.sprite, 0, 0, 16, 16);
|
||||||
|
}
|
||||||
|
});
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
body {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100dvh;
|
||||||
|
width: 100dvw;
|
||||||
|
background: #161616;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#gameContainer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvasContainer {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
user-select: none;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import type { Component, JSX } from "solid-js";
|
||||||
|
import style from "./controls.module.css";
|
||||||
|
|
||||||
|
export const RangeSlider: Component<{
|
||||||
|
name: string;
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
step: number;
|
||||||
|
value: number;
|
||||||
|
children?: JSX.Element;
|
||||||
|
onChange?: (value: number) => void;
|
||||||
|
onInput?: (value: number) => void;
|
||||||
|
}> = (props) => (
|
||||||
|
<label class={style.rangeSlider}>
|
||||||
|
{props.children}
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
name={props.name}
|
||||||
|
min={props.min}
|
||||||
|
max={props.max}
|
||||||
|
step={props.step}
|
||||||
|
value={props.value}
|
||||||
|
onChange={(e) => props.onChange?.(e.target.valueAsNumber)}
|
||||||
|
onInput={(e) => props.onInput?.(e.target.valueAsNumber)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
);
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
.rangeSlider {
|
||||||
|
width: 100%;
|
||||||
|
color: var(--c-fg-2);
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--sp-2);
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-weight: bold;
|
||||||
|
padding: var(--sp-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rangeSlider [type="range"] {
|
||||||
|
cursor: pointer;
|
||||||
|
appearance: none;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: var(--sp-2);
|
||||||
|
height: var(--sp-3);
|
||||||
|
flex: auto;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-slider-runnable-track {
|
||||||
|
width: 100%;
|
||||||
|
height: var(--sp-2);
|
||||||
|
border-radius: var(--sp-3);
|
||||||
|
color: transparent;
|
||||||
|
background: var(--c-bg-3);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
&::-webkit-slider-thumb {
|
||||||
|
height: var(--sp-3);
|
||||||
|
width: var(--sp-3);
|
||||||
|
border-radius: var(--sp-3);
|
||||||
|
border: none;
|
||||||
|
background: var(--c-fg-1);
|
||||||
|
margin-top: calc(var(--sp-1) * -1);
|
||||||
|
--webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
}
|
||||||
|
&:focus::-webkit-slider-thumb {
|
||||||
|
outline-width: 2px;
|
||||||
|
outline-style: solid;
|
||||||
|
outline-color: var(--c-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-range-track {
|
||||||
|
width: 100%;
|
||||||
|
height: var(--sp-2);
|
||||||
|
border-radius: var(--sp-3);
|
||||||
|
color: transparent;
|
||||||
|
background: var(--c-bg-3);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
&::-moz-range-thumb {
|
||||||
|
height: var(--sp-3);
|
||||||
|
width: var(--sp-3);
|
||||||
|
border-radius: var(--sp-3);
|
||||||
|
border: none;
|
||||||
|
background: var(--c-fg-1);
|
||||||
|
}
|
||||||
|
&:focus::-moz-range-thumb {
|
||||||
|
outline-width: 2px;
|
||||||
|
outline-style: solid;
|
||||||
|
outline-color: var(--c-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
.devTools {
|
||||||
|
--font-sans:
|
||||||
|
ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
||||||
|
"Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
--font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
||||||
|
--font-mono:
|
||||||
|
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
||||||
|
"Courier New", monospace;
|
||||||
|
|
||||||
|
--rgb-blurple: 101, 114, 245;
|
||||||
|
--c-blurple: rgb(var(--rgb-blurple));
|
||||||
|
|
||||||
|
--rgb-fuchsia: 238, 69, 158;
|
||||||
|
--c-fuchsia: rgb(var(--rgb-fuchsia));
|
||||||
|
|
||||||
|
--rgb-green: 35, 165, 89;
|
||||||
|
--c-green: rgb(var(--rgb-green));
|
||||||
|
|
||||||
|
--rgb-yellow: 240, 178, 50;
|
||||||
|
--c-yellow: rgb(var(--rgb-yellow));
|
||||||
|
|
||||||
|
--rgb-orange: 255, 144, 0;
|
||||||
|
--c-orange: rgb(var(--rgb-orange));
|
||||||
|
|
||||||
|
--rgb-red: 218, 55, 60;
|
||||||
|
--c-red: rgb(var(--rgb-red));
|
||||||
|
|
||||||
|
--rgb-cyan: 95, 205, 228;
|
||||||
|
--c-cyan: rgb(var(--rgb-cyan));
|
||||||
|
|
||||||
|
--rgb-pink: 246, 42, 245;
|
||||||
|
--c-pink: rgb(var(--rgb-pink));
|
||||||
|
|
||||||
|
--rgb-gray: 117, 126, 138;
|
||||||
|
--c-gray: rgb(var(--rgb-gray));
|
||||||
|
|
||||||
|
--rgb-white: 255, 255, 255;
|
||||||
|
--c-white: rgb(var(--rgb-white));
|
||||||
|
|
||||||
|
--rgb-black: 30, 31, 34;
|
||||||
|
--c-black: rgb(var(--rgb-black));
|
||||||
|
|
||||||
|
--c-primary: var(--c-blurple);
|
||||||
|
--c-secondary: var(--c-fuchsia);
|
||||||
|
--c-alert: var(--c-orange);
|
||||||
|
--c-error: var(--c-red);
|
||||||
|
|
||||||
|
--c-bg-0: rgb(30, 31, 34);
|
||||||
|
--c-bg-1: rgb(43, 45, 49);
|
||||||
|
--c-bg-2: rgb(49, 51, 56);
|
||||||
|
--c-bg-3: rgb(64, 66, 73);
|
||||||
|
|
||||||
|
--c-fg-0: rgb(255 255 225);
|
||||||
|
--c-fg-1: rgb(219 222 225);
|
||||||
|
--c-fg-2: rgb(181 186 193);
|
||||||
|
--c-fg-3: rgb(113 116 120);
|
||||||
|
|
||||||
|
--sp-1: 4px;
|
||||||
|
--sp-2: 8px;
|
||||||
|
--sp-3: 16px;
|
||||||
|
--sp-4: 24px;
|
||||||
|
--sp-5: 32px;
|
||||||
|
--sp-6: 48px;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
min-width: 1px;
|
||||||
|
max-width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
order: -1;
|
||||||
|
font-size: medium;
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::after,
|
||||||
|
*::before {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
*:focus {
|
||||||
|
outline-width: 2px;
|
||||||
|
outline-style: solid;
|
||||||
|
outline-color: var(--c-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolBar {
|
||||||
|
overflow: hidden;
|
||||||
|
border-right: 1px solid var(--c-fg-3);
|
||||||
|
background: var(--c-bg-1);
|
||||||
|
color: var(--c-fg-1);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolBarResize {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: -3px;
|
||||||
|
width: 5px;
|
||||||
|
height: 100%;
|
||||||
|
cursor: ew-resize;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { type Component, createSignal, onMount } from "solid-js";
|
||||||
|
import { render } from "solid-js/web";
|
||||||
|
import { setScale, viewport } from "#/engine/Viewport.ts";
|
||||||
|
import { RangeSlider } from "#/tools/controls/RangeSlider.tsx";
|
||||||
|
import style from "./main.module.css";
|
||||||
|
|
||||||
|
function adjustGameContainer(gameContainer: HTMLElement, width: number): void {
|
||||||
|
gameContainer.style = `position: relative; top: 0; left: ${width}px; width: ${document.body.offsetWidth - width}px;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DevTools: Component<{ gameContainer: HTMLElement }> = ({
|
||||||
|
gameContainer,
|
||||||
|
}) => {
|
||||||
|
const [width, setWidth] = createSignal(320);
|
||||||
|
let isResizing = false;
|
||||||
|
|
||||||
|
const startResizing = (): void => {
|
||||||
|
isResizing = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopResizing = (): void => {
|
||||||
|
isResizing = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseMove = (event: MouseEvent) => {
|
||||||
|
if (isResizing) {
|
||||||
|
setWidth(event.clientX);
|
||||||
|
self.dispatchEvent(new Event("resize"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
adjustGameContainer(gameContainer, width());
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
self.addEventListener("resize", () => {
|
||||||
|
adjustGameContainer(gameContainer, width());
|
||||||
|
});
|
||||||
|
self.dispatchEvent(new Event("resize"));
|
||||||
|
|
||||||
|
document.addEventListener("mousemove", handleMouseMove);
|
||||||
|
document.addEventListener("mouseup", stopResizing);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={style.devTools} style={{ width: `${width()}px` }}>
|
||||||
|
<div class={style.toolBar}>
|
||||||
|
<RangeSlider
|
||||||
|
name="scale"
|
||||||
|
min={1}
|
||||||
|
max={8}
|
||||||
|
step={1}
|
||||||
|
value={viewport.initialScale}
|
||||||
|
onInput={setScale}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class={style.toolBarResize} onMouseDown={startResizing}></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function use(container: HTMLElement): void {
|
||||||
|
render(() => <DevTools gameContainer={container} />, document.body);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"jsx": "preserve",
|
||||||
|
"jsxImportSource": "solid-js",
|
||||||
|
"allowJs": true,
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"composite": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"noUnusedParameters": false,
|
||||||
|
"noPropertyAccessFromIndexSignature": false,
|
||||||
|
"paths": {
|
||||||
|
"#/*": ["./*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { fileURLToPath, URL } from "node:url";
|
||||||
|
import { defineConfig } from "vite";
|
||||||
|
import solidPlugin from "vite-plugin-solid";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
server: {
|
||||||
|
host: "localhost",
|
||||||
|
port: 3080,
|
||||||
|
hmr: false,
|
||||||
|
},
|
||||||
|
build: { target: "esnext" },
|
||||||
|
plugins: [solidPlugin()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"#/": fileURLToPath(new URL("./", import.meta.url)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user