This is an automated email from the ASF dual-hosted git repository.

guan404ming pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new 75a48a0e2d [Web] Add support for OPFS (#19494)
75a48a0e2d is described below

commit 75a48a0e2d285f50f8d3a08e35548ac0a62ce573
Author: Akaash Parthasarathy <[email protected]>
AuthorDate: Wed May 6 01:24:09 2026 -0400

    [Web] Add support for OPFS (#19494)
    
    Add OPFS as an alternative caching mechanism for artifacts:
    
https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system.
---
 web/package-lock.json     | 555 ++++++++++++++++++++++++----------------------
 web/src/artifact_cache.ts |  92 +++++++-
 web/src/index.ts          |   1 +
 web/src/opfs_store.ts     | 262 ++++++++++++++++++++++
 web/src/runtime.ts        |   2 +-
 5 files changed, 642 insertions(+), 270 deletions(-)

diff --git a/web/package-lock.json b/web/package-lock.json
index 79c9874fdf..7706ea9960 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -47,9 +47,9 @@
       }
     },
     "node_modules/@babel/compat-data": {
-      "version": "7.29.0",
-      "resolved": 
"https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz";,
-      "integrity": 
"sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
+      "version": "7.29.3",
+      "resolved": 
"https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz";,
+      "integrity": 
"sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -239,9 +239,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.29.2",
-      "resolved": 
"https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz";,
-      "integrity": 
"sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==",
+      "version": "7.29.3",
+      "resolved": 
"https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz";,
+      "integrity": 
"sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -549,21 +549,21 @@
       "license": "MIT"
     },
     "node_modules/@emnapi/core": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz";,
-      "integrity": 
"sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==",
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz";,
+      "integrity": 
"sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
       "dev": true,
       "license": "MIT",
       "optional": true,
       "dependencies": {
-        "@emnapi/wasi-threads": "1.2.0",
+        "@emnapi/wasi-threads": "1.2.1",
         "tslib": "^2.4.0"
       }
     },
     "node_modules/@emnapi/runtime": {
-      "version": "1.9.1",
-      "resolved": 
"https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz";,
-      "integrity": 
"sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==",
+      "version": "1.10.0",
+      "resolved": 
"https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz";,
+      "integrity": 
"sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
       "dev": true,
       "license": "MIT",
       "optional": true,
@@ -572,9 +572,9 @@
       }
     },
     "node_modules/@emnapi/wasi-threads": {
-      "version": "1.2.0",
-      "resolved": 
"https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz";,
-      "integrity": 
"sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==",
+      "version": "1.2.1",
+      "resolved": 
"https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz";,
+      "integrity": 
"sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
       "dev": true,
       "license": "MIT",
       "optional": true,
@@ -612,13 +612,13 @@
       }
     },
     "node_modules/@eslint/config-array": {
-      "version": "0.23.3",
-      "resolved": 
"https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.3.tgz";,
-      "integrity": 
"sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==",
+      "version": "0.23.5",
+      "resolved": 
"https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz";,
+      "integrity": 
"sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==",
       "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
-        "@eslint/object-schema": "^3.0.3",
+        "@eslint/object-schema": "^3.0.5",
         "debug": "^4.3.1",
         "minimatch": "^10.2.4"
       },
@@ -627,22 +627,22 @@
       }
     },
     "node_modules/@eslint/config-helpers": {
-      "version": "0.5.3",
-      "resolved": 
"https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.3.tgz";,
-      "integrity": 
"sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==",
+      "version": "0.5.5",
+      "resolved": 
"https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz";,
+      "integrity": 
"sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==",
       "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
-        "@eslint/core": "^1.1.1"
+        "@eslint/core": "^1.2.1"
       },
       "engines": {
         "node": "^20.19.0 || ^22.13.0 || >=24"
       }
     },
     "node_modules/@eslint/core": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.1.tgz";,
-      "integrity": 
"sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz";,
+      "integrity": 
"sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==",
       "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
@@ -653,9 +653,9 @@
       }
     },
     "node_modules/@eslint/object-schema": {
-      "version": "3.0.3",
-      "resolved": 
"https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.3.tgz";,
-      "integrity": 
"sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==",
+      "version": "3.0.5",
+      "resolved": 
"https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz";,
+      "integrity": 
"sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==",
       "dev": true,
       "license": "Apache-2.0",
       "engines": {
@@ -663,13 +663,13 @@
       }
     },
     "node_modules/@eslint/plugin-kit": {
-      "version": "0.6.1",
-      "resolved": 
"https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz";,
-      "integrity": 
"sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==",
+      "version": "0.7.1",
+      "resolved": 
"https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz";,
+      "integrity": 
"sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==",
       "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
-        "@eslint/core": "^1.1.1",
+        "@eslint/core": "^1.2.1",
         "levn": "^0.4.1"
       },
       "engines": {
@@ -691,29 +691,43 @@
       }
     },
     "node_modules/@humanfs/core": {
-      "version": "0.19.1",
-      "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz";,
-      "integrity": 
"sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+      "version": "0.19.2",
+      "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz";,
+      "integrity": 
"sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==",
       "dev": true,
       "license": "Apache-2.0",
+      "dependencies": {
+        "@humanfs/types": "^0.15.0"
+      },
       "engines": {
         "node": ">=18.18.0"
       }
     },
     "node_modules/@humanfs/node": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz";,
-      "integrity": 
"sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+      "version": "0.16.8",
+      "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz";,
+      "integrity": 
"sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==",
       "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
-        "@humanfs/core": "^0.19.1",
+        "@humanfs/core": "^0.19.2",
+        "@humanfs/types": "^0.15.0",
         "@humanwhocodes/retry": "^0.4.0"
       },
       "engines": {
         "node": ">=18.18.0"
       }
     },
+    "node_modules/@humanfs/types": {
+      "version": "0.15.0",
+      "resolved": 
"https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz";,
+      "integrity": 
"sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=18.18.0"
+      }
+    },
     "node_modules/@humanwhocodes/module-importer": {
       "version": "1.0.1",
       "resolved": 
"https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz";,
@@ -834,9 +848,9 @@
       }
     },
     "node_modules/@istanbuljs/schema": {
-      "version": "0.1.3",
-      "resolved": 
"https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz";,
-      "integrity": 
"sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+      "version": "0.1.6",
+      "resolved": 
"https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz";,
+      "integrity": 
"sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -1373,9 +1387,9 @@
       }
     },
     "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz";,
-      "integrity": 
"sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz";,
+      "integrity": 
"sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==",
       "cpu": [
         "arm"
       ],
@@ -1387,9 +1401,9 @@
       ]
     },
     "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz";,
-      "integrity": 
"sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz";,
+      "integrity": 
"sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==",
       "cpu": [
         "arm64"
       ],
@@ -1401,9 +1415,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz";,
-      "integrity": 
"sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz";,
+      "integrity": 
"sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==",
       "cpu": [
         "arm64"
       ],
@@ -1415,9 +1429,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz";,
-      "integrity": 
"sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz";,
+      "integrity": 
"sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==",
       "cpu": [
         "x64"
       ],
@@ -1429,9 +1443,9 @@
       ]
     },
     "node_modules/@rollup/rollup-freebsd-arm64": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz";,
-      "integrity": 
"sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz";,
+      "integrity": 
"sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==",
       "cpu": [
         "arm64"
       ],
@@ -1443,9 +1457,9 @@
       ]
     },
     "node_modules/@rollup/rollup-freebsd-x64": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz";,
-      "integrity": 
"sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz";,
+      "integrity": 
"sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==",
       "cpu": [
         "x64"
       ],
@@ -1457,9 +1471,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz";,
-      "integrity": 
"sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz";,
+      "integrity": 
"sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==",
       "cpu": [
         "arm"
       ],
@@ -1471,9 +1485,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-musleabihf": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz";,
-      "integrity": 
"sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz";,
+      "integrity": 
"sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==",
       "cpu": [
         "arm"
       ],
@@ -1485,9 +1499,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz";,
-      "integrity": 
"sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz";,
+      "integrity": 
"sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==",
       "cpu": [
         "arm64"
       ],
@@ -1499,9 +1513,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz";,
-      "integrity": 
"sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz";,
+      "integrity": 
"sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==",
       "cpu": [
         "arm64"
       ],
@@ -1513,9 +1527,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-loong64-gnu": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz";,
-      "integrity": 
"sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz";,
+      "integrity": 
"sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==",
       "cpu": [
         "loong64"
       ],
@@ -1527,9 +1541,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-loong64-musl": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz";,
-      "integrity": 
"sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz";,
+      "integrity": 
"sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==",
       "cpu": [
         "loong64"
       ],
@@ -1541,9 +1555,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-ppc64-gnu": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz";,
-      "integrity": 
"sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz";,
+      "integrity": 
"sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==",
       "cpu": [
         "ppc64"
       ],
@@ -1555,9 +1569,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-ppc64-musl": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz";,
-      "integrity": 
"sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz";,
+      "integrity": 
"sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==",
       "cpu": [
         "ppc64"
       ],
@@ -1569,9 +1583,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz";,
-      "integrity": 
"sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz";,
+      "integrity": 
"sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==",
       "cpu": [
         "riscv64"
       ],
@@ -1583,9 +1597,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-riscv64-musl": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz";,
-      "integrity": 
"sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz";,
+      "integrity": 
"sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==",
       "cpu": [
         "riscv64"
       ],
@@ -1597,9 +1611,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-s390x-gnu": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz";,
-      "integrity": 
"sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz";,
+      "integrity": 
"sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==",
       "cpu": [
         "s390x"
       ],
@@ -1611,9 +1625,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz";,
-      "integrity": 
"sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz";,
+      "integrity": 
"sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==",
       "cpu": [
         "x64"
       ],
@@ -1625,9 +1639,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz";,
-      "integrity": 
"sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz";,
+      "integrity": 
"sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==",
       "cpu": [
         "x64"
       ],
@@ -1639,9 +1653,9 @@
       ]
     },
     "node_modules/@rollup/rollup-openbsd-x64": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz";,
-      "integrity": 
"sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz";,
+      "integrity": 
"sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==",
       "cpu": [
         "x64"
       ],
@@ -1653,9 +1667,9 @@
       ]
     },
     "node_modules/@rollup/rollup-openharmony-arm64": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz";,
-      "integrity": 
"sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz";,
+      "integrity": 
"sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==",
       "cpu": [
         "arm64"
       ],
@@ -1667,9 +1681,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz";,
-      "integrity": 
"sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz";,
+      "integrity": 
"sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==",
       "cpu": [
         "arm64"
       ],
@@ -1681,9 +1695,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz";,
-      "integrity": 
"sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz";,
+      "integrity": 
"sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==",
       "cpu": [
         "ia32"
       ],
@@ -1695,9 +1709,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-x64-gnu": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz";,
-      "integrity": 
"sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz";,
+      "integrity": 
"sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==",
       "cpu": [
         "x64"
       ],
@@ -1709,9 +1723,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.60.1",
-      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz";,
-      "integrity": 
"sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==",
+      "version": "4.60.2",
+      "resolved": 
"https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz";,
+      "integrity": 
"sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==",
       "cpu": [
         "x64"
       ],
@@ -1789,9 +1803,9 @@
       }
     },
     "node_modules/@sinonjs/fake-timers": {
-      "version": "15.1.1",
-      "resolved": 
"https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz";,
-      "integrity": 
"sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==",
+      "version": "15.3.2",
+      "resolved": 
"https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz";,
+      "integrity": 
"sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==",
       "dev": true,
       "license": "BSD-3-Clause",
       "dependencies": {
@@ -1913,13 +1927,13 @@
       "license": "MIT"
     },
     "node_modules/@types/node": {
-      "version": "25.5.0",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz";,
-      "integrity": 
"sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==",
+      "version": "25.6.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz";,
+      "integrity": 
"sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "undici-types": "~7.18.0"
+        "undici-types": "~7.19.0"
       }
     },
     "node_modules/@types/resolve": {
@@ -1961,17 +1975,17 @@
       "license": "MIT"
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.0.tgz";,
-      "integrity": 
"sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.1.tgz";,
+      "integrity": 
"sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@eslint-community/regexpp": "^4.12.2",
-        "@typescript-eslint/scope-manager": "8.58.0",
-        "@typescript-eslint/type-utils": "8.58.0",
-        "@typescript-eslint/utils": "8.58.0",
-        "@typescript-eslint/visitor-keys": "8.58.0",
+        "@typescript-eslint/scope-manager": "8.59.1",
+        "@typescript-eslint/type-utils": "8.59.1",
+        "@typescript-eslint/utils": "8.59.1",
+        "@typescript-eslint/visitor-keys": "8.59.1",
         "ignore": "^7.0.5",
         "natural-compare": "^1.4.0",
         "ts-api-utils": "^2.5.0"
@@ -1984,23 +1998,23 @@
         "url": "https://opencollective.com/typescript-eslint";
       },
       "peerDependencies": {
-        "@typescript-eslint/parser": "^8.58.0",
+        "@typescript-eslint/parser": "^8.59.1",
         "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
         "typescript": ">=4.8.4 <6.1.0"
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.0.tgz";,
-      "integrity": 
"sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.1.tgz";,
+      "integrity": 
"sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==",
       "dev": true,
       "license": "MIT",
       "peer": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "8.58.0",
-        "@typescript-eslint/types": "8.58.0",
-        "@typescript-eslint/typescript-estree": "8.58.0",
-        "@typescript-eslint/visitor-keys": "8.58.0",
+        "@typescript-eslint/scope-manager": "8.59.1",
+        "@typescript-eslint/types": "8.59.1",
+        "@typescript-eslint/typescript-estree": "8.59.1",
+        "@typescript-eslint/visitor-keys": "8.59.1",
         "debug": "^4.4.3"
       },
       "engines": {
@@ -2016,14 +2030,14 @@
       }
     },
     "node_modules/@typescript-eslint/project-service": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.0.tgz";,
-      "integrity": 
"sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz";,
+      "integrity": 
"sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/tsconfig-utils": "^8.58.0",
-        "@typescript-eslint/types": "^8.58.0",
+        "@typescript-eslint/tsconfig-utils": "^8.59.1",
+        "@typescript-eslint/types": "^8.59.1",
         "debug": "^4.4.3"
       },
       "engines": {
@@ -2038,14 +2052,14 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.0.tgz";,
-      "integrity": 
"sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz";,
+      "integrity": 
"sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.58.0",
-        "@typescript-eslint/visitor-keys": "8.58.0"
+        "@typescript-eslint/types": "8.59.1",
+        "@typescript-eslint/visitor-keys": "8.59.1"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2056,9 +2070,9 @@
       }
     },
     "node_modules/@typescript-eslint/tsconfig-utils": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.0.tgz";,
-      "integrity": 
"sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz";,
+      "integrity": 
"sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -2073,15 +2087,15 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.0.tgz";,
-      "integrity": 
"sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.1.tgz";,
+      "integrity": 
"sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.58.0",
-        "@typescript-eslint/typescript-estree": "8.58.0",
-        "@typescript-eslint/utils": "8.58.0",
+        "@typescript-eslint/types": "8.59.1",
+        "@typescript-eslint/typescript-estree": "8.59.1",
+        "@typescript-eslint/utils": "8.59.1",
         "debug": "^4.4.3",
         "ts-api-utils": "^2.5.0"
       },
@@ -2098,9 +2112,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.0.tgz";,
-      "integrity": 
"sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz";,
+      "integrity": 
"sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -2112,16 +2126,16 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.0.tgz";,
-      "integrity": 
"sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz";,
+      "integrity": 
"sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/project-service": "8.58.0",
-        "@typescript-eslint/tsconfig-utils": "8.58.0",
-        "@typescript-eslint/types": "8.58.0",
-        "@typescript-eslint/visitor-keys": "8.58.0",
+        "@typescript-eslint/project-service": "8.59.1",
+        "@typescript-eslint/tsconfig-utils": "8.59.1",
+        "@typescript-eslint/types": "8.59.1",
+        "@typescript-eslint/visitor-keys": "8.59.1",
         "debug": "^4.4.3",
         "minimatch": "^10.2.2",
         "semver": "^7.7.3",
@@ -2140,16 +2154,16 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.0.tgz";,
-      "integrity": 
"sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.1.tgz";,
+      "integrity": 
"sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.9.1",
-        "@typescript-eslint/scope-manager": "8.58.0",
-        "@typescript-eslint/types": "8.58.0",
-        "@typescript-eslint/typescript-estree": "8.58.0"
+        "@typescript-eslint/scope-manager": "8.59.1",
+        "@typescript-eslint/types": "8.59.1",
+        "@typescript-eslint/typescript-estree": "8.59.1"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2164,13 +2178,13 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "8.58.0",
-      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.0.tgz";,
-      "integrity": 
"sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==",
+      "version": "8.59.1",
+      "resolved": 
"https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz";,
+      "integrity": 
"sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.58.0",
+        "@typescript-eslint/types": "8.59.1",
         "eslint-visitor-keys": "^5.0.0"
       },
       "engines": {
@@ -2502,9 +2516,9 @@
       }
     },
     "node_modules/ajv": {
-      "version": "6.14.0",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz";,
-      "integrity": 
"sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
+      "version": "6.15.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz";,
+      "integrity": 
"sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -2718,9 +2732,9 @@
       }
     },
     "node_modules/baseline-browser-mapping": {
-      "version": "2.10.12",
-      "resolved": 
"https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz";,
-      "integrity": 
"sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==",
+      "version": "2.10.25",
+      "resolved": 
"https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.25.tgz";,
+      "integrity": 
"sha512-QO/VHsXCQdnzADMfmkeOPvHdIAkoB7i0/rGjINPJEetLx75hNttVWGQ/jycHUDP9zZ9rupbm60WRxcwViB0MiA==",
       "dev": true,
       "license": "Apache-2.0",
       "bin": {
@@ -2744,9 +2758,9 @@
       }
     },
     "node_modules/browserslist": {
-      "version": "4.28.1",
-      "resolved": 
"https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz";,
-      "integrity": 
"sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+      "version": "4.28.2",
+      "resolved": 
"https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz";,
+      "integrity": 
"sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
       "dev": true,
       "funding": [
         {
@@ -2765,11 +2779,11 @@
       "license": "MIT",
       "peer": true,
       "dependencies": {
-        "baseline-browser-mapping": "^2.9.0",
-        "caniuse-lite": "^1.0.30001759",
-        "electron-to-chromium": "^1.5.263",
-        "node-releases": "^2.0.27",
-        "update-browserslist-db": "^1.2.0"
+        "baseline-browser-mapping": "^2.10.12",
+        "caniuse-lite": "^1.0.30001782",
+        "electron-to-chromium": "^1.5.328",
+        "node-releases": "^2.0.36",
+        "update-browserslist-db": "^1.2.3"
       },
       "bin": {
         "browserslist": "cli.js"
@@ -2816,9 +2830,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001782",
-      "resolved": 
"https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001782.tgz";,
-      "integrity": 
"sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==",
+      "version": "1.0.30001791",
+      "resolved": 
"https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz";,
+      "integrity": 
"sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==",
       "dev": true,
       "funding": [
         {
@@ -3106,9 +3120,9 @@
       "license": "MIT"
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.5.328",
-      "resolved": 
"https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz";,
-      "integrity": 
"sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==",
+      "version": "1.5.349",
+      "resolved": 
"https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.349.tgz";,
+      "integrity": 
"sha512-QsWVGyRuY07Aqb234QytTfwd5d9AJlfNIQ5wIOl1L+PZDzI9d9+Fn0FRale/QYlFxt/bUnB0/nLd1jFPGxGK1A==",
       "dev": true,
       "license": "ISC"
     },
@@ -3155,6 +3169,16 @@
         "is-arrayish": "^0.2.1"
       }
     },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz";,
+      "integrity": 
"sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/escalade": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz";,
@@ -3179,19 +3203,19 @@
       }
     },
     "node_modules/eslint": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.1.0.tgz";,
-      "integrity": 
"sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==",
+      "version": "10.3.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.3.0.tgz";,
+      "integrity": 
"sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==",
       "dev": true,
       "license": "MIT",
       "peer": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.8.0",
         "@eslint-community/regexpp": "^4.12.2",
-        "@eslint/config-array": "^0.23.3",
-        "@eslint/config-helpers": "^0.5.3",
-        "@eslint/core": "^1.1.1",
-        "@eslint/plugin-kit": "^0.6.1",
+        "@eslint/config-array": "^0.23.5",
+        "@eslint/config-helpers": "^0.5.5",
+        "@eslint/core": "^1.2.1",
+        "@eslint/plugin-kit": "^0.7.1",
         "@humanfs/node": "^0.16.6",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@humanwhocodes/retry": "^0.4.2",
@@ -3695,9 +3719,9 @@
       "license": "MIT"
     },
     "node_modules/glob/node_modules/brace-expansion": {
-      "version": "2.0.3",
-      "resolved": 
"https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz";,
-      "integrity": 
"sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==",
+      "version": "2.1.0",
+      "resolved": 
"https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz";,
+      "integrity": 
"sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -3738,9 +3762,9 @@
       }
     },
     "node_modules/hasown": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz";,
-      "integrity": 
"sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz";,
+      "integrity": 
"sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -4903,9 +4927,9 @@
       "license": "MIT"
     },
     "node_modules/node-releases": {
-      "version": "2.0.36",
-      "resolved": 
"https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz";,
-      "integrity": 
"sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==",
+      "version": "2.0.38",
+      "resolved": 
"https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz";,
+      "integrity": 
"sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==",
       "dev": true,
       "license": "MIT"
     },
@@ -5305,12 +5329,13 @@
       }
     },
     "node_modules/resolve": {
-      "version": "1.22.11",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz";,
-      "integrity": 
"sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
+      "version": "1.22.12",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz";,
+      "integrity": 
"sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
+        "es-errors": "^1.3.0",
         "is-core-module": "^2.16.1",
         "path-parse": "^1.0.7",
         "supports-preserve-symlinks-flag": "^1.0.0"
@@ -5349,9 +5374,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "4.60.1",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz";,
-      "integrity": 
"sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==",
+      "version": "4.60.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz";,
+      "integrity": 
"sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==",
       "dev": true,
       "license": "MIT",
       "peer": true,
@@ -5366,31 +5391,31 @@
         "npm": ">=8.0.0"
       },
       "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.60.1",
-        "@rollup/rollup-android-arm64": "4.60.1",
-        "@rollup/rollup-darwin-arm64": "4.60.1",
-        "@rollup/rollup-darwin-x64": "4.60.1",
-        "@rollup/rollup-freebsd-arm64": "4.60.1",
-        "@rollup/rollup-freebsd-x64": "4.60.1",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.60.1",
-        "@rollup/rollup-linux-arm-musleabihf": "4.60.1",
-        "@rollup/rollup-linux-arm64-gnu": "4.60.1",
-        "@rollup/rollup-linux-arm64-musl": "4.60.1",
-        "@rollup/rollup-linux-loong64-gnu": "4.60.1",
-        "@rollup/rollup-linux-loong64-musl": "4.60.1",
-        "@rollup/rollup-linux-ppc64-gnu": "4.60.1",
-        "@rollup/rollup-linux-ppc64-musl": "4.60.1",
-        "@rollup/rollup-linux-riscv64-gnu": "4.60.1",
-        "@rollup/rollup-linux-riscv64-musl": "4.60.1",
-        "@rollup/rollup-linux-s390x-gnu": "4.60.1",
-        "@rollup/rollup-linux-x64-gnu": "4.60.1",
-        "@rollup/rollup-linux-x64-musl": "4.60.1",
-        "@rollup/rollup-openbsd-x64": "4.60.1",
-        "@rollup/rollup-openharmony-arm64": "4.60.1",
-        "@rollup/rollup-win32-arm64-msvc": "4.60.1",
-        "@rollup/rollup-win32-ia32-msvc": "4.60.1",
-        "@rollup/rollup-win32-x64-gnu": "4.60.1",
-        "@rollup/rollup-win32-x64-msvc": "4.60.1",
+        "@rollup/rollup-android-arm-eabi": "4.60.2",
+        "@rollup/rollup-android-arm64": "4.60.2",
+        "@rollup/rollup-darwin-arm64": "4.60.2",
+        "@rollup/rollup-darwin-x64": "4.60.2",
+        "@rollup/rollup-freebsd-arm64": "4.60.2",
+        "@rollup/rollup-freebsd-x64": "4.60.2",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.60.2",
+        "@rollup/rollup-linux-arm-musleabihf": "4.60.2",
+        "@rollup/rollup-linux-arm64-gnu": "4.60.2",
+        "@rollup/rollup-linux-arm64-musl": "4.60.2",
+        "@rollup/rollup-linux-loong64-gnu": "4.60.2",
+        "@rollup/rollup-linux-loong64-musl": "4.60.2",
+        "@rollup/rollup-linux-ppc64-gnu": "4.60.2",
+        "@rollup/rollup-linux-ppc64-musl": "4.60.2",
+        "@rollup/rollup-linux-riscv64-gnu": "4.60.2",
+        "@rollup/rollup-linux-riscv64-musl": "4.60.2",
+        "@rollup/rollup-linux-s390x-gnu": "4.60.2",
+        "@rollup/rollup-linux-x64-gnu": "4.60.2",
+        "@rollup/rollup-linux-x64-musl": "4.60.2",
+        "@rollup/rollup-openbsd-x64": "4.60.2",
+        "@rollup/rollup-openharmony-arm64": "4.60.2",
+        "@rollup/rollup-win32-arm64-msvc": "4.60.2",
+        "@rollup/rollup-win32-ia32-msvc": "4.60.2",
+        "@rollup/rollup-win32-x64-gnu": "4.60.2",
+        "@rollup/rollup-win32-x64-msvc": "4.60.2",
         "fsevents": "~2.3.2"
       }
     },
@@ -5750,9 +5775,9 @@
       "license": "MIT"
     },
     "node_modules/test-exclude/node_modules/brace-expansion": {
-      "version": "1.1.13",
-      "resolved": 
"https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz";,
-      "integrity": 
"sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
+      "version": "1.1.14",
+      "resolved": 
"https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz";,
+      "integrity": 
"sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -5796,14 +5821,14 @@
       }
     },
     "node_modules/tinyglobby": {
-      "version": "0.2.15",
-      "resolved": 
"https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz";,
-      "integrity": 
"sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+      "version": "0.2.16",
+      "resolved": 
"https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz";,
+      "integrity": 
"sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "fdir": "^6.5.0",
-        "picomatch": "^4.0.3"
+        "picomatch": "^4.0.4"
       },
       "engines": {
         "node": ">=12.0.0"
@@ -5876,9 +5901,9 @@
       }
     },
     "node_modules/typedoc": {
-      "version": "0.28.18",
-      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.18.tgz";,
-      "integrity": 
"sha512-NTWTUOFRQ9+SGKKTuWKUioUkjxNwtS3JDRPVKZAXGHZy2wCA8bdv2iJiyeePn0xkmK+TCCqZFT0X7+2+FLjngA==",
+      "version": "0.28.19",
+      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.19.tgz";,
+      "integrity": 
"sha512-wKh+lhdmMFivMlc6vRRcMGXeGEHGU2g8a2CkPTJjJlwRf1iXbimWIPcFolCqe4E0d/FRtGszpIrsp3WLpDB8Pw==",
       "dev": true,
       "license": "Apache-2.0",
       "peer": true,
@@ -5886,8 +5911,8 @@
         "@gerrit0/mini-shiki": "^3.23.0",
         "lunr": "^2.3.9",
         "markdown-it": "^14.1.1",
-        "minimatch": "^10.2.4",
-        "yaml": "^2.8.2"
+        "minimatch": "^10.2.5",
+        "yaml": "^2.8.3"
       },
       "bin": {
         "typedoc": "bin/typedoc"
@@ -5952,9 +5977,9 @@
       }
     },
     "node_modules/undici-types": {
-      "version": "7.18.2",
-      "resolved": 
"https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz";,
-      "integrity": 
"sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
+      "version": "7.19.2",
+      "resolved": 
"https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz";,
+      "integrity": 
"sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==",
       "dev": true,
       "license": "MIT"
     },
@@ -6241,9 +6266,9 @@
       "license": "ISC"
     },
     "node_modules/yaml": {
-      "version": "2.8.3",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz";,
-      "integrity": 
"sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==",
+      "version": "2.8.4",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz";,
+      "integrity": 
"sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==",
       "dev": true,
       "license": "ISC",
       "bin": {
diff --git a/web/src/artifact_cache.ts b/web/src/artifact_cache.ts
index 9b4494805b..d36573cccc 100644
--- a/web/src/artifact_cache.ts
+++ b/web/src/artifact_cache.ts
@@ -17,6 +17,8 @@
  * under the License.
  */
 
+import { OPFSStore } from "./opfs_store";
+
 export interface TensorCacheEntry {
   name: string;
   shape: Array<number>;
@@ -83,7 +85,7 @@ export interface ArtifactCacheTemplate {
   deleteInCache(url: string): Promise<void>;
 }
 
-export type ArtifactCacheType = "cache" | "indexeddb" | "cross-origin";
+export type ArtifactCacheType = "cache" | "indexeddb" | "cross-origin" | 
"opfs";
 
 export interface TensorCacheAccessOptions {
   cacheScope?: string;
@@ -194,7 +196,6 @@ class CrossOriginStorage {
     this.hashCache.set(url, hash);
   }
 
-  // eslint-disable-next-line @typescript-eslint/no-unused-vars
   async delete(_request: RequestLike): Promise<void> {
     // Cross-origin storage extension currently has no delete API.
     return;
@@ -549,6 +550,83 @@ export class ArtifactIndexedDBCache implements 
ArtifactCacheTemplate {
   }
 }
 
+/**
+ * Cache by Origin Private File System (OPFS).
+ */
+export class ArtifactOPFSCache implements ArtifactCacheTemplate {
+  private readonly store: OPFSStore;
+
+  constructor(scope: string) {
+    this.store = new OPFSStore(scope);
+  }
+
+  static isAvailable(): boolean {
+    return OPFSStore.isAvailable();
+  }
+
+  async fetchWithCache(
+    url: string,
+    storetype?: string,
+    signal?: AbortSignal,
+  ): Promise<any> {
+    await this.addToCache(url, storetype, signal);
+    const cachedResponse = await this.store.read(url);
+    if (cachedResponse === undefined) {
+      throw new Error("ArtifactOPFSCache failed to fetch: " + url);
+    }
+    return this.responseToStoreType(cachedResponse, storetype);
+  }
+
+  async addToCache(
+    url: string,
+    _storetype?: string,
+    signal?: AbortSignal,
+  ): Promise<void> {
+    if (await this.store.has(url)) {
+      return;
+    }
+    const request = new Request(
+      url,
+      signal ? { ...DEFAULT_FETCH_OPTIONS, signal } : DEFAULT_FETCH_OPTIONS,
+    );
+    const response = await fetch(request);
+    if (!response.ok) {
+      throw new Error(
+        `ArtifactOPFSCache: Unable to fetch ${url}, received status 
${response.status}`,
+      );
+    }
+    await this.store.write(url, response.clone());
+  }
+
+  async hasAllKeys(keys: string[]): Promise<boolean> {
+    const results = await Promise.all(
+      keys.map(async (key) => await this.store.has(key)),
+    );
+    return results.every((result) => result);
+  }
+
+  async deleteInCache(url: string): Promise<void> {
+    await this.store.remove(url);
+  }
+
+  private async responseToStoreType(
+    response: Response,
+    storetype?: StoreType,
+  ): Promise<any> {
+    if (storetype === undefined) {
+      return response;
+    }
+    const format = storetype.toLowerCase();
+    if (format === "json") {
+      return response.json();
+    }
+    if (format === "arraybuffer") {
+      return response.arrayBuffer();
+    }
+    return response;
+  }
+}
+
 /**
  * Cache by cross-origin storage extension.
  */
@@ -647,6 +725,9 @@ function normalizeCacheType(cacheType?: string): 
ArtifactCacheType {
   if (normalized === "cross-origin") {
     return "cross-origin";
   }
+  if (normalized === "opfs") {
+    return "opfs";
+  }
   console.error("Unsupported cacheType: " + cacheType + ", using default 
ArtifactCache.");
   return "cache";
 }
@@ -692,6 +773,9 @@ export function createArtifactCache(
       crossOriginFallbackWarningLogged = true;
     }
   }
+  if (cacheType === "opfs") {
+    return new ArtifactOPFSCache(scope);
+  }
   return new ArtifactCache(scope);
 }
 
@@ -701,7 +785,7 @@ export function createArtifactCache(
  *
  * @param tensorCacheUrl The cache url which links to the Tensor
  * @param cacheScope The scope identifier of the cache
- * @param cacheType The type of the cache: "cache", "indexedDB", or 
"cross-origin"
+ * @param cacheType The type of the cache: "cache", "indexedDB", 
"cross-origin", or "opfs"
  * @returns the result if the cache has Tensor
  */
 export async function hasTensorInCache(
@@ -739,7 +823,7 @@ export async function hasTensorInCache(
  *
  * @param cacheUrl The cacheUrl for the items
  * @param cacheScope The scope identifier of the cache
- * @param cacheType The type of the cache: "cache", "indexedDB", or 
"cross-origin"
+ * @param cacheType The type of the cache: "cache", "indexedDB", 
"cross-origin", or "opfs"
  */
 export async function deleteTensorCache(
   cacheUrl: string,
diff --git a/web/src/index.ts b/web/src/index.ts
index 32450a7779..925f24feb9 100644
--- a/web/src/index.ts
+++ b/web/src/index.ts
@@ -30,6 +30,7 @@ export {
   ArtifactCacheTemplate,
   ArtifactCache,
   ArtifactIndexedDBCache,
+  ArtifactOPFSCache,
   ArtifactCrossOriginStorageCache,
   createArtifactCache,
   hasTensorInCache,
diff --git a/web/src/opfs_store.ts b/web/src/opfs_store.ts
new file mode 100644
index 0000000000..828e2bfbf0
--- /dev/null
+++ b/web/src/opfs_store.ts
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+interface OPFSWritableFileStream extends WritableStream<Uint8Array> {
+  write(data: Blob | BufferSource | string): Promise<void>;
+  close(): Promise<void>;
+}
+
+interface OPFSFileHandle {
+  getFile(): Promise<Blob>;
+  createWritable(): Promise<OPFSWritableFileStream>;
+}
+
+interface OPFSDirectoryHandle {
+  getDirectoryHandle(
+    name: string,
+    options?: { create?: boolean },
+  ): Promise<OPFSDirectoryHandle>;
+  getFileHandle(
+    name: string,
+    options?: { create?: boolean },
+  ): Promise<OPFSFileHandle>;
+  removeEntry(name: string): Promise<void>;
+}
+
+interface OPFSStorageManager {
+  getDirectory?: () => Promise<OPFSDirectoryHandle>;
+}
+
+interface OPFSStoreMetadata {
+  url: string;
+  contentType?: string;
+}
+
+const HASH_ALGORITHM = "SHA-256";
+const OPFS_STORE_ROOT_DIRECTORY = "tvmjs-opfs-store";
+
+export class OPFSStore {
+  private readonly scope: string;
+  private directoryPromise?: Promise<OPFSDirectoryHandle>;
+
+  constructor(scope: string) {
+    this.scope = scope;
+  }
+
+  static isAvailable(): boolean {
+    const storage = OPFSStore.getStorageManager();
+    return storage !== undefined && typeof storage.getDirectory === "function";
+  }
+
+  async has(url: string): Promise<boolean> {
+    return (await this.read(url)) !== undefined;
+  }
+
+  async read(url: string): Promise<Response | undefined> {
+    const directory = await this.getScopedDirectory();
+    const baseName = await this.hashUrl(url);
+    const dataHandle = await this.getFileHandleIfExists(
+      directory,
+      `${baseName}.bin`,
+      false,
+    );
+    if (dataHandle === undefined) {
+      return undefined;
+    }
+    const dataBlob = await dataHandle.getFile();
+    const metadataHandle = await this.getFileHandleIfExists(
+      directory,
+      `${baseName}.meta.json`,
+      false,
+    );
+    let metadata: OPFSStoreMetadata | undefined = undefined;
+    if (metadataHandle !== undefined) {
+      metadata = await this.readMetadata(metadataHandle);
+      if (metadata?.url !== undefined && metadata.url !== url) {
+        throw new Error("OPFSStore: metadata URL does not match key URL.");
+      }
+    }
+    const headers =
+      metadata?.contentType !== undefined
+        ? { "content-type": metadata.contentType }
+        : undefined;
+    return new Response(dataBlob, headers ? { headers } : undefined);
+  }
+
+  async write(url: string, response: Response): Promise<void> {
+    const directory = await this.getScopedDirectory();
+    const baseName = await this.hashUrl(url);
+    const dataHandle = await directory.getFileHandle(`${baseName}.bin`, {
+      create: true,
+    });
+    const metadataHandle = await directory.getFileHandle(
+      `${baseName}.meta.json`,
+      { create: true },
+    );
+    const metadata: OPFSStoreMetadata = {
+      url,
+      contentType: response.headers.get("content-type") ?? undefined,
+    };
+    const writable = await dataHandle.createWritable();
+    if (response.body !== null) {
+      await response.body.pipeTo(writable);
+    } else {
+      await writable.write(await response.arrayBuffer());
+      await writable.close();
+    }
+    await this.writeFile(
+      metadataHandle,
+      new TextEncoder().encode(JSON.stringify(metadata)),
+    );
+  }
+
+  async remove(url: string): Promise<void> {
+    const directory = await this.getScopedDirectory();
+    const baseName = await this.hashUrl(url);
+    await this.removeEntryIfExists(directory, `${baseName}.bin`);
+    await this.removeEntryIfExists(directory, `${baseName}.meta.json`);
+  }
+
+  private static getStorageManager(): OPFSStorageManager | undefined {
+    if (typeof navigator === "undefined") {
+      return undefined;
+    }
+    return navigator.storage as unknown as OPFSStorageManager;
+  }
+
+  private async getScopedDirectory(): Promise<OPFSDirectoryHandle> {
+    if (this.directoryPromise !== undefined) {
+      return this.directoryPromise;
+    }
+    // Cache scoped directory handle to avoid repeated tree traversal
+    this.directoryPromise = (async () => {
+      const storage = OPFSStore.getStorageManager();
+      if (storage === undefined || typeof storage.getDirectory !== "function") 
{
+        throw new Error("OPFSStore: OPFS API unavailable.");
+      }
+      let directory = await storage.getDirectory();
+      directory = await 
directory.getDirectoryHandle(OPFS_STORE_ROOT_DIRECTORY, {
+        create: true,
+      });
+      const scopeParts = this.scope.split("/").filter((part) => part.length > 
0);
+      for (const part of scopeParts) {
+        directory = await directory.getDirectoryHandle(
+          encodeURIComponent(part),
+          { create: true },
+        );
+      }
+      return directory;
+    })();
+    return this.directoryPromise;
+  }
+
+  private async readMetadata(
+    fileHandle: OPFSFileHandle,
+  ): Promise<OPFSStoreMetadata | undefined> {
+    try {
+      const text = await (await fileHandle.getFile()).text();
+      const parsed = JSON.parse(text);
+      if (
+        parsed === undefined ||
+        parsed === null ||
+        typeof parsed !== "object" ||
+        typeof parsed.url !== "string"
+      ) {
+        throw new Error("OPFSStore: invalid metadata format.");
+      }
+      const metadata: OPFSStoreMetadata = {
+        url: parsed.url,
+      };
+      if (typeof parsed.contentType === "string") {
+        metadata.contentType = parsed.contentType;
+      }
+      return metadata;
+    } catch (err) {
+      if (this.isNotFoundError(err)) {
+        // Treat metadata disappearance between lookup and read as a cache miss
+        return undefined;
+      }
+      throw err;
+    }
+  }
+
+  private async writeFile(
+    handle: OPFSFileHandle,
+    data: Blob | BufferSource | string,
+  ): Promise<void> {
+    const writable = await handle.createWritable();
+    await writable.write(data);
+    await writable.close();
+  }
+
+  private async getFileHandleIfExists(
+    directory: OPFSDirectoryHandle,
+    filename: string,
+    create: boolean,
+  ): Promise<OPFSFileHandle | undefined> {
+    try {
+      return await directory.getFileHandle(filename, { create });
+    } catch (err) {
+      if (this.isNotFoundError(err)) {
+        // NotFound maps to cache miss semantics
+        return undefined;
+      }
+      throw err;
+    }
+  }
+
+  private async removeEntryIfExists(
+    directory: OPFSDirectoryHandle,
+    filename: string,
+  ): Promise<void> {
+    try {
+      await directory.removeEntry(filename);
+    } catch (err) {
+      if (this.isNotFoundError(err)) {
+        // Delete is intentionally idempotent for missing entries
+        return;
+      }
+      throw err;
+    }
+  }
+
+  private async hashUrl(url: string): Promise<string> {
+    const textEncoder = new TextEncoder();
+    const input = textEncoder.encode(url);
+    if (
+      typeof crypto === "undefined" ||
+      crypto.subtle === undefined ||
+      typeof crypto.subtle.digest !== "function"
+    ) {
+      throw new Error("OPFSStore: crypto.subtle.digest is unavailable.");
+    }
+    const digest = await crypto.subtle.digest(HASH_ALGORITHM, input);
+    return Array.from(new Uint8Array(digest))
+      .map((byte) => byte.toString(16).padStart(2, "0"))
+      .join("");
+  }
+
+  private isNotFoundError(err: unknown): boolean {
+    if (err && typeof err === "object" && "name" in err) {
+      const name = (err as { name?: unknown }).name;
+      return name === "NotFoundError";
+    }
+    return false;
+  }
+}
diff --git a/web/src/runtime.ts b/web/src/runtime.ts
index a7b3a56f3e..078a0c7df2 100644
--- a/web/src/runtime.ts
+++ b/web/src/runtime.ts
@@ -1259,7 +1259,7 @@ export class Instance implements Disposable {
    * @param device The device to be fetched to.
    * @param options Options object.
    * @param cacheScope The scope identifier of the cache (legacy positional 
overload).
-   * @param cacheType The type of the cache: "cache", "indexeddb", or 
"cross-origin" (legacy positional overload).
+   * @param cacheType The type of the cache: "cache", "indexeddb", 
"cross-origin", or "opfs" (legacy positional overload).
    * @param signal An optional AbortSignal to abort the fetch (legacy 
positional overload).
    * @returns The meta data
    */

Reply via email to