diff --git a/materialious/android/app/build.gradle b/materialious/android/app/build.gradle index 9ad0aa93..9824dd06 100644 --- a/materialious/android/app/build.gradle +++ b/materialious/android/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "us.materialio.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 151 - versionName "1.10.10" + versionCode 152 + versionName "1.10.11" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/materialious/electron/materialious.metainfo.xml b/materialious/electron/materialious.metainfo.xml index 0db33502..13d29a65 100644 --- a/materialious/electron/materialious.metainfo.xml +++ b/materialious/electron/materialious.metainfo.xml @@ -68,7 +68,11 @@ - + + + https://github.com/Materialious/Materialious/releases/tag/1.10.11 + + https://github.com/Materialious/Materialious/releases/tag/1.10.10 diff --git a/materialious/electron/package-lock.json b/materialious/electron/package-lock.json index 4a1451a0..efede855 100644 --- a/materialious/electron/package-lock.json +++ b/materialious/electron/package-lock.json @@ -1,12 +1,12 @@ { "name": "Materialious", - "version": "1.10.10", + "version": "1.10.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Materialious", - "version": "1.10.10", + "version": "1.10.11", "license": "MIT", "dependencies": { "@capacitor-community/electron": "^5.0.0", @@ -22,7 +22,7 @@ "jsonfile": "^6.2.0" }, "devDependencies": { - "electron": "^38.1.0", + "electron": "^38.1.2", "electron-builder": "^26.0.12", "electron-rebuild": "^3.2.9", "typescript": "^5.9.2" @@ -2558,9 +2558,9 @@ } }, "node_modules/electron": { - "version": "38.1.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-38.1.0.tgz", - "integrity": "sha512-ypA8GF8RU4HD5pA1sa0/2U8k+92EPP2c7pX+3XbgB760F7OmqrFXtYkOilVw6HfV4+lk88XxqigmsUKTACQYoQ==", + "version": "38.1.2", + "resolved": "https://registry.npmjs.org/electron/-/electron-38.1.2.tgz", + "integrity": "sha512-WXUcN3W8h8NTTZViA3KNX0rV2YBU0X0mEUM3ubupXTDY4QtIN7tmiqYVOKSKpR2LckTmBWGuEeY4D6xVoffwKQ==", "dev": true, "hasInstallScript": true, "license": "MIT", diff --git a/materialious/electron/package.json b/materialious/electron/package.json index afdb6eda..5430b992 100644 --- a/materialious/electron/package.json +++ b/materialious/electron/package.json @@ -1,6 +1,6 @@ { "name": "Materialious", - "version": "1.10.10", + "version": "1.10.11", "description": "Modern material design for Invidious.", "author": { "name": "Ward Pearce", @@ -35,7 +35,7 @@ "jsonfile": "^6.2.0" }, "devDependencies": { - "electron": "^38.1.0", + "electron": "^38.1.2", "electron-builder": "^26.0.12", "electron-rebuild": "^3.2.9", "typescript": "^5.9.2" @@ -44,4 +44,4 @@ "capacitor", "electron" ] -} \ No newline at end of file +} diff --git a/materialious/electron/src/index.ts b/materialious/electron/src/index.ts index 642bc1e3..dc765dca 100644 --- a/materialious/electron/src/index.ts +++ b/materialious/electron/src/index.ts @@ -74,75 +74,91 @@ app.on('activate', async function () { }); // Place all ipc or other electron api calls and custom functionality under this line -ipcMain.handle( - 'generatePoToken', - async (_, bgChallenge: any, requestKey: string, visitorData: string) => { - const youtubeUrl = 'https://www.youtube.com/'; +ipcMain.handle('generatePoToken', async (_, requestKey: string, visitorData: string) => { + const youtubeUrl = 'https://www.youtube.com/'; - const dom = new JSDOM( - '', - { - url: youtubeUrl, - referrer: youtubeUrl, - origin: youtubeUrl, - USER_AGENT - } - ); - - Object.assign(globalThis, { - window: dom.window, - document: dom.window.document, - location: dom.window.location, - origin: dom.window.origin - }); - - if (!Reflect.has(globalThis, 'navigator')) { - Object.defineProperty(globalThis, 'navigator', { value: dom.window.navigator }); + const dom = new JSDOM( + 'YouTube', + { + url: youtubeUrl, + referrer: youtubeUrl, + origin: youtubeUrl, + USER_AGENT } + ); - const interpreterUrl = - bgChallenge.interpreter_url.private_do_not_access_or_else_trusted_resource_url_wrapped_value; - const bgScriptResponse = await fetch(`https:${interpreterUrl}`); - const interpreterJavascript = await bgScriptResponse.text(); + Object.assign(globalThis, { + window: dom.window, + document: dom.window.document, + location: dom.window.location, + origin: dom.window.origin + }); - if (interpreterJavascript) { - new Function(interpreterJavascript)(); - } else throw new Error('Could not load VM'); - - const botguardClient = await BG.BotGuardClient.create({ - program: bgChallenge.program, - globalName: bgChallenge.global_name, - globalObj: globalThis - }); - - const webPoSignalOutput: WebPoSignalOutput = []; - const botguardResponse = await botguardClient.snapshot({ webPoSignalOutput }); - - const integrityTokenResponse = await fetch(buildURL('GenerateIT', true), { - method: 'POST', - headers: { - 'content-type': 'application/json+protobuf', - 'x-goog-api-key': GOOG_API_KEY, - 'x-user-agent': 'grpc-web-javascript/0.1' - }, - body: JSON.stringify([requestKey, botguardResponse]) - }); - - const integrityTokenResponseData = await integrityTokenResponse.json(); - - if (typeof integrityTokenResponseData[0] !== 'string') - throw new Error('Could not get integrity token'); - - const integrityToken = integrityTokenResponseData[0]; - - const integrityTokenBasedMinter = await BG.WebPoMinter.create( - { integrityToken }, - webPoSignalOutput - ); - - return await integrityTokenBasedMinter.mintAsWebsafeString(decodeURIComponent(visitorData)); + if (!Reflect.has(globalThis, 'navigator')) { + Object.defineProperty(globalThis, 'navigator', { value: dom.window.navigator }); } -); + + const challengeResponse = await fetch(buildURL('Create', true), { + method: 'POST', + headers: { + 'content-type': 'application/json+protobuf', + 'x-goog-api-key': GOOG_API_KEY, + 'x-user-agent': 'grpc-web-javascript/0.1' + }, + body: JSON.stringify([requestKey]) + }); + + const challengeResponseData = await challengeResponse.json(); + const bgChallenge = BG.Challenge.parseChallengeData(challengeResponseData); + + if (!bgChallenge) throw new Error('Unable to parse challenge data'); + + const interpreterJavascript = + bgChallenge.interpreterJavascript.privateDoNotAccessOrElseSafeScriptWrappedValue; + + if (!interpreterJavascript) { + throw new Error( + `Could not get integrity token. Interpreter Hash: ${bgChallenge.interpreterHash}` + ); + } + if (interpreterJavascript) { + new Function(interpreterJavascript)(); + } else throw new Error('Could not load VM'); + + const botguardClient = await BG.BotGuardClient.create({ + program: bgChallenge.program, + globalName: bgChallenge.globalName, + globalObj: globalThis + }); + + const webPoSignalOutput: WebPoSignalOutput = []; + const botguardResponse = await botguardClient.snapshot({ webPoSignalOutput }); + + const integrityTokenResponse = await fetch(buildURL('GenerateIT', true), { + method: 'POST', + headers: { + 'content-type': 'application/json+protobuf', + 'x-goog-api-key': GOOG_API_KEY, + 'x-user-agent': 'grpc-web-javacript/0.1' + }, + body: JSON.stringify([requestKey, botguardResponse]) + }); + + const integrityTokenResponseData = await integrityTokenResponse.json(); + const integrityToken = integrityTokenResponseData[0] as string | undefined; + + if (!integrityToken) { + throw new Error( + `Could not get integrity token. Interpreter Hash: ${bgChallenge.interpreterHash}` + ); + } + + const integrityTokenBasedMinter = await BG.WebPoMinter.create( + { integrityToken }, + webPoSignalOutput + ); + return await integrityTokenBasedMinter.mintAsWebsafeString(decodeURIComponent(visitorData)); +}); ipcMain.handle('setAllowInsecureSSL', async (_, allow) => { allowInsecureSSL = allow; diff --git a/materialious/electron/src/preload.ts b/materialious/electron/src/preload.ts index b27e251d..78ac20f2 100644 --- a/materialious/electron/src/preload.ts +++ b/materialious/electron/src/preload.ts @@ -1,11 +1,9 @@ -import { DescrambledChallenge } from 'bgutils-js'; - const { contextBridge, ipcRenderer } = require('electron'); require('./rt/electron-rt'); contextBridge.exposeInMainWorld('electronAPI', { - generatePoToken: (bgChallenge: DescrambledChallenge, requestKey: string, visitorData: string) => - ipcRenderer.invoke('generatePoToken', bgChallenge, requestKey, visitorData), + generatePoToken: (requestKey: string, visitorData: string) => + ipcRenderer.invoke('generatePoToken', requestKey, visitorData), setAllowInsecureSSL: async (allow: boolean) => { return await ipcRenderer.invoke('setAllowInsecureSSL', allow); }, diff --git a/materialious/package-lock.json b/materialious/package-lock.json index 1aeae27d..390f5223 100644 --- a/materialious/package-lock.json +++ b/materialious/package-lock.json @@ -1,12 +1,12 @@ { "name": "materialious", - "version": "1.10.10", + "version": "1.10.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "materialious", - "version": "1.10.10", + "version": "1.10.11", "hasInstallScript": true, "dependencies": { "@capacitor-community/electron": "^5.0.1", @@ -15,15 +15,15 @@ "@capacitor/app": "^7.1.0", "@capacitor/browser": "^7.0.0", "@capacitor/clipboard": "^7.0.0", - "@capacitor/core": "^7.0.0", + "@capacitor/core": "^7.4.3", "@capacitor/screen-orientation": "^7.0.0", "beercss": "^3.8.0", "bgutils-js": "^3.2.0", "capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz", "fuse.js": "^7.0.0", - "googlevideo": "^3.0.0", + "googlevideo": "^4.0.4", "he": "^1.2.0", - "human-number": "^2.0.4", + "human-number": "^2.0.6", "i18next": "^25.5.0", "iso-3166": "^4.3.0", "iso-639-1": "^3.1.5", @@ -51,7 +51,7 @@ "@types/mousetrap": "^1.6.15", "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.18.0", - "@vite-pwa/sveltekit": "^0.6.6", + "@vite-pwa/sveltekit": "^1.0.0", "eslint": "^8.56.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-svelte": "^3.11.0", @@ -79,49 +79,47 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", + "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", - "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.10", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.10", - "@babel/parser": "^7.26.10", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.10", - "@babel/types": "^7.26.10", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -142,23 +140,21 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", - "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/parser": "^7.27.0", - "@babel/types": "^7.27.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" }, "engines": { @@ -166,29 +162,27 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", - "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/types": "^7.25.9" + "@babel/types": "^7.27.3" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", - "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/compat-data": "^7.26.8", - "@babel/helper-validator-option": "^7.25.9", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -203,7 +197,6 @@ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "yallist": "^3.0.2" } @@ -214,7 +207,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -224,23 +216,21 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.0.tgz", - "integrity": "sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", + "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-member-expression-to-functions": "^7.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/helper-replace-supers": "^7.26.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/traverse": "^7.27.0", + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.3", "semver": "^6.3.1" }, "engines": { @@ -256,20 +246,18 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.0.tgz", - "integrity": "sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", + "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-annotate-as-pure": "^7.27.1", "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, @@ -286,70 +274,100 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", - "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", - "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -359,41 +377,38 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", - "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/types": "^7.25.9" + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", - "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", - "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-wrap-function": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -403,16 +418,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", - "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/traverse": "^7.26.5" + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -422,35 +436,33 @@ } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", - "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, "license": "MIT", "engines": { @@ -458,56 +470,52 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", - "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", + "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", - "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", - "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/types": "^7.27.0" + "@babel/types": "^7.28.4" }, "bin": { "parser": "bin/babel-parser.js" @@ -517,15 +525,14 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", - "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", + "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -535,14 +542,13 @@ } }, "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", - "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -552,14 +558,13 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", - "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -569,16 +574,15 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", - "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/plugin-transform-optional-chaining": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -588,15 +592,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", - "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", + "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -611,7 +614,6 @@ "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" }, @@ -620,14 +622,13 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", - "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -637,14 +638,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", - "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -659,7 +659,6 @@ "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -672,14 +671,13 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", - "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -689,16 +687,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", - "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5", - "@babel/helper-remap-async-to-generator": "^7.25.9", - "@babel/traverse": "^7.26.8" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -708,16 +705,15 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", - "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-remap-async-to-generator": "^7.25.9" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -727,14 +723,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", - "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -744,14 +739,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.0.tgz", - "integrity": "sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz", + "integrity": "sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -761,15 +755,14 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", - "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -779,15 +772,14 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", - "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-class-features-plugin": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -797,19 +789,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", - "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", + "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9", - "@babel/traverse": "^7.25.9", - "globals": "^11.1.0" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.4" }, "engines": { "node": ">=6.9.0" @@ -818,27 +809,15 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-classes/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", - "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/template": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -848,14 +827,14 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", - "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", + "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -865,15 +844,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", - "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -883,14 +861,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", - "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -900,15 +877,14 @@ } }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", - "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -918,14 +894,30 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", - "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", + "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -935,14 +927,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", - "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", + "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -952,14 +943,13 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", - "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -969,15 +959,14 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz", - "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -987,16 +976,15 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", - "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1006,14 +994,13 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", - "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1023,14 +1010,13 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", - "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1040,14 +1026,13 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", - "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", + "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1057,14 +1042,13 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", - "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1074,15 +1058,14 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", - "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1092,15 +1075,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", - "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1110,17 +1092,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", - "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", + "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1130,15 +1111,14 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", - "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1148,15 +1128,14 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", - "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1166,14 +1145,13 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", - "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1183,14 +1161,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.26.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", - "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1200,14 +1177,13 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", - "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1217,16 +1193,17 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", - "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", + "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/plugin-transform-parameters": "^7.25.9" + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.4" }, "engines": { "node": ">=6.9.0" @@ -1236,15 +1213,14 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", - "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1254,14 +1230,13 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", - "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1271,15 +1246,14 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", - "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1289,14 +1263,13 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", - "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1306,15 +1279,14 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", - "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1324,16 +1296,15 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", - "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1343,14 +1314,13 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", - "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1360,15 +1330,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.0.tgz", - "integrity": "sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", + "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5", - "regenerator-transform": "^0.15.2" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1378,15 +1346,14 @@ } }, "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", - "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1396,14 +1363,13 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", - "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1413,14 +1379,13 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", - "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1430,15 +1395,14 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", - "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1448,14 +1412,13 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", - "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1465,14 +1428,13 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz", - "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1482,14 +1444,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.0.tgz", - "integrity": "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1499,14 +1460,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", - "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1516,15 +1476,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", - "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1534,15 +1493,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", - "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1552,15 +1510,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", - "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1570,81 +1527,81 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", - "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz", + "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/compat-data": "^7.26.8", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-plugin-utils": "^7.26.5", - "@babel/helper-validator-option": "^7.25.9", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/compat-data": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.26.0", - "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.25.9", - "@babel/plugin-transform-async-generator-functions": "^7.26.8", - "@babel/plugin-transform-async-to-generator": "^7.25.9", - "@babel/plugin-transform-block-scoped-functions": "^7.26.5", - "@babel/plugin-transform-block-scoping": "^7.25.9", - "@babel/plugin-transform-class-properties": "^7.25.9", - "@babel/plugin-transform-class-static-block": "^7.26.0", - "@babel/plugin-transform-classes": "^7.25.9", - "@babel/plugin-transform-computed-properties": "^7.25.9", - "@babel/plugin-transform-destructuring": "^7.25.9", - "@babel/plugin-transform-dotall-regex": "^7.25.9", - "@babel/plugin-transform-duplicate-keys": "^7.25.9", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", - "@babel/plugin-transform-dynamic-import": "^7.25.9", - "@babel/plugin-transform-exponentiation-operator": "^7.26.3", - "@babel/plugin-transform-export-namespace-from": "^7.25.9", - "@babel/plugin-transform-for-of": "^7.26.9", - "@babel/plugin-transform-function-name": "^7.25.9", - "@babel/plugin-transform-json-strings": "^7.25.9", - "@babel/plugin-transform-literals": "^7.25.9", - "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", - "@babel/plugin-transform-member-expression-literals": "^7.25.9", - "@babel/plugin-transform-modules-amd": "^7.25.9", - "@babel/plugin-transform-modules-commonjs": "^7.26.3", - "@babel/plugin-transform-modules-systemjs": "^7.25.9", - "@babel/plugin-transform-modules-umd": "^7.25.9", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", - "@babel/plugin-transform-new-target": "^7.25.9", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", - "@babel/plugin-transform-numeric-separator": "^7.25.9", - "@babel/plugin-transform-object-rest-spread": "^7.25.9", - "@babel/plugin-transform-object-super": "^7.25.9", - "@babel/plugin-transform-optional-catch-binding": "^7.25.9", - "@babel/plugin-transform-optional-chaining": "^7.25.9", - "@babel/plugin-transform-parameters": "^7.25.9", - "@babel/plugin-transform-private-methods": "^7.25.9", - "@babel/plugin-transform-private-property-in-object": "^7.25.9", - "@babel/plugin-transform-property-literals": "^7.25.9", - "@babel/plugin-transform-regenerator": "^7.25.9", - "@babel/plugin-transform-regexp-modifiers": "^7.26.0", - "@babel/plugin-transform-reserved-words": "^7.25.9", - "@babel/plugin-transform-shorthand-properties": "^7.25.9", - "@babel/plugin-transform-spread": "^7.25.9", - "@babel/plugin-transform-sticky-regex": "^7.25.9", - "@babel/plugin-transform-template-literals": "^7.26.8", - "@babel/plugin-transform-typeof-symbol": "^7.26.7", - "@babel/plugin-transform-unicode-escapes": "^7.25.9", - "@babel/plugin-transform-unicode-property-regex": "^7.25.9", - "@babel/plugin-transform-unicode-regex": "^7.25.9", - "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.0", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.3", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.28.0", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.3", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.11.0", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.40.0", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "engines": { @@ -1660,7 +1617,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -1671,7 +1627,6 @@ "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -1691,62 +1646,48 @@ } }, "node_modules/@babel/template": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", - "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", - "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.27.0", - "@babel/parser": "^7.27.0", - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/types": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", - "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -2137,9 +2078,9 @@ } }, "node_modules/@capacitor/core": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.4.2.tgz", - "integrity": "sha512-akCf9A1FUR8AWTtmgGjHEq6LmGsjA2U7igaJ9PxiCBfyxKqlDbuGHrlNdpvHEjV5tUPH3KYtkze6gtFcNKPU9A==", + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.4.3.tgz", + "integrity": "sha512-wCWr8fQ9Wxn0466vPg7nMn0tivbNVjNy1yL4GvDSIZuZx7UpU2HeVGNe9QjN/quEd+YLRFeKEBLBw619VqUiNg==", "license": "MIT", "dependencies": { "tslib": "^2.1.0" @@ -2729,17 +2670,24 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -2751,22 +2699,12 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/source-map": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -2779,9 +2717,9 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -2888,7 +2826,6 @@ "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", @@ -2914,7 +2851,6 @@ "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "serialize-javascript": "^6.0.1", "smob": "^1.0.0", @@ -2933,12 +2869,11 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", - "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -2957,12 +2892,11 @@ } }, "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -3263,7 +3197,6 @@ "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "ejs": "^3.1.6", "json5": "^2.2.0", @@ -3277,7 +3210,6 @@ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "sourcemap-codec": "^1.4.8" } @@ -3633,8 +3565,7 @@ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/slice-ansi": { "version": "4.0.0", @@ -3647,8 +3578,7 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.18.0", @@ -3851,25 +3781,25 @@ "license": "ISC" }, "node_modules/@vite-pwa/sveltekit": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@vite-pwa/sveltekit/-/sveltekit-0.6.8.tgz", - "integrity": "sha512-KCrADea4HajwOIJPMB/tKW/x6Xa7X2NiNoWJ5MoggNGguSFQfmtclNc9ejNuXkI7uPNLUvH2zaFmsZRrPl+Tdg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@vite-pwa/sveltekit/-/sveltekit-1.0.0.tgz", + "integrity": "sha512-Tv2Bb0EtXlkYQ/7sFSaK69KYcRJiybGvQbJOcdwna+GngCPAM1g1EsvKQ5Be+r7WqtNJfCzKnMhVVbOGxXjF5A==", "dev": true, "license": "MIT", "dependencies": { "kolorist": "^1.8.0", - "tinyglobby": "^0.2.9" + "tinyglobby": "^0.2.9", + "vite-plugin-pwa": "^1.0.0" }, "engines": { - "node": ">=16.14 || >=18.13" + "node": ">=18.13" }, "funding": { "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { "@sveltejs/kit": "^1.3.1 || ^2.0.1", - "@vite-pwa/assets-generator": "^0.2.6", - "vite-plugin-pwa": ">=0.21.2 <1" + "@vite-pwa/assets-generator": "^1.0.0" }, "peerDependenciesMeta": { "@vite-pwa/assets-generator": { @@ -4031,7 +3961,6 @@ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" @@ -4066,7 +3995,6 @@ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", @@ -4114,8 +4042,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/async-function": { "version": "1.0.0", @@ -4123,7 +4050,6 @@ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" } @@ -4149,7 +4075,6 @@ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -4188,15 +4113,14 @@ "license": "Apache-2.0" }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", - "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.4", + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { @@ -4209,35 +4133,32 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", - "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3", - "core-js-compat": "^3.40.0" + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", - "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.4" + "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -4347,6 +4268,16 @@ ], "license": "MIT" }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.6.tgz", + "integrity": "sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/beercss": { "version": "3.10.8", "resolved": "https://registry.npmjs.org/beercss/-/beercss-3.10.8.tgz", @@ -4462,9 +4393,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.26.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz", + "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==", "dev": true, "funding": [ { @@ -4481,12 +4412,12 @@ } ], "license": "MIT", - "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "baseline-browser-mapping": "^2.8.3", + "caniuse-lite": "^1.0.30001741", + "electron-to-chromium": "^1.5.218", + "node-releases": "^2.0.21", + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -4509,8 +4440,7 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/call-bind": { "version": "1.0.8", @@ -4600,9 +4530,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001716", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001716.tgz", - "integrity": "sha512-49/c1+x3Kwz7ZIWt+4DvK3aMJy9oYXXG6/97JKsnjdCk/6n9vVyWL8NAwVt95Lwt9eigI10Hl782kDfZUUlRXw==", + "version": "1.0.30001743", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz", + "integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==", "dev": true, "funding": [ { @@ -4618,8 +4548,7 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "CC-BY-4.0", - "peer": true + "license": "CC-BY-4.0" }, "node_modules/capacitor-nodejs": { "version": "1.0.0-beta.9", @@ -4835,7 +4764,6 @@ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4.0.0" } @@ -5112,8 +5040,7 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", @@ -5126,14 +5053,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.42.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.42.0.tgz", - "integrity": "sha512-bQasjMfyDGyaeWKBIu33lHh9qlSR0MFE/Nmc6nMjf/iU9b3rSMdAYz1Baxrv4lPdGUsTqZudHA4jIGSJy0SWZQ==", + "version": "3.45.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz", + "integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "browserslist": "^4.24.4" + "browserslist": "^4.25.3" }, "funding": { "type": "opencollective", @@ -5237,7 +5163,6 @@ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -5256,7 +5181,6 @@ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -5275,7 +5199,6 @@ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -5440,7 +5363,6 @@ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -5710,7 +5632,6 @@ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "jake": "^10.8.5" }, @@ -5731,12 +5652,11 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.145", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.145.tgz", - "integrity": "sha512-pZ5EcTWRq/055MvSBgoFEyKf2i4apwfoqJbK/ak2jnFq8oHjZ+vzc3AhRcz37Xn+ZJfL58R666FLJx0YOK9yTw==", + "version": "1.5.222", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.222.tgz", + "integrity": "sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/elementtree": { "version": "0.1.7", @@ -5796,29 +5716,28 @@ } }, "node_modules/es-abstract": { - "version": "1.23.9", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", - "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.0", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", @@ -5830,21 +5749,24 @@ "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", + "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.0", + "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.3", + "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.3", + "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", @@ -5853,7 +5775,7 @@ "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.18" + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -5913,7 +5835,6 @@ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", @@ -6197,8 +6118,7 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", @@ -6294,9 +6214,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, "funding": [ { @@ -6308,8 +6228,7 @@ "url": "https://opencollective.com/fastify" } ], - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/fastq": { "version": "1.19.1", @@ -6349,7 +6268,6 @@ "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "minimatch": "^5.0.1" } @@ -6360,7 +6278,6 @@ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6519,7 +6436,6 @@ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-callable": "^1.2.7" }, @@ -6674,7 +6590,6 @@ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -6696,7 +6611,6 @@ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6716,7 +6630,6 @@ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -6760,8 +6673,7 @@ "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/get-pkg-repo": { "version": "4.2.1", @@ -6883,7 +6795,6 @@ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -7051,7 +6962,6 @@ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -7085,9 +6995,9 @@ } }, "node_modules/googlevideo": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/googlevideo/-/googlevideo-3.0.0.tgz", - "integrity": "sha512-8LGFjbZFG4RCsyhMbjX2+IlU5Suj94FeQr1JandPSsKfAMrqL08pOoQsBYl/5P+bqIFm0wQEVpKIhm5wpiekwg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/googlevideo/-/googlevideo-4.0.4.tgz", + "integrity": "sha512-S/rfuoPBI+qXCEUPJeVhXsHoISMgVhOz8hHSpGWa0OztfHhh+g9EKaEcqAb/+ttO7meoNQNqIy9dfIpz7HPc4g==", "funding": [ "https://github.com/sponsors/LuanRT" ], @@ -7172,7 +7082,6 @@ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -7208,7 +7117,6 @@ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "dunder-proto": "^1.0.0" }, @@ -7281,9 +7189,9 @@ } }, "node_modules/human-number": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/human-number/-/human-number-2.0.4.tgz", - "integrity": "sha512-OENvA941poJU1VGR6s5Nf/GpYNPE+81lmHkIVLO9FgiyHxB+BSlVOJV3lnItk5tfHzcEbZv3kTQrzpZK0+ExRA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/human-number/-/human-number-2.0.6.tgz", + "integrity": "sha512-ZqC6hloPr6qI+HP14ls2ia/iLDH9UBOYLKYlS1d3F7qz+cwNAX8t0SdQq1GF4CHpS+hU2ElVxPUh89swOymPPQ==", "license": "MIT", "dependencies": { "round-to": "~5.0.0" @@ -7328,8 +7236,7 @@ "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/ieee754": { "version": "1.2.1", @@ -7432,7 +7339,6 @@ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", @@ -7448,7 +7354,6 @@ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -7474,7 +7379,6 @@ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", @@ -7495,7 +7399,6 @@ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "has-bigints": "^1.0.2" }, @@ -7512,7 +7415,6 @@ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -7530,7 +7432,6 @@ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -7560,7 +7461,6 @@ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", @@ -7579,7 +7479,6 @@ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" @@ -7622,7 +7521,6 @@ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3" }, @@ -7648,7 +7546,6 @@ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "get-proto": "^1.0.0", @@ -7690,7 +7587,6 @@ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -7703,8 +7599,20 @@ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true, + "license": "MIT" + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, "license": "MIT", - "peer": true + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/is-number": { "version": "7.0.0", @@ -7722,7 +7630,6 @@ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -7789,7 +7696,6 @@ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", @@ -7809,7 +7715,6 @@ "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7820,7 +7725,6 @@ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -7834,7 +7738,6 @@ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3" }, @@ -7864,7 +7767,6 @@ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -7882,7 +7784,6 @@ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", @@ -7914,7 +7815,6 @@ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "which-typed-array": "^1.1.16" }, @@ -7943,7 +7843,6 @@ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -7957,7 +7856,6 @@ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3" }, @@ -7974,7 +7872,6 @@ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" @@ -8046,17 +7943,15 @@ } }, "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", + "async": "^3.2.6", "filelist": "^1.0.4", - "minimatch": "^3.1.2" + "picocolors": "^1.1.1" }, "bin": { "jake": "bin/cli.js" @@ -8065,32 +7960,6 @@ "node": ">=10" } }, - "node_modules/jake/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/jake/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/jintr": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jintr/-/jintr-3.3.1.tgz", @@ -8129,7 +7998,6 @@ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jsesc": "bin/jsesc" }, @@ -8162,8 +8030,7 @@ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)", - "peer": true + "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -8212,7 +8079,6 @@ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -8258,7 +8124,6 @@ "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -8338,7 +8203,6 @@ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -8434,8 +8298,7 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lodash.ismatch": { "version": "4.4.0", @@ -8456,8 +8319,7 @@ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -9117,12 +8979,11 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", + "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/normalize-package-data": { "version": "3.0.3", @@ -9159,7 +9020,6 @@ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -9183,7 +9043,6 @@ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -9298,7 +9157,6 @@ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", @@ -9726,7 +9584,6 @@ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" } @@ -9903,9 +9760,9 @@ "license": "ISC" }, "node_modules/prebuild-install/node_modules/tar-fs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9975,7 +9832,6 @@ "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^14.13.1 || >=16.0.0" }, @@ -10088,7 +9944,6 @@ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -10329,7 +10184,6 @@ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -10352,16 +10206,14 @@ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", - "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "regenerate": "^1.4.2" }, @@ -10369,17 +10221,6 @@ "node": ">=4" } }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, "node_modules/regexp-to-ast": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", @@ -10393,7 +10234,6 @@ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -10410,19 +10250,18 @@ } }, "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.3.1.tgz", + "integrity": "sha512-DzcswPr252wEr7Qz8AyAVbfyBDKLoYp6eRA1We2Fa9qirRFSdtkP5sHr3yglDKy2BbA0fd2T+j/CUSKes3FeVQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.0", + "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" + "unicode-match-property-value-ecmascript": "^2.2.1" }, "engines": { "node": ">=4" @@ -10433,8 +10272,7 @@ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/regjsparser": { "version": "0.12.0", @@ -10442,7 +10280,6 @@ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "jsesc": "~3.0.2" }, @@ -10456,7 +10293,6 @@ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jsesc": "bin/jsesc" }, @@ -10764,7 +10600,6 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -10945,7 +10780,6 @@ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -10986,7 +10820,6 @@ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" @@ -11004,7 +10837,6 @@ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -11047,7 +10879,6 @@ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "randombytes": "^2.1.0" } @@ -11090,7 +10921,6 @@ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -11107,7 +10937,6 @@ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", @@ -11177,7 +11006,6 @@ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -11198,7 +11026,6 @@ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -11216,7 +11043,6 @@ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -11236,7 +11062,6 @@ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -11399,8 +11224,7 @@ "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/source-map": { "version": "0.6.1", @@ -11428,7 +11252,6 @@ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -11440,8 +11263,7 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "deprecated": "Please use @jridgewell/sourcemap-codec instead", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/spdx-correct": { "version": "3.2.0", @@ -11511,6 +11333,20 @@ "axios": "^1.4.0" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/stream-buffers": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", @@ -11579,7 +11415,6 @@ "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -11608,7 +11443,6 @@ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -11631,7 +11465,6 @@ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -11651,7 +11484,6 @@ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11670,7 +11502,6 @@ "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", @@ -11686,7 +11517,6 @@ "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -11732,7 +11562,6 @@ "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" } @@ -11980,9 +11809,9 @@ } }, "node_modules/tar-fs": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz", - "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "license": "MIT", "dependencies": { @@ -12064,7 +11893,6 @@ "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -12083,8 +11911,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/text-decoder": { "version": "1.2.3", @@ -12351,7 +12178,6 @@ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -12367,7 +12193,6 @@ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", @@ -12388,7 +12213,6 @@ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", @@ -12411,7 +12235,6 @@ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -12461,7 +12284,6 @@ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", @@ -12496,7 +12318,6 @@ "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } @@ -12507,7 +12328,6 @@ "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -12517,23 +12337,21 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", - "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } @@ -12575,7 +12393,6 @@ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4", "yarn": "*" @@ -12601,7 +12418,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" @@ -12733,12 +12549,11 @@ } }, "node_modules/vite-plugin-pwa": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.21.2.tgz", - "integrity": "sha512-vFhH6Waw8itNu37hWUJxL50q+CBbNcMVzsKaYHQVrfxTt3ihk3PeLO22SbiP1UNWzcEPaTQv+YVxe4G0KOjAkg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.0.3.tgz", + "integrity": "sha512-/OpqIpUldALGxcsEnv/ekQiQ5xHkQ53wcoN5ewX4jiIDNGs3W+eNcI1WYZeyOLmzoEjg09D7aX0O89YGjen1aw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", @@ -12753,8 +12568,8 @@ "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { - "@vite-pwa/assets-generator": "^0.2.6", - "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", + "@vite-pwa/assets-generator": "^1.0.0", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "workbox-build": "^7.3.0", "workbox-window": "^7.3.0" }, @@ -12765,12 +12580,11 @@ } }, "node_modules/vite-plugin-pwa/node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ms": "^2.1.3" }, @@ -12788,8 +12602,7 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/vite/node_modules/@esbuild/aix-ppc64": { "version": "0.25.3", @@ -13332,7 +13145,6 @@ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", @@ -13353,7 +13165,6 @@ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", @@ -13382,7 +13193,6 @@ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -13409,7 +13219,6 @@ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", @@ -13449,7 +13258,6 @@ "integrity": "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "idb": "^7.0.1", "workbox-core": "7.3.0" @@ -13461,7 +13269,6 @@ "integrity": "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-core": "7.3.0" } @@ -13472,7 +13279,6 @@ "integrity": "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@apideck/better-ajv-errors": "^0.3.1", "@babel/core": "^7.24.4", @@ -13522,7 +13328,6 @@ "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "json-schema": "^0.4.0", "jsonpointer": "^5.0.0", @@ -13541,7 +13346,6 @@ "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-module-imports": "^7.10.4", "@rollup/pluginutils": "^3.1.0" @@ -13566,7 +13370,6 @@ "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rollup/pluginutils": "^3.1.0", "magic-string": "^0.25.7" @@ -13581,7 +13384,6 @@ "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "0.0.39", "estree-walker": "^1.0.1", @@ -13599,8 +13401,7 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/workbox-build/node_modules/ajv": { "version": "8.17.1", @@ -13608,7 +13409,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -13626,7 +13426,6 @@ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -13637,8 +13436,7 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/workbox-build/node_modules/fs-extra": { "version": "9.1.0", @@ -13646,7 +13444,6 @@ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -13664,7 +13461,6 @@ "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -13685,8 +13481,7 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/workbox-build/node_modules/magic-string": { "version": "0.25.9", @@ -13694,7 +13489,6 @@ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "sourcemap-codec": "^1.4.8" } @@ -13705,7 +13499,6 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -13719,7 +13512,6 @@ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" }, @@ -13733,7 +13525,6 @@ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -13748,9 +13539,9 @@ "version": "0.8.0-beta.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "deprecated": "The work that was done in this beta branch won't be included in future versions", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "whatwg-url": "^7.0.0" }, @@ -13764,7 +13555,6 @@ "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-stream": "^2.0.0", "temp-dir": "^2.0.0", @@ -13784,7 +13574,6 @@ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -13795,7 +13584,6 @@ "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", "dev": true, "license": "(MIT OR CC0-1.0)", - "peer": true, "engines": { "node": ">=10" }, @@ -13808,8 +13596,7 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true, - "license": "BSD-2-Clause", - "peer": true + "license": "BSD-2-Clause" }, "node_modules/workbox-build/node_modules/whatwg-url": { "version": "7.1.0", @@ -13817,7 +13604,6 @@ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -13830,7 +13616,6 @@ "integrity": "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-core": "7.3.0" } @@ -13840,8 +13625,7 @@ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz", "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/workbox-expiration": { "version": "7.3.0", @@ -13849,7 +13633,6 @@ "integrity": "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "idb": "^7.0.1", "workbox-core": "7.3.0" @@ -13861,7 +13644,6 @@ "integrity": "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-background-sync": "7.3.0", "workbox-core": "7.3.0", @@ -13875,7 +13657,6 @@ "integrity": "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-core": "7.3.0" } @@ -13886,7 +13667,6 @@ "integrity": "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-core": "7.3.0", "workbox-routing": "7.3.0", @@ -13899,7 +13679,6 @@ "integrity": "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-core": "7.3.0" } @@ -13910,7 +13689,6 @@ "integrity": "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-cacheable-response": "7.3.0", "workbox-core": "7.3.0", @@ -13926,7 +13704,6 @@ "integrity": "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-core": "7.3.0" } @@ -13937,7 +13714,6 @@ "integrity": "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-core": "7.3.0" } @@ -13948,7 +13724,6 @@ "integrity": "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "workbox-core": "7.3.0", "workbox-routing": "7.3.0" @@ -13959,8 +13734,7 @@ "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.3.0.tgz", "integrity": "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/workbox-window": { "version": "7.3.0", @@ -13968,7 +13742,6 @@ "integrity": "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/trusted-types": "^2.0.2", "workbox-core": "7.3.0" diff --git a/materialious/package.json b/materialious/package.json index c57ed81f..00253cdf 100644 --- a/materialious/package.json +++ b/materialious/package.json @@ -1,6 +1,6 @@ { "name": "materialious", - "version": "1.10.10", + "version": "1.10.11", "private": true, "scripts": { "dev": "vite dev", @@ -27,7 +27,7 @@ "@types/mousetrap": "^1.6.15", "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.18.0", - "@vite-pwa/sveltekit": "^0.6.6", + "@vite-pwa/sveltekit": "^1.0.0", "eslint": "^8.56.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-svelte": "^3.11.0", @@ -48,15 +48,15 @@ "@capacitor/app": "^7.1.0", "@capacitor/browser": "^7.0.0", "@capacitor/clipboard": "^7.0.0", - "@capacitor/core": "^7.0.0", + "@capacitor/core": "^7.4.3", "@capacitor/screen-orientation": "^7.0.0", "beercss": "^3.8.0", "bgutils-js": "^3.2.0", "capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz", "fuse.js": "^7.0.0", - "googlevideo": "^3.0.0", + "googlevideo": "^4.0.4", "he": "^1.2.0", - "human-number": "^2.0.4", + "human-number": "^2.0.6", "i18next": "^25.5.0", "iso-3166": "^4.3.0", "iso-639-1": "^3.1.5", @@ -70,4 +70,4 @@ "svelte-persisted-store": "^0.12.0", "youtubei.js": "^15.1.1" } -} \ No newline at end of file +} diff --git a/materialious/src/app.d.ts b/materialious/src/app.d.ts index 6848f211..247e8ecd 100644 --- a/materialious/src/app.d.ts +++ b/materialious/src/app.d.ts @@ -1,7 +1,5 @@ // See https://kit.svelte.dev/docs/types#app -import type { IGetChallengeResponse } from 'youtubei.js'; - // for information about these interfaces declare global { namespace App { @@ -13,11 +11,7 @@ declare global { } interface Window { electronAPI: { - generatePoToken: ( - bgChallenge: IGetChallengeResponse, - requestKey: string, - visitorData: string - ) => Promise; + generatePoToken: (requestKey: string, visitorData: string) => Promise; setAllowInsecureSSL: (allowInsecureSSL: boolean) => Promoise; doUpdateCheck: (disableAutoUpdate: boolean) => Promise; }; diff --git a/materialious/src/lib/android/youtube/minter.ts b/materialious/src/lib/android/youtube/minter.ts index d24db38a..bc27bfda 100644 --- a/materialious/src/lib/android/youtube/minter.ts +++ b/materialious/src/lib/android/youtube/minter.ts @@ -1,24 +1,45 @@ import { BG, buildURL, GOOG_API_KEY, type WebPoSignalOutput } from 'bgutils-js'; -import type { IBotguardChallenge } from 'youtubei.js'; export async function androidPoTokenMinter( - bgChallenge: IBotguardChallenge, requestKey: string, visitorData: string ): Promise { - const interpreterUrl = - bgChallenge.interpreter_url.private_do_not_access_or_else_trusted_resource_url_wrapped_value; - const bgScriptResponse = await fetch(`https:${interpreterUrl}`); - const interpreterJavascript = await bgScriptResponse.text(); + const challengeResponse = await fetch(buildURL('Create', true), { + method: 'POST', + headers: { + 'content-type': 'application/json+protobuf', + 'x-goog-api-key': GOOG_API_KEY, + 'x-user-agent': 'grpc-web-javascript/0.1' + }, + body: JSON.stringify([requestKey]) + }); - if (interpreterJavascript) { - new Function(interpreterJavascript)(); - } else throw new Error('Could not load VM'); + const challengeResponseData = await challengeResponse.json(); + const bgChallenge = BG.Challenge.parseChallengeData(challengeResponseData); + + if (!bgChallenge) throw new Error('Unable to parse challenge data'); + + const interpreterJavascript = + bgChallenge.interpreterJavascript.privateDoNotAccessOrElseSafeScriptWrappedValue; + + if (!interpreterJavascript) { + throw new Error( + `Could not get integrity token. Interpreter Hash: ${bgChallenge.interpreterHash}` + ); + } + + if (!document.getElementById(bgChallenge.interpreterHash)) { + const script = document.createElement('script'); + script.type = 'text/javascript'; + script.id = bgChallenge.interpreterHash; + script.textContent = interpreterJavascript; + document.head.appendChild(script); + } const botguardClient = await BG.BotGuardClient.create({ - program: bgChallenge.program, - globalName: bgChallenge.global_name, - globalObj: globalThis + globalObj: globalThis, + globalName: bgChallenge.globalName, + program: bgChallenge.program }); const webPoSignalOutput: WebPoSignalOutput = []; @@ -29,22 +50,23 @@ export async function androidPoTokenMinter( headers: { 'content-type': 'application/json+protobuf', 'x-goog-api-key': GOOG_API_KEY, - 'x-user-agent': 'grpc-web-javascript/0.1' + 'x-user-agent': 'grpc-web-javacript/0.1' }, body: JSON.stringify([requestKey, botguardResponse]) }); const integrityTokenResponseData = await integrityTokenResponse.json(); + const integrityToken = integrityTokenResponseData[0] as string | undefined; - if (typeof integrityTokenResponseData[0] !== 'string') - throw new Error('Could not get integrity token'); - - const integrityToken = integrityTokenResponseData[0]; + if (!integrityToken) { + throw new Error( + `Could not get integrity token. Interpreter Hash: ${bgChallenge.interpreterHash}` + ); + } const integrityTokenBasedMinter = await BG.WebPoMinter.create( { integrityToken }, webPoSignalOutput ); - return await integrityTokenBasedMinter.mintAsWebsafeString(decodeURIComponent(visitorData)); } diff --git a/materialious/src/lib/components/Player.svelte b/materialious/src/lib/components/Player.svelte index 4599a0c8..be69b2c6 100644 --- a/materialious/src/lib/components/Player.svelte +++ b/materialious/src/lib/components/Player.svelte @@ -7,7 +7,6 @@ import { Capacitor } from '@capacitor/core'; import { ScreenOrientation, type ScreenOrientationResult } from '@capacitor/screen-orientation'; import { error, type Page } from '@sveltejs/kit'; - import { HttpFetchPlugin } from '$lib/sabr/shakaHttpPlugin'; import ui from 'beercss'; import ISO6391 from 'iso-639-1'; import Mousetrap from 'mousetrap'; @@ -37,6 +36,7 @@ playerStatisticsByDefault, playerYouTubeJsFallback, playlistSettingsStore, + poTokenCacheStore, sponsorBlockCategoriesStore, sponsorBlockDisplayToastStore, sponsorBlockStore, @@ -47,7 +47,6 @@ themeColorStore } from '../store'; import { getDynamicTheme, setStatusBarColor } from '../theme'; - import { injectSABR } from '$lib/sabr'; import { patchYoutubeJs } from '$lib/patches/youtubejs'; import { playbackRates } from '$lib/player'; import { EndTimeElement } from '$lib/shaka-elements/endTime'; @@ -56,6 +55,8 @@ import { unsafeRandomItem } from '$lib/misc'; import type { PlayerEvents } from '$lib/player'; import { dashManifestDomainInclusion } from '$lib/android/youtube/dash'; + import { injectSabr } from '$lib/sabr'; + import type { SabrStreamingAdapter } from 'googlevideo/sabr-streaming-adapter'; interface Props { data: { video: VideoPlay; content: PhasedDescription; playlistId: string | null }; @@ -75,11 +76,11 @@ let snackBarAlert = $state(''); let originalOrigination: ScreenOrientationResult | undefined; let watchProgressTimeout: NodeJS.Timeout; - let playerElementResizeObserver: ResizeObserver | undefined; let showVideoRetry = $state(false); let player: shaka.Player; let shakaUi: shaka.ui.Overlay; + let sabrAdapter: SabrStreamingAdapter | null; const STORAGE_KEY_VOLUME = 'shaka-preferred-volume'; @@ -158,9 +159,8 @@ } if (selectedTrack) { - player.selectVariantTrack(selectedTrack, true); - HttpFetchPlugin.cacheManager.clearCache(); player.configure({ abr: { enabled: false } }); + player.selectVariantTrack(selectedTrack, true); } else { player.configure({ abr: { enabled: true } }); } @@ -294,8 +294,8 @@ async function loadVideo() { showVideoRetry = false; - // Will inject requirements for SABR if SABR is required. - playerElementResizeObserver = injectSABR(player, playerElement as HTMLMediaElement, data.video); + + sabrAdapter = injectSabr(data.video, player); try { document.getElementsByClassName('shaka-ad-info')[0].remove(); @@ -395,6 +395,7 @@ restoreQualityPreference(); restoreDefaultLanguage(); + if ($playerCCByDefault) { toggleSubtitles(); } @@ -424,17 +425,11 @@ return; } - HttpFetchPlugin.cacheManager.clearCache(); - player = new shaka.Player(); player.configure({ abr: { - enabled: true, - restrictions: { - maxWidth: 1920, - maxHeight: 1080 - } + enabled: true }, streaming: { failureCallback: (error: shaka.util.Error) => { @@ -442,7 +437,7 @@ player.retryStreaming(5); }, bufferingGoal: 120, - rebufferingGoal: 0.01, + rebufferingGoal: 2, bufferBehind: 300, retryParameters: { maxAttempts: 8, @@ -456,11 +451,9 @@ // Change instantly to stop video from being loud for a second restoreVolumePreference(); - shakaUi = new shaka.ui.Overlay( - player, - document.getElementById('shaka-container') as HTMLElement, - playerElement - ); + const playerContainer = document.getElementById('shaka-container') as HTMLElement; + + shakaUi = new shaka.ui.Overlay(player, playerContainer, playerElement); await player.attach(playerElement); @@ -471,6 +464,7 @@ }); shakaUi.configure({ + addBigPlayButton: Capacitor.getPlatform() === 'android', controlPanelElements: [ 'play_pause', Capacitor.getPlatform() === 'android' ? '' : 'volume', @@ -596,6 +590,17 @@ }); } + const volumeContainer = playerContainer.getElementsByClassName('shaka-volume-bar-container'); + volumeContainer[0]?.addEventListener('mousewheel', (event) => { + event.preventDefault(); + const delta = Math.sign((event as any).deltaY); + const newVolume = Math.max( + 0, + Math.min(1, (playerElement as HTMLMediaElement).volume - delta * 0.05) + ); + (playerElement as HTMLMediaElement).volume = newVolume; + }); + Mousetrap.bind('c', () => { toggleSubtitles(); return false; @@ -781,18 +786,12 @@ clearTimeout(watchProgressTimeout); } - HttpFetchPlugin.cacheManager.clearCache(); - - if (playerElementResizeObserver) { - playerElementResizeObserver.disconnect(); - } - - if (playerElement) { - playerElement.src = ''; - playerElement.load(); + if (sabrAdapter) { + sabrAdapter.dispose(); } if (player) { + player.unload(); player.destroy(); } diff --git a/materialious/src/lib/css/shaka-player-theme.css b/materialious/src/lib/css/shaka-player-theme.css index 6263473d..a3cecd58 100644 --- a/materialious/src/lib/css/shaka-player-theme.css +++ b/materialious/src/lib/css/shaka-player-theme.css @@ -1,11 +1,11 @@ .player-theme { - font-family: var(--font); - color: var(--on-surface); + font-family: var(--font) !important; + color: var(--on-surface) !important; } .player-theme .shaka-video-container * { - font-family: var(--font); - color: var(--on-surface); + font-family: var(--font) !important; + color: var(--on-surface) !important; } @media screen and (max-width: 650px) { diff --git a/materialious/src/lib/patches/youtubejs.ts b/materialious/src/lib/patches/youtubejs.ts index 514d0bb1..9c8379ff 100644 --- a/materialious/src/lib/patches/youtubejs.ts +++ b/materialious/src/lib/patches/youtubejs.ts @@ -7,7 +7,6 @@ import type { VideoBase, VideoPlay } from '$lib/api/model'; -import { fromFormat } from '$lib/sabr/formatKeyUtils'; import { interfaceRegionStore, poTokenCacheStore } from '$lib/store'; import { Capacitor } from '@capacitor/core'; import BG, { USER_AGENT } from 'bgutils-js'; @@ -24,40 +23,32 @@ export async function patchYoutubeJs(videoId: string): Promise { cache: new UniversalCache(false), location: get(interfaceRegionStore), user_agent: USER_AGENT, - enable_session_cache: false + player_id: '0004de42' }); const visitorData = youtube.session.context.client.visitorData ?? ''; const requestKey = 'O43z0dpjhgX20SCx4KAo'; - const challengeResponse = await youtube.getAttestationChallenge('ENGAGEMENT_TYPE_UNBOUND'); - - if (!challengeResponse.bg_challenge) throw new Error('Could not get challenge'); const platformMinter = Capacitor.getPlatform() === 'android' ? androidPoTokenMinter : window.electronAPI.generatePoToken; - const extraArgs: Record = { - playbackContext: { - contentPlaybackContext: { - vis: 0, - splay: false, - lactMilliseconds: '-1', - signatureTimestamp: youtube.session.player?.sts - } - }, - contentCheckOk: true, - racyCheckOk: true - }; - - const clientPlaybackNonce = Utils.generateRandomString(12); + const clientPlaybackNonce = Utils.generateRandomString(16); const watchEndpoint = new YTNodes.NavigationEndpoint({ watchEndpoint: { videoId } }); const rawPlayerResponse = await watchEndpoint.call(youtube.actions, { - ...extraArgs, - parse: false + contentCheckOk: true, + racyCheckOk: true, + playbackContext: { + adPlaybackContext: { + pyv: true + }, + contentPlaybackContext: { + signatureTimestamp: youtube.session.player?.sts + } + } }); const rawNextResponse = await watchEndpoint.call(youtube.actions, { override_endpoint: '/next' @@ -73,38 +64,39 @@ export async function patchYoutubeJs(videoId: string): Promise { } if (video.basic_info.is_live) { - poTokenCacheStore.set( - await platformMinter(challengeResponse.bg_challenge, requestKey, visitorData) - ); + poTokenCacheStore.set(await platformMinter(requestKey, visitorData)); } else { poTokenCacheStore.set(BG.PoToken.generateColdStartToken(visitorData)); - platformMinter(challengeResponse.bg_challenge, requestKey, visitorData).then((poToken) => - poTokenCacheStore.set(poToken) - ); + platformMinter(requestKey, visitorData).then((poToken) => poTokenCacheStore.set(poToken)); } let dashUri: string | undefined; - if (video.streaming_data) { - video.streaming_data.adaptive_formats.forEach((format) => { - const formatKey = fromFormat(format) || ''; - format.url = `https://sabr?___key=${formatKey}`; - format.signature_cipher = undefined; - format.decipher = () => format.url || ''; - return format; - }); + const isPostLiveDVR = + !!video.basic_info.is_post_live_dvr || + (video.basic_info.is_live_content && + !!(video.streaming_data?.dash_manifest_url || video.streaming_data?.hls_manifest_url)); + if (video.streaming_data) { if (video.basic_info.is_live) { dashUri = video.streaming_data.dash_manifest_url ? `${video.streaming_data.dash_manifest_url}/mpd_version/7` : video.streaming_data.hls_manifest_url; - } else if (video.streaming_data.dash_manifest_url && video.basic_info.is_post_live_dvr) { + } else if (isPostLiveDVR) { dashUri = video.streaming_data.hls_manifest_url ? video.streaming_data.hls_manifest_url // HLS is preferred for DVR streams. : `${video.streaming_data.dash_manifest_url}/mpd_version/7`; } else { - dashUri = `data:application/dash+xml;base64,${btoa(await video.toDash({ manifest_options: { captions_format: 'vtt' } }))}`; + dashUri = `data:application/dash+xml;base64,${btoa( + await video.toDash({ + manifest_options: { + is_sabr: true, + captions_format: 'vtt', + include_thumbnails: false + } + }) + )}`; } } diff --git a/materialious/src/lib/sabr/ShakaPlayerAdapter.ts b/materialious/src/lib/sabr/ShakaPlayerAdapter.ts new file mode 100644 index 00000000..2946778f --- /dev/null +++ b/materialious/src/lib/sabr/ShakaPlayerAdapter.ts @@ -0,0 +1,598 @@ +import shaka from 'shaka-player/dist/shaka-player.ui'; + +import { + FormatKeyUtils, + type CacheManager, + type RequestMetadataManager, + isGoogleVideoURL +} from 'googlevideo/utils'; + +import type { SabrFormat } from 'googlevideo/shared-types'; + +import { + SabrUmpProcessor, + type RequestFilter, + type ResponseFilter, + type SabrPlayerAdapter, + type SabrRequestMetadata, + type UmpProcessingResult +} from 'googlevideo/sabr-streaming-adapter'; + +import { + asMap, + createRecoverableError, + headersToGenericObject, + makeResponse +} from '$lib/sabr/helpers'; + +interface ShakaResponseArgs { + uri: string; + request: shaka.extern.Request; + requestType: shaka.net.NetworkingEngine.RequestType; + response: Response; + arrayBuffer?: Uint8Array | ArrayBuffer; +} + +export class ShakaPlayerAdapter implements SabrPlayerAdapter { + protected player: shaka.Player | null = null; + private requestMetadataManager?: RequestMetadataManager; + private cacheManager?: CacheManager; + private abortController?: AbortController; + + private requestFilter?: ( + type: shaka.net.NetworkingEngine.RequestType, + request: shaka.extern.Request, + context?: shaka.extern.RequestContext + ) => Promise; + private responseFilter?: ( + type: shaka.net.NetworkingEngine.RequestType, + response: shaka.extern.Response, + context?: shaka.extern.RequestContext + ) => Promise; + + public initialize( + player: shaka.Player, + requestMetadataManager: RequestMetadataManager, + cacheManager: CacheManager + ): void { + this.player = player; + this.requestMetadataManager = requestMetadataManager; + this.cacheManager = cacheManager; + + const networkingEngine = shaka.net.NetworkingEngine; + const schemes = ['http', 'https']; + + if (!shaka.net.HttpFetchPlugin.isSupported()) + throw new Error('The Fetch API is not supported in this browser.'); + + schemes.forEach((scheme) => { + networkingEngine.registerScheme( + scheme, + this.parseRequest.bind(this), + networkingEngine.PluginPriority.PREFERRED + ); + }); + } + + private parseRequest( + uri: string, + request: shaka.extern.Request, + requestType: shaka.net.NetworkingEngine.RequestType, + progressUpdated: shaka.extern.ProgressUpdated, + headersReceived: shaka.extern.HeadersReceived, + config: shaka.extern.SchemePluginConfig + ): shaka.extern.IAbortableOperation { + const headers = new Headers(); + asMap(request.headers).forEach((value, key) => { + headers.append(key as string, value); + }); + + const controller = new AbortController(); + this.abortController = controller; + + const init: RequestInit = { + body: (request.body as any) || undefined, + headers, + method: request.method, + signal: this.abortController.signal, + credentials: request.allowCrossSiteCredentials ? 'include' : undefined + }; + + const abortStatus = { canceled: false, timedOut: false }; + + const minBytes = config.minBytesForProgressEvents || 0; + + const pendingRequest = this.request( + uri, + request, + requestType, + init, + controller, + abortStatus, + progressUpdated, + headersReceived, + minBytes + ); + + const operation = new shaka.util.AbortableOperation(pendingRequest, () => { + abortStatus.canceled = true; + controller.abort(); + return Promise.resolve(); + }); + + const timeoutMs = request.retryParameters.timeout; + if (timeoutMs) { + const timer = new shaka.util.Timer(() => { + abortStatus.timedOut = true; + controller.abort(); + console.warn('[ShakaPlayerAdapter]', 'Request aborted due to timeout:', uri, requestType); + }); + timer.tickAfter(timeoutMs / 1000); + operation.finally(() => timer.stop()); + } + + return operation; + } + + private async handleCachedRequest( + requestMetadata: SabrRequestMetadata, + uri: string, + request: shaka.extern.Request, + progressUpdated: shaka.extern.ProgressUpdated, + headersReceived: shaka.extern.HeadersReceived, + requestType: shaka.net.NetworkingEngine.RequestType + ): Promise { + if (!requestMetadata.byteRange || !this.cacheManager) { + return null; + } + + const segmentKey = FormatKeyUtils.createSegmentCacheKeyFromMetadata(requestMetadata); + + let arrayBuffer = ( + requestMetadata.isInit + ? this.cacheManager.getInitSegment(segmentKey) + : this.cacheManager.getSegment(segmentKey) + )?.buffer as ArrayBuffer; + + if (!arrayBuffer) { + return null; + } + + if (requestMetadata.isInit) { + arrayBuffer = arrayBuffer.slice( + requestMetadata.byteRange.start, + requestMetadata.byteRange.end + 1 + ); + } + + const headers = { + 'content-type': requestMetadata.format?.mimeType?.split(';')[0] || '', + 'content-length': arrayBuffer.byteLength.toString(), + 'x-shaka-from-cache': 'true' + }; + + headersReceived(headers); + progressUpdated(0, arrayBuffer.byteLength, 0); + + return makeResponse(headers, arrayBuffer, 200, uri, uri, request, requestType); + } + + private async handleUmpResponse( + response: Response, + requestMetadata: SabrRequestMetadata, + uri: string, + request: shaka.extern.Request, + requestType: shaka.net.NetworkingEngine.RequestType, + progressUpdated: shaka.extern.ProgressUpdated, + abortController: AbortController, + minBytes: number + ): Promise { + let lastTime = Date.now(); + + const sabrUmpReader = new SabrUmpProcessor(requestMetadata, this.cacheManager); + + const checkResultIntegrity = (result: UmpProcessingResult) => { + if ( + !result.data && + (!!requestMetadata.error || + requestMetadata.streamInfo?.streamProtectionStatus?.status === 3) && + !requestMetadata.streamInfo?.sabrContextUpdate + ) { + throw createRecoverableError('Server streaming error', requestMetadata); + } + }; + + const shouldReturnEmptyResponse = () => { + return ( + requestMetadata.isSABR && + (requestMetadata.streamInfo?.redirect || requestMetadata.streamInfo?.sabrContextUpdate) + ); + }; + + // Fetch returning a ReadableStream response body is not currently + // supported by all browsers. + // Browser compatibility: + // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API + // If it is not supported, returning the whole segment when + // it's ready (as xhr) + if (!response.body) { + const arrayBuffer = await response.arrayBuffer(); + const currentTime = Date.now(); + + progressUpdated(currentTime - lastTime, arrayBuffer.byteLength, 0); + + const result = await sabrUmpReader.processChunk(new Uint8Array(arrayBuffer)); + + if (result) { + checkResultIntegrity(result); + return this.createShakaResponse({ + uri, + request, + requestType, + response, + arrayBuffer: result.data + }); + } + + if (shouldReturnEmptyResponse()) { + return this.createShakaResponse({ + uri, + request, + requestType, + response, + arrayBuffer: undefined + }); + } + + throw createRecoverableError('Empty response with no redirect information', requestMetadata); + } else { + const reader = response.body.getReader(); + + let loaded = 0; + let lastLoaded = 0; + let contentLength; + + while (!abortController.signal.aborted) { + let readObj; + try { + readObj = await reader.read(); + } catch { + // If we abort the request while reading, we'll get an error here. Just ignore it. + break; + } + + const { value, done } = readObj; + + if (done) { + // If we got here, we read the whole response but there was no segment data; it means we must follow a + // redirect, or handle protocol updates. + if (shouldReturnEmptyResponse()) { + return this.createShakaResponse({ + uri, + request, + requestType, + response, + arrayBuffer: undefined + }); + } + throw createRecoverableError( + 'Empty response with no redirect information', + requestMetadata + ); + } + + const result = await sabrUmpReader.processChunk(value); + + const segmentInfo = sabrUmpReader.getSegmentInfo(); + + if (segmentInfo) { + if (!contentLength) { + contentLength = segmentInfo.mediaHeader.contentLength; + } + + loaded += segmentInfo.lastChunkSize || 0; + segmentInfo.lastChunkSize = 0; + } + + const currentTime = Date.now(); + const chunkSize = loaded - lastLoaded; + + // If the time between last time and this time we got + // progress event is long enough, or if a whole segment + // is downloaded, call progressUpdated(). + if ((currentTime - lastTime > 100 && chunkSize >= minBytes) || result) { + // If we have a result, check its integrity before attempting anything. + if (result) checkResultIntegrity(result); + if (contentLength) { + const numBytesRemaining = result ? 0 : parseInt(contentLength) - loaded; + try { + progressUpdated(currentTime - lastTime, chunkSize, numBytesRemaining); + } catch { + /** no-op */ + } finally { + lastLoaded = loaded; + lastTime = currentTime; + } + } + } + + if (result) { + abortController.abort(); + return this.createShakaResponse({ + uri, + request, + requestType, + response, + arrayBuffer: result.data + }); + } + } + + // Unreachable if the loop is aborted correctly. + throw createRecoverableError( + 'UMP stream processing was aborted but did not produce a result.', + requestMetadata + ); + } + } + + private async request( + uri: string, + request: shaka.extern.Request, + requestType: shaka.net.NetworkingEngine.RequestType, + init: RequestInit, + abortController: AbortController, + abortStatus: { canceled: boolean; timedOut: boolean }, + progressUpdated: shaka.extern.ProgressUpdated, + headersReceived: shaka.extern.HeadersReceived, + minBytes: number + ): Promise { + try { + const requestMetadata = this.requestMetadataManager?.getRequestMetadata(uri); + + // Check the cache first. + if (requestMetadata) { + const cachedResponse = await this.handleCachedRequest( + requestMetadata, + uri, + request, + progressUpdated, + headersReceived, + requestType + ); + if (cachedResponse) { + return cachedResponse; + } + } + + const response = await fetch(uri, init); + headersReceived(headersToGenericObject(response.headers)); + + if ( + requestMetadata && + init.method !== 'HEAD' && + response.headers.get('content-type') === 'application/vnd.yt-ump' + ) { + return this.handleUmpResponse( + response, + requestMetadata, + uri, + request, + requestType, + progressUpdated, + abortController, + minBytes + ); + } + + // Handle other requests normally. + const lastTime = Date.now(); + + const arrayBuffer = await response.arrayBuffer(); + const currentTime = Date.now(); + + progressUpdated(currentTime - lastTime, arrayBuffer.byteLength, 0); + + return this.createShakaResponse({ + uri, + request, + requestType, + response, + arrayBuffer + }); + } catch (error) { + if (abortStatus.canceled) { + throw new shaka.util.Error( + shaka.util.Error.Severity.RECOVERABLE, + shaka.util.Error.Category.NETWORK, + shaka.util.Error.Code.OPERATION_ABORTED, + uri, + requestType + ); + } else if (abortStatus.timedOut) { + throw new shaka.util.Error( + shaka.util.Error.Severity.RECOVERABLE, + shaka.util.Error.Category.NETWORK, + shaka.util.Error.Code.TIMEOUT, + uri, + requestType + ); + } + throw new shaka.util.Error( + shaka.util.Error.Severity.RECOVERABLE, + shaka.util.Error.Category.NETWORK, + shaka.util.Error.Code.HTTP_ERROR, + uri, + error, + requestType + ); + } + } + + public checkPlayerStatus(): asserts this is { player: shaka.Player } & this { + if (!this.player) { + throw new Error('Player not initialized'); + } + } + + public getPlayerTime() { + this.checkPlayerStatus(); + return this.player.getMediaElement()?.currentTime || 0; + } + + public getPlaybackRate() { + this.checkPlayerStatus(); + return this.player.getPlaybackRate(); + } + + public getBandwidthEstimate() { + this.checkPlayerStatus(); + return this.player.getStats().estimatedBandwidth; + } + + public getActiveTrackFormats( + activeFormat: SabrFormat, + sabrFormats: SabrFormat[] + ): { + videoFormat?: SabrFormat; + audioFormat?: SabrFormat; + } { + this.checkPlayerStatus(); + + const activeVariant = this.player + .getVariantTracks() + .find( + (track) => + FormatKeyUtils.getUniqueFormatId(activeFormat) === + (activeFormat.width ? track.originalVideoId : track.originalAudioId) + ); + + if (!activeVariant) { + return { videoFormat: undefined, audioFormat: undefined }; + } + + const formatMap = new Map( + sabrFormats.map((format) => [FormatKeyUtils.getUniqueFormatId(format), format]) + ); + + return { + videoFormat: activeVariant.originalVideoId + ? formatMap.get(activeVariant.originalVideoId) + : undefined, + audioFormat: activeVariant.originalAudioId + ? formatMap.get(activeVariant.originalAudioId) + : undefined + }; + } + + public registerRequestInterceptor(interceptor: RequestFilter): void { + this.checkPlayerStatus(); + + const networkingEngine = this.player.getNetworkingEngine(); + if (!networkingEngine) return; + + this.requestFilter = async (type, request, context) => { + if ( + type !== shaka.net.NetworkingEngine.RequestType.SEGMENT || + !isGoogleVideoURL(request.uris[0]) + ) + return; + + const modifiedRequest = await interceptor({ + headers: request.headers, + url: request.uris[0], + method: request.method, + segment: { + getStartTime: () => context?.segment?.getStartTime() ?? null, + isInit: () => !context?.segment + }, + body: request.body + }); + + if (modifiedRequest) { + request.uris = modifiedRequest.url ? [modifiedRequest.url] : request.uris; + request.method = modifiedRequest.method || request.method; + request.headers = modifiedRequest.headers || request.headers; + request.body = modifiedRequest.body || request.body; + } + }; + + networkingEngine.registerRequestFilter(this.requestFilter); + } + + public registerResponseInterceptor(interceptor: ResponseFilter): void { + this.checkPlayerStatus(); + const networkingEngine = this.player.getNetworkingEngine(); + if (!networkingEngine) return; + + this.responseFilter = async (type, response, context) => { + if ( + type !== shaka.net.NetworkingEngine.RequestType.SEGMENT || + !isGoogleVideoURL(response.uri) + ) + return; + + const modifiedResponse = await interceptor({ + url: response.originalRequest.uris[0], + method: response.originalRequest.method, + headers: response.headers, + data: response.data, + makeRequest: async (url: string, headers: Record) => { + const retryParameters = this.player!.getConfiguration().streaming.retryParameters; + const redirectRequest = shaka.net.NetworkingEngine.makeRequest([url], retryParameters); + Object.assign(redirectRequest.headers, headers); + + const requestOperation = networkingEngine.request(type, redirectRequest, context); + const redirectResponse = await requestOperation.promise; + + return { + url: redirectResponse.uri, + method: redirectResponse.originalRequest.method, + headers: redirectResponse.headers, + data: redirectResponse.data + }; + } + }); + + if (modifiedResponse) { + response.data = modifiedResponse.data ?? response.data; + Object.assign(response.headers, modifiedResponse.headers); + } + }; + + networkingEngine.registerResponseFilter(this.responseFilter); + } + + public createShakaResponse(args: ShakaResponseArgs): shaka.extern.Response { + return makeResponse( + headersToGenericObject(args.response.headers), + (args.arrayBuffer as any) || new ArrayBuffer(0), + args.response.status, + args.uri, + args.response.url, + args.request, + args.requestType + ); + } + + public dispose(): void { + if (this.abortController) { + this.abortController.abort(); + this.abortController = undefined; + } + + if (this.player) { + const networkingEngine = this.player.getNetworkingEngine(); + + if (networkingEngine && this.requestFilter && this.responseFilter) { + networkingEngine.unregisterRequestFilter(this.requestFilter); + networkingEngine.unregisterResponseFilter(this.responseFilter); + } + + shaka.net.NetworkingEngine.unregisterScheme('http'); + shaka.net.NetworkingEngine.unregisterScheme('https'); + + this.player = null; + } + } +} diff --git a/materialious/src/lib/sabr/cacheHelper.ts b/materialious/src/lib/sabr/cacheHelper.ts deleted file mode 100644 index 9296f26f..00000000 --- a/materialious/src/lib/sabr/cacheHelper.ts +++ /dev/null @@ -1,74 +0,0 @@ -import type shaka from 'shaka-player/dist/shaka-player.ui'; -import type { Misc } from 'youtubei.js'; - -import type { SabrStreamingContext } from './shakaHttpPlugin'; -import { HttpFetchPlugin } from './shakaHttpPlugin'; -import { createSegmentCacheKey, createSegmentCacheKeyFromContext } from './formatKeyUtils'; -import type { Segment } from './sabrUmpParser'; - -/** - * Caches a segment with its associated format - * @param segment - The segment to cache - * @param format - The format object - */ -export function cacheSegment(segment: Segment, format: Misc.Format) { - const isInit = segment.mediaHeader.isInitSeg; - const segmentKey = createSegmentCacheKey(segment.mediaHeader, isInit, format); - - if (isInit) { - HttpFetchPlugin.cacheManager.setInitSegment( - segmentKey, - segment.data as Uint8Array - ); - } else { - HttpFetchPlugin.cacheManager.setSegment(segmentKey, segment.data as Uint8Array); - } -} - -/** - * Retrieves a cached segment based on streaming context - * @param decodedStreamingContext - The SABR streaming context - * @param request - The original request. - * @param requestType - The Shaka request type - * @param uri - The request URI - * @returns A Shaka response object or undefined if not found - */ -export function retrieveCachedSegment( - decodedStreamingContext: SabrStreamingContext, - request: shaka.extern.Request, - requestType: shaka.net.NetworkingEngine.RequestType, - uri: string -): shaka.extern.Response | null { - if (!decodedStreamingContext.byteRange || !decodedStreamingContext.format) return null; - - const segmentKey = createSegmentCacheKeyFromContext({ - ...decodedStreamingContext, - isInit: decodedStreamingContext.isInit - }); - - let arrayBuffer: ArrayBuffer | undefined; - - arrayBuffer = ( - decodedStreamingContext.isInit - ? HttpFetchPlugin.cacheManager.getInitSegment(segmentKey) - : HttpFetchPlugin.cacheManager.getSegment(segmentKey) - )?.buffer; - - if (arrayBuffer) { - if (decodedStreamingContext.isInit) { - arrayBuffer = arrayBuffer.slice( - decodedStreamingContext.byteRange.start, - decodedStreamingContext.byteRange.end + 1 - ); - } - - const headers = HttpFetchPlugin.headersToGenericObject_(new Headers()); - headers['X-Streaming-Context'] = btoa(JSON.stringify(decodedStreamingContext)); - headers['content-type'] = decodedStreamingContext.format.mime_type.split(';')[0]; - headers['content-length'] = arrayBuffer.byteLength.toString(); - - return HttpFetchPlugin.makeResponse(headers, arrayBuffer, 200, uri, uri, request, requestType); - } - - return null; -} diff --git a/materialious/src/lib/sabr/cacheManager.ts b/materialious/src/lib/sabr/cacheManager.ts deleted file mode 100644 index d7a697dc..00000000 --- a/materialious/src/lib/sabr/cacheManager.ts +++ /dev/null @@ -1,147 +0,0 @@ -export interface CacheEntry { - data: Uint8Array; - timestamp: number; - size: number; -} - -/** - * A "proper" cache for storing segments. - */ -export class CacheManager { - private initSegmentCache = new Map(); - private segmentCache = new Map(); - private currentSize = 0; - private readonly maxCacheSize: number; - private readonly maxAge: number; - - constructor(maxSizeMB = 50, maxAgeSeconds = 300) { - this.maxCacheSize = maxSizeMB * 1024 * 1024; - this.maxAge = maxAgeSeconds * 1000; - this.startGarbageCollection(); - } - - public setInitSegment(key: string, data: Uint8Array): void { - const entry: CacheEntry = { - data, - timestamp: Date.now(), - size: data.byteLength - }; - - if (!this.initSegmentCache.has(key)) { - this.currentSize += entry.size; - this.enforceStorageLimit(); - } - - this.initSegmentCache.set(key, entry); - } - - public setSegment(key: string, data: Uint8Array): void { - const entry: CacheEntry = { - data, - timestamp: Date.now(), - size: data.byteLength - }; - - this.currentSize += entry.size; - this.enforceStorageLimit(); - this.segmentCache.set(key, entry); - } - - public getInitSegment(key: string): Uint8Array | undefined { - const entry = this.initSegmentCache.get(key); - - if (entry && !this.isExpired(entry)) { - entry.timestamp = Date.now(); // Update last access time - return entry.data; - } - - // Expired. Get rid of it. - if (entry) { - this.initSegmentCache.delete(key); - this.currentSize -= entry.size; - } - - return undefined; - } - - public getSegment(key: string): Uint8Array | undefined { - const entry = this.segmentCache.get(key); - if (entry && !this.isExpired(entry)) { - const data = entry.data; - this.segmentCache.delete(key); - this.currentSize -= entry.size; - return data; - } - - // Expired. Get rid of it. - if (entry) { - this.segmentCache.delete(key); - this.currentSize -= entry.size; - } - - return undefined; - } - - private isExpired(entry: CacheEntry): boolean { - return Date.now() - entry.timestamp > this.maxAge; - } - - private enforceStorageLimit(): void { - if (this.currentSize <= this.maxCacheSize) return; - - this.clearExpiredEntries(); - - // If still over limit, remove oldest entries - if (this.currentSize > this.maxCacheSize) { - this.removeOldestEntries(); - } - } - - private clearExpiredEntries(): void { - const now = Date.now(); - - for (const [key, entry] of this.segmentCache.entries()) { - if (now - entry.timestamp > this.maxAge) { - this.segmentCache.delete(key); - this.currentSize -= entry.size; - } - } - - for (const [key, entry] of this.initSegmentCache.entries()) { - if (now - entry.timestamp > this.maxAge) { - this.initSegmentCache.delete(key); - this.currentSize -= entry.size; - } - } - } - - private removeOldestEntries(): void { - const segments = Array.from(this.segmentCache.entries()); - const initSegments = Array.from(this.initSegmentCache.entries()); - - const allEntries = [...segments, ...initSegments].sort( - (a, b) => a[1].timestamp - b[1].timestamp - ); - - // Remove oldest entries until under limit - while (this.currentSize > this.maxCacheSize && allEntries.length > 0) { - const [key, entry] = allEntries.shift()!; - this.segmentCache.delete(key); - this.initSegmentCache.delete(key); - this.currentSize -= entry.size; - } - } - - private startGarbageCollection(): void { - // Should there be a way to stop this? :p - setInterval(() => { - this.clearExpiredEntries(); - }, 60000); - } - - public clearCache(): void { - this.initSegmentCache.clear(); - this.segmentCache.clear(); - this.currentSize = 0; - } -} diff --git a/materialious/src/lib/sabr/formatKeyUtils.ts b/materialious/src/lib/sabr/formatKeyUtils.ts deleted file mode 100644 index b9df6a0f..00000000 --- a/materialious/src/lib/sabr/formatKeyUtils.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type { Misc } from 'youtubei.js/web'; -import type { Protos } from 'googlevideo'; -import type { SabrStreamingContext } from './shakaHttpPlugin'; - -/** - * Creates a format key based on itag and xtags - * @param itag - The itag value - * @param xtags - The xtags value (optional) - * @returns A string format key - */ -export function createKey(itag: number | undefined, xtags: string | undefined): string { - return `${itag || ''}:${xtags || ''}`; -} - -/** - * Creates a format key from a Format object - * @param format - The format object - * @returns A string format key or undefined if format is undefined - */ -export function fromFormat(format: Misc.Format | undefined): string | undefined { - if (!format) return undefined; - return createKey(format.itag, format.xtags); -} - -/** - * Creates a format key from a MediaHeader object - * @param mediaHeader - The MediaHeader object - * @returns A string format key - */ -export function fromMediaHeader(mediaHeader: Protos.MediaHeader): string { - return createKey(mediaHeader.itag, mediaHeader.xtags); -} - -/** - * Creates a format key from FormatInitializationMetadata - * @param formatInitMetadata - The FormatInitializationMetadata object - * @returns A string format key or undefined if formatId is undefined - */ -export function fromFormatInitializationMetadata( - formatInitMetadata: Protos.FormatInitializationMetadata -): string { - if (!formatInitMetadata.formatId) return ''; - return createKey(formatInitMetadata.formatId.itag, formatInitMetadata.formatId.xtags); -} - -/** - * Creates a segment cache key - * @param mediaHeader - The MediaHeader object - * @param isInit - Whether it's an initialization segment - * @param format - Format object (needed for init segments) - * @returns A string key for caching segments - */ -export function createSegmentCacheKey( - mediaHeader: Protos.MediaHeader, - isInit?: boolean, - format?: Misc.Format -): string { - if (isInit && format) { - return `${mediaHeader.itag}:${mediaHeader.xtags || ''}:${format.content_length || ''}:${format.mime_type || ''}`; - } - // @ts-expect-error Invalid typing - return `${mediaHeader.startRange || '0'}-${mediaHeader.itag}-${mediaHeader.xtags || ''}`; -} - -/** - * Creates a segment cache key from a SabrStreamingContext object - * @param context - The SabrStreamingContext object - * @returns A string key for caching segments - */ -export function createSegmentCacheKeyFromContext(context: SabrStreamingContext): string { - if (!context.byteRange || !context.format) - throw new Error('Invalid context: byteRange or format is missing'); - - const pseudoMediaHeader = { - itag: context.format.itag, - xtags: context.format.xtags || '', - startDataRange: context.byteRange.start, - isInitSeg: context.isInit - }; - - return createSegmentCacheKey( - pseudoMediaHeader as any, - !!context.isInit, - context.isInit ? context.format : undefined - ); -} - -export function getUniqueFormatId(format: Misc.Format) { - if (format.has_video) return format.itag.toString(); - - const uid_parts = [format.itag.toString()]; - - if (format.audio_track) { - uid_parts.push(format.audio_track.id); - } - - if (format.is_drc) { - uid_parts.push('drc'); - } - - return uid_parts.join('-'); -} diff --git a/materialious/src/lib/sabr/helpers.ts b/materialious/src/lib/sabr/helpers.ts new file mode 100644 index 00000000..33eb6b40 --- /dev/null +++ b/materialious/src/lib/sabr/helpers.ts @@ -0,0 +1,75 @@ +import shaka from 'shaka-player/dist/shaka-player.ui'; + +export function asMap(object: Record): Map { + const map = new Map(); + for (const key of Object.keys(object)) { + map.set(key as K, object[key]); + } + return map; +} + +export function createRecoverableError(message: string, info?: Record) { + return new shaka.util.Error( + shaka.util.Error.Severity.RECOVERABLE, + shaka.util.Error.Category.NETWORK, + shaka.util.Error.Code.HTTP_ERROR, + message, + { info } + ); +} + +export function headersToGenericObject(headers: Headers): Record { + const headersObj: Record = {}; + headers.forEach((value, key) => { + // Since Edge incorrectly returns the header with a leading new line + // character ('\n'), we trim the header here. + headersObj[key.trim()] = value; + }); + return headersObj; +} + +export function makeResponse( + headers: Record, + data: BufferSource, + status: number, + uri: string, + responseURL: string, + request: shaka.extern.Request, + requestType: shaka.net.NetworkingEngine.RequestType +): shaka.extern.Response & { originalRequest: shaka.extern.Request } { + if (status >= 200 && status <= 299 && status !== 202) { + return { + uri: responseURL || uri, + originalUri: uri, + data, + status, + headers, + originalRequest: request, + fromCache: !!headers['x-shaka-from-cache'] + }; + } + + let responseText: string | null = null; + try { + responseText = shaka.util.StringUtils.fromBytesAutoDetect(data); + } catch { + /* no-op */ + } + + const severity = + status === 401 || status === 403 + ? shaka.util.Error.Severity.CRITICAL + : shaka.util.Error.Severity.RECOVERABLE; + + throw new shaka.util.Error( + severity, + shaka.util.Error.Category.NETWORK, + shaka.util.Error.Code.BAD_HTTP_STATUS, + uri, + status, + responseText, + headers, + requestType, + responseURL || uri + ); +} diff --git a/materialious/src/lib/sabr/index.ts b/materialious/src/lib/sabr/index.ts index c65270cd..05fc5f32 100644 --- a/materialious/src/lib/sabr/index.ts +++ b/materialious/src/lib/sabr/index.ts @@ -1,428 +1,96 @@ -import shaka from 'shaka-player/dist/shaka-player.ui'; -import { base64ToU8, Protos } from 'googlevideo'; -import { Constants, type Misc } from 'youtubei.js'; -import { HttpFetchPlugin, type SabrStreamingContext } from '$lib/sabr/shakaHttpPlugin'; -import { - fromFormat, - fromFormatInitializationMetadata, - fromMediaHeader, - getUniqueFormatId -} from '$lib/sabr/formatKeyUtils'; import type { VideoPlay } from '$lib/api/model'; -import { poTokenCacheStore } from '$lib/store'; +import { Capacitor } from '@capacitor/core'; +import { SabrStreamingAdapter } from 'googlevideo/sabr-streaming-adapter'; +import type shaka from 'shaka-player/dist/shaka-player.ui'; +import { ShakaPlayerAdapter } from './ShakaPlayerAdapter'; +import { Constants, YT } from 'youtubei.js'; import { get } from 'svelte/store'; +import { poTokenCacheStore } from '$lib/store'; +import { buildSabrFormat } from 'googlevideo/utils'; -export function injectSABR( - player: shaka.Player, - playerElement: HTMLMediaElement, - video: VideoPlay -): ResizeObserver | undefined { - if (!video.ytjs) return; +export function injectSabr(video: VideoPlay, player: shaka.Player): SabrStreamingAdapter | null { + if (!video.ytjs || !Capacitor.isNativePlatform()) return null; - shaka.net.NetworkingEngine.registerScheme( - 'http', - HttpFetchPlugin.parse, - shaka.net.NetworkingEngine.PluginPriority.PREFERRED - ); - shaka.net.NetworkingEngine.registerScheme( - 'https', - HttpFetchPlugin.parse, - shaka.net.NetworkingEngine.PluginPriority.PREFERRED - ); - - const sessionId = Array.from(Array(16), () => Math.floor(Math.random() * 36).toString(36)).join( - '' - ); - let videoPlaybackUstreamerConfig: string | undefined; - let serverAbrStreamingUrl: URL | undefined = undefined; - let drmParams: string | undefined; - const lastRequestMs = 0; - let lastSeekMs = 0; - let lastManualFormatSelectionMs = 0; - let lastActionMs = 0; - let clientViewportHeight = playerElement?.clientHeight || 0; - let clientViewportWidth = playerElement?.clientWidth || 0; - let lastPlaybackCookie: Protos.PlaybackCookie | undefined; - const initializedFormats = new Map< - string, - { - lastSegmentMetadata?: { - formatId: Protos.FormatId; - startTimeMs: number; - startSequenceNumber: number; - endSequenceNumber: number; - durationMs: number; - }; - formatInitializationMetadata: Protos.FormatInitializationMetadata; - } - >(); - let formatList: Misc.Format[] = []; - - const playerElementResizeObserver = new ResizeObserver(() => { - if (playerElement) { - clientViewportHeight = playerElement.clientHeight; - clientViewportWidth = playerElement.clientWidth; + const sabrAdapter = new SabrStreamingAdapter({ + playerAdapter: new ShakaPlayerAdapter(), + clientInfo: { + osName: video.ytjs.innertube.session.context.client.osName, + osVersion: video.ytjs.innertube.session.context.client.osVersion, + clientName: parseInt( + Constants.CLIENT_NAME_IDS[ + video.ytjs.innertube.session.context.client + .clientName as keyof typeof Constants.CLIENT_NAME_IDS + ] + ), + clientVersion: video.ytjs.innertube.session.context.client.clientVersion } }); - playerElementResizeObserver?.observe(playerElement); + sabrAdapter.onMintPoToken(async () => { + return get(poTokenCacheStore) || ''; + }); - if ( - video.ytjs.rawApiResponse.data.streamingData && - (video.ytjs.rawApiResponse.data.streamingData as any).drmParams - ) { - drmParams = (video.ytjs.rawApiResponse.data.streamingData as any).drmParams; - player.configure({ - drm: { - servers: { - 'com.widevine.alpha': - 'https://www.youtube.com/youtubei/v1/player/get_drm_license?alt=json' - } + sabrAdapter.onReloadPlayerResponse(async (reloadContext) => { + console.log('[SABR]', 'Reloading player response...'); + + if (!video.ytjs) return; + + const reloadedInfo = await video.ytjs.innertube.actions.execute('/player', { + videoId: video.videoId, + contentCheckOk: true, + racyCheckOk: true, + playbackContext: { + adPlaybackContext: { + pyv: true + }, + contentPlaybackContext: { + signatureTimestamp: video.ytjs.innertube.session.player?.sts + }, + reloadPlaybackContext: reloadContext } }); - } - videoPlaybackUstreamerConfig = - video.ytjs.video.page[0].player_config?.media_common_config.media_ustreamer_request_config - ?.video_playback_ustreamer_config; - - if (video.ytjs.video.streaming_data) { - formatList = video.ytjs.video.streaming_data.adaptive_formats; - } - - if (video.ytjs.video.streaming_data?.server_abr_streaming_url) - serverAbrStreamingUrl = new URL( + const parsedInfo = new YT.VideoInfo( + [reloadedInfo], + video.ytjs.innertube.actions, + video.ytjs.video.cpn + ); + sabrAdapter.setStreamingURL( video.ytjs.innertube.session.player!.decipher( - video.ytjs.video.streaming_data.server_abr_streaming_url + parsedInfo.streaming_data?.server_abr_streaming_url ) ); - - playerElement?.addEventListener('seeked', () => (lastSeekMs = Date.now())); - - player?.addEventListener('variantchanged', (event) => { - // Technically, all variant changes here are manual, given we don't handle ABR updates from the server. - if (event.type !== 'variant') { - lastManualFormatSelectionMs = Date.now(); - } - - lastActionMs = Date.now(); + sabrAdapter.setUstreamerConfig( + video.ytjs.video.player_config?.media_common_config.media_ustreamer_request_config + ?.video_playback_ustreamer_config + ); }); - const networkingEngine = player.getNetworkingEngine(); + const isLive = video.ytjs.video.basic_info.is_live; + const isPostLiveDVR = + !!video.ytjs.video.basic_info.is_post_live_dvr || + (video.ytjs.video.basic_info.is_live_content && + !!( + video.ytjs.video.streaming_data?.dash_manifest_url || + video.ytjs.video.streaming_data?.hls_manifest_url + )); - if (!networkingEngine) return; + if (video.ytjs.video.streaming_data && !isPostLiveDVR && !isLive) { + sabrAdapter.setStreamingURL( + video.ytjs.innertube.session.player!.decipher( + video.ytjs.video.streaming_data?.server_abr_streaming_url + ) + ); + sabrAdapter.setUstreamerConfig( + video.ytjs.video.player_config?.media_common_config.media_ustreamer_request_config + ?.video_playback_ustreamer_config + ); + sabrAdapter.setServerAbrFormats( + video.ytjs.video.streaming_data.adaptive_formats.map(buildSabrFormat) + ); + } - // Based off the following - // https://github.com/FreeTubeApp/FreeTube/blob/d270c9e251a433f1e4246a3f6a37acef707d22aa/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js#L1206 - // https://github.com/LuanRT/BgUtils/blob/6b121166be1ccb0b952dee1bdac488808365ae6b/examples/browser/web/src/main.ts#L293 - // https://github.com/LuanRT/yt-sabr-shaka-demo/blob/main/src/components/VideoPlayer.vue - networkingEngine.registerRequestFilter(async (type, request, context) => { - if (!player) return; + sabrAdapter.attach(player); - const originalUrl = new URL(request.uris[0]); - const url = originalUrl.hostname === 'sabr' ? serverAbrStreamingUrl : originalUrl; - const headers = request.headers; - - if (!url) return; - - if ( - type === shaka.net.NetworkingEngine.RequestType.SEGMENT && - url.pathname.includes('videoplayback') - ) { - if (!video.liveNow && !video.ytjs?.video.basic_info.is_post_live_dvr) { - const currentFormat = formatList.find( - (format) => - fromFormat(format) === (new URL(request.uris[0]).searchParams.get('___key') || '') - ); - - if (!videoPlaybackUstreamerConfig) throw new Error('Ustreamer config not found.'); - - if (!currentFormat) throw new Error('No format found for SABR request.'); - - if (!playerElement) throw new Error('No video element found.'); - - const activeVariant = player - .getVariantTracks() - .find( - (track) => - getUniqueFormatId(currentFormat) === - (currentFormat.has_video ? track.originalVideoId : track.originalAudioId) - ); - - let videoFormat: Misc.Format | undefined; - let audioFormat: Misc.Format | undefined; - let videoFormatId: Protos.FormatId | undefined; - let audioFormatId: Protos.FormatId | undefined; - - if (activeVariant) { - for (const fmt of formatList) { - const uniqueFormatId = getUniqueFormatId(fmt); - if (uniqueFormatId === activeVariant.originalVideoId) { - videoFormat = fmt; - } else if (uniqueFormatId === activeVariant.originalAudioId) { - audioFormat = fmt; - } - } - } - - if (videoFormat) { - videoFormatId = { - itag: videoFormat.itag, - lastModified: parseInt(videoFormat.last_modified_ms), - xtags: videoFormat.xtags - }; - } - - if (audioFormat) { - audioFormatId = { - itag: audioFormat.itag, - lastModified: parseInt(audioFormat.last_modified_ms), - xtags: audioFormat.xtags - }; - } - - const isInit = context ? !context.segment : true; - - const videoPlaybackAbrRequest: Protos.VideoPlaybackAbrRequest = { - clientAbrState: { - playbackRate: player.getPlaybackRate(), - playerTimeMs: Math.round( - (context?.segment?.getStartTime() ?? playerElement.currentTime) * 1000 - ), - elapsedWallTimeMs: Date.now() - lastRequestMs, - timeSinceLastSeek: lastSeekMs === 0 ? 0 : Date.now() - lastSeekMs, - timeSinceLastActionMs: lastActionMs === 0 ? 0 : Date.now() - lastActionMs, - timeSinceLastManualFormatSelectionMs: - lastManualFormatSelectionMs === 0 ? 0 : Date.now() - lastManualFormatSelectionMs, - clientViewportIsFlexible: false, - bandwidthEstimate: Math.round(player.getStats().estimatedBandwidth), - drcEnabled: currentFormat.is_drc === true, - enabledTrackTypesBitfield: currentFormat.has_audio ? 1 : 2, - clientViewportHeight, - clientViewportWidth - }, - bufferedRanges: [], - selectedFormatIds: [], - selectedAudioFormatIds: [audioFormatId || {}], - selectedVideoFormatIds: [videoFormatId || {}], - videoPlaybackUstreamerConfig: base64ToU8(videoPlaybackUstreamerConfig), - streamerContext: { - poToken: base64ToU8(get(poTokenCacheStore) ?? ''), - playbackCookie: lastPlaybackCookie - ? Protos.PlaybackCookie.encode(lastPlaybackCookie).finish() - : undefined, - clientInfo: { - clientName: parseInt(Constants.CLIENT_NAME_IDS.WEB), - clientVersion: video.ytjs?.innertube.session.context.client.clientVersion, - osName: 'Windows', - osVersion: '10.0' - }, - field5: [], - field6: [] - }, - field1000: [] - }; - - // Normalize the resolution. - if (currentFormat.width && currentFormat.height) { - let resolution = currentFormat.height; - - const aspectRatio = currentFormat.height / currentFormat.width; - - if (aspectRatio > 16 / 9) { - resolution = Math.round((currentFormat.width * 9) / 16); - } - - if (resolution && videoPlaybackAbrRequest.clientAbrState) { - videoPlaybackAbrRequest.clientAbrState.stickyResolution = resolution; - videoPlaybackAbrRequest.clientAbrState.lastManualSelectedResolution = resolution; - } - } - - if (!isInit) { - // Add the currently/previously active formats to the list of buffered ranges and selected formats - // so that the server doesn't send its init data again. - const initializedFormatsArray = Array.from(initializedFormats.values()); - - for (const initializedFormat of initializedFormatsArray) { - if (initializedFormat.lastSegmentMetadata) { - videoPlaybackAbrRequest.bufferedRanges.push({ - formatId: initializedFormat.lastSegmentMetadata.formatId, - startSegmentIndex: initializedFormat.lastSegmentMetadata.startSequenceNumber, - durationMs: initializedFormat.lastSegmentMetadata.durationMs, - startTimeMs: 0, - endSegmentIndex: initializedFormat.lastSegmentMetadata.endSequenceNumber - }); - } - } - - if (audioFormatId) videoPlaybackAbrRequest.selectedFormatIds.push(audioFormatId); - - if (videoFormatId) videoPlaybackAbrRequest.selectedFormatIds.push(videoFormatId); - } - - request.body = Protos.VideoPlaybackAbrRequest.encode(videoPlaybackAbrRequest).finish(); - - const byteRange = headers.Range - ? { - start: Number(headers.Range.split('=')[1].split('-')[0]), - end: Number(headers.Range.split('=')[1].split('-')[1]) - } - : null; - - const sabrStreamingContext = { - byteRange, - format: currentFormat, - isInit, - isUMP: true, - isSABR: true, - playerTimeMs: videoPlaybackAbrRequest.clientAbrState?.playerTimeMs - }; - - // @NOTE: Not a real header. See the http plugin code for more info. - request.headers['X-Streaming-Context'] = btoa(JSON.stringify(sabrStreamingContext)); - delete headers.Range; - } else { - if (!video.liveNow && !video.ytjs?.video.basic_info.is_post_live_dvr) { - url.searchParams.set('ump', '1'); - url.searchParams.set('srfvp', '1'); - if (headers.Range) { - url.searchParams.set('range', headers.Range?.split('=')[1]); - delete headers.Range; - } - } else { - url.pathname += '/ump/1'; - url.pathname += '/srfvp/1'; - } - - request.headers['X-Streaming-Context'] = btoa( - JSON.stringify({ - isUMP: true, - isSABR: false - }) - ); - } - - request.method = 'POST'; - } else if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) { - const wrapped = {} as Record; - wrapped.context = video.ytjs?.innertube.session.context; - wrapped.cpn = video.ytjs?.clientPlaybackNonce; - wrapped.drmParams = decodeURIComponent(drmParams || ''); - wrapped.drmSystem = 'DRM_SYSTEM_WIDEVINE'; - wrapped.drmVideoFeature = 'DRM_VIDEO_FEATURE_SDR'; - wrapped.licenseRequest = shaka.util.Uint8ArrayUtils.toBase64( - request.body as ArrayBuffer | ArrayBufferView - ); - wrapped.sessionId = sessionId; - wrapped.videoId = video.videoId; - request.body = shaka.util.StringUtils.toUTF8(JSON.stringify(wrapped)); - } - - request.uris[0] = url.toString(); - }); - - networkingEngine.registerResponseFilter(async (type, response, context) => { - if (type === shaka.net.NetworkingEngine.RequestType.SEGMENT) { - const url = new URL(response.uri); - if ( - url.hostname.endsWith('.youtube.com') && - url.pathname === '/api/timedtext' && - url.searchParams.get('caps') === 'asr' && - url.searchParams.get('kind') === 'asr' && - url.searchParams.get('fmt') === 'vtt' - ) { - const stringBody = new TextDecoder().decode(response.data); - // position:0% for LTR text and position:100% for RTL text - const cleaned = stringBody.replaceAll(/ align:start position:(?:10)?0%$/gm, ''); - - /* @ts-ignore */ - response.data = new TextEncoder().encode(cleaned).buffer; - } else { - const sabrStreamingContext = response.headers['X-Streaming-Context']; - - if (sabrStreamingContext) { - const { streamInfo, format, byteRange } = JSON.parse( - atob(sabrStreamingContext) - ) as SabrStreamingContext; - - if (streamInfo) { - const sabrRedirect = streamInfo.redirect; - const playbackCookie = streamInfo.playbackCookie; - const streamProtectionStatus = streamInfo.streamProtectionStatus; - const formatInitMetadata = streamInfo.formatInitMetadata || []; - const mainSegmentMediaHeader = streamInfo.mediaHeader; - - // If we have a redirect, follow it. - if (sabrRedirect?.url && !response.data.byteLength) { - let redirectUrl = new URL(sabrRedirect.url); - - serverAbrStreamingUrl = redirectUrl; - redirectUrl = new URL(`https://sabr?___key=${fromFormat(format) || ''}`); - - const retryParameters = player!.getConfiguration().streaming.retryParameters; - - const redirectRequest = shaka.net.NetworkingEngine.makeRequest( - [redirectUrl.toString()], - retryParameters - ); - - // Keep range so we can slice the response (only if it's the init segment). - if (typeof byteRange !== 'undefined') { - redirectRequest.headers['Range'] = `bytes=${byteRange.start}-${byteRange.end}`; - } - - const requestOperation = player! - .getNetworkingEngine() - ?.request(type, redirectRequest, context); - const redirectResponse = await requestOperation!.promise; - - // Modify the original response to contain the results of the redirect - // response. - Object.assign(response, redirectResponse); - return; - } - - if (playbackCookie) lastPlaybackCookie = streamInfo.playbackCookie; - - if (streamProtectionStatus && streamProtectionStatus.status === 3) { - console.warn('[UMP] Attestation required.'); - } - - for (const metadata of formatInitMetadata) { - const key = fromFormatInitializationMetadata(metadata); - if (!initializedFormats.has(key)) { - initializedFormats.set(key, { - formatInitializationMetadata: metadata - }); - console.log(`[SABR] Initialized format ${key}`); - } - } - - if (mainSegmentMediaHeader) { - const formatKey = fromMediaHeader(mainSegmentMediaHeader); - const initializedFormat = initializedFormats.get(formatKey); - - if (initializedFormat) { - initializedFormat.lastSegmentMetadata = { - formatId: mainSegmentMediaHeader.formatId!, - startTimeMs: mainSegmentMediaHeader.startMs || 0, - startSequenceNumber: mainSegmentMediaHeader.sequenceNumber || 1, - endSequenceNumber: mainSegmentMediaHeader.sequenceNumber || 1, - durationMs: mainSegmentMediaHeader.durationMs || 0 - }; - } - } - } - } - } - } else if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) { - const wrappedString = shaka.util.StringUtils.fromUTF8(response.data); - const wrapped = JSON.parse(wrappedString); - const rawLicenseBase64 = wrapped.license; - response.data = shaka.util.Uint8ArrayUtils.fromBase64(rawLicenseBase64); - } - }); - - return playerElementResizeObserver; + return sabrAdapter; } diff --git a/materialious/src/lib/sabr/sabrUmpParser.ts b/materialious/src/lib/sabr/sabrUmpParser.ts deleted file mode 100644 index c6ac7567..00000000 --- a/materialious/src/lib/sabr/sabrUmpParser.ts +++ /dev/null @@ -1,282 +0,0 @@ -import { GoogleVideo, Protos, concatenateChunks, type Part, PART } from 'googlevideo'; -import shaka from 'shaka-player/dist/shaka-player.ui'; - -import { cacheSegment } from './cacheHelper'; -import { fromFormat, fromMediaHeader } from './formatKeyUtils'; -import { HttpFetchPlugin } from './shakaHttpPlugin'; -import type { SabrStreamingContext } from './shakaHttpPlugin'; - -export interface Segment { - headerId?: number; - mediaHeader: Protos.MediaHeader; - complete?: boolean; - data: Uint8Array; -} - -export class SabrUmpParser { - private partialPart?: Part; - private formatInitMetadata: Protos.FormatInitializationMetadata[] = []; - private playbackCookie?: Protos.PlaybackCookie; - private targetHeaderId?: number; - private targetSegment?: Segment; - - constructor( - private response: Response, - private decodedStreamingContext: SabrStreamingContext, - private uri: string, - private request: shaka.extern.Request, - private requestType: shaka.net.NetworkingEngine.RequestType, - private abortController: AbortController - ) {} - - async parse(): Promise { - const reader = this.response.clone().body!.getReader(); - - while (!this.abortController.signal.aborted) { - const { value, done } = await reader.read(); - - if (done) { - // If we got here, we read the whole stream but there was no data; it means we must follow this redirect. - if ( - this.decodedStreamingContext.isSABR && - this.decodedStreamingContext.streamInfo?.redirect - ) { - return this.createShakaResponse(); - } - - // We should never reach here, but if we do, it means we got nothing at all. - throw this.createRecoverableError( - 'Empty response with no redirect information', - this.decodedStreamingContext - ); - } - - let chunk; - - if (this.partialPart) { - chunk = this.partialPart.data; - chunk.append(value); - } else { - chunk = new GoogleVideo.ChunkedDataBuffer([value]); - } - - const result = await this.process(chunk); - if (result) { - if (this.shouldThrowServerError(result)) { - throw this.createRecoverableError('Server streaming error', this.decodedStreamingContext); - } - return result; - } - } - - // Never happens. Here just in case. - throw this.createRecoverableError( - "Couldn't read any data from the stream", - this.decodedStreamingContext - ); - } - - private shouldThrowServerError(result: shaka.extern.Response): boolean { - return ( - !result.data.byteLength && - (!!this.decodedStreamingContext.error || - this.decodedStreamingContext.streamInfo?.streamProtectionStatus?.status === 3) - ); - } - - private createRecoverableError(message: string, info?: Record) { - return new shaka.util.Error( - shaka.util.Error.Severity.RECOVERABLE, - shaka.util.Error.Category.NETWORK, - shaka.util.Error.Code.HTTP_ERROR, - message, - { info } - ); - } - - private process( - value: GoogleVideo.ChunkedDataBuffer - ): Promise { - return new Promise((resolve) => { - const ump = new GoogleVideo.UMP(value); - - this.partialPart = ump.parse((part: Part) => { - const result = this.handlePart(part); - if (result) { - resolve(result); - } - }); - - resolve(undefined); - }); - } - - private handlePart(part: Part): shaka.extern.Response | undefined { - try { - switch (part.type) { - case PART.FORMAT_INITIALIZATION_METADATA: - this.handleFormatInitMetadata(part); - break; - case PART.NEXT_REQUEST_POLICY: - this.handleNextRequestPolicy(part); - break; - case PART.MEDIA_HEADER: - this.handleMediaHeader(part); - break; - case PART.MEDIA: - this.handleMedia(part); - break; - case PART.MEDIA_END: - return this.handleMediaEnd(part); - case PART.SABR_ERROR: - return this.handleSabrError(part); - case PART.STREAM_PROTECTION_STATUS: - return this.handleStreamProtectionStatus(part); - case PART.SABR_REDIRECT: - return this.handleSabrRedirect(part); - default: - } - } catch {} - } - - private handleFormatInitMetadata(part: Part) { - const formatInitMetadata = Protos.FormatInitializationMetadata.decode(part.data.chunks[0]); - this.formatInitMetadata.push(formatInitMetadata); - } - - private handleNextRequestPolicy(part: Part) { - const nextRequestPolicy = Protos.NextRequestPolicy.decode(part.data.chunks[0]); - if (this.decodedStreamingContext.format?.has_video) { - this.playbackCookie = nextRequestPolicy.playbackCookie; - } - } - - private handleMediaHeader(part: Part) { - const mediaHeader = Protos.MediaHeader.decode(part.data.chunks[0]); - const formatKey = fromFormat(this.decodedStreamingContext.format); - const segmentFormatKey = fromMediaHeader(mediaHeader); - - if (!this.decodedStreamingContext.isSABR || segmentFormatKey === formatKey) { - if (!this.targetHeaderId) { - this.targetHeaderId = mediaHeader.headerId; - this.targetSegment = { - headerId: mediaHeader.headerId, - mediaHeader: mediaHeader, - data: new Uint8Array() - }; - } - } - } - - private handleMedia(part: Part) { - const headerId = part.data.getUint8(0); - const buffer = part.data.split(1).remainingBuffer; - - if (this.targetSegment && headerId === this.targetHeaderId) { - this.targetSegment.data = concatenateChunks([this.targetSegment.data, ...buffer.chunks]); - } - } - - private handleMediaEnd(part: Part) { - const headerId = part.data.getUint8(0); - - if (this.targetSegment && headerId === this.targetHeaderId) { - if (this.decodedStreamingContext) { - this.decodedStreamingContext.streamInfo = { - ...this.decodedStreamingContext.streamInfo, - playbackCookie: this.playbackCookie, - formatInitMetadata: this.formatInitMetadata, - mediaHeader: this.targetSegment.mediaHeader.isInitSeg - ? undefined - : this.targetSegment.mediaHeader - }; - } - - let arrayBuffer: Uint8Array; - - // Why cache the init segment? Well, SABR responses are still a bit larger than usual - caching the init segment - // helps reduce the delay when switching between different qualities or initializing a new stream. - if ( - this.decodedStreamingContext.isInit && - this.decodedStreamingContext.format && - this.decodedStreamingContext.byteRange - ) { - cacheSegment(this.targetSegment, this.decodedStreamingContext.format); - arrayBuffer = this.targetSegment.data.slice( - this.decodedStreamingContext.byteRange.start, - this.decodedStreamingContext.byteRange.end + 1 - ); - } else { - arrayBuffer = this.targetSegment.data; - } - - // We got what we wanted; close the stream and abort the request. - this.abortController.abort(); - return this.createShakaResponse(arrayBuffer); - } - } - - private handleSabrError(part: Part) { - const sabrError = Protos.SabrError.decode(part.data.chunks[0]); - - if (this.decodedStreamingContext) { - this.decodedStreamingContext.error = { sabrError }; - } - - this.abortController.abort(); - return this.createShakaResponse(); - } - - private handleStreamProtectionStatus(part: Part) { - const streamProtectionStatus = Protos.StreamProtectionStatus.decode(part.data.chunks[0]); - - if (this.decodedStreamingContext) { - this.decodedStreamingContext.streamInfo = { - ...this.decodedStreamingContext.streamInfo, - streamProtectionStatus - }; - } - - if (streamProtectionStatus.status === 3) { - this.abortController.abort(); - return this.createShakaResponse(); - } - } - - private handleSabrRedirect(part: Part) { - const redirect = Protos.SabrRedirect.decode(part.data.chunks[0]); - - if (this.decodedStreamingContext) { - this.decodedStreamingContext.streamInfo = { - ...this.decodedStreamingContext.streamInfo, - redirect - }; - } - - // With pure UMP, redirects should be followed immediately. - if (this.decodedStreamingContext.isUMP && !this.decodedStreamingContext.isSABR) { - this.abortController.abort(); - return this.createShakaResponse(); - } - } - - private createShakaResponse(body?: Uint8Array): shaka.extern.Response { - return HttpFetchPlugin.makeResponse( - this.createContextHeaders(), - body || new ArrayBuffer(0), - this.response.status, - this.uri, - this.response.url, - this.request, - this.requestType - ); - } - - private createContextHeaders(): Record { - const headers = HttpFetchPlugin.headersToGenericObject_(this.response.headers); - if (this.decodedStreamingContext) { - headers['X-Streaming-Context'] = btoa(JSON.stringify(this.decodedStreamingContext)); - } - return headers; - } -} diff --git a/materialious/src/lib/sabr/shakaHttpPlugin.ts b/materialious/src/lib/sabr/shakaHttpPlugin.ts deleted file mode 100644 index 24dc1a03..00000000 --- a/materialious/src/lib/sabr/shakaHttpPlugin.ts +++ /dev/null @@ -1,265 +0,0 @@ -import shaka from 'shaka-player/dist/shaka-player.ui'; -import type { Misc } from 'youtubei.js/web'; -import type { Protos } from 'googlevideo'; - -import { retrieveCachedSegment } from './cacheHelper'; -import { SabrUmpParser } from './sabrUmpParser'; -import { CacheManager } from './cacheManager'; -import { Capacitor } from '@capacitor/core'; - -export interface SabrStreamingContext { - byteRange?: { start: number; end: number }; - format?: Misc.Format; - isInit?: boolean; - isUMP?: boolean; - isSABR?: boolean; - playerTimeMs?: number; - streamInfo?: { - playbackCookie?: Protos.PlaybackCookie; - formatInitMetadata?: Protos.FormatInitializationMetadata[]; - streamProtectionStatus?: Protos.StreamProtectionStatus; - mediaHeader?: Protos.MediaHeader; - redirect?: Protos.SabrRedirect; - }; - error?: { - sabrError?: Protos.SabrError; - }; -} - -export class HttpFetchPlugin { - private static fetch_ = window.fetch; - private static AbortController_ = window.AbortController; - private static Headers_ = window.Headers; - public static cacheManager = new CacheManager(); - - private static asMap(object: Record): Map { - const map = new Map(); - for (const key of Object.keys(object)) { - map.set(key as K, object[key]); - } - return map; - } - - static parse( - uri: string, - request: shaka.extern.Request, - requestType: shaka.net.NetworkingEngine.RequestType, - _progressUpdated: shaka.extern.ProgressUpdated, - headersReceived: shaka.extern.HeadersReceived - ): shaka.extern.IAbortableOperation { - const headers = new HttpFetchPlugin.Headers_(); - - HttpFetchPlugin.asMap(request.headers).forEach((value, key) => { - headers.append(key as string, value); - }); - - let sabrStreamingContext: string | null = null; - - // Save the streaming context for later use, then remove it from the headers - // as it's only used by the player and not the server. - if (headers.has('X-Streaming-Context')) { - sabrStreamingContext = headers.get('X-Streaming-Context'); - headers.delete('X-Streaming-Context'); - } - - // Parse uri and remove "___key" query param (same situation as above). - const url = new URL(uri); - url.searchParams.delete('___key'); - uri = url.toString(); - - const controller = new HttpFetchPlugin.AbortController_(); - const init: RequestInit = { - body: request.body || undefined, - headers, - method: request.method, - signal: controller.signal, - credentials: request.allowCrossSiteCredentials ? 'include' : undefined - }; - - const abortStatus = { - canceled: false, - timedOut: false - }; - - const pendingRequest = HttpFetchPlugin.request_( - uri, - request, - requestType, - init, - controller, - abortStatus, - headersReceived, - sabrStreamingContext - ); - - const op = new shaka.util.AbortableOperation(pendingRequest, () => { - abortStatus.canceled = true; - controller.abort(); - return Promise.resolve(); - }); - - const timeoutMs = request.retryParameters.timeout; - if (timeoutMs && Capacitor.getPlatform() !== 'android') { - const timer = new shaka.util.Timer(() => { - abortStatus.timedOut = true; - controller.abort(); - }); - - timer.tickAfter(timeoutMs / 1000); - op.finally(() => timer.stop()); - } - - return op; - } - - private static async request_( - uri: string, - request: shaka.extern.Request, - requestType: shaka.net.NetworkingEngine.RequestType, - init: RequestInit, - abortController: AbortController, - abortStatus: { canceled: boolean; timedOut: boolean }, - headersReceived: shaka.extern.HeadersReceived, - streamingContext: string | null - ): Promise { - const fetch = HttpFetchPlugin.fetch_; - const decodedStreamingContext = streamingContext - ? (JSON.parse(atob(streamingContext)) as SabrStreamingContext) - : undefined; - - let response: Response; - let arrayBuffer: ArrayBuffer | undefined; - - try { - // Try to use cached segment first - if (decodedStreamingContext && decodedStreamingContext.format) { - const cachedResponse = retrieveCachedSegment( - decodedStreamingContext, - request, - requestType, - uri - ); - if (cachedResponse) { - return cachedResponse; - } - } - - response = await fetch(uri, init); - headersReceived(HttpFetchPlugin.headersToGenericObject_(response.headers)); - - // Handle UMP responses - if ( - init.method !== 'HEAD' && - decodedStreamingContext && - response.headers.get('content-type') === 'application/vnd.yt-ump' - ) { - const parser = new SabrUmpParser( - response, - decodedStreamingContext, - uri, - request, - requestType, - abortController - ); - return parser.parse(); - } - - arrayBuffer = await response.arrayBuffer(); - } catch (error) { - if (abortStatus.canceled) { - throw new shaka.util.Error( - shaka.util.Error.Severity.RECOVERABLE, - shaka.util.Error.Category.NETWORK, - shaka.util.Error.Code.OPERATION_ABORTED, - uri, - requestType - ); - } else if (abortStatus.timedOut) { - throw new shaka.util.Error( - shaka.util.Error.Severity.RECOVERABLE, - shaka.util.Error.Category.NETWORK, - shaka.util.Error.Code.TIMEOUT, - uri, - requestType - ); - } - throw new shaka.util.Error( - shaka.util.Error.Severity.RECOVERABLE, - shaka.util.Error.Category.NETWORK, - shaka.util.Error.Code.HTTP_ERROR, - uri, - error, - requestType - ); - } - - const headers = HttpFetchPlugin.headersToGenericObject_(response.headers); - if (streamingContext) { - headers['X-Streaming-Context'] = streamingContext; - } - - return HttpFetchPlugin.makeResponse( - headers, - arrayBuffer!, - response.status, - uri, - response.url, - request, - requestType - ); - } - - public static makeResponse( - headers: Record, - data: BufferSource, - status: number, - uri: string, - responseURL: string, - request: shaka.extern.Request, - requestType: shaka.net.NetworkingEngine.RequestType - ): shaka.extern.Response & { originalRequest: shaka.extern.Request } { - if (status >= 200 && status <= 299 && status !== 202) { - return { - uri: responseURL || uri, - originalUri: uri, - data, - status, - headers, - originalRequest: request, - fromCache: !!headers['x-shaka-from-cache'] - }; - } - - let responseText: string | null = null; - try { - responseText = shaka.util.StringUtils.fromBytesAutoDetect(data); - } catch { - /* no-op */ - } - - const severity = - status === 401 || status === 403 - ? shaka.util.Error.Severity.CRITICAL - : shaka.util.Error.Severity.RECOVERABLE; - - throw new shaka.util.Error( - severity, - shaka.util.Error.Category.NETWORK, - shaka.util.Error.Code.BAD_HTTP_STATUS, - uri, - status, - responseText, - headers, - requestType, - responseURL || uri - ); - } - - public static headersToGenericObject_(headers: Headers): Record { - const headersObj: Record = {}; - headers.forEach((value, key) => { - headersObj[key.trim()] = value; - }); - return headersObj; - } -} diff --git a/update_versions.py b/update_versions.py index db71ce42..25b2eeed 100644 --- a/update_versions.py +++ b/update_versions.py @@ -3,7 +3,7 @@ import os import re from datetime import datetime -LATEST_VERSION = "1.10.10" +LATEST_VERSION = "1.10.11" RELEASE_DATE = datetime.now().strftime("%Y-%-m-%d") # Format: YYYY-M-D WORKING_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "materialious")