From a8469101813dc692e14608bf954174d1c591c7ce Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 17 Jun 2026 07:53:46 +0900 Subject: [PATCH 1/6] #292 update packages --- package-lock.json | 449 +++++++++++++++++++++++----------------------- package.json | 14 +- 2 files changed, 233 insertions(+), 230 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0db8286b..8855f041 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@next2d/player", - "version": "3.6.0", + "version": "3.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@next2d/player", - "version": "3.6.0", + "version": "3.7.0", "license": "MIT", "workspaces": [ "packages/*" @@ -14,22 +14,22 @@ "devDependencies": { "@eslint/eslintrc": "^3.3.5", "@eslint/js": "^10.0.1", - "@playwright/test": "^1.60.0", + "@playwright/test": "^1.61.0", "@rollup/plugin-commonjs": "^29.0.3", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^1.0.0", "@rollup/plugin-typescript": "^12.3.0", - "@typescript-eslint/eslint-plugin": "^8.61.0", - "@typescript-eslint/parser": "^8.61.0", + "@typescript-eslint/eslint-plugin": "^8.61.1", + "@typescript-eslint/parser": "^8.61.1", "@webgpu/types": "^0.1.70", - "eslint": "^10.4.1", + "eslint": "^10.5.0", "eslint-plugin-unused-imports": "^4.4.1", "globals": "^17.6.0", "jsdom": "^29.1.1", - "rollup": "^4.61.1", + "rollup": "^4.62.0", "typescript": "^6.0.3", "vite": "^8.0.16", - "vitest": "^4.1.8", + "vitest": "^4.1.9", "vitest-webgl-canvas-mock": "^1.1.0" }, "funding": { @@ -707,13 +707,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.60.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.60.0.tgz", - "integrity": "sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==", + "version": "1.61.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.61.0.tgz", + "integrity": "sha512-cKA5B6lpFEMyMGjxF54QihfYpB4FkEGH+qZhtArDEG+wezQAJY8Pq6C7T1SjWz+FFzt3TbyoXBQYk/0292TdJA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.60.0" + "playwright": "1.61.0" }, "bin": { "playwright": "cli.js" @@ -1130,9 +1130,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", - "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.0.tgz", + "integrity": "sha512-IPIQ55ythEHkfEd9jMEi32OQ7SxURsGA43JI22lj01OLZNt2NUbJX8YUHxkVWyQ6daHPNn0truF5nSj3DQp6YQ==", "cpu": [ "arm" ], @@ -1144,9 +1144,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", - "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.0.tgz", + "integrity": "sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA==", "cpu": [ "arm64" ], @@ -1158,9 +1158,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", - "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.0.tgz", + "integrity": "sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw==", "cpu": [ "arm64" ], @@ -1172,9 +1172,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", - "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.0.tgz", + "integrity": "sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w==", "cpu": [ "x64" ], @@ -1186,9 +1186,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", - "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.0.tgz", + "integrity": "sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ==", "cpu": [ "arm64" ], @@ -1200,9 +1200,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", - "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.0.tgz", + "integrity": "sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ==", "cpu": [ "x64" ], @@ -1214,9 +1214,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", - "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.0.tgz", + "integrity": "sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ==", "cpu": [ "arm" ], @@ -1231,9 +1231,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", - "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.0.tgz", + "integrity": "sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA==", "cpu": [ "arm" ], @@ -1248,9 +1248,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", - "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.0.tgz", + "integrity": "sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g==", "cpu": [ "arm64" ], @@ -1265,9 +1265,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", - "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.0.tgz", + "integrity": "sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw==", "cpu": [ "arm64" ], @@ -1282,9 +1282,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", - "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.0.tgz", + "integrity": "sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg==", "cpu": [ "loong64" ], @@ -1299,9 +1299,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", - "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.0.tgz", + "integrity": "sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA==", "cpu": [ "loong64" ], @@ -1316,9 +1316,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", - "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.0.tgz", + "integrity": "sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w==", "cpu": [ "ppc64" ], @@ -1333,9 +1333,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", - "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.0.tgz", + "integrity": "sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg==", "cpu": [ "ppc64" ], @@ -1350,9 +1350,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", - "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.0.tgz", + "integrity": "sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg==", "cpu": [ "riscv64" ], @@ -1367,9 +1367,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", - "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.0.tgz", + "integrity": "sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg==", "cpu": [ "riscv64" ], @@ -1384,9 +1384,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", - "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.0.tgz", + "integrity": "sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA==", "cpu": [ "s390x" ], @@ -1401,9 +1401,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", - "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.0.tgz", + "integrity": "sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg==", "cpu": [ "x64" ], @@ -1418,9 +1418,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", - "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.0.tgz", + "integrity": "sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw==", "cpu": [ "x64" ], @@ -1435,9 +1435,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", - "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.0.tgz", + "integrity": "sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg==", "cpu": [ "x64" ], @@ -1449,9 +1449,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", - "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.0.tgz", + "integrity": "sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg==", "cpu": [ "arm64" ], @@ -1463,9 +1463,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", - "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.0.tgz", + "integrity": "sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw==", "cpu": [ "arm64" ], @@ -1477,9 +1477,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", - "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.0.tgz", + "integrity": "sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw==", "cpu": [ "ia32" ], @@ -1491,9 +1491,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", - "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.0.tgz", + "integrity": "sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA==", "cpu": [ "x64" ], @@ -1505,9 +1505,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", - "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.0.tgz", + "integrity": "sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA==", "cpu": [ "x64" ], @@ -1583,17 +1583,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.0.tgz", - "integrity": "sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.1.tgz", + "integrity": "sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.61.0", - "@typescript-eslint/type-utils": "8.61.0", - "@typescript-eslint/utils": "8.61.0", - "@typescript-eslint/visitor-keys": "8.61.0", + "@typescript-eslint/scope-manager": "8.61.1", + "@typescript-eslint/type-utils": "8.61.1", + "@typescript-eslint/utils": "8.61.1", + "@typescript-eslint/visitor-keys": "8.61.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -1606,7 +1606,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.61.0", + "@typescript-eslint/parser": "^8.61.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -1622,16 +1622,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.0.tgz", - "integrity": "sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.1.tgz", + "integrity": "sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.61.0", - "@typescript-eslint/types": "8.61.0", - "@typescript-eslint/typescript-estree": "8.61.0", - "@typescript-eslint/visitor-keys": "8.61.0", + "@typescript-eslint/scope-manager": "8.61.1", + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/typescript-estree": "8.61.1", + "@typescript-eslint/visitor-keys": "8.61.1", "debug": "^4.4.3" }, "engines": { @@ -1647,14 +1647,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.0.tgz", - "integrity": "sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.1.tgz", + "integrity": "sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.61.0", - "@typescript-eslint/types": "^8.61.0", + "@typescript-eslint/tsconfig-utils": "^8.61.1", + "@typescript-eslint/types": "^8.61.1", "debug": "^4.4.3" }, "engines": { @@ -1669,14 +1669,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.0.tgz", - "integrity": "sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.1.tgz", + "integrity": "sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.61.0", - "@typescript-eslint/visitor-keys": "8.61.0" + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/visitor-keys": "8.61.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1687,9 +1687,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.0.tgz", - "integrity": "sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.1.tgz", + "integrity": "sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==", "dev": true, "license": "MIT", "engines": { @@ -1704,15 +1704,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.0.tgz", - "integrity": "sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.1.tgz", + "integrity": "sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.61.0", - "@typescript-eslint/typescript-estree": "8.61.0", - "@typescript-eslint/utils": "8.61.0", + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/typescript-estree": "8.61.1", + "@typescript-eslint/utils": "8.61.1", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1729,9 +1729,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.0.tgz", - "integrity": "sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.1.tgz", + "integrity": "sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==", "dev": true, "license": "MIT", "engines": { @@ -1743,16 +1743,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.0.tgz", - "integrity": "sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.1.tgz", + "integrity": "sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.61.0", - "@typescript-eslint/tsconfig-utils": "8.61.0", - "@typescript-eslint/types": "8.61.0", - "@typescript-eslint/visitor-keys": "8.61.0", + "@typescript-eslint/project-service": "8.61.1", + "@typescript-eslint/tsconfig-utils": "8.61.1", + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/visitor-keys": "8.61.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1810,16 +1810,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.0.tgz", - "integrity": "sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.1.tgz", + "integrity": "sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.61.0", - "@typescript-eslint/types": "8.61.0", - "@typescript-eslint/typescript-estree": "8.61.0" + "@typescript-eslint/scope-manager": "8.61.1", + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/typescript-estree": "8.61.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1834,13 +1834,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.0.tgz", - "integrity": "sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==", + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.1.tgz", + "integrity": "sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/types": "8.61.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -1865,16 +1865,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz", - "integrity": "sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.9.tgz", + "integrity": "sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/spy": "4.1.9", + "@vitest/utils": "4.1.9", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -1883,13 +1883,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.8.tgz", - "integrity": "sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.9.tgz", + "integrity": "sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.8", + "@vitest/spy": "4.1.9", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -1920,9 +1920,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.8.tgz", - "integrity": "sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.9.tgz", + "integrity": "sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==", "dev": true, "license": "MIT", "dependencies": { @@ -1933,13 +1933,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.8.tgz", - "integrity": "sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.9.tgz", + "integrity": "sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.8", + "@vitest/utils": "4.1.9", "pathe": "^2.0.3" }, "funding": { @@ -1947,14 +1947,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.8.tgz", - "integrity": "sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.9.tgz", + "integrity": "sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/pretty-format": "4.1.9", + "@vitest/utils": "4.1.9", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -1963,9 +1963,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.8.tgz", - "integrity": "sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.9.tgz", + "integrity": "sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==", "dev": true, "license": "MIT", "funding": { @@ -1973,13 +1973,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.8.tgz", - "integrity": "sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.9.tgz", + "integrity": "sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.8", + "@vitest/pretty-format": "4.1.9", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -2286,11 +2286,14 @@ } }, "node_modules/eslint": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.4.1.tgz", - "integrity": "sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.5.0.tgz", + "integrity": "sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==", "dev": true, "license": "MIT", + "workspaces": [ + "packages/*" + ], "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", @@ -3450,13 +3453,13 @@ } }, "node_modules/playwright": { - "version": "1.60.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz", - "integrity": "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==", + "version": "1.61.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.0.tgz", + "integrity": "sha512-Z+7BeeqQPRRzklHsVFP4KTGIyMxKUmfeRA4WisM6G3/XW6nwGeX6fX9qYaDa+CiUqpOkb2f6X3nar05R3kSuJQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.60.0" + "playwright-core": "1.61.0" }, "bin": { "playwright": "cli.js" @@ -3469,9 +3472,9 @@ } }, "node_modules/playwright-core": { - "version": "1.60.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz", - "integrity": "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==", + "version": "1.61.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.0.tgz", + "integrity": "sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3607,9 +3610,9 @@ } }, "node_modules/rollup": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", - "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.0.tgz", + "integrity": "sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==", "dev": true, "license": "MIT", "dependencies": { @@ -3623,31 +3626,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.61.1", - "@rollup/rollup-android-arm64": "4.61.1", - "@rollup/rollup-darwin-arm64": "4.61.1", - "@rollup/rollup-darwin-x64": "4.61.1", - "@rollup/rollup-freebsd-arm64": "4.61.1", - "@rollup/rollup-freebsd-x64": "4.61.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", - "@rollup/rollup-linux-arm-musleabihf": "4.61.1", - "@rollup/rollup-linux-arm64-gnu": "4.61.1", - "@rollup/rollup-linux-arm64-musl": "4.61.1", - "@rollup/rollup-linux-loong64-gnu": "4.61.1", - "@rollup/rollup-linux-loong64-musl": "4.61.1", - "@rollup/rollup-linux-ppc64-gnu": "4.61.1", - "@rollup/rollup-linux-ppc64-musl": "4.61.1", - "@rollup/rollup-linux-riscv64-gnu": "4.61.1", - "@rollup/rollup-linux-riscv64-musl": "4.61.1", - "@rollup/rollup-linux-s390x-gnu": "4.61.1", - "@rollup/rollup-linux-x64-gnu": "4.61.1", - "@rollup/rollup-linux-x64-musl": "4.61.1", - "@rollup/rollup-openbsd-x64": "4.61.1", - "@rollup/rollup-openharmony-arm64": "4.61.1", - "@rollup/rollup-win32-arm64-msvc": "4.61.1", - "@rollup/rollup-win32-ia32-msvc": "4.61.1", - "@rollup/rollup-win32-x64-gnu": "4.61.1", - "@rollup/rollup-win32-x64-msvc": "4.61.1", + "@rollup/rollup-android-arm-eabi": "4.62.0", + "@rollup/rollup-android-arm64": "4.62.0", + "@rollup/rollup-darwin-arm64": "4.62.0", + "@rollup/rollup-darwin-x64": "4.62.0", + "@rollup/rollup-freebsd-arm64": "4.62.0", + "@rollup/rollup-freebsd-x64": "4.62.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.0", + "@rollup/rollup-linux-arm-musleabihf": "4.62.0", + "@rollup/rollup-linux-arm64-gnu": "4.62.0", + "@rollup/rollup-linux-arm64-musl": "4.62.0", + "@rollup/rollup-linux-loong64-gnu": "4.62.0", + "@rollup/rollup-linux-loong64-musl": "4.62.0", + "@rollup/rollup-linux-ppc64-gnu": "4.62.0", + "@rollup/rollup-linux-ppc64-musl": "4.62.0", + "@rollup/rollup-linux-riscv64-gnu": "4.62.0", + "@rollup/rollup-linux-riscv64-musl": "4.62.0", + "@rollup/rollup-linux-s390x-gnu": "4.62.0", + "@rollup/rollup-linux-x64-gnu": "4.62.0", + "@rollup/rollup-linux-x64-musl": "4.62.0", + "@rollup/rollup-openbsd-x64": "4.62.0", + "@rollup/rollup-openharmony-arm64": "4.62.0", + "@rollup/rollup-win32-arm64-msvc": "4.62.0", + "@rollup/rollup-win32-ia32-msvc": "4.62.0", + "@rollup/rollup-win32-x64-gnu": "4.62.0", + "@rollup/rollup-win32-x64-msvc": "4.62.0", "fsevents": "~2.3.2" } }, @@ -4076,19 +4079,19 @@ } }, "node_modules/vitest": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.8.tgz", - "integrity": "sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.9.tgz", + "integrity": "sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.8", - "@vitest/mocker": "4.1.8", - "@vitest/pretty-format": "4.1.8", - "@vitest/runner": "4.1.8", - "@vitest/snapshot": "4.1.8", - "@vitest/spy": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/expect": "4.1.9", + "@vitest/mocker": "4.1.9", + "@vitest/pretty-format": "4.1.9", + "@vitest/runner": "4.1.9", + "@vitest/snapshot": "4.1.9", + "@vitest/spy": "4.1.9", + "@vitest/utils": "4.1.9", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -4116,12 +4119,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.8", - "@vitest/browser-preview": "4.1.8", - "@vitest/browser-webdriverio": "4.1.8", - "@vitest/coverage-istanbul": "4.1.8", - "@vitest/coverage-v8": "4.1.8", - "@vitest/ui": "4.1.8", + "@vitest/browser-playwright": "4.1.9", + "@vitest/browser-preview": "4.1.9", + "@vitest/browser-webdriverio": "4.1.9", + "@vitest/coverage-istanbul": "4.1.9", + "@vitest/coverage-v8": "4.1.9", + "@vitest/ui": "4.1.9", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" diff --git a/package.json b/package.json index 9bc020ee..c3ed0156 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@next2d/player", - "version": "3.6.0", + "version": "3.7.0", "description": "Experience the fast and beautiful anti-aliased rendering of WebGL/WebGPU. You can create rich, interactive graphics, cross-platform applications and games without worrying about browser or device compatibility.", "author": "Toshiyuki Ienaga (https://github.com/ienaga/)", "license": "MIT", @@ -50,22 +50,22 @@ "devDependencies": { "@eslint/eslintrc": "^3.3.5", "@eslint/js": "^10.0.1", - "@playwright/test": "^1.60.0", + "@playwright/test": "^1.61.0", "@rollup/plugin-commonjs": "^29.0.3", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^1.0.0", "@rollup/plugin-typescript": "^12.3.0", - "@typescript-eslint/eslint-plugin": "^8.61.0", - "@typescript-eslint/parser": "^8.61.0", + "@typescript-eslint/eslint-plugin": "^8.61.1", + "@typescript-eslint/parser": "^8.61.1", "@webgpu/types": "^0.1.70", - "eslint": "^10.4.1", + "eslint": "^10.5.0", "eslint-plugin-unused-imports": "^4.4.1", "globals": "^17.6.0", "jsdom": "^29.1.1", - "rollup": "^4.61.1", + "rollup": "^4.62.0", "typescript": "^6.0.3", "vite": "^8.0.16", - "vitest": "^4.1.8", + "vitest": "^4.1.9", "vitest-webgl-canvas-mock": "^1.1.0" }, "peerDependencies": { From 0b90f9ba4397228d343a635fded771d626605228 Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 17 Jun 2026 07:54:00 +0900 Subject: [PATCH 2/6] =?UTF-8?q?#292=20=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E6=83=85=E5=A0=B1=E3=82=92=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 32a3817e..a56cbd15 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import { Next2D } from "@next2d/core"; if (!("next2d" in window)) { - console.log("%c Next2D Player %c 3.6.0 %c https://next2d.app", + console.log("%c Next2D Player %c 3.7.0 %c https://next2d.app", "color: #fff; background: #5f5f5f", "color: #fff; background: #4bc729", ""); From 434e9156c17897f2daf2d86fd79fc5c4f9a18f45 Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 17 Jun 2026 07:54:26 +0900 Subject: [PATCH 3/6] =?UTF-8?q?#292=20=E3=83=89=E3=82=AD=E3=83=A5=E3=83=A1?= =?UTF-8?q?=E3=83=B3=E3=83=88=E3=81=AB=E6=83=85=E5=A0=B1=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- specs/cn/events.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++ specs/en/events.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++ specs/ja/events.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) diff --git a/specs/cn/events.md b/specs/cn/events.md index 926605d2..8307fa42 100644 --- a/specs/cn/events.md +++ b/specs/cn/events.md @@ -204,6 +204,57 @@ stage.addEventListener(KeyboardEvent.KEY_DOWN, (event) => { }); ``` +## 手柄事件 + +通过 Web Gamepad API 处理游戏控制器输入。所有手柄事件均发送至 `stage`。 + +> **浏览器要求**:在页面获得焦点的状态下按下控制器按钮后,手柄才会被识别(浏览器安全规范)。 + +| 事件 | 常量 | 说明 | +|------|------|------| +| `gamepadconnected` | `GamepadEvent.GAMEPAD_CONNECTED` | 手柄已连接并被识别 | +| `gamepaddisconnected` | `GamepadEvent.GAMEPAD_DISCONNECTED` | 手柄已断开连接 | +| `gamepadbuttondown` | `GamepadEvent.BUTTON_DOWN` | 按钮被按下 | +| `gamepadbuttonup` | `GamepadEvent.BUTTON_UP` | 按钮被释放 | +| `gamepadaxesmotion` | `GamepadEvent.AXES_MOTION` | 摇杆(轴)发生变化(阈值 0.1) | + +### GamepadEvent 属性 + +| 属性 | 类型 | 说明 | +|------|------|------| +| `gamepadIndex` | number | 手柄的索引编号 | +| `buttonIndex` | number \| undefined | 按钮编号(BUTTON_DOWN/UP 时) | +| `buttonValue` | number \| undefined | 按钮按压程度 0.0〜1.0(BUTTON_DOWN/UP 时) | +| `axisIndex` | number \| undefined | 轴的编号(AXES_MOTION 时) | +| `axisValue` | number \| undefined | 轴的值 -1.0〜1.0(AXES_MOTION 时) | + +```typescript +const { GamepadEvent } = next2d.events; + +// 连接 / 断开 +stage.addEventListener(GamepadEvent.GAMEPAD_CONNECTED, (event) => { + console.log(`手柄 ${event.gamepadIndex} 已连接`); +}); + +stage.addEventListener(GamepadEvent.GAMEPAD_DISCONNECTED, (event) => { + console.log(`手柄 ${event.gamepadIndex} 已断开`); +}); + +// 按钮输入 +stage.addEventListener(GamepadEvent.BUTTON_DOWN, (event) => { + console.log(`按钮 ${event.buttonIndex} 按下 (value: ${event.buttonValue})`); +}); + +stage.addEventListener(GamepadEvent.BUTTON_UP, (event) => { + console.log(`按钮 ${event.buttonIndex} 释放`); +}); + +// 摇杆输入 +stage.addEventListener(GamepadEvent.AXES_MOTION, (event) => { + console.log(`轴 ${event.axisIndex}: ${event.axisValue}`); +}); +``` + ## 焦点事件 | 事件 | 常量 | 说明 | diff --git a/specs/en/events.md b/specs/en/events.md index 5d27bac3..f4a7d474 100644 --- a/specs/en/events.md +++ b/specs/en/events.md @@ -204,6 +204,57 @@ stage.addEventListener(KeyboardEvent.KEY_DOWN, (event) => { }); ``` +## Gamepad Events + +Handles game controller input through the Web Gamepad API. All gamepad events are dispatched to `stage`. + +> **Browser requirement**: A gamepad is recognized when the user presses a button on the controller while the page has focus (browser security requirement). + +| Event | Constant | Description | +|-------|----------|-------------| +| `gamepadconnected` | `GamepadEvent.GAMEPAD_CONNECTED` | Gamepad connected and recognized | +| `gamepaddisconnected` | `GamepadEvent.GAMEPAD_DISCONNECTED` | Gamepad disconnected | +| `gamepadbuttondown` | `GamepadEvent.BUTTON_DOWN` | Button pressed | +| `gamepadbuttonup` | `GamepadEvent.BUTTON_UP` | Button released | +| `gamepadaxesmotion` | `GamepadEvent.AXES_MOTION` | Stick (axis) changed (threshold 0.1) | + +### GamepadEvent Properties + +| Property | Type | Description | +|----------|------|-------------| +| `gamepadIndex` | number | Gamepad index number | +| `buttonIndex` | number \| undefined | Button number (on BUTTON_DOWN/UP) | +| `buttonValue` | number \| undefined | Degree of button press 0.0–1.0 (on BUTTON_DOWN/UP) | +| `axisIndex` | number \| undefined | Axis number (on AXES_MOTION) | +| `axisValue` | number \| undefined | Axis value -1.0–1.0 (on AXES_MOTION) | + +```typescript +const { GamepadEvent } = next2d.events; + +// Connect / disconnect +stage.addEventListener(GamepadEvent.GAMEPAD_CONNECTED, (event) => { + console.log(`Gamepad ${event.gamepadIndex} connected`); +}); + +stage.addEventListener(GamepadEvent.GAMEPAD_DISCONNECTED, (event) => { + console.log(`Gamepad ${event.gamepadIndex} disconnected`); +}); + +// Button input +stage.addEventListener(GamepadEvent.BUTTON_DOWN, (event) => { + console.log(`Button ${event.buttonIndex} pressed (value: ${event.buttonValue})`); +}); + +stage.addEventListener(GamepadEvent.BUTTON_UP, (event) => { + console.log(`Button ${event.buttonIndex} released`); +}); + +// Stick input +stage.addEventListener(GamepadEvent.AXES_MOTION, (event) => { + console.log(`Axis ${event.axisIndex}: ${event.axisValue}`); +}); +``` + ## Focus Events | Event | Constant | Description | diff --git a/specs/ja/events.md b/specs/ja/events.md index 31c2acf7..6da9a167 100644 --- a/specs/ja/events.md +++ b/specs/ja/events.md @@ -204,6 +204,57 @@ stage.addEventListener(KeyboardEvent.KEY_DOWN, (event) => { }); ``` +## ゲームパッドイベント + +Web Gamepad APIを通じてゲームコントローラーの入力を処理します。すべてのゲームパッドイベントは `stage` に対して発行されます。 + +> **ブラウザ要件**: ゲームパッドはページにフォーカスがある状態でコントローラーのボタンを押すことで認識されます(ブラウザのセキュリティ仕様)。 + +| イベント | 定数 | 説明 | +|----------|------|------| +| `gamepadconnected` | `GamepadEvent.GAMEPAD_CONNECTED` | ゲームパッドが接続・認識された | +| `gamepaddisconnected` | `GamepadEvent.GAMEPAD_DISCONNECTED` | ゲームパッドが切断された | +| `gamepadbuttondown` | `GamepadEvent.BUTTON_DOWN` | ボタンが押された | +| `gamepadbuttonup` | `GamepadEvent.BUTTON_UP` | ボタンが離された | +| `gamepadaxesmotion` | `GamepadEvent.AXES_MOTION` | スティック(軸)が変化した(閾値 0.1) | + +### GamepadEvent プロパティ + +| プロパティ | 型 | 説明 | +|-----------|------|------| +| `gamepadIndex` | number | ゲームパッドのインデックス番号 | +| `buttonIndex` | number \| undefined | ボタン番号(BUTTON_DOWN/UP 時) | +| `buttonValue` | number \| undefined | ボタンの押し具合 0.0〜1.0(BUTTON_DOWN/UP 時) | +| `axisIndex` | number \| undefined | 軸の番号(AXES_MOTION 時) | +| `axisValue` | number \| undefined | 軸の値 -1.0〜1.0(AXES_MOTION 時) | + +```typescript +const { GamepadEvent } = next2d.events; + +// 接続・切断 +stage.addEventListener(GamepadEvent.GAMEPAD_CONNECTED, (event) => { + console.log(`ゲームパッド ${event.gamepadIndex} が接続されました`); +}); + +stage.addEventListener(GamepadEvent.GAMEPAD_DISCONNECTED, (event) => { + console.log(`ゲームパッド ${event.gamepadIndex} が切断されました`); +}); + +// ボタン操作 +stage.addEventListener(GamepadEvent.BUTTON_DOWN, (event) => { + console.log(`ボタン ${event.buttonIndex} 押下 (value: ${event.buttonValue})`); +}); + +stage.addEventListener(GamepadEvent.BUTTON_UP, (event) => { + console.log(`ボタン ${event.buttonIndex} 解放`); +}); + +// スティック操作 +stage.addEventListener(GamepadEvent.AXES_MOTION, (event) => { + console.log(`軸 ${event.axisIndex}: ${event.axisValue}`); +}); +``` + ## フォーカスイベント | イベント | 定数 | 説明 | From 0021f62e7d674511620a54c6d87b36b1c6bac337 Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 17 Jun 2026 07:54:45 +0900 Subject: [PATCH 4/6] =?UTF-8?q?#292=20Gamepads=E3=81=AE=E3=82=A4=E3=83=99?= =?UTF-8?q?=E3=83=B3=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 46 ------ packages/core/src/Events.ts | 2 + packages/core/src/GamepadState.ts | 17 ++ .../PlayerGamepadConnectService.test.ts | 66 ++++++++ .../service/PlayerGamepadConnectService.ts | 37 +++++ .../PlayerGamepadDisconnectService.test.ts | 72 +++++++++ .../service/PlayerGamepadDisconnectService.ts | 31 ++++ .../PlayerGamepadTickerService.test.ts | 143 +++++++++++++++++ .../service/PlayerGamepadTickerService.ts | 120 +++++++++++++++ .../PlayerRegisterEventUseCase.test.ts | 18 ++- .../usecase/PlayerRegisterEventUseCase.ts | 10 +- .../usecase/PlayerTickerUseCase.test.ts | 4 + .../src/Player/usecase/PlayerTickerUseCase.ts | 4 + packages/core/src/interface/IEvents.ts | 2 + packages/events/src/GamepadEvent.test.ts | 52 +++++++ packages/events/src/GamepadEvent.ts | 145 ++++++++++++++++++ packages/events/src/index.ts | 1 + 17 files changed, 719 insertions(+), 51 deletions(-) create mode 100644 packages/core/src/GamepadState.ts create mode 100644 packages/core/src/Player/service/PlayerGamepadConnectService.test.ts create mode 100644 packages/core/src/Player/service/PlayerGamepadConnectService.ts create mode 100644 packages/core/src/Player/service/PlayerGamepadDisconnectService.test.ts create mode 100644 packages/core/src/Player/service/PlayerGamepadDisconnectService.ts create mode 100644 packages/core/src/Player/service/PlayerGamepadTickerService.test.ts create mode 100644 packages/core/src/Player/service/PlayerGamepadTickerService.ts create mode 100644 packages/events/src/GamepadEvent.test.ts create mode 100644 packages/events/src/GamepadEvent.ts diff --git a/index.html b/index.html index 32f7d609..0d6c3cdf 100644 --- a/index.html +++ b/index.html @@ -11,52 +11,6 @@ window.addEventListener("DOMContentLoaded", async () => { await next2d.load("develop"); - return ; - - const count = 8000; - const root = next2d - .createRootMovieClip(1000, 416, 60) - .then((root) => - { - const { Shape } = next2d.display; - - - const rects = []; - for (let i = 0; i < count; i++) { - const x = Math.random() * 1000; - const y = Math.random() * 416; - const size = 10 + Math.random() * 40; - const speed = 1 + Math.random(); - - var rect = new Shape(); - - rect - .graphics - .beginFill("#fff") - .lineStyle(1, "#000") - .drawRect(0, 0, size, size); - - rect.x = x; - rect.y = y; - - root.addChild(rect); - - rects.push({ size, speed, el: rect }); - } - - root.addEventListener("enterFrame", () => - { - for (let i = 0; i < count; i++) { - const rect = rects[i]; - - if (rect.el.x + rect.size < 0) { - rect.el.x = 1000 + rect.size / 2; - } - - rect.el.x -= rect.speed; - } - }); - }); }); diff --git a/packages/core/src/Events.ts b/packages/core/src/Events.ts index 9b101ea1..8b3bade9 100644 --- a/packages/core/src/Events.ts +++ b/packages/core/src/Events.ts @@ -4,6 +4,7 @@ import { EventDispatcher, EventPhase, FocusEvent, + GamepadEvent, HTTPStatusEvent, IOErrorEvent, PointerEvent, @@ -17,6 +18,7 @@ const events: IEvents = { EventDispatcher, EventPhase, FocusEvent, + GamepadEvent, HTTPStatusEvent, IOErrorEvent, PointerEvent, diff --git a/packages/core/src/GamepadState.ts b/packages/core/src/GamepadState.ts new file mode 100644 index 00000000..afe43647 --- /dev/null +++ b/packages/core/src/GamepadState.ts @@ -0,0 +1,17 @@ +/** + * @description ゲームパッドの前フレームのボタン押下状態 (gamepadIndex => boolean[]) + * Previous frame button pressed state per gamepad (gamepadIndex => boolean[]) + * + * @type {Map} + * @protected + */ +export const $gamepadButtonStates: Map = new Map(); + +/** + * @description ゲームパッドの前フレームの軸値 (gamepadIndex => number[]) + * Previous frame axis values per gamepad (gamepadIndex => number[]) + * + * @type {Map} + * @protected + */ +export const $gamepadAxisStates: Map = new Map(); diff --git a/packages/core/src/Player/service/PlayerGamepadConnectService.test.ts b/packages/core/src/Player/service/PlayerGamepadConnectService.test.ts new file mode 100644 index 00000000..da7b9fea --- /dev/null +++ b/packages/core/src/Player/service/PlayerGamepadConnectService.test.ts @@ -0,0 +1,66 @@ +import { execute } from "./PlayerGamepadConnectService"; +import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState"; +import { stage } from "@next2d/display"; +import { GamepadEvent } from "@next2d/events"; +import { describe, expect, it, vi, beforeEach } from "vitest"; + +describe("PlayerGamepadConnectService.js test", () => +{ + beforeEach(() => + { + $gamepadButtonStates.clear(); + $gamepadAxisStates.clear(); + }); + + it("execute test case: gamepad is null", () => + { + const mockEvent = { "gamepad": null } as unknown as GamepadEvent; + + stage.hasEventListener = vi.fn().mockReturnValue(true); + stage.dispatchEvent = vi.fn(); + + execute(mockEvent); + expect(stage.dispatchEvent).not.toHaveBeenCalled(); + }); + + it("execute test case: no stage listener", () => + { + const mockEvent = { + "gamepad": { "index": 0, "buttons": [{}], "axes": [0] } + } as unknown as GamepadEvent; + + let result = ""; + stage.hasEventListener = vi.fn().mockReturnValue(false); + stage.dispatchEvent = vi.fn((event) => + { + result = event.type; + }); + + execute(mockEvent); + expect($gamepadButtonStates.has(0)).toBe(true); + expect($gamepadAxisStates.has(0)).toBe(true); + expect(result).toBe(""); + }); + + it("execute test case: dispatches GAMEPAD_CONNECTED", () => + { + const mockEvent = { + "gamepad": { "index": 1, "buttons": [{}, {}, {}], "axes": [0, 0] } + } as unknown as GamepadEvent; + + let result = ""; + let gamepadIndex = -1; + stage.hasEventListener = vi.fn().mockReturnValue(true); + stage.dispatchEvent = vi.fn((event: GamepadEvent) => + { + result = event.type; + gamepadIndex = event.gamepadIndex; + }); + + execute(mockEvent); + expect($gamepadButtonStates.get(1)).toEqual([false, false, false]); + expect($gamepadAxisStates.get(1)).toEqual([0, 0]); + expect(result).toBe("gamepadconnected"); + expect(gamepadIndex).toBe(1); + }); +}); diff --git a/packages/core/src/Player/service/PlayerGamepadConnectService.ts b/packages/core/src/Player/service/PlayerGamepadConnectService.ts new file mode 100644 index 00000000..a28fa103 --- /dev/null +++ b/packages/core/src/Player/service/PlayerGamepadConnectService.ts @@ -0,0 +1,37 @@ +import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState"; +import { stage } from "@next2d/display"; +import { GamepadEvent } from "@next2d/events"; + +/** + * @description ゲームパッド接続イベントを実行する + * Execute the gamepad connected event + * + * @param {GamepadEvent} event + * @return {void} + * @method + * @protected + */ +export const execute = (event: GamepadEvent): void => +{ + const gamepad = event.gamepad; + if (!gamepad) { + return ; + } + + $gamepadButtonStates.set( + gamepad.index, + Array.from({ "length": gamepad.buttons.length }, () => false) + ); + $gamepadAxisStates.set( + gamepad.index, + Array.from({ "length": gamepad.axes.length }, () => 0) + ); + + if (!stage.hasEventListener(GamepadEvent.GAMEPAD_CONNECTED)) { + return ; + } + + const gamepadEvent = new GamepadEvent(GamepadEvent.GAMEPAD_CONNECTED); + gamepadEvent.gamepadIndex = gamepad.index; + stage.dispatchEvent(gamepadEvent); +}; diff --git a/packages/core/src/Player/service/PlayerGamepadDisconnectService.test.ts b/packages/core/src/Player/service/PlayerGamepadDisconnectService.test.ts new file mode 100644 index 00000000..a8c0ad20 --- /dev/null +++ b/packages/core/src/Player/service/PlayerGamepadDisconnectService.test.ts @@ -0,0 +1,72 @@ +import { execute } from "./PlayerGamepadDisconnectService"; +import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState"; +import { stage } from "@next2d/display"; +import { GamepadEvent } from "@next2d/events"; +import { describe, expect, it, vi, beforeEach } from "vitest"; + +describe("PlayerGamepadDisconnectService.js test", () => +{ + beforeEach(() => + { + $gamepadButtonStates.clear(); + $gamepadAxisStates.clear(); + }); + + it("execute test case: gamepad is null", () => + { + const mockEvent = { "gamepad": null } as unknown as GamepadEvent; + + stage.hasEventListener = vi.fn().mockReturnValue(true); + stage.dispatchEvent = vi.fn(); + + execute(mockEvent); + expect(stage.dispatchEvent).not.toHaveBeenCalled(); + }); + + it("execute test case: no stage listener", () => + { + $gamepadButtonStates.set(0, [false, false]); + $gamepadAxisStates.set(0, [0, 0]); + + const mockEvent = { + "gamepad": { "index": 0, "buttons": [{}, {}], "axes": [0, 0] } + } as unknown as GamepadEvent; + + let result = ""; + stage.hasEventListener = vi.fn().mockReturnValue(false); + stage.dispatchEvent = vi.fn((event) => + { + result = event.type; + }); + + execute(mockEvent); + expect($gamepadButtonStates.has(0)).toBe(false); + expect($gamepadAxisStates.has(0)).toBe(false); + expect(result).toBe(""); + }); + + it("execute test case: dispatches GAMEPAD_DISCONNECTED", () => + { + $gamepadButtonStates.set(2, [false]); + $gamepadAxisStates.set(2, [0]); + + const mockEvent = { + "gamepad": { "index": 2, "buttons": [{}], "axes": [0] } + } as unknown as GamepadEvent; + + let result = ""; + let gamepadIndex = -1; + stage.hasEventListener = vi.fn().mockReturnValue(true); + stage.dispatchEvent = vi.fn((event: GamepadEvent) => + { + result = event.type; + gamepadIndex = event.gamepadIndex; + }); + + execute(mockEvent); + expect($gamepadButtonStates.has(2)).toBe(false); + expect($gamepadAxisStates.has(2)).toBe(false); + expect(result).toBe("gamepaddisconnected"); + expect(gamepadIndex).toBe(2); + }); +}); diff --git a/packages/core/src/Player/service/PlayerGamepadDisconnectService.ts b/packages/core/src/Player/service/PlayerGamepadDisconnectService.ts new file mode 100644 index 00000000..7caab6eb --- /dev/null +++ b/packages/core/src/Player/service/PlayerGamepadDisconnectService.ts @@ -0,0 +1,31 @@ +import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState"; +import { stage } from "@next2d/display"; +import { GamepadEvent } from "@next2d/events"; + +/** + * @description ゲームパッド切断イベントを実行する + * Execute the gamepad disconnected event + * + * @param {GamepadEvent} event + * @return {void} + * @method + * @protected + */ +export const execute = (event: GamepadEvent): void => +{ + const gamepad = event.gamepad; + if (!gamepad) { + return ; + } + + $gamepadButtonStates.delete(gamepad.index); + $gamepadAxisStates.delete(gamepad.index); + + if (!stage.hasEventListener(GamepadEvent.GAMEPAD_DISCONNECTED)) { + return ; + } + + const gamepadEvent = new GamepadEvent(GamepadEvent.GAMEPAD_DISCONNECTED); + gamepadEvent.gamepadIndex = gamepad.index; + stage.dispatchEvent(gamepadEvent); +}; diff --git a/packages/core/src/Player/service/PlayerGamepadTickerService.test.ts b/packages/core/src/Player/service/PlayerGamepadTickerService.test.ts new file mode 100644 index 00000000..228ddcf8 --- /dev/null +++ b/packages/core/src/Player/service/PlayerGamepadTickerService.test.ts @@ -0,0 +1,143 @@ +import { execute } from "./PlayerGamepadTickerService"; +import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState"; +import { stage } from "@next2d/display"; +import { GamepadEvent } from "@next2d/events"; +import { describe, expect, it, vi, beforeEach } from "vitest"; + +const mockGetGamepads = vi.fn(); +Object.defineProperty(navigator, "getGamepads", { + "value": mockGetGamepads, + "writable": true, + "configurable": true +}); + +describe("PlayerGamepadTickerService.js test", () => +{ + beforeEach(() => + { + $gamepadButtonStates.clear(); + $gamepadAxisStates.clear(); + }); + + it("execute test case: no connected gamepads", () => + { + mockGetGamepads.mockReturnValue([]); + stage.dispatchEvent = vi.fn(); + execute(); + expect(stage.dispatchEvent).not.toHaveBeenCalled(); + }); + + it("execute test case: button pressed dispatches BUTTON_DOWN", () => + { + $gamepadButtonStates.set(0, [false, false]); + $gamepadAxisStates.set(0, [0, 0]); + + const mockGamepad = { + "index": 0, + "buttons": [ + { "pressed": true, "value": 1.0 }, + { "pressed": false, "value": 0.0 } + ], + "axes": [0, 0] + } as unknown as Gamepad; + + mockGetGamepads.mockReturnValue([mockGamepad]); + + const events: GamepadEvent[] = []; + stage.hasEventListener = vi.fn().mockReturnValue(true); + stage.dispatchEvent = vi.fn((event: GamepadEvent) => + { + events.push(event); + }); + + execute(); + + expect(events.length).toBe(1); + expect(events[0].type).toBe("gamepadbuttondown"); + expect(events[0].gamepadIndex).toBe(0); + expect(events[0].buttonIndex).toBe(0); + expect(events[0].buttonValue).toBe(1.0); + expect($gamepadButtonStates.get(0)).toEqual([true, false]); + }); + + it("execute test case: button released dispatches BUTTON_UP", () => + { + $gamepadButtonStates.set(0, [true, false]); + $gamepadAxisStates.set(0, [0, 0]); + + const mockGamepad = { + "index": 0, + "buttons": [ + { "pressed": false, "value": 0.0 }, + { "pressed": false, "value": 0.0 } + ], + "axes": [0, 0] + } as unknown as Gamepad; + + mockGetGamepads.mockReturnValue([mockGamepad]); + + const events: GamepadEvent[] = []; + stage.hasEventListener = vi.fn().mockReturnValue(true); + stage.dispatchEvent = vi.fn((event: GamepadEvent) => + { + events.push(event); + }); + + execute(); + + expect(events.length).toBe(1); + expect(events[0].type).toBe("gamepadbuttonup"); + expect(events[0].gamepadIndex).toBe(0); + expect(events[0].buttonIndex).toBe(0); + }); + + it("execute test case: axis motion within dead zone does not dispatch", () => + { + $gamepadButtonStates.set(0, [false]); + $gamepadAxisStates.set(0, [0, 0]); + + const mockGamepad = { + "index": 0, + "buttons": [{ "pressed": false, "value": 0.0 }], + "axes": [0.05, 0.0] + } as unknown as Gamepad; + + mockGetGamepads.mockReturnValue([mockGamepad]); + + stage.hasEventListener = vi.fn().mockReturnValue(true); + stage.dispatchEvent = vi.fn(); + + execute(); + expect(stage.dispatchEvent).not.toHaveBeenCalled(); + }); + + it("execute test case: axis motion beyond dead zone dispatches AXES_MOTION", () => + { + $gamepadButtonStates.set(0, [false]); + $gamepadAxisStates.set(0, [0, 0]); + + const mockGamepad = { + "index": 0, + "buttons": [{ "pressed": false, "value": 0.0 }], + "axes": [0.8, 0.0] + } as unknown as Gamepad; + + mockGetGamepads.mockReturnValue([mockGamepad]); + + const events: GamepadEvent[] = []; + stage.hasEventListener = vi.fn().mockReturnValue(true); + stage.dispatchEvent = vi.fn((event: GamepadEvent) => + { + events.push(event); + }); + + execute(); + + expect(events.length).toBe(1); + expect(events[0].type).toBe("gamepadaxesmotion"); + expect(events[0].gamepadIndex).toBe(0); + expect(events[0].axisIndex).toBe(0); + expect(events[0].axisValue).toBe(0.8); + expect($gamepadAxisStates.get(0)).toEqual([0.8, 0]); + }); +}); diff --git a/packages/core/src/Player/service/PlayerGamepadTickerService.ts b/packages/core/src/Player/service/PlayerGamepadTickerService.ts new file mode 100644 index 00000000..93975805 --- /dev/null +++ b/packages/core/src/Player/service/PlayerGamepadTickerService.ts @@ -0,0 +1,120 @@ +import { $gamepadButtonStates, $gamepadAxisStates } from "../../GamepadState"; +import { stage } from "@next2d/display"; +import { GamepadEvent } from "@next2d/events"; + +/** + * @private + * @constant + * @type {number} + */ +const AXIS_DEAD_ZONE: number = 0.1; + +/** + * @description ゲームパッドのボタン変化を処理する + * Process gamepad button changes + * + * @param {Gamepad} gamepad + * @param {boolean[]} prevButtons + * @return {void} + * @method + * @private + */ +const processButtons = (gamepad: Gamepad, prevButtons: boolean[]): void => +{ + const hasButtonDown = stage.hasEventListener(GamepadEvent.BUTTON_DOWN); + const hasButtonUp = stage.hasEventListener(GamepadEvent.BUTTON_UP); + + if (!hasButtonDown && !hasButtonUp) { + return ; + } + + for (let i = 0; i < gamepad.buttons.length; i++) { + const pressed = gamepad.buttons[i].pressed; + if (pressed === prevButtons[i]) { + continue; + } + + const type = pressed ? GamepadEvent.BUTTON_DOWN : GamepadEvent.BUTTON_UP; + if (pressed && !hasButtonDown || !pressed && !hasButtonUp) { + prevButtons[i] = pressed; + continue; + } + + const event = new GamepadEvent(type); + event.gamepadIndex = gamepad.index; + event.buttonIndex = i; + event.buttonValue = gamepad.buttons[i].value; + stage.dispatchEvent(event); + + prevButtons[i] = pressed; + } +}; + +/** + * @description ゲームパッドの軸変化を処理する + * Process gamepad axis changes + * + * @param {Gamepad} gamepad + * @param {number[]} prevAxes + * @return {void} + * @method + * @private + */ +const processAxes = (gamepad: Gamepad, prevAxes: number[]): void => +{ + if (!stage.hasEventListener(GamepadEvent.AXES_MOTION)) { + return ; + } + + for (let i = 0; i < gamepad.axes.length; i++) { + const value = gamepad.axes[i]; + if (Math.abs(value - prevAxes[i]) < AXIS_DEAD_ZONE) { + continue; + } + + const event = new GamepadEvent(GamepadEvent.AXES_MOTION); + event.gamepadIndex = gamepad.index; + event.axisIndex = i; + event.axisValue = value; + stage.dispatchEvent(event); + + prevAxes[i] = value; + } +}; + +/** + * @description ゲームパッドのポーリング処理を実行する + * Execute gamepad polling process + * + * @return {void} + * @method + * @protected + */ +export const execute = (): void => +{ + const gamepads = navigator.getGamepads(); + + for (let idx = 0; idx < gamepads.length; idx++) { + const gamepad = gamepads[idx]; + if (!gamepad) { + continue; + } + + if (!$gamepadButtonStates.has(gamepad.index)) { + $gamepadButtonStates.set( + gamepad.index, + Array.from({ "length": gamepad.buttons.length }, () => false) + ); + $gamepadAxisStates.set( + gamepad.index, + Array.from({ "length": gamepad.axes.length }, () => 0) + ); + } + + const prevButtons = $gamepadButtonStates.get(gamepad.index) as boolean[]; + const prevAxes = $gamepadAxisStates.get(gamepad.index) as number[]; + + processButtons(gamepad, prevButtons); + processAxes(gamepad, prevAxes); + } +}; diff --git a/packages/core/src/Player/usecase/PlayerRegisterEventUseCase.test.ts b/packages/core/src/Player/usecase/PlayerRegisterEventUseCase.test.ts index 35b87674..55454205 100644 --- a/packages/core/src/Player/usecase/PlayerRegisterEventUseCase.test.ts +++ b/packages/core/src/Player/usecase/PlayerRegisterEventUseCase.test.ts @@ -1,6 +1,6 @@ import { execute } from "./PlayerRegisterEventUseCase"; import { describe, expect, it, vi } from "vitest"; -import { KeyboardEvent } from "@next2d/events"; +import { KeyboardEvent, GamepadEvent } from "@next2d/events"; describe("PlayerRegisterEventUseCase.js test", () => { @@ -8,6 +8,8 @@ describe("PlayerRegisterEventUseCase.js test", () => { let keyDown = false; let keyUp = false; + let gamepadConnected = false; + let gamepadDisconnected = false; window.addEventListener = vi.fn((type) => { switch (type) { @@ -20,16 +22,28 @@ describe("PlayerRegisterEventUseCase.js test", () => keyUp = true; break; + case GamepadEvent.GAMEPAD_CONNECTED: + gamepadConnected = true; + break; + + case GamepadEvent.GAMEPAD_DISCONNECTED: + gamepadDisconnected = true; + break; + default: break; } }); - + expect(keyDown).toBe(false); expect(keyUp).toBe(false); + expect(gamepadConnected).toBe(false); + expect(gamepadDisconnected).toBe(false); execute(); expect(keyDown).toBe(true); expect(keyUp).toBe(true); + expect(gamepadConnected).toBe(true); + expect(gamepadDisconnected).toBe(true); }); }); \ No newline at end of file diff --git a/packages/core/src/Player/usecase/PlayerRegisterEventUseCase.ts b/packages/core/src/Player/usecase/PlayerRegisterEventUseCase.ts index 6ca6b44d..2df0ecbb 100644 --- a/packages/core/src/Player/usecase/PlayerRegisterEventUseCase.ts +++ b/packages/core/src/Player/usecase/PlayerRegisterEventUseCase.ts @@ -1,10 +1,12 @@ import { execute as playerKeyDownEventService } from "../service/PlayerKeyDownEventService"; import { execute as playerKeyUpEventService } from "../service/PlayerKeyUpEventService"; -import { KeyboardEvent } from "@next2d/events"; +import { execute as playerGamepadConnectService } from "../service/PlayerGamepadConnectService"; +import { execute as playerGamepadDisconnectService } from "../service/PlayerGamepadDisconnectService"; +import { KeyboardEvent, GamepadEvent } from "@next2d/events"; /** - * @description キーボードイベントを登録する - * Register keyboard events + * @description キーボード・ゲームパッドイベントを登録する + * Register keyboard and gamepad events * * @return {void} * @method @@ -14,4 +16,6 @@ export const execute = (): void => { window.addEventListener(KeyboardEvent.KEY_DOWN, playerKeyDownEventService as EventListener); window.addEventListener(KeyboardEvent.KEY_UP, playerKeyUpEventService as EventListener); + window.addEventListener(GamepadEvent.GAMEPAD_CONNECTED, playerGamepadConnectService as EventListener); + window.addEventListener(GamepadEvent.GAMEPAD_DISCONNECTED, playerGamepadDisconnectService as EventListener); }; \ No newline at end of file diff --git a/packages/core/src/Player/usecase/PlayerTickerUseCase.test.ts b/packages/core/src/Player/usecase/PlayerTickerUseCase.test.ts index 118c7e25..b8125ca6 100644 --- a/packages/core/src/Player/usecase/PlayerTickerUseCase.test.ts +++ b/packages/core/src/Player/usecase/PlayerTickerUseCase.test.ts @@ -45,6 +45,10 @@ vi.mock("../service/PlayerRemoveCachePostMessageService", () => ({ execute: vi.fn() })); +vi.mock("../service/PlayerGamepadTickerService", () => ({ + execute: vi.fn() +})); + describe("PlayerTickerUseCase.js test", () => { beforeEach(() => { diff --git a/packages/core/src/Player/usecase/PlayerTickerUseCase.ts b/packages/core/src/Player/usecase/PlayerTickerUseCase.ts index a4853923..62e01112 100644 --- a/packages/core/src/Player/usecase/PlayerTickerUseCase.ts +++ b/packages/core/src/Player/usecase/PlayerTickerUseCase.ts @@ -4,6 +4,7 @@ import { Event } from "@next2d/events"; import { $cacheStore } from "@next2d/cache"; import { execute as playerRenderingPostMessageService } from "../service/PlayerRenderingPostMessageService"; import { execute as playerRemoveCachePostMessageService } from "../service/PlayerRemoveCachePostMessageService"; +import { execute as playerGamepadTickerService } from "../service/PlayerGamepadTickerService"; /** * @private @@ -40,6 +41,9 @@ export const execute = (timestamp: number): void => // 定期処理 stage.$ticker(); + // gamepad polling + playerGamepadTickerService(); + // enter frame event if (stage.hasEventListener(Event.ENTER_FRAME)) { stage.dispatchEvent(enterFrameEvent); diff --git a/packages/core/src/interface/IEvents.ts b/packages/core/src/interface/IEvents.ts index 832dfdd8..c9592dfc 100644 --- a/packages/core/src/interface/IEvents.ts +++ b/packages/core/src/interface/IEvents.ts @@ -3,6 +3,7 @@ import type { EventDispatcher, EventPhase, FocusEvent, + GamepadEvent, HTTPStatusEvent, IOErrorEvent, PointerEvent, @@ -16,6 +17,7 @@ export interface IEvents { EventDispatcher: typeof EventDispatcher; EventPhase: typeof EventPhase; FocusEvent: typeof FocusEvent; + GamepadEvent: typeof GamepadEvent; HTTPStatusEvent: typeof HTTPStatusEvent; IOErrorEvent: typeof IOErrorEvent; PointerEvent: typeof PointerEvent; diff --git a/packages/events/src/GamepadEvent.test.ts b/packages/events/src/GamepadEvent.test.ts new file mode 100644 index 00000000..673c713c --- /dev/null +++ b/packages/events/src/GamepadEvent.test.ts @@ -0,0 +1,52 @@ +import { GamepadEvent } from "./GamepadEvent"; +import { describe, expect, it } from "vitest"; + +describe("GamepadEvent.js property test", () => +{ + it("GAMEPAD_CONNECTED test", () => + { + expect(GamepadEvent.GAMEPAD_CONNECTED).toBe("gamepadconnected"); + }); + + it("GAMEPAD_DISCONNECTED test", () => + { + expect(GamepadEvent.GAMEPAD_DISCONNECTED).toBe("gamepaddisconnected"); + }); + + it("BUTTON_DOWN test", () => + { + expect(GamepadEvent.BUTTON_DOWN).toBe("gamepadbuttondown"); + }); + + it("BUTTON_UP test", () => + { + expect(GamepadEvent.BUTTON_UP).toBe("gamepadbuttonup"); + }); + + it("AXES_MOTION test", () => + { + expect(GamepadEvent.AXES_MOTION).toBe("gamepadaxesmotion"); + }); + + it("instance default properties test", () => + { + const event = new GamepadEvent(GamepadEvent.BUTTON_DOWN); + expect(event.type).toBe("gamepadbuttondown"); + expect(event.gamepadIndex).toBe(0); + expect(event.buttonIndex).toBeUndefined(); + expect(event.buttonValue).toBeUndefined(); + expect(event.axisIndex).toBeUndefined(); + expect(event.axisValue).toBeUndefined(); + }); + + it("instance property assignment test", () => + { + const event = new GamepadEvent(GamepadEvent.BUTTON_DOWN); + event.gamepadIndex = 1; + event.buttonIndex = 3; + event.buttonValue = 0.8; + expect(event.gamepadIndex).toBe(1); + expect(event.buttonIndex).toBe(3); + expect(event.buttonValue).toBe(0.8); + }); +}); diff --git a/packages/events/src/GamepadEvent.ts b/packages/events/src/GamepadEvent.ts new file mode 100644 index 00000000..9d3406b1 --- /dev/null +++ b/packages/events/src/GamepadEvent.ts @@ -0,0 +1,145 @@ +import { Event } from "./Event"; + +/** + * @description ゲームパッドによるユーザーの操作を示します。 + * Indicates user operation via gamepad. + * + * @class + * @memberOf next2d.events + * @extends Event + */ +export class GamepadEvent extends Event +{ + /** + * @description ゲームパッドのインデックス番号 + * Index number of the gamepad + * + * @type {number} + * @default 0 + * @public + */ + public gamepadIndex: number; + + /** + * @description ボタンイベント時のボタン番号 + * Button number at the time of button event + * + * @type {number | undefined} + * @default undefined + * @public + */ + public buttonIndex: number | undefined; + + /** + * @description ボタンの押し具合 (0.0〜1.0) + * The degree of button press (0.0 to 1.0) + * + * @type {number | undefined} + * @default undefined + * @public + */ + public buttonValue: number | undefined; + + /** + * @description 軸イベント時の軸番号 + * Axis number at the time of axis event + * + * @type {number | undefined} + * @default undefined + * @public + */ + public axisIndex: number | undefined; + + /** + * @description 軸の値 (-1.0〜1.0) + * Axis value (-1.0 to 1.0) + * + * @type {number | undefined} + * @default undefined + * @public + */ + public axisValue: number | undefined; + + /** + * @param {string} type + * @param {boolean} [bubbles=true] + * + * @constructor + * @public + */ + constructor (type: string, bubbles: boolean = true) + { + super(type, bubbles); + + this.gamepadIndex = 0; + this.buttonIndex = undefined; + this.buttonValue = undefined; + this.axisIndex = undefined; + this.axisValue = undefined; + } + + /** + * @description ゲームパッドが接続されたときに発生します。 + * Occurs when a gamepad is connected. + * + * @return {string} + * @const + * @static + */ + static get GAMEPAD_CONNECTED (): string + { + return "gamepadconnected"; + } + + /** + * @description ゲームパッドが切断されたときに発生します。 + * Occurs when a gamepad is disconnected. + * + * @return {string} + * @const + * @static + */ + static get GAMEPAD_DISCONNECTED (): string + { + return "gamepaddisconnected"; + } + + /** + * @description ゲームパッドのボタンが押されたときに発生します。 + * Occurs when a gamepad button is pressed. + * + * @return {string} + * @const + * @static + */ + static get BUTTON_DOWN (): string + { + return "gamepadbuttondown"; + } + + /** + * @description ゲームパッドのボタンが離されたときに発生します。 + * Occurs when a gamepad button is released. + * + * @return {string} + * @const + * @static + */ + static get BUTTON_UP (): string + { + return "gamepadbuttonup"; + } + + /** + * @description ゲームパッドのスティック(軸)が変化したときに発生します。 + * Occurs when a gamepad stick (axis) changes. + * + * @return {string} + * @const + * @static + */ + static get AXES_MOTION (): string + { + return "gamepadaxesmotion"; + } +} diff --git a/packages/events/src/index.ts b/packages/events/src/index.ts index 82934e2e..27f6a8b4 100644 --- a/packages/events/src/index.ts +++ b/packages/events/src/index.ts @@ -2,6 +2,7 @@ export * from "./Event"; export * from "./EventDispatcher"; export * from "./EventPhase"; export * from "./FocusEvent"; +export * from "./GamepadEvent"; export * from "./HTTPStatusEvent"; export * from "./IOErrorEvent"; export * from "./PointerEvent"; From fa23c235b0b9524cd218d0214c7a8692bdaaed97 Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 17 Jun 2026 08:02:14 +0900 Subject: [PATCH 5/6] =?UTF-8?q?#292=20=E3=83=99=E3=83=B3=E3=83=81=E3=83=9E?= =?UTF-8?q?=E3=83=BC=E3=82=AF=E3=82=B3=E3=83=BC=E3=83=89=E3=81=AF=E6=AE=8B?= =?UTF-8?q?=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/index.html b/index.html index 0d6c3cdf..21849741 100644 --- a/index.html +++ b/index.html @@ -11,6 +11,52 @@ window.addEventListener("DOMContentLoaded", async () => { await next2d.load("develop"); + return ; + + const count = 8000; + const root = next2d + .createRootMovieClip(1000, 416, 60) + .then((root) => + { + const { Shape } = next2d.display; + + + const rects = []; + for (let i = 0; i < count; i++) { + const x = Math.random() * 1000; + const y = Math.random() * 416; + const size = 10 + Math.random() * 40; + const speed = 1 + Math.random(); + + var rect = new Shape(); + + rect + .graphics + .beginFill("#fff") + .lineStyle(1, "#000") + .drawRect(0, 0, size, size); + + rect.x = x; + rect.y = y; + + root.addChild(rect); + + rects.push({ size, speed, el: rect }); + } + + root.addEventListener("enterFrame", () => + { + for (let i = 0; i < count; i++) { + const rect = rects[i]; + + if (rect.el.x + rect.size < 0) { + rect.el.x = 1000 + rect.size / 2; + } + + rect.el.x -= rect.speed; + } + }); + }); }); From e3e777a22c42f379ce31c6e215ffb2942d4d49b5 Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 17 Jun 2026 08:15:55 +0900 Subject: [PATCH 6/6] #292 delete auto-assign.yml --- .github/workflows/auto-assign.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/auto-assign.yml diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml deleted file mode 100644 index 2c9c96dc..00000000 --- a/.github/workflows/auto-assign.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Auto Assign -on: - issues: - types: [opened] - pull_request: - types: [opened] -jobs: - run: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - name: 'Auto-assign issue' - uses: pozil/auto-assign-issue@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - assignees: ienaga - numOfAssignee: 1 \ No newline at end of file