diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 2bcea4db85..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,12 +0,0 @@ -**/node_modules -scripts/**/*.js -packages/*/dist -packages/**/*.d.ts -packages/*/src/*-css.ts - -packages/model-viewer/**/* -packages/model-viewer-effects/**/* -packages/modelviewer.dev/**/* -packages/render-fidelity-tools/**/* -packages/shared-assets/**/* -packages/space-opera/**/* diff --git a/.eslintrc.yaml b/.eslintrc.yaml deleted file mode 100644 index 08972faca1..0000000000 --- a/.eslintrc.yaml +++ /dev/null @@ -1,68 +0,0 @@ -extends: - - eslint:recommended - - google - - plugin:@typescript-eslint/eslint-recommended - - plugin:@typescript-eslint/recommended - - plugin:wc/recommended -globals: - goog: false -env: - browser: true -parser: "@typescript-eslint/parser" -plugins: - - "@typescript-eslint" - - mocha - - wc -parserOptions: - ecmaVersion: 2017 - sourceType: module -settings: - wc: - elementBaseClasses: ["BaseElement", "LitElement", "FormElement"] -rules: - # Rules temporally disabled - "@typescript-eslint/explicit-function-return-type": off - - # Rules disabled in favor of clang-format - "@typescript-eslint/indent": off - indent: off - max-len: off - block-spacing: off - # Remove if we switch away from clang-format: - keyword-spacing: off - - # clang-format wants async(foo) => {} without a space - space-before-function-paren: off - - "@typescript-eslint/explicit-member-accessibility": [error, {"accessibility": "no-public"}] - - no-new: warn - quotes: [error, single, {"avoidEscape": true}] - no-var: error - curly: error - no-floating-decimal: error - # tsc handles this for us, and eslint has false positives - no-unused-vars: error - "@typescript-eslint/no-unused-vars": off - - require-jsdoc: off - valid-jsdoc: off - - prefer-const: error - comma-dangle: off - - mocha/handle-done-callback: error - mocha/no-exclusive-tests: error - mocha/no-identical-title: error - mocha/no-nested-tests: error - mocha/no-pending-tests: error - mocha/no-skipped-tests: error -overrides: - - files: ["packages/**/*.ts"] - rules: - no-unused-vars: off - no-invalid-this: off - new-cap: off - - files: ["packages/**/*.ts"] - rules: - "@typescript-eslint/no-non-null-assertion": off \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000000..ec465ab3fb --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,133 @@ +import js from '@eslint/js'; +import globals from 'globals'; +import tseslint from '@typescript-eslint/eslint-plugin'; +import tsParser from '@typescript-eslint/parser'; +import mochaPlugin from 'eslint-plugin-mocha'; +import wcPlugin from 'eslint-plugin-wc'; + +export default [ + { + ignores: [ + '**/node_modules', + 'scripts/**/*.js', + 'packages/*/dist', + 'packages/**/*.d.ts', + 'packages/*/src/*-css.ts', + ], + }, + js.configs.recommended, + { + files: ['**/*.ts', '**/*.js'], + languageOptions: { + ecmaVersion: 2017, + sourceType: 'module', + globals: { + ...globals.browser, + goog: false, + }, + parser: tsParser, + parserOptions: { + ecmaVersion: 2017, + sourceType: 'module', + }, + }, + plugins: { + '@typescript-eslint': tseslint, + mocha: mochaPlugin, + wc: wcPlugin, + }, + settings: { + wc: { + elementBaseClasses: ['BaseElement', 'LitElement', 'FormElement'], + }, + }, + rules: { + // قوانین پایه + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/indent': 'off', + 'indent': 'off', + 'max-len': 'off', + 'block-spacing': 'off', + 'keyword-spacing': 'off', + 'space-before-function-paren': 'off', + '@typescript-eslint/explicit-member-accessibility': ['error', { accessibility: 'no-public' }], + + // سبک کدنویسی + 'no-new': 'warn', + 'quotes': ['error', 'single', { avoidEscape: true }], + 'no-var': 'error', + 'curly': 'error', + 'no-floating-decimal': 'error', + 'prefer-const': 'error', + 'comma-dangle': 'off', + 'require-jsdoc': 'off', + 'valid-jsdoc': 'off', + + // برای type/const هم‌نام و shadow + 'no-redeclare': 'off', + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': 'off', + 'no-undef': 'off', + + // استفاده نشده‌ها + 'no-unused-vars': 'error', + '@typescript-eslint/no-unused-vars': 'off', + + // قوانین mocha + 'mocha/handle-done-callback': 'error', + 'mocha/no-exclusive-tests': 'error', + 'mocha/no-identical-title': 'error', + 'mocha/no-nested-tests': 'error', + 'mocha/no-pending-tests': 'error', + }, + }, + { + files: ['packages/**/*.ts'], + rules: { + 'no-unused-vars': 'off', + 'no-invalid-this': 'off', + 'new-cap': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + 'no-undef': 'off', + }, + }, + { + files: [ + 'packages/**/test/**/*.ts', + 'packages/**/test/**/*.js', + 'packages/**/*.spec.ts', + 'packages/**/*.spec.js', + 'packages/**/*.spec.mjs', + 'packages/**/*.spec.cjs', + 'packages/**/*.test.ts', + 'packages/**/*.test.js', + 'packages/**/*.test.mjs', + 'packages/**/*.test.cjs', + ], + languageOptions: { + globals: { + ...globals.mocha, + ...globals.browser, + goog: false, + }, + }, + }, + { + files: [ + 'scripts/**/*.js', + 'packages/render-fidelity-tools/**/*.{js,ts}', + 'packages/model-viewer/scripts/**/*.js', + 'packages/model-viewer/tools/**/*.js', + 'packages/model-viewer/tools/**/*.ts', + 'packages/model-viewer-effects/scripts/**/*.js', + 'packages/model-viewer-effects/tools/**/*.js', + 'packages/model-viewer-effects/tools/**/*.ts', + ], + languageOptions: { + globals: { + ...globals.node, + goog: false, + }, + }, + }, +]; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e8413e901b..6780c21a86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,19 +14,21 @@ "packages/space-opera" ], "dependencies": { - "puppeteer": "^24.4.0" + "puppeteer": "^24.11.1", + "ua-parser-js": "^2.0.4" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^8.26.1", - "@typescript-eslint/parser": "^8.26.1", + "@types/ua-parser-js": "^0.7.39", + "@typescript-eslint/eslint-plugin": "^8.35.1", + "@typescript-eslint/parser": "^8.35.1", "clang-format": "^1.8.0", - "eslint": "^9.22.0", + "eslint": "^9.30.0", "eslint-config-google": "^0.14.0", - "eslint-plugin-mocha": "^10.5.0", - "eslint-plugin-wc": "^2.2.1", + "eslint-plugin-mocha": "^11.1.0", + "eslint-plugin-wc": "^3.0.1", "http-server": "^14.1.1", "husky": "^9.1.7", - "typescript": "5.8.2" + "typescript": "5.8.3" }, "engines": { "node": ">=12.0.0" @@ -82,23 +84,23 @@ } }, "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==", "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.27.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.7.tgz", + "integrity": "sha512-xgu/ySj2mTiUFmdE9yCMfBxLp4DHd5DwmbbD05YAuICfodYT3VvRxbrh81LGQ/8UpSdtMdfKMn3KouYDX59DGQ==", "dev": true, "license": "MIT", "engines": { @@ -106,22 +108,22 @@ } }, "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.27.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.7.tgz", + "integrity": "sha512-BU2f9tlKQ5CAthiMIgpzAh4eDTLWo1mqi9jqE2OxMG0E/OM199VJt2q8BztTxpnSW0i1ymdwLXRJnYzvDM5r2w==", "dev": true, "license": "MIT", "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.27.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.6", + "@babel/parser": "^7.27.7", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.7", + "@babel/types": "^7.27.7", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -147,14 +149,14 @@ } }, "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.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.27.0", - "@babel/types": "^7.27.0", + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -164,27 +166,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", "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", "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" @@ -214,13 +216,13 @@ } }, "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", "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" }, @@ -255,43 +257,43 @@ } }, "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==", + "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.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-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", "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.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", "dev": true, "license": "MIT", "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.27.3" }, "engines": { "node": ">=6.9.0" @@ -301,22 +303,22 @@ } }, "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", "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", "engines": { @@ -324,15 +326,15 @@ } }, "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", "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" @@ -342,15 +344,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", "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" @@ -360,23 +362,23 @@ } }, "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", "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", "engines": { @@ -384,18 +386,18 @@ } }, "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==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "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", "engines": { @@ -403,42 +405,42 @@ } }, "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.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz", + "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/template": "^7.27.1", + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "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.27.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" }, "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.27.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.7.tgz", + "integrity": "sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.27.0" + "@babel/types": "^7.27.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -448,13 +450,13 @@ } }, "node_modules/@babel/plugin-external-helpers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.25.9.tgz", - "integrity": "sha512-Ro9pBweUvdxKyKKmWsqYaloZrxc2V+bseyPI7mV5DqBNvyNeGFFX+rPqicuEyOssiFYfoGyMjOF8n3ZAGBOPtg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.27.1.tgz", + "integrity": "sha512-0al8J5LZL5fYva7ls8lueIl7WYLMhFz2p0Fx91oM2SEQfcJzEpLs7j7HySGVwHN7KVRiE3NUJUnh2fg9anuThQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -557,13 +559,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -573,15 +575,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", "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" @@ -591,13 +593,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -607,13 +609,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.27.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.5.tgz", + "integrity": "sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -623,17 +625,17 @@ } }, "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.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.7.tgz", + "integrity": "sha512-CuLkokN1PEZ0Fsjtq+001aog/C2drDK9nTfK/NRK0n6rBin6cBrvM+zfQjDE+UllhR6/J4a6w8Xq9i4yi3mQrw==", "dev": true, "license": "MIT", "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", + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.27.7", "globals": "^11.1.0" }, "engines": { @@ -654,14 +656,14 @@ } }, "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", "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" @@ -671,13 +673,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.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.7.tgz", + "integrity": "sha512-pg3ZLdIKWCP0CrJm0O4jYjVthyBeioVfvz9nwt6o5paUxsgJ/8GucSMAIaj6M7xA4WY+SrvtGu2LijzkdyecWQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.7" }, "engines": { "node": ">=6.9.0" @@ -687,13 +690,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -703,13 +706,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -719,14 +722,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", "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" @@ -736,15 +739,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", "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" @@ -754,13 +757,13 @@ } }, "node_modules/@babel/plugin-transform-instanceof": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-instanceof/-/plugin-transform-instanceof-7.25.9.tgz", - "integrity": "sha512-VqDNoU3+6RYzZ7ks5VlOpHSolZ/2GxemLEOCQY1yUSpLZWh/lNBBrklREE8XKF4r2Qog5jp5N+nmLtEfPKmwPQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-instanceof/-/plugin-transform-instanceof-7.27.1.tgz", + "integrity": "sha512-9P3XssOYPOsDiqMyHSNktw5bKKbPcndYp2ktQ3i/4/2lybuI8wK094t/rlJJjBrsOXGn9wuIPyVkoxBC4NnL6g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -770,13 +773,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -786,14 +789,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", "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" @@ -803,14 +806,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", "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" @@ -820,13 +823,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -836,14 +839,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.27.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.5.tgz", + "integrity": "sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==", "dev": true, "license": "MIT", "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" @@ -853,13 +855,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -869,14 +871,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", "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" @@ -886,13 +888,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -902,13 +904,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -918,13 +920,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", "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -934,14 +936,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", "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" @@ -951,52 +953,42 @@ } }, "node_modules/@babel/runtime": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", - "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", "dev": true, "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/runtime/node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true, - "license": "MIT" - }, "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", "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.27.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.7.tgz", + "integrity": "sha512-X6ZlfR/O/s5EQ/SnUSLzr+6kGnkg8HXGMzpgsMsrJVcfDtH1vIp6ctCN4eZ1LS5c0+te5Cb6Y514fASjMRJ1nw==", "dev": true, "license": "MIT", "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", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.5", + "@babel/parser": "^7.27.7", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1015,14 +1007,14 @@ } }, "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.27.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.7.tgz", + "integrity": "sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==", "dev": true, "license": "MIT", "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" @@ -1050,10 +1042,17 @@ "kuler": "^2.0.0" } }, + "node_modules/@dimforge/rapier3d-compat": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz", + "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/@emnapi/runtime": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.0.tgz", - "integrity": "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", "dev": true, "license": "MIT", "optional": true, @@ -1062,9 +1061,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", - "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, "license": "MIT", "dependencies": { @@ -1091,9 +1090,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1106,9 +1105,9 @@ } }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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", "dependencies": { @@ -1130,9 +1129,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", + "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1140,9 +1139,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", - "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1177,9 +1176,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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", "dependencies": { @@ -1187,6 +1186,16 @@ "concat-map": "0.0.1" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1201,13 +1210,16 @@ } }, "node_modules/@eslint/js": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", - "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.0.tgz", + "integrity": "sha512-Wzw3wQwPvc9sHM+NjakWTcPx11mbZyiYHuwWa/QfZ7cIRX7WK54PSk7bdyXDaoaopUcMatv1zaQvOAAO8hCdww==", "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { @@ -1221,13 +1233,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz", + "integrity": "sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.13.0", + "@eslint/core": "^0.15.1", "levn": "^0.4.1" }, "engines": { @@ -1235,9 +1247,9 @@ } }, "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", + "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1257,9 +1269,9 @@ } }, "node_modules/@gltf-transform/core": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@gltf-transform/core/-/core-4.1.3.tgz", - "integrity": "sha512-N+73Vo9DTXV2QmsnetLRY4q3z0Q0oyH0i/ymvzEkgpgNEAq+RP73ZLY0HK+Ia0rTUMgFwQHFNyHDyFiENToBZA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@gltf-transform/core/-/core-4.2.0.tgz", + "integrity": "sha512-43FtHNxMhT+VX/WZeXISorbtknwusdcfwu0qzfrDa1azsk5CBVOaZwM+ul7DsHty47eC49lSPN0g8uNso35WVw==", "dev": true, "license": "MIT", "dependencies": { @@ -1270,13 +1282,13 @@ } }, "node_modules/@gltf-transform/extensions": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@gltf-transform/extensions/-/extensions-4.1.3.tgz", - "integrity": "sha512-RcjA6UfBqOQPMqYhY/ftHAjrO1mnGLxUIXwErrH8qBoMprgkfLmi3fZuNL1tgZXlSPTjYdMCd7zEOc707F8Ekg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@gltf-transform/extensions/-/extensions-4.2.0.tgz", + "integrity": "sha512-ujw3RdS1/tVEixFUNuI21cApCgYXTeew4VCF22S0PzHT1I3O+oxFctyllhJOo+BYnlC9w/AnCuQpTAy+pMIboA==", "dev": true, "license": "MIT", "dependencies": { - "@gltf-transform/core": "^4.1.3", + "@gltf-transform/core": "^4.2.0", "ktx-parse": "^1.0.0" }, "funding": { @@ -1284,14 +1296,14 @@ } }, "node_modules/@gltf-transform/functions": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@gltf-transform/functions/-/functions-4.1.3.tgz", - "integrity": "sha512-SS0WH43lA/ttysXB0DovwhKF5yuAXOW/BWUqFlQPCX/NDqt+7qMDqGYL7zCB24NdUh43ipd4k/7QRVMwyrBZUA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@gltf-transform/functions/-/functions-4.2.0.tgz", + "integrity": "sha512-Umi/ATt5ktPBylD3a/l5oC1jPbZF60Xnm87qmVBJiLbRMcubN881WB2xP2d7je/UjVSd10fgIZ78GoS37Lpygg==", "dev": true, "license": "MIT", "dependencies": { - "@gltf-transform/core": "^4.1.3", - "@gltf-transform/extensions": "^4.1.3", + "@gltf-transform/core": "^4.2.0", + "@gltf-transform/extensions": "^4.2.0", "ktx-parse": "^1.0.0", "ndarray": "^1.0.19", "ndarray-lanczos": "^0.3.0", @@ -1381,9 +1393,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1774,6 +1786,27 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1941,9 +1974,9 @@ "license": "BSD-3-Clause" }, "node_modules/@lit/reactive-element": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", - "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.0.tgz", + "integrity": "sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==", "license": "BSD-3-Clause", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.2.0" @@ -3782,16 +3815,16 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.9.0.tgz", - "integrity": "sha512-8+xM+cFydYET4X/5/3yZMHs7sjS6c9I6H5I3xJdb6cinzxWUT/I2QVw4avxCQ8QDndwdHkG/FiSZIrCjAbaKvQ==", + "version": "2.10.5", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.5.tgz", + "integrity": "sha512-eifa0o+i8dERnngJwKrfp3dEq7ia5XFyoqB17S4gK8GhsQE4/P8nxOfQSE0zQHxzzLo/cmF+7+ywEQ7wK7Fb+w==", "license": "Apache-2.0", "dependencies": { - "debug": "^4.4.0", + "debug": "^4.4.1", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", - "semver": "^7.7.1", + "semver": "^7.7.2", "tar-fs": "^3.0.8", "yargs": "^17.7.2" }, @@ -3803,12 +3836,14 @@ } }, "node_modules/@reduxjs/toolkit": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.6.1.tgz", - "integrity": "sha512-SSlIqZNYhqm/oMkXbtofwZSt9lrncblzo6YcZ9zoX+zLngRBrCOjK4lNLdkNucJF58RHOWrD9txT3bT3piH7Zw==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.8.2.tgz", + "integrity": "sha512-MYlOhQ0sLdw4ud48FoC5w0dH9VfWQjtCjreKwYTT3l+r427qYC5Y8PihNutepr8XrNaBUDQo9khWUwQxZaqt5A==", "dev": true, "license": "MIT", "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", "immer": "^10.0.3", "redux": "^5.0.1", "redux-thunk": "^3.1.0", @@ -3828,9 +3863,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.3.tgz", - "integrity": "sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==", + "version": "28.0.6", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.6.tgz", + "integrity": "sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw==", "dev": true, "license": "MIT", "dependencies": { @@ -3855,9 +3890,9 @@ } }, "node_modules/@rollup/plugin-commonjs/node_modules/fdir": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", - "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -3976,9 +4011,9 @@ } }, "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.2.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", + "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==", "dev": true, "license": "MIT", "dependencies": { @@ -4012,9 +4047,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.39.0.tgz", - "integrity": "sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.1.tgz", + "integrity": "sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==", "cpu": [ "arm" ], @@ -4026,9 +4061,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.39.0.tgz", - "integrity": "sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.1.tgz", + "integrity": "sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==", "cpu": [ "arm64" ], @@ -4040,9 +4075,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.39.0.tgz", - "integrity": "sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.1.tgz", + "integrity": "sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==", "cpu": [ "arm64" ], @@ -4054,9 +4089,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.39.0.tgz", - "integrity": "sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.1.tgz", + "integrity": "sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==", "cpu": [ "x64" ], @@ -4068,9 +4103,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.39.0.tgz", - "integrity": "sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.1.tgz", + "integrity": "sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==", "cpu": [ "arm64" ], @@ -4082,9 +4117,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.39.0.tgz", - "integrity": "sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.1.tgz", + "integrity": "sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==", "cpu": [ "x64" ], @@ -4096,9 +4131,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.39.0.tgz", - "integrity": "sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.1.tgz", + "integrity": "sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==", "cpu": [ "arm" ], @@ -4110,9 +4145,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.39.0.tgz", - "integrity": "sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.1.tgz", + "integrity": "sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==", "cpu": [ "arm" ], @@ -4124,9 +4159,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.39.0.tgz", - "integrity": "sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.1.tgz", + "integrity": "sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==", "cpu": [ "arm64" ], @@ -4138,9 +4173,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.39.0.tgz", - "integrity": "sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.1.tgz", + "integrity": "sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==", "cpu": [ "arm64" ], @@ -4152,9 +4187,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.39.0.tgz", - "integrity": "sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.1.tgz", + "integrity": "sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==", "cpu": [ "loong64" ], @@ -4166,9 +4201,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.39.0.tgz", - "integrity": "sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.1.tgz", + "integrity": "sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==", "cpu": [ "ppc64" ], @@ -4180,9 +4215,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.39.0.tgz", - "integrity": "sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.1.tgz", + "integrity": "sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==", "cpu": [ "riscv64" ], @@ -4194,9 +4229,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.39.0.tgz", - "integrity": "sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.1.tgz", + "integrity": "sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==", "cpu": [ "riscv64" ], @@ -4208,9 +4243,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.39.0.tgz", - "integrity": "sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.1.tgz", + "integrity": "sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==", "cpu": [ "s390x" ], @@ -4222,9 +4257,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.39.0.tgz", - "integrity": "sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.1.tgz", + "integrity": "sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==", "cpu": [ "x64" ], @@ -4236,9 +4271,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.39.0.tgz", - "integrity": "sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.1.tgz", + "integrity": "sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==", "cpu": [ "x64" ], @@ -4250,9 +4285,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.39.0.tgz", - "integrity": "sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.1.tgz", + "integrity": "sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==", "cpu": [ "arm64" ], @@ -4264,9 +4299,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.39.0.tgz", - "integrity": "sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.1.tgz", + "integrity": "sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==", "cpu": [ "ia32" ], @@ -4278,9 +4313,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.39.0.tgz", - "integrity": "sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.1.tgz", + "integrity": "sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==", "cpu": [ "x64" ], @@ -4291,16 +4326,30 @@ "win32" ] }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "dev": true, + "license": "MIT" + }, "node_modules/@swc/core": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.11.18.tgz", - "integrity": "sha512-ORZxyCKKiqYt2iHdh1C7pfVR1GBjkuFOdwqZggQzaq0vt22DpGca+2JsUtkUoWQmWcct04v5+ScwgvsHuMObxA==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.12.9.tgz", + "integrity": "sha512-O+LfT2JlVMsIMWG9x+rdxg8GzpzeGtCZQfXV7cKc1PjIKUkLFf1QJ7okuseA4f/9vncu37dQ2ZcRrPKy0Ndd5g==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.21" + "@swc/types": "^0.1.23" }, "engines": { "node": ">=10" @@ -4310,19 +4359,19 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.11.18", - "@swc/core-darwin-x64": "1.11.18", - "@swc/core-linux-arm-gnueabihf": "1.11.18", - "@swc/core-linux-arm64-gnu": "1.11.18", - "@swc/core-linux-arm64-musl": "1.11.18", - "@swc/core-linux-x64-gnu": "1.11.18", - "@swc/core-linux-x64-musl": "1.11.18", - "@swc/core-win32-arm64-msvc": "1.11.18", - "@swc/core-win32-ia32-msvc": "1.11.18", - "@swc/core-win32-x64-msvc": "1.11.18" + "@swc/core-darwin-arm64": "1.12.9", + "@swc/core-darwin-x64": "1.12.9", + "@swc/core-linux-arm-gnueabihf": "1.12.9", + "@swc/core-linux-arm64-gnu": "1.12.9", + "@swc/core-linux-arm64-musl": "1.12.9", + "@swc/core-linux-x64-gnu": "1.12.9", + "@swc/core-linux-x64-musl": "1.12.9", + "@swc/core-win32-arm64-msvc": "1.12.9", + "@swc/core-win32-ia32-msvc": "1.12.9", + "@swc/core-win32-x64-msvc": "1.12.9" }, "peerDependencies": { - "@swc/helpers": "*" + "@swc/helpers": ">=0.5.17" }, "peerDependenciesMeta": { "@swc/helpers": { @@ -4331,9 +4380,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.18.tgz", - "integrity": "sha512-K6AntdUlNMQg8aChqjeXwnVhK6d4WRZ9TgtLSTmdU0Ugll4an7QK49s9NrT7XQU91cEsVvzdr++p1bNImx0hJg==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.12.9.tgz", + "integrity": "sha512-GACFEp4nD6V+TZNR2JwbMZRHB+Yyvp14FrcmB6UCUYmhuNWjkxi+CLnEvdbuiKyQYv0zA+TRpCHZ+whEs6gwfA==", "cpu": [ "arm64" ], @@ -4348,9 +4397,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.11.18.tgz", - "integrity": "sha512-RCRvC6Q9M5BArTvj/IzUAAYGrgxYFbTTnAtf6UX7JFq2DAn+hEwYUjmC1m0gFso9HqFU0m5QZUGfZvVmACGWUw==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.12.9.tgz", + "integrity": "sha512-hv2kls7Ilkm2EpeJz+I9MCil7pGS3z55ZAgZfxklEuYsxpICycxeH+RNRv4EraggN44ms+FWCjtZFu0LGg2V3g==", "cpu": [ "x64" ], @@ -4365,9 +4414,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.18.tgz", - "integrity": "sha512-wteAKf8YKb3jOnZFm3EzuIMzzCVXMuQOLHsz1IgEOc44/gdgNXKxaYTWAowZuej7t68tf/w0cRNMc7Le414v/g==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.12.9.tgz", + "integrity": "sha512-od9tDPiG+wMU9wKtd6y3nYJdNqgDOyLdgRRcrj1/hrbHoUPOM8wZQZdwQYGarw63iLXGgsw7t5HAF9Yc51ilFA==", "cpu": [ "arm" ], @@ -4382,9 +4431,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.18.tgz", - "integrity": "sha512-hY6jJYZ6PKHSBo5OATswfyKsUgsWu9+4nDcN8liYIRRgz3E0G9wk0VUTP4cFPivBFeHWTTAGz687/Nf2aQEIpw==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.12.9.tgz", + "integrity": "sha512-6qx1ka9LHcLzxIgn2Mros+CZLkHK2TawlXzi/h7DJeNnzi8F1Hw0Yzjp8WimxNCg6s2n+o3jnmin1oXB7gg8rw==", "cpu": [ "arm64" ], @@ -4399,9 +4448,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.18.tgz", - "integrity": "sha512-slu0mlP2nucvQalttnapfpqpD/LlM9NHx9g3ofgsLzjObyMEBiX4ZysQ3y65U8Mjw71RNqtLd/ZmvxI6OmLdiQ==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.12.9.tgz", + "integrity": "sha512-yghFZWKPVVGbUdqiD7ft23G0JX6YFGDJPz9YbLLAwGuKZ9th3/jlWoQDAw1Naci31LQhVC+oIji6ozihSuwB2A==", "cpu": [ "arm64" ], @@ -4416,9 +4465,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.18.tgz", - "integrity": "sha512-h9a/8PA25arMCQ9t8CE8rA1s0c77z4kCZZ7dUuUkD88yEXIrARMca1IKR7of+S3slfQrf1Zlq3Ac1Fb1HVJziQ==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.12.9.tgz", + "integrity": "sha512-SFUxyhWLZRNL8QmgGNqdi2Q43PNyFVkRZ2zIif30SOGFSxnxcf2JNeSeBgKIGVgaLSuk6xFVVCtJ3KIeaStgRg==", "cpu": [ "x64" ], @@ -4433,9 +4482,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.18.tgz", - "integrity": "sha512-0sMDJj5qUGK9QEw4lrxLxkTP/4AoKciqNzXvqbk+J9XuXN2aIv4BsR1Y7z3GwAeMFGsba2lbHLOtJlDsaqIsiA==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.12.9.tgz", + "integrity": "sha512-9FB0wM+6idCGTI20YsBNBg9xSWtkDBymnpaTCsZM3qDc0l4uOpJMqbfWhQvp17x7r/ulZfb2QY8RDvQmCL6AcQ==", "cpu": [ "x64" ], @@ -4450,9 +4499,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.18.tgz", - "integrity": "sha512-zGv9HnfgBcKyt54MJRWdwRNu9BuYkAFM7bx+tWtKhd37Ef7ZX20QLs9xXl5wWDXCbsOdRxXIZgXs6PEL+Pzmrw==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.12.9.tgz", + "integrity": "sha512-zHOusMVbOH9ik5RtRrMiGzLpKwxrPXgXkBm3SbUCa65HAdjV33NZ0/R9Rv1uPESALtEl2tzMYLUxYA5ECFDFhA==", "cpu": [ "arm64" ], @@ -4467,9 +4516,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.18.tgz", - "integrity": "sha512-uBKj0S1lYv/E2ZhxHZOxSiQwoegYmzbPRpjq6eHBZDv97mu7W3K27/lsnPbvAfQ6b6rnv8BI+EsmJ7VLQBAHBQ==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.12.9.tgz", + "integrity": "sha512-aWZf0PqE0ot7tCuhAjRkDFf41AzzSQO0x2xRfTbnhpROp57BRJ/N5eee1VULO/UA2PIJRG7GKQky5bSGBYlFug==", "cpu": [ "ia32" ], @@ -4484,9 +4533,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.18.tgz", - "integrity": "sha512-8USTRcdgeFMNBgvVXl8tz6n4+9s9m+zHsfDeBT4jPgwnq2bnLBlTUlwnPwzDxfg9nUJr6RFD4xeKfWyZZRosZg==", + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.12.9.tgz", + "integrity": "sha512-C25fYftXOras3P3anSUeXXIpxmEkdAcsIL9yrr0j1xepTZ/yKwpnQ6g3coj8UXdeJy4GTVlR6+Ow/QiBgZQNOg==", "cpu": [ "x64" ], @@ -4508,9 +4557,9 @@ "license": "Apache-2.0" }, "node_modules/@swc/types": { - "version": "0.1.21", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.21.tgz", - "integrity": "sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.23.tgz", + "integrity": "sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4585,9 +4634,9 @@ } }, "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, "license": "MIT", "dependencies": { @@ -4669,9 +4718,9 @@ } }, "node_modules/@types/content-disposition": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz", - "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.9.tgz", + "integrity": "sha512-8uYXI3Gw35MhiVYhG3s295oihrxRyytcRHjSjqnqZVDDy/xcGBRny7+Xj1Wgfhv5QzRtN2hB2dVRBUX9XW3UcQ==", "dev": true, "license": "MIT" }, @@ -4683,9 +4732,9 @@ "license": "MIT" }, "node_modules/@types/cookies": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.0.tgz", - "integrity": "sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-E/DPgzifH4sM1UMadJMWd6mO2jOd4g1Ejwzx8/uRCDpJis1IrlyQEcGAYEomtAqRYmD5ORbNXMeI9U0RiVGZbg==", "dev": true, "license": "MIT", "dependencies": { @@ -4725,9 +4774,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -4739,9 +4788,9 @@ "license": "MIT" }, "node_modules/@types/express": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.1.tgz", - "integrity": "sha512-UZUw8vjpWFXuDnjFTh7/5c2TWDlQqeXHi6hcN7F2XSVT5P+WmUnnbFS3KA6Jnc6IsEqI2qCVu2bK0R0J4A8ZQQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz", + "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==", "dev": true, "license": "MIT", "dependencies": { @@ -4764,9 +4813,9 @@ } }, "node_modules/@types/glob-stream": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@types/glob-stream/-/glob-stream-8.0.2.tgz", - "integrity": "sha512-kyuRfGE+yiSJWzSO3t74rXxdZNdYfLcllO0IUha4eX1fl40pm9L02Q/TEc3mykTLjoWz4STBNwYnUWdFu3I0DA==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@types/glob-stream/-/glob-stream-8.0.3.tgz", + "integrity": "sha512-vctgrT9AH/GK3TRaIbRUU0TZn12GBU4kzelZdPyJp1Sc8L/6Wrq21UrtN4+x4saqTg6COUIUtFV6JSYcVln/EQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4806,9 +4855,9 @@ "license": "MIT" }, "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "dev": true, "license": "MIT" }, @@ -4942,12 +4991,22 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.14.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz", - "integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==", + "version": "24.0.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.4.tgz", + "integrity": "sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "@types/node": "*", + "form-data": "^4.0.0" } }, "node_modules/@types/parse5": { @@ -4987,9 +5046,9 @@ "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.18", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", - "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "dev": true, "license": "MIT" }, @@ -5035,9 +5094,9 @@ "license": "MIT" }, "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", "dev": true, "license": "MIT", "dependencies": { @@ -5046,9 +5105,9 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", "dev": true, "license": "MIT", "dependencies": { @@ -5058,9 +5117,9 @@ } }, "node_modules/@types/stats.js": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", - "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", + "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", "dev": true, "license": "MIT" }, @@ -5075,12 +5134,13 @@ } }, "node_modules/@types/three": { - "version": "0.174.0", - "resolved": "https://registry.npmjs.org/@types/three/-/three-0.174.0.tgz", - "integrity": "sha512-De/+vZnfg2aVWNiuy1Ldu+n2ydgw1osinmiZTAn0necE++eOfsygL8JpZgFjR2uHmAPo89MkxBj3JJ+2BMe+Uw==", + "version": "0.177.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.177.0.tgz", + "integrity": "sha512-/ZAkn4OLUijKQySNci47lFO+4JLE1TihEjsGWPUT+4jWqxtwOPPEwJV1C3k5MEx0mcBPCdkFjzRzDOnHEI1R+A==", "dev": true, "license": "MIT", "dependencies": { + "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": "*", @@ -5150,9 +5210,9 @@ } }, "node_modules/@types/webxr": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.21.tgz", - "integrity": "sha512-geZIAtLzjGmgY2JUi6VxXdCrTb99A7yP49lxLr2Nm/uIK0PkkxcEi4OGhoGDO4pxCf3JwGz2GiJL2Ej4K2bKaA==", + "version": "0.5.22", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.22.tgz", + "integrity": "sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==", "dev": true, "license": "MIT" }, @@ -5204,21 +5264,21 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz", - "integrity": "sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz", + "integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.29.1", - "@typescript-eslint/type-utils": "8.29.1", - "@typescript-eslint/utils": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/type-utils": "8.35.1", + "@typescript-eslint/utils": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5228,22 +5288,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "@typescript-eslint/parser": "^8.35.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.1.tgz", - "integrity": "sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz", + "integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.29.1", - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/typescript-estree": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4" }, "engines": { @@ -5258,15 +5318,37 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz", + "integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.35.1", + "@typescript-eslint/types": "^8.35.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz", - "integrity": "sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5276,17 +5358,34 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz", + "integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.1.tgz", - "integrity": "sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz", + "integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.29.1", - "@typescript-eslint/utils": "8.29.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/utils": "8.35.1", "debug": "^4.3.4", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5301,9 +5400,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.1.tgz", - "integrity": "sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "license": "MIT", "engines": { @@ -5315,20 +5414,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz", - "integrity": "sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1", + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5342,16 +5443,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.1.tgz", - "integrity": "sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz", + "integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.29.1", - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/typescript-estree": "8.29.1" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5366,14 +5467,14 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz", - "integrity": "sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.29.1", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5384,9 +5485,9 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5589,16 +5690,16 @@ } }, "node_modules/@web/test-runner": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.20.0.tgz", - "integrity": "sha512-xN+4wgEm5xh0VSiC08eUYXW0QDt/NuzZyey4s7Nnjyjs9NkuJHd1jG9aNzfgL1edpJJ/RldHc0KiM2to1h2kxQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.20.2.tgz", + "integrity": "sha512-zfEGYEDnS0EI8qgoWFjmtkIXhqP15W40NW3dCaKtbxj5eU0a7E53f3GV/tZGD0GlZKF8d4Fyw+AFrwOJU9Z4GA==", "dev": true, "license": "MIT", "dependencies": { "@web/browser-logs": "^0.4.0", "@web/config-loader": "^0.3.0", "@web/dev-server": "^0.4.0", - "@web/test-runner-chrome": "^0.18.0", + "@web/test-runner-chrome": "^0.18.1", "@web/test-runner-commands": "^0.9.0", "@web/test-runner-core": "^0.13.0", "@web/test-runner-mocha": "^0.9.0", @@ -5621,15 +5722,14 @@ } }, "node_modules/@web/test-runner-chrome": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@web/test-runner-chrome/-/test-runner-chrome-0.18.0.tgz", - "integrity": "sha512-EkB70HtHwY36pIbgn9HzqtKAv+i53qa0/UBrs+H0m8j24TxIEH9oWIdF9O/RFxjYpla7fIvZMhOFOjejgrRU5g==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@web/test-runner-chrome/-/test-runner-chrome-0.18.1.tgz", + "integrity": "sha512-eO6ctCaqSguGM6G3cFobGHnrEs9wlv9Juj/Akyr4XLjeEMTheNULdvOXw9Bygi+QC/ir/0snMmt+/YKnfy8rYA==", "dev": true, "license": "MIT", "dependencies": { "@web/test-runner-core": "^0.13.0", "@web/test-runner-coverage-v8": "^0.8.0", - "async-mutex": "0.4.0", "chrome-launcher": "^0.15.0", "puppeteer-core": "^24.0.0" }, @@ -5651,19 +5751,6 @@ "node": ">=18.0.0" } }, - "node_modules/@web/test-runner-commands/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@web/test-runner-core": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.4.tgz", @@ -5753,15 +5840,15 @@ } }, "node_modules/@web/test-runner-playwright": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.11.0.tgz", - "integrity": "sha512-s+f43DSAcssKYVOD9SuzueUcctJdHzq1by45gAnSCKa9FQcaTbuYe8CzmxA21g+NcL5+ayo4z+MA9PO4H+PssQ==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.11.1.tgz", + "integrity": "sha512-l9tmX0LtBqMaKAApS4WshpB87A/M8sOHZyfCobSGuYqnREgz5rqQpX314yx+4fwHXLLTa5N64mTrawsYkLjliw==", "dev": true, "license": "MIT", "dependencies": { "@web/test-runner-core": "^0.13.0", "@web/test-runner-coverage-v8": "^0.8.0", - "playwright": "^1.22.2" + "playwright": "^1.53.0" }, "engines": { "node": ">=18.0.0" @@ -5784,9 +5871,9 @@ "license": "BSD-3-Clause" }, "node_modules/@webgpu/types": { - "version": "0.1.60", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.60.tgz", - "integrity": "sha512-8B/tdfRFKdrnejqmvq95ogp8tf52oZ51p3f4QD5m5Paey/qlX4Rhhy5Y8tgFMi7Ms70HzcMMw3EQjH/jdhTwlA==", + "version": "0.1.63", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.63.tgz", + "integrity": "sha512-s9Kuh0nE/2+nKrvmKNMB2fE5Zlr3DL2t3OFKM55v5jRcfCOxbkOHhQoshoFum5mmXIfEtRXtLCWmkeTJsVjE9w==", "dev": true, "license": "BSD-3-Clause" }, @@ -5815,9 +5902,9 @@ } }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -5920,16 +6007,6 @@ "node": ">=4" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -5946,19 +6023,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -5990,30 +6054,6 @@ "dev": true, "license": "MIT" }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -6170,15 +6210,11 @@ "node": ">= 0.4" } }, - "node_modules/async-mutex": { + "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", - "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - } + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/available-typed-arrays": { "version": "1.0.7", @@ -6703,6 +6739,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, "license": "MIT" }, "node_modules/bare-events": { @@ -6713,9 +6750,9 @@ "optional": true }, "node_modules/bare-fs": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.2.tgz", - "integrity": "sha512-8wSeOia5B7LwD4+h465y73KOdj5QHsbbuoUfPBi+pXgFJIPuG7SsiOdJuijWMyfid49eD+WivpfY7KT8gbAzBA==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.5.tgz", + "integrity": "sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -6819,19 +6856,6 @@ "node": ">=10.0.0" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/blocking-elements": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/blocking-elements/-/blocking-elements-0.1.1.tgz", @@ -6994,9 +7018,10 @@ } }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -7029,6 +7054,33 @@ "node": ">=8.0" } }, + "node_modules/browser-capabilities/node_modules/ua-parser-js": { + "version": "0.7.40", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz", + "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -7037,9 +7089,9 @@ "license": "ISC" }, "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.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "dev": true, "funding": [ { @@ -7057,10 +7109,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -7257,9 +7309,9 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001712", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001712.tgz", - "integrity": "sha512-MBqPpGYYdQ7/hfKiet9SCI+nmN5/hp4ZzveOJubl5DTAMa5oggjAuoi0Z4onBpKPFI2ePGnQuQIzF3VxDjDJig==", + "version": "1.0.30001726", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", + "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", "dev": true, "funding": [ { @@ -7385,9 +7437,9 @@ } }, "node_modules/chromium-bidi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-3.0.0.tgz", - "integrity": "sha512-ZOGRDAhBMX1uxL2Cm2TDuhImbrsEz5A/tTcVU6RpXEWaTNUNwsHW6njUXizh51Ir6iqHbKAfhA2XK33uBcLo5A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-5.1.0.tgz", + "integrity": "sha512-9MSRhWRVoRPDG0TgzkHrshFSJJNZzfY5UFqUMuksg7zL1yoZIZ3jLB0YAgHclbiAxPI86pBnwDX1tbzoiV8aFw==", "license": "Apache-2.0", "dependencies": { "mitt": "^3.0.1", @@ -7608,6 +7660,18 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/command-line-args": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", @@ -8161,9 +8225,9 @@ "license": "MIT" }, "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.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -8304,6 +8368,15 @@ "node": ">= 14" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -8342,6 +8415,26 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-europe-js": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/detect-europe-js/-/detect-europe-js-0.1.2.tgz", + "integrity": "sha512-lgdERlL3u0aUdHocoouzT10d9I89VVhk0qNRmll7mXdGfJT1/wqZ2ZLA4oJAjeACPY5fT1wsbq2AT+GkuInsow==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "license": "MIT" + }, "node_modules/detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", @@ -8356,9 +8449,9 @@ } }, "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -8366,9 +8459,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1425554", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1425554.tgz", - "integrity": "sha512-uRfxR6Nlzdzt0ihVIkV+sLztKgs7rgquY/Mhcv1YNCWDh5IZgl5mnn2aeEnW5stYTE0wwiF4RYVz8eMEpV1SEw==", + "version": "0.0.1464554", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1464554.tgz", + "integrity": "sha512-CAoP3lYfwAGQTaAXYvA6JZR0fjGUb7qec1qf4mToyoH2TZgUFeIqYcjh6f9jNuhHfuZiEdH+PONHYrLhRQX6aw==", "license": "BSD-3-Clause" }, "node_modules/diff": { @@ -8555,9 +8648,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.134", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.134.tgz", - "integrity": "sha512-zSwzrLg3jNP3bwsLqWHmS5z2nIOQ5ngMnfMZOWWtXnqqQkPVyOipxK98w+1beLw1TB+EImPNcG8wVP/cLVs2Og==", + "version": "1.5.177", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.177.tgz", + "integrity": "sha512-7EH2G59nLsEMj97fpDuvVcYi6lwTcM1xuWw3PssD8xzboAW7zj7iB3COEEEATUfjLHrs5uKBLQT03V/8URx06g==", "dev": true, "license": "ISC" }, @@ -8594,9 +8687,9 @@ } }, "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "license": "MIT", "dependencies": { "once": "^1.4.0" @@ -8628,9 +8721,9 @@ "license": "MIT" }, "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", "dependencies": { @@ -8638,18 +8731,18 @@ "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", @@ -8661,21 +8754,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", @@ -8684,7 +8780,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" @@ -8712,9 +8808,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "dev": true, "license": "MIT" }, @@ -8734,7 +8830,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -8822,20 +8917,20 @@ } }, "node_modules/eslint": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz", - "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.30.0.tgz", + "integrity": "sha512-iN/SiPxmQu6EVkf+m1qpBxzUhE12YqFLOSySuOyVLJLEF9nzTf+h/1AJYc1JWzCnktggeNrjvQGLngDzXirU6g==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.0", - "@eslint/core": "^0.12.0", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.0", + "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.24.0", - "@eslint/plugin-kit": "^0.2.7", + "@eslint/js": "9.30.0", + "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -8846,9 +8941,9 @@ "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -8896,57 +8991,50 @@ } }, "node_modules/eslint-plugin-mocha": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.5.0.tgz", - "integrity": "sha512-F2ALmQVPT1GoP27O1JTZGrV9Pqg8k79OeIuvw63UxMtQKREZtmkK1NFgkZQ2TW7L2JSSFKHFPTtHu5z8R9QNRw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-11.1.0.tgz", + "integrity": "sha512-rKntVWRsQFPbf8OkSgVNRVRrcVAPaGTyEgWCEyXaPDJkTl0v5/lwu1vTk5sWiUJU8l2sxwvGUZzSNrEKdVMeQw==", "dev": true, "license": "MIT", "dependencies": { - "eslint-utils": "^3.0.0", - "globals": "^13.24.0", - "rambda": "^7.4.0" - }, - "engines": { - "node": ">=14.0.0" + "@eslint-community/eslint-utils": "^4.4.1", + "globals": "^15.14.0" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": ">=9.0.0" } }, "node_modules/eslint-plugin-mocha/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint-plugin-wc": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.2.1.tgz", - "integrity": "sha512-KstLqGmyQz088DvFlDYHg0sHih+w2QeulreCi1D1ftr357klO2zqHdG/bbnNMmuQdVFDuNkopNIyNhmG0XCT/g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-3.0.1.tgz", + "integrity": "sha512-0p1wkSlA2Ue3FA4qW+5LZ+15sy0p1nUyVl1eyBMLq4rtN1LtE9IdI49BXNWMz8N8bM/y7Ulx8SWGAni5f8XO5g==", "dev": true, "license": "MIT", "dependencies": { "is-valid-element-name": "^1.0.0", - "js-levenshtein-esm": "^1.2.0" + "js-levenshtein-esm": "^2.0.0" }, "peerDependencies": { "eslint": ">=8.40.0" } }, "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -8960,35 +9048,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -9003,9 +9062,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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", "dependencies": { @@ -9014,9 +9073,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -9026,6 +9085,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -9040,15 +9109,15 @@ } }, "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.14.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9058,9 +9127,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -9617,6 +9686,22 @@ "dev": true, "license": "BSD" }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -9708,6 +9793,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -9912,9 +10009,9 @@ } }, "node_modules/glob-stream/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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", "dependencies": { @@ -10079,9 +10176,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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", "dependencies": { @@ -10166,6 +10263,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/gltf-validator": { "version": "2.0.0-dev.3.10", "resolved": "https://registry.npmjs.org/gltf-validator/-/gltf-validator-2.0.0-dev.3.10.tgz", @@ -10268,9 +10375,9 @@ } }, "node_modules/gulp-match/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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", "dependencies": { @@ -10415,7 +10522,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -10671,9 +10777,9 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, "license": "MIT", "engines": { @@ -10933,19 +11039,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-boolean-object": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", @@ -11223,6 +11316,19 @@ "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", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -11404,6 +11510,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-standalone-pwa": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-standalone-pwa/-/is-standalone-pwa-0.1.1.tgz", + "integrity": "sha512-9Cbovsa52vNQCjdXOzeQq5CnCbAcRk05aU62K20WO372NrTv0NxibLFCK6lQ4/iZEFdEA3p3t2VNOn8AJ53F5g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "license": "MIT" + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -11750,9 +11876,9 @@ } }, "node_modules/js-levenshtein-esm": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/js-levenshtein-esm/-/js-levenshtein-esm-1.2.0.tgz", - "integrity": "sha512-fzreKVq1eD7eGcQr7MtRpQH94f8gIfhdrc7yeih38xh684TNMK9v5aAu2wxfIRMk/GpAJRrzcirMAPIaSDaByQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/js-levenshtein-esm/-/js-levenshtein-esm-2.0.0.tgz", + "integrity": "sha512-1n4LEPOL4wRXY8rOQcuA7Iuaphe5xCMayvufCzlLAi+hRsnBRDbSS6XPuV58CBVJxj5D9ApFLyjQ7KzFToyHBw==", "dev": true, "license": "MIT" }, @@ -12012,9 +12138,9 @@ } }, "node_modules/ktx-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-1.0.0.tgz", - "integrity": "sha512-Z31kVizz4DF/6vo9YiSYVBhuXAfyQy9bGxlW3+mB5OELoZjfXVZQpRoctsx8IEDKxBd6SagXKo7qRvu38i8Jfg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-1.0.1.tgz", + "integrity": "sha512-djwUWv/82Xc8LOVinJU4EBrVqYkO8OsUDSPEtY/OOVY8BSe3DMU7D7PlIAZ0pI7ZZtErj7mqpJcgffUTABvgaA==", "dev": true, "license": "MIT" }, @@ -12116,31 +12242,31 @@ "license": "MIT" }, "node_modules/lit": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz", - "integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.0.tgz", + "integrity": "sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==", "license": "BSD-3-Clause", "dependencies": { - "@lit/reactive-element": "^2.0.4", - "lit-element": "^4.1.0", - "lit-html": "^3.2.0" + "@lit/reactive-element": "^2.1.0", + "lit-element": "^4.2.0", + "lit-html": "^3.3.0" } }, "node_modules/lit-element": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz", - "integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.0.tgz", + "integrity": "sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==", "license": "BSD-3-Clause", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.2.0", - "@lit/reactive-element": "^2.0.4", - "lit-html": "^3.2.0" + "@lit/reactive-element": "^2.1.0", + "lit-html": "^3.3.0" } }, "node_modules/lit-html": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.1.tgz", - "integrity": "sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.0.tgz", + "integrity": "sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==", "license": "BSD-3-Clause", "dependencies": { "@types/trusted-types": "^2.0.2" @@ -12364,9 +12490,9 @@ } }, "node_modules/loupe": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", - "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz", + "integrity": "sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==", "dev": true, "license": "MIT" }, @@ -12433,9 +12559,9 @@ } }, "node_modules/marky": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", - "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz", + "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==", "dev": true, "license": "Apache-2.0" }, @@ -12573,7 +12699,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -12583,7 +12708,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -12629,9 +12753,9 @@ } }, "node_modules/minimatch-all/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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", "dependencies": { @@ -12677,44 +12801,42 @@ "license": "MIT" }, "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, "license": "MIT", "bin": { - "mkdirp": "dist/cjs/src/bin.js" + "mkdirp": "bin/cmd.js" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mocha": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", - "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==", + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.1.tgz", + "integrity": "sha512-5EK+Cty6KheMS/YLPPMJC64g5V61gIR25KsRItHw6x4hEKT6Njp1n9LOlH4gpevuwMVS66SXaBBpg+RWZkza4A==", "dev": true, "license": "MIT", "dependencies": { - "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", + "chokidar": "^4.0.1", "debug": "^4.3.5", - "diff": "^5.2.0", + "diff": "^7.0.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", "glob": "^10.4.5", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", + "minimatch": "^9.0.5", "ms": "^2.1.3", + "picocolors": "^1.1.1", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", - "workerpool": "^6.5.1", + "workerpool": "^9.2.0", "yargs": "^17.7.2", "yargs-parser": "^21.1.1", "yargs-unparser": "^2.0.0" @@ -12727,29 +12849,14 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/mocha/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/mocha/node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, + "license": "BSD-3-Clause", "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "node": ">=0.3.1" } }, "node_modules/mocha/node_modules/glob": { @@ -12773,71 +12880,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mocha/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -12997,6 +13039,48 @@ "lower-case": "^1.1.1" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -13096,9 +13180,9 @@ } }, "node_modules/npm-run-all/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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", "dependencies": { @@ -13815,9 +13899,9 @@ } }, "node_modules/pathval": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", - "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { @@ -13906,13 +13990,13 @@ } }, "node_modules/playwright": { - "version": "1.51.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz", - "integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==", + "version": "1.53.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.1.tgz", + "integrity": "sha512-LJ13YLr/ocweuwxyGf1XNFWIU4M2zUSo149Qbp+A4cpwDjsxRPj7k6H25LBrEHiEwxvRbD8HdwvQmRMSvquhYw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.51.1" + "playwright-core": "1.53.1" }, "bin": { "playwright": "cli.js" @@ -13925,9 +14009,9 @@ } }, "node_modules/playwright-core": { - "version": "1.51.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz", - "integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==", + "version": "1.53.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.1.tgz", + "integrity": "sha512-Z46Oq7tLAyT0lGoFx4DOuB1IA9D1TPj0QkYxpPVUnGDqHHvDpCftu1J2hM2PiWsNMoZh8+LQaarAWcDfPBc6zg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -14048,9 +14132,9 @@ } }, "node_modules/polymer-analyzer/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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", "dependencies": { @@ -14579,9 +14663,9 @@ } }, "node_modules/portfinder": { - "version": "1.0.35", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.35.tgz", - "integrity": "sha512-73JaFg4NwYNAufDtS5FsFu/PdM49ahJrO1i44aCRsDWju1z5wuGDaqyFUQWR6aJoK2JPDWlaYYAGFNIGTSUHSw==", + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.37.tgz", + "integrity": "sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==", "license": "MIT", "dependencies": { "async": "^3.2.6", @@ -14602,12 +14686,12 @@ } }, "node_modules/postprocessing": { - "version": "6.37.2", - "resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.37.2.tgz", - "integrity": "sha512-Xm3n1Usgk2eBkufb1ssYDNGb3EXmV2wdQQIRGAWD9yppOYwsHpb8/w/+Opvnx6uEOFyt3US1dFbET5DTSyrRiA==", + "version": "6.37.4", + "resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.37.4.tgz", + "integrity": "sha512-O4dv29MDRSjXgMF1Luz3YHlT7NawKIliCfO2OgUCtIMTLNMCg+v0RLuT9/LQSDtVNXxUHGyy3mucbF3UePcElA==", "license": "Zlib", "peerDependencies": { - "three": ">= 0.157.0 < 0.176.0" + "three": ">= 0.157.0 < 0.178.0" } }, "node_modules/prelude-ls": { @@ -14732,9 +14816,9 @@ "license": "ISC" }, "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -14752,17 +14836,17 @@ } }, "node_modules/puppeteer": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.6.0.tgz", - "integrity": "sha512-wYTB8WkzAr7acrlsp+0at1PZjOJPOxe6dDWKOG/kaX4Zjck9RXCFx3CtsxsAGzPn/Yv6AzgJC/CW1P5l+qxsqw==", + "version": "24.11.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.11.1.tgz", + "integrity": "sha512-QbccB/LgxX4tSZRzr9KQ1Jajdvu3n35Dlf/Otjz0QfR+6mDoZdMWLcWF94uQoC3OJerCyYm5hlU2Ru4nBoId2A==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.9.0", - "chromium-bidi": "3.0.0", + "@puppeteer/browsers": "2.10.5", + "chromium-bidi": "5.1.0", "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1425554", - "puppeteer-core": "24.6.0", + "devtools-protocol": "0.0.1464554", + "puppeteer-core": "24.11.1", "typed-query-selector": "^2.12.0" }, "bin": { @@ -14773,17 +14857,17 @@ } }, "node_modules/puppeteer-core": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.6.0.tgz", - "integrity": "sha512-Cukxysy12m0v350bhl/Gzof0XQYmtON9l2VvGp3D4BOQZVgyf+y5wIpcjDZQ/896Okoi95dKRGRV8E6a7SYAQQ==", + "version": "24.11.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.11.1.tgz", + "integrity": "sha512-I0Gv3jWBRY9E3NTBElp7br7Gaid5RbFTxCRRMHym1kCf0ompO0Pel4REGsGDwMWkg3uwFzIH7t7qXs3T4DKRWA==", "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.9.0", - "chromium-bidi": "3.0.0", - "debug": "^4.4.0", - "devtools-protocol": "0.0.1425554", + "@puppeteer/browsers": "2.10.5", + "chromium-bidi": "5.1.0", + "debug": "^4.4.1", + "devtools-protocol": "0.0.1464554", "typed-query-selector": "^2.12.0", - "ws": "^8.18.1" + "ws": "^8.18.2" }, "engines": { "node": ">=18" @@ -14850,13 +14934,6 @@ ], "license": "MIT" }, - "node_modules/rambda": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.5.0.tgz", - "integrity": "sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==", - "dev": true, - "license": "MIT" - }, "node_modules/randomatic": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", @@ -15295,16 +15372,6 @@ "dev": true, "license": "MIT" }, - "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", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, "node_modules/regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -15676,14 +15743,14 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", - "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" @@ -15699,9 +15766,9 @@ } }, "node_modules/rimraf/node_modules/jackspeak": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", - "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -15723,12 +15790,12 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { "node": "20 || >=22" @@ -15761,13 +15828,13 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.39.0.tgz", - "integrity": "sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.1.tgz", + "integrity": "sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.7" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -15777,26 +15844,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.39.0", - "@rollup/rollup-android-arm64": "4.39.0", - "@rollup/rollup-darwin-arm64": "4.39.0", - "@rollup/rollup-darwin-x64": "4.39.0", - "@rollup/rollup-freebsd-arm64": "4.39.0", - "@rollup/rollup-freebsd-x64": "4.39.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.39.0", - "@rollup/rollup-linux-arm-musleabihf": "4.39.0", - "@rollup/rollup-linux-arm64-gnu": "4.39.0", - "@rollup/rollup-linux-arm64-musl": "4.39.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.39.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.39.0", - "@rollup/rollup-linux-riscv64-gnu": "4.39.0", - "@rollup/rollup-linux-riscv64-musl": "4.39.0", - "@rollup/rollup-linux-s390x-gnu": "4.39.0", - "@rollup/rollup-linux-x64-gnu": "4.39.0", - "@rollup/rollup-linux-x64-musl": "4.39.0", - "@rollup/rollup-win32-arm64-msvc": "4.39.0", - "@rollup/rollup-win32-ia32-msvc": "4.39.0", - "@rollup/rollup-win32-x64-msvc": "4.39.0", + "@rollup/rollup-android-arm-eabi": "4.44.1", + "@rollup/rollup-android-arm64": "4.44.1", + "@rollup/rollup-darwin-arm64": "4.44.1", + "@rollup/rollup-darwin-x64": "4.44.1", + "@rollup/rollup-freebsd-arm64": "4.44.1", + "@rollup/rollup-freebsd-x64": "4.44.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.44.1", + "@rollup/rollup-linux-arm-musleabihf": "4.44.1", + "@rollup/rollup-linux-arm64-gnu": "4.44.1", + "@rollup/rollup-linux-arm64-musl": "4.44.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.44.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.44.1", + "@rollup/rollup-linux-riscv64-gnu": "4.44.1", + "@rollup/rollup-linux-riscv64-musl": "4.44.1", + "@rollup/rollup-linux-s390x-gnu": "4.44.1", + "@rollup/rollup-linux-x64-gnu": "4.44.1", + "@rollup/rollup-linux-x64-musl": "4.44.1", + "@rollup/rollup-win32-arm64-msvc": "4.44.1", + "@rollup/rollup-win32-ia32-msvc": "4.44.1", + "@rollup/rollup-win32-x64-msvc": "4.44.1", "fsevents": "~2.3.2" } }, @@ -16052,9 +16119,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -16235,9 +16302,9 @@ } }, "node_modules/shell-quote": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", - "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "dev": true, "license": "MIT", "engines": { @@ -16481,9 +16548,9 @@ } }, "node_modules/socks": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", - "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", + "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", "license": "MIT", "dependencies": { "ip-address": "^9.0.5", @@ -16607,6 +16674,20 @@ "node": ">= 0.6" } }, + "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": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", @@ -16625,9 +16706,9 @@ "license": "MIT" }, "node_modules/streamx": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", - "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", + "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", "license": "MIT", "dependencies": { "fast-fifo": "^1.3.2", @@ -16970,9 +17051,9 @@ } }, "node_modules/tar-fs": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz", - "integrity": "sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.10.tgz", + "integrity": "sha512-C1SwlQGNLe/jPNqapK8epDsXME7CAJR5RL3GcE6KWx1d9OUByzoHVcbu1VPI8tevg9H8Alae0AApHHFGzrD5zA==", "license": "MIT", "dependencies": { "pump": "^3.0.0", @@ -17162,14 +17243,14 @@ } }, "node_modules/terser": { - "version": "5.39.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", - "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.14.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -17227,9 +17308,9 @@ } }, "node_modules/three": { - "version": "0.174.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.174.0.tgz", - "integrity": "sha512-p+WG3W6Ov74alh3geCMkGK9NWuT62ee21cV3jEnun201zodVF4tCE5aZa2U122/mkLRmhJJUQmLLW1BH00uQJQ==", + "version": "0.177.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.177.0.tgz", + "integrity": "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg==", "license": "MIT" }, "node_modules/through2": { @@ -17311,9 +17392,9 @@ } }, "node_modules/tr46": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.0.tgz", - "integrity": "sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", "dev": true, "license": "MIT", "dependencies": { @@ -17412,9 +17493,9 @@ } }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -17523,9 +17604,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", - "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "devOptional": true, "license": "Apache-2.0", "bin": { @@ -17546,11 +17627,30 @@ "node": ">=8" } }, + "node_modules/ua-is-frozen": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ua-is-frozen/-/ua-is-frozen-0.1.2.tgz", + "integrity": "sha512-RwKDW2p3iyWn4UbaxpP2+VxwqXh0jpvdxsYpZ5j/MLLiQOfbsV5shpgQiw93+KMYQPcteeMQ289MaAFzs3G9pw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "license": "MIT" + }, "node_modules/ua-parser-js": { - "version": "0.7.40", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz", - "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==", - "dev": true, + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-2.0.4.tgz", + "integrity": "sha512-XiBOnM/UpUq21ZZ91q2AVDOnGROE6UQd37WrO9WBgw4u2eGvUCNOheMmZ3EfEUj7DLHr8tre+Um/436Of/Vwzg==", "funding": [ { "type": "opencollective", @@ -17565,7 +17665,14 @@ "url": "https://github.com/sponsors/faisalman" } ], - "license": "MIT", + "license": "AGPL-3.0-or-later", + "dependencies": { + "@types/node-fetch": "^2.6.12", + "detect-europe-js": "^0.1.2", + "is-standalone-pwa": "^0.1.1", + "node-fetch": "^2.7.0", + "ua-is-frozen": "^0.1.2" + }, "bin": { "ua-parser-js": "script/cli.js" }, @@ -17629,9 +17736,9 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -18453,9 +18560,9 @@ } }, "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.3.tgz", + "integrity": "sha512-slxCaKbYjEdFT/o2rH9xS1hf4uRDch1w7Uo+apxhZ+sf/1d9e0ZVkn42kPNGP2dgjIx6YFvSevj0zHvbWe2jdw==", "dev": true, "license": "Apache-2.0" }, @@ -18513,9 +18620,9 @@ } }, "node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -18666,9 +18773,9 @@ "license": "BSD-3-Clause" }, "node_modules/zod": { - "version": "3.24.2", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", - "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", + "version": "3.25.67", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz", + "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -18680,37 +18787,38 @@ "license": "Apache-2.0", "dependencies": { "@monogrid/gainmap-js": "^3.1.0", - "lit": "^3.2.1" + "lit": "^3.3.0", + "ua-parser-js": "^2.0.4" }, "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.3", - "@rollup/plugin-node-resolve": "^16.0.0", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@rollup/plugin-swc": "^0.4.0", "@rollup/plugin-terser": "^0.4.4", - "@swc/core": "^1.11.8", + "@swc/core": "^1.12.9", "@types/mocha": "^10.0.10", "@types/pngjs": "^6.0.5", - "@types/three": "^0.174.0", + "@types/three": "^0.177.0", "@ungap/event-target": "^0.2.4", - "@web/test-runner": "^0.20.0", - "@web/test-runner-playwright": "^0.11.0", + "@web/test-runner": "^0.20.2", + "@web/test-runner-playwright": "^0.11.1", "chai": "^5.2.0", "http-server": "^14.1.1", - "mocha": "^11.1.0", + "mocha": "^11.7.1", "npm-run-all": "^4.1.5", - "rollup": "^4.35.0", + "rollup": "^4.44.1", "rollup-plugin-cleanup": "^3.2.1", - "rollup-plugin-dts": "^6.1.1", + "rollup-plugin-dts": "^6.2.1", "rollup-plugin-polyfill": "^4.2.0", - "three": "^0.174.0", - "typescript": "5.8.2" + "three": "^0.177.0", + "typescript": "5.8.3" }, "engines": { "node": ">=6.0.0" }, "peerDependencies": { - "three": "^0.174.0" + "three": "^0.177.0" } }, "packages/model-viewer-effects": { @@ -18718,34 +18826,34 @@ "version": "1.4.0", "license": "Apache-2.0", "dependencies": { - "lit": "^3.2.1", - "postprocessing": "^6.37.1" + "lit": "^3.3.0", + "postprocessing": "^6.37.4" }, "devDependencies": { "@google/model-viewer": "^4.1.0", - "@rollup/plugin-commonjs": "^28.0.3", - "@rollup/plugin-node-resolve": "^16.0.0", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@rollup/plugin-swc": "^0.4.0", "@rollup/plugin-terser": "^0.4.4", - "@swc/core": "^1.11.8", + "@swc/core": "^1.12.9", "@types/mocha": "^10.0.10", "@types/pngjs": "^6.0.5", - "@types/three": "^0.174.0", + "@types/three": "^0.177.0", "@ungap/event-target": "^0.2.4", - "@web/test-runner": "^0.20.0", - "@web/test-runner-playwright": "^0.11.0", + "@web/test-runner": "^0.20.2", + "@web/test-runner-playwright": "^0.11.1", "chai": "^5.2.0", "focus-visible": "^5.2.1", "http-server": "^14.1.1", - "mocha": "^11.1.0", + "mocha": "^11.7.1", "npm-run-all": "^4.1.5", - "rollup": "^4.35.0", + "rollup": "^4.44.1", "rollup-plugin-cleanup": "^3.2.1", - "rollup-plugin-dts": "^6.1.1", + "rollup-plugin-dts": "^6.2.1", "rollup-plugin-polyfill": "^4.2.0", - "three": "^0.174.0", - "typescript": "5.8.2" + "three": "^0.177.0", + "typescript": "5.8.3" }, "engines": { "node": ">=6.0.0" @@ -18760,22 +18868,36 @@ "license": "Apache-2.0", "dependencies": { "@google/model-viewer": "^4.1.0", - "@google/model-viewer-effects": "^1.4.0", + "@google/model-viewer-effects": "^1.5.0", "@types/prismjs": "^1.26.5", "focus-visible": "^5.2.1", - "lit": "^3.2.1", + "lit": "^3.3.0", "prismjs": "^1.30.0" }, "devDependencies": { - "@rollup/plugin-node-resolve": "^16.0.0", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@rollup/plugin-swc": "^0.4.0", - "@swc/core": "^1.11.8", - "rollup": "^4.35.0", - "typescript": "5.8.2" + "@swc/core": "^1.12.9", + "rollup": "^4.44.1", + "typescript": "5.8.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "packages/modelviewer.dev/node_modules/@google/model-viewer-effects": { + "version": "1.5.0", + "license": "Apache-2.0", + "dependencies": { + "lit": "^3.2.1", + "postprocessing": "^6.37.1" }, "engines": { "node": ">=6.0.0" + }, + "peerDependencies": { + "@google/model-viewer": "^4.1.0" } }, "packages/render-fidelity-tools": { @@ -18790,36 +18912,151 @@ "@polymer/paper-slider": "^3.0.1", "@types/http-server": "^0.12.4", "@types/pngjs": "^6.0.5", + "get-east-asian-width": "^1.3.0", "http-server": "^14.1.1", - "lit": "^3.2.1", + "lit": "^3.3.0", "mkdirp": "^3.0.1", "pngjs": "^7.0.0", - "puppeteer": "^24.4.0", + "puppeteer": "^24.11.1", "rimraf": "^6.0.1", - "yargs": "^17.7.2" + "yargs": "^18.0.0" }, "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.3", - "@rollup/plugin-node-resolve": "^16.0.0", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@types/yargs": "^17.0.33", "polymer-build": "^3.1.4", - "rollup": "^4.35.0", + "rollup": "^4.44.1", "rollup-plugin-external-globals": "^0.13.0", - "typescript": "5.8.2" + "typescript": "5.8.3" }, "engines": { "node": ">=12.0.0" } }, + "packages/render-fidelity-tools/node_modules/ansi-regex": { + "version": "6.1.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "packages/render-fidelity-tools/node_modules/ansi-styles": { + "version": "6.2.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "packages/render-fidelity-tools/node_modules/cliui": { + "version": "9.0.1", + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "packages/render-fidelity-tools/node_modules/emoji-regex": { + "version": "10.4.0", + "license": "MIT" + }, + "packages/render-fidelity-tools/node_modules/mkdirp": { + "version": "3.0.1", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/render-fidelity-tools/node_modules/string-width": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/render-fidelity-tools/node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "packages/render-fidelity-tools/node_modules/wrap-ansi": { + "version": "9.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "packages/render-fidelity-tools/node_modules/yargs": { + "version": "18.0.0", + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "packages/render-fidelity-tools/node_modules/yargs-parser": { + "version": "22.0.0", + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, "packages/space-opera": { "name": "@google/model-viewer-space-opera", "version": "0.0.1", "license": "Apache-2.0", "devDependencies": { - "@gltf-transform/core": "^4.1.2", - "@gltf-transform/extensions": "^4.1.2", - "@gltf-transform/functions": "^4.1.2", + "@gltf-transform/core": "^4.2.0", + "@gltf-transform/extensions": "^4.2.0", + "@gltf-transform/functions": "^4.2.0", "@google/model-viewer": "^4.1.0", "@material/mwc-button": "^0.27.0", "@material/mwc-checkbox": "^0.27.0", @@ -18834,30 +19071,30 @@ "@polymer/paper-item": "^3.0.1", "@polymer/paper-listbox": "^3.0.1", "@polymer/paper-slider": "^3.0.1", - "@reduxjs/toolkit": "^2.6.1", - "@rollup/plugin-commonjs": "^28.0.3", - "@rollup/plugin-node-resolve": "^16.0.0", + "@reduxjs/toolkit": "^2.8.2", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-swc": "^0.4.0", - "@swc/core": "^1.11.8", + "@swc/core": "^1.12.9", "@types/js-beautify": "^1.14.3", "@types/remote-redux-devtools": "^0.5.8", - "@web/test-runner": "^0.20.0", - "@web/test-runner-playwright": "^0.11.0", + "@web/test-runner": "^0.20.2", + "@web/test-runner-playwright": "^0.11.1", "chai": "^5.2.0", "gltf-validator": "^2.0.0-dev.3.10", "http-server": "^14.1.1", "js-beautify": "^1.15.4", "jszip": "^3.10.1", - "lit": "^3.2.1", + "lit": "^3.3.0", "npm-run-all": "^4.1.5", "pwa-helpers": "^0.9.1", "qrious": "^4.0.2", "redux": "^5.0.1", "remote-redux-devtools": "^0.5.16", - "rollup": "^4.35.0", + "rollup": "^4.44.1", "simple-dropzone": "^0.8.3", "ts-closure-library": "^2022.502.5", - "typescript": "5.8.2", + "typescript": "5.8.3", "web-animations-js": "^2.3.2" }, "engines": { diff --git a/package.json b/package.json index a8a9411258..e73ea3ad61 100644 --- a/package.json +++ b/package.json @@ -39,18 +39,20 @@ }, "homepage": "https://github.com/google/model-viewer#readme", "devDependencies": { - "@typescript-eslint/eslint-plugin": "^8.26.1", - "@typescript-eslint/parser": "^8.26.1", + "@types/ua-parser-js": "^0.7.39", + "@typescript-eslint/eslint-plugin": "^8.35.1", + "@typescript-eslint/parser": "^8.35.1", "clang-format": "^1.8.0", - "eslint": "^9.22.0", + "eslint": "^9.30.0", "eslint-config-google": "^0.14.0", - "eslint-plugin-mocha": "^10.5.0", - "eslint-plugin-wc": "^2.2.1", + "eslint-plugin-mocha": "^11.1.0", + "eslint-plugin-wc": "^3.0.1", "http-server": "^14.1.1", "husky": "^9.1.7", - "typescript": "5.8.2" + "typescript": "5.8.3" }, "dependencies": { - "puppeteer": "^24.4.0" + "puppeteer": "^24.11.1", + "ua-parser-js": "^2.0.4" } } diff --git a/packages/model-viewer-effects/package.json b/packages/model-viewer-effects/package.json index 56e9c9e56a..6b4ccc7cc3 100644 --- a/packages/model-viewer-effects/package.json +++ b/packages/model-viewer-effects/package.json @@ -72,37 +72,37 @@ "filter" ], "dependencies": { - "lit": "^3.2.1", - "postprocessing": "^6.37.1" + "lit": "^3.3.0", + "postprocessing": "^6.37.4" }, "peerDependencies": { "@google/model-viewer": "^4.1.0" }, "devDependencies": { "@google/model-viewer": "^4.1.0", - "@rollup/plugin-commonjs": "^28.0.3", - "@rollup/plugin-node-resolve": "^16.0.0", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@types/mocha": "^10.0.10", "@types/pngjs": "^6.0.5", - "@types/three": "^0.174.0", + "@types/three": "^0.177.0", "@ungap/event-target": "^0.2.4", - "@web/test-runner": "^0.20.0", - "@web/test-runner-playwright": "^0.11.0", + "@web/test-runner": "^0.20.2", + "@web/test-runner-playwright": "^0.11.1", "chai": "^5.2.0", "@rollup/plugin-swc": "^0.4.0", - "@swc/core": "^1.11.8", + "@swc/core": "^1.12.9", "focus-visible": "^5.2.1", "http-server": "^14.1.1", - "mocha": "^11.1.0", + "mocha": "^11.7.1", "npm-run-all": "^4.1.5", - "rollup": "^4.35.0", + "rollup": "^4.44.1", "rollup-plugin-cleanup": "^3.2.1", - "rollup-plugin-dts": "^6.1.1", + "rollup-plugin-dts": "^6.2.1", "rollup-plugin-polyfill": "^4.2.0", "@rollup/plugin-terser": "^0.4.4", - "three": "^0.174.0", - "typescript": "5.8.2" + "three": "^0.177.0", + "typescript": "5.8.3" }, "publishConfig": { "access": "public" diff --git a/packages/model-viewer-effects/src/effect-composer.ts b/packages/model-viewer-effects/src/effect-composer.ts index 0d803ec048..02103bd244 100644 --- a/packages/model-viewer-effects/src/effect-composer.ts +++ b/packages/model-viewer-effects/src/effect-composer.ts @@ -44,9 +44,9 @@ const $updateProperties = Symbol('updateProperties'); * `camera at a top level, and setting them for every {@link Pass} added. */ export class EffectComposer extends PPEffectComposer { - public camera?: Camera; - public scene?: ModelScene; - public dirtyRender?: boolean; + camera?: Camera; + scene?: ModelScene; + dirtyRender?: boolean; [$tonemapping]: ToneMapping = NeutralToneMapping; @@ -162,9 +162,10 @@ export class MVEffectComposer extends ReactiveElement { protected[$userEffectCount]: number = 0; get[$effectComposer]() { - if (!this[$composer]) + if (!this[$composer]) { throw new Error( 'The EffectComposer has not been instantiated yet. Please make sure the component is properly mounted on the Document within a element.'); + } return this[$composer]; } @@ -177,9 +178,10 @@ export class MVEffectComposer extends ReactiveElement { } get modelViewerElement() { - if (!this[$modelViewerElement]) + if (!this[$modelViewerElement]) { throw new Error( ' must be a child of a component.'); + } return this[$modelViewerElement]; } @@ -294,11 +296,13 @@ export class MVEffectComposer extends ReactiveElement { * Default is `true`. */ removePass(pass: Pass, dispose: boolean = true): void { - if (!this[$effectComposer].passes.includes(pass)) + if (!this[$effectComposer].passes.includes(pass)) { throw new Error(`Pass ${pass.name} not found.`); + } this[$effectComposer].removePass(pass); - if (dispose) + if (dispose) { pass.dispose(); + } // Enable the normalPass and dirtyRendering if required by any effect. this[$updateProperties](); this[$userEffectCount]--; @@ -367,8 +371,9 @@ export class MVEffectComposer extends ReactiveElement { const effects: IMVEffect[] = []; for (let i = 0; i < this.children.length; i++) { const childEffect = this.children.item(i) as MVEffectBase; - if (!childEffect.effects) + if (!childEffect.effects) { continue; + } const childEffects = childEffect.effects; if (childEffects) { effects.push(...childEffects.filter((effect) => !effect.disabled)); @@ -390,7 +395,8 @@ export class MVEffectComposer extends ReactiveElement { // Place all Geometries in the selection this[$selection].clear(); this[$scene]?.traverse( - (obj) => obj.hasOwnProperty('geometry') && this[$selection].add(obj)); + (obj) => Object.prototype.hasOwnProperty.call(obj, 'geometry') && + this[$selection].add(obj)); this.dispatchEvent(new CustomEvent('updated-selection')); }; diff --git a/packages/model-viewer-effects/src/effects/bloom.ts b/packages/model-viewer-effects/src/effects/bloom.ts index 1e77561ba7..a9146071de 100644 --- a/packages/model-viewer-effects/src/effects/bloom.ts +++ b/packages/model-viewer-effects/src/effects/bloom.ts @@ -13,9 +13,10 @@ * limitations under the License. */ -import { property } from 'lit/decorators.js'; -import { BlendFunction, BloomEffect } from 'postprocessing'; -import { $updateProperties, $effectOptions, MVEffectBase } from './mixins/effect-base.js'; +import {property} from 'lit/decorators.js'; +import {BlendFunction, BloomEffect} from 'postprocessing'; + +import {$effectOptions, $updateProperties, MVEffectBase} from './mixins/effect-base.js'; export class MVBloomEffect extends MVEffectBase { static get is() { @@ -25,25 +26,24 @@ export class MVBloomEffect extends MVEffectBase { /** * The strength of the bloom effect. */ - @property({ type: Number, attribute: 'strength', reflect: true }) - strength = 1; + @property({type: Number, attribute: 'strength', reflect: true}) strength = 1; /** - * Value in the range of (0, 1). Pixels with a brightness above this will bloom. + * Value in the range of (0, 1). Pixels with a brightness above this will + * bloom. */ - @property({ type: Number, attribute: 'threshold', reflect: true }) + @property({type: Number, attribute: 'threshold', reflect: true}) threshold = 0.85; /** * Value in the range of (0, 1). */ - @property({ type: Number, attribute: 'radius', reflect: true }) - radius = 0.85; + @property({type: Number, attribute: 'radius', reflect: true}) radius = 0.85; /** * Value in the range of (0, 1). */ - @property({ type: Number, attribute: 'smoothing', reflect: true }) + @property({type: Number, attribute: 'smoothing', reflect: true}) smoothing = 0.025; constructor() { @@ -57,27 +57,26 @@ export class MVBloomEffect extends MVEffectBase { this[$updateProperties](); } - updated(changedProperties: Map) { + updated(changedProperties: Map) { super.updated(changedProperties); - if ( - changedProperties.has('strength') || - changedProperties.has('threshold') || - changedProperties.has('smoothing') || - changedProperties.has('radius') - ) { + if (changedProperties.has('strength') || + changedProperties.has('threshold') || + changedProperties.has('smoothing') || changedProperties.has('radius')) { this[$updateProperties](); } } [$updateProperties](): void { - (this.effects[0] as BloomEffect).luminanceMaterial.threshold = this.threshold; - (this.effects[0] as BloomEffect).luminanceMaterial.smoothing = this.smoothing; + (this.effects[0] as BloomEffect).luminanceMaterial.threshold = + this.threshold; + (this.effects[0] as BloomEffect).luminanceMaterial.smoothing = + this.smoothing; (this.effects[0] as BloomEffect).intensity = this.strength; (this.effects[0] as any).mipmapBlurPass.radius = this.radius; this.effectComposer.queueRender(); } - get [$effectOptions]() { + get[$effectOptions]() { return { blendFunction: BlendFunction.ADD, mipmapBlur: true, diff --git a/packages/model-viewer-effects/src/effects/glitch.ts b/packages/model-viewer-effects/src/effects/glitch.ts index 3629d1a025..70763a539b 100644 --- a/packages/model-viewer-effects/src/effects/glitch.ts +++ b/packages/model-viewer-effects/src/effects/glitch.ts @@ -13,11 +13,13 @@ * limitations under the License. */ -import { property } from 'lit/decorators.js'; -import { ChromaticAberrationEffect, GlitchEffect, GlitchMode as Mode } from 'postprocessing'; -import { Vector2 } from 'three'; -import { clamp, validateLiteralType } from '../utilities.js'; -import { $updateProperties, $effectOptions, MVEffectBase } from './mixins/effect-base.js'; +import {property} from 'lit/decorators.js'; +import {ChromaticAberrationEffect, GlitchEffect, GlitchMode as Mode} from 'postprocessing'; +import {Vector2} from 'three'; + +import {clamp, validateLiteralType} from '../utilities.js'; + +import {$effectOptions, $updateProperties, MVEffectBase} from './mixins/effect-base.js'; export const GLITCH_MODES = ['sporadic', 'constant'] as const; @@ -31,20 +33,21 @@ export class MVGlitchEffect extends MVEffectBase { /** * Value in the range of (0, 1). */ - @property({ type: Number, attribute: 'strength', reflect: true }) + @property({type: Number, attribute: 'strength', reflect: true}) strength: number = 0.5; /** * `sporadic` | `constant` * @default 'sporadic' */ - @property({ type: String, attribute: 'mode', reflect: true }) + @property({type: String, attribute: 'mode', reflect: true}) mode: GlitchMode = 'sporadic'; constructor() { super(); const chromaticAberrationEffect = new ChromaticAberrationEffect(); - const glitchEffect = new GlitchEffect(this[$effectOptions](chromaticAberrationEffect)); + const glitchEffect = + new GlitchEffect(this[$effectOptions](chromaticAberrationEffect)); this.effects = [glitchEffect, chromaticAberrationEffect]; this.effects[1].requireDirtyRender = true; } @@ -54,7 +57,7 @@ export class MVGlitchEffect extends MVEffectBase { this[$updateProperties](); } - updated(changedProperties: Map) { + updated(changedProperties: Map) { super.updated(changedProperties); if (changedProperties.has('mode') || changedProperties.has('strength')) { this[$updateProperties](); @@ -66,15 +69,17 @@ export class MVGlitchEffect extends MVEffectBase { this.mode = this.mode.toLowerCase() as GlitchMode; try { validateLiteralType(GLITCH_MODES, this.mode); - } catch(e) { - console.error((e as Error).message + + "\nmode defaulting to 'sporadic'") + } catch (e) { + console.error((e as Error).message + +'\nmode defaulting to \'sporadic\'') } if (this.strength == 0) { (this.effects[0] as GlitchEffect).columns = 0; - (this.effects[0] as GlitchEffect).mode = this.mode === 'constant' ? Mode.CONSTANT_MILD : Mode.SPORADIC; + (this.effects[0] as GlitchEffect).mode = + this.mode === 'constant' ? Mode.CONSTANT_MILD : Mode.SPORADIC; } else { (this.effects[0] as GlitchEffect).columns = 0.06; - (this.effects[0] as GlitchEffect).mode = this.mode === 'constant' ? Mode.CONSTANT_WILD : Mode.SPORADIC; + (this.effects[0] as GlitchEffect).mode = + this.mode === 'constant' ? Mode.CONSTANT_WILD : Mode.SPORADIC; } (this.effects[0] as GlitchEffect).maxStrength = this.strength; (this.effects[0] as GlitchEffect).ratio = 1 - this.strength; diff --git a/packages/model-viewer-effects/src/effects/mixins/blend-mode.ts b/packages/model-viewer-effects/src/effects/mixins/blend-mode.ts index 4e160ee672..eeb04cf33d 100644 --- a/packages/model-viewer-effects/src/effects/mixins/blend-mode.ts +++ b/packages/model-viewer-effects/src/effects/mixins/blend-mode.ts @@ -13,11 +13,13 @@ * limitations under the License. */ -import { ReactiveElement } from 'lit'; -import { property } from 'lit/decorators.js'; -import { BlendFunction } from 'postprocessing'; -import { Constructor, clampNormal, validateLiteralType } from '../../utilities.js'; -import { IEffectBaseMixin } from './effect-base.js'; +import {ReactiveElement} from 'lit'; +import {property} from 'lit/decorators.js'; +import {BlendFunction} from 'postprocessing'; + +import {clampNormal, Constructor, validateLiteralType} from '../../utilities.js'; + +import {IEffectBaseMixin} from './effect-base.js'; export const $setDefaultProperties = Symbol('setDefaultProperties'); @@ -30,56 +32,63 @@ export interface IBlendModeMixin { [$setDefaultProperties](): void; } -export const BlendModeMixin = >( - EffectClass: T -): Constructor & T => { - class BlendEffectElement extends EffectClass { - /** - * The function to use to blend the effect with the base render. - */ - @property({ type: String, attribute: 'blend-mode', reflect: true }) - blendMode: 'DEFAULT' | BlendMode = 'DEFAULT'; +export const BlendModeMixin = + >( + EffectClass: T): Constructor&T => { + class BlendEffectElement extends EffectClass { + /** + * The function to use to blend the effect with the base render. + */ + @property({type: String, attribute: 'blend-mode', reflect: true}) + blendMode: 'DEFAULT'|BlendMode = 'DEFAULT'; - /** - * The opacity of the effect that will be blended with the base render. - */ - @property({ type: Number, attribute: 'opacity', reflect: true }) - opacity: number = 1; + /** + * The opacity of the effect that will be blended with the base render. + */ + @property({type: Number, attribute: 'opacity', reflect: true}) + opacity: number = 1; - connectedCallback() { - super.connectedCallback && super.connectedCallback(); - this[$setDefaultProperties](); - } + connectedCallback() { + super.connectedCallback && super.connectedCallback(); + this[$setDefaultProperties](); + } - updated(changedProperties: Map) { - super.updated(changedProperties); - if (changedProperties.has('blendMode') || changedProperties.has('opacity')) { - this.opacity = clampNormal(this.opacity); - this.blendMode = this.blendMode.toUpperCase() as BlendMode; - this.effects.forEach((effect) => { - if (this.blendMode === 'DEFAULT') { - if (effect.blendMode.defaultBlendFunction === undefined) throw new Error(`${effect.name} has no default blend function`); - effect.blendMode.blendFunction = effect.blendMode.defaultBlendFunction; - } else { - validateLiteralType(BLEND_MODES, this.blendMode); - effect.blendMode.blendFunction = BlendFunction[this.blendMode]; + updated(changedProperties: Map) { + super.updated(changedProperties); + if (changedProperties.has('blendMode') || + changedProperties.has('opacity')) { + this.opacity = clampNormal(this.opacity); + this.blendMode = this.blendMode.toUpperCase() as BlendMode; + this.effects.forEach((effect) => { + if (this.blendMode === 'DEFAULT') { + if (effect.blendMode.defaultBlendFunction === undefined) { + throw new Error( + `${effect.name} has no default blend function`); + } + effect.blendMode.blendFunction = + effect.blendMode.defaultBlendFunction; + } else { + validateLiteralType(BLEND_MODES, this.blendMode); + effect.blendMode.blendFunction = BlendFunction[this.blendMode]; + } + effect.disabled = this.blendMode === 'SKIP'; + effect.blendMode.setOpacity(this.opacity); + }); + // Recreate EffectPasses if the new or old value was 'skip' + if (this.blendMode === 'SKIP' || + changedProperties.get('blendMode') === 'SKIP') { + this.effectComposer.updateEffects(); + } + this.effectComposer.queueRender(); } - effect.disabled = this.blendMode === 'SKIP'; - effect.blendMode.setOpacity(this.opacity); - }); - // Recreate EffectPasses if the new or old value was 'skip' - if (this.blendMode === 'SKIP' || changedProperties.get('blendMode') === 'SKIP') { - this.effectComposer.updateEffects(); } - this.effectComposer.queueRender(); - } - } - protected [$setDefaultProperties]() { - this.effects.forEach((effect) => { - effect.blendMode.defaultBlendFunction = effect.blendMode.blendFunction; - }); - } - } - return BlendEffectElement as Constructor & T; -}; + protected[$setDefaultProperties]() { + this.effects.forEach((effect) => { + effect.blendMode.defaultBlendFunction = + effect.blendMode.blendFunction; + }); + } + } + return BlendEffectElement as Constructor& T; + }; diff --git a/packages/model-viewer-effects/src/effects/mixins/effect-base.ts b/packages/model-viewer-effects/src/effects/mixins/effect-base.ts index 2df8a159a8..f80211120a 100644 --- a/packages/model-viewer-effects/src/effects/mixins/effect-base.ts +++ b/packages/model-viewer-effects/src/effects/mixins/effect-base.ts @@ -13,12 +13,14 @@ * limitations under the License. */ -import { LitElement, ReactiveElement } from 'lit'; -import { BlendFunction, BlendMode, Effect } from 'postprocessing'; -import { $effectComposer, MVEffectComposer } from '../../effect-composer.js'; -import { Constructor } from '../../utilities.js'; -import { BlendModeMixin } from './blend-mode.js'; -import { getComponentName } from '../utilities.js'; +import {LitElement, ReactiveElement} from 'lit'; +import {BlendFunction, BlendMode, Effect} from 'postprocessing'; + +import {$effectComposer, MVEffectComposer} from '../../effect-composer.js'; +import {Constructor} from '../../utilities.js'; +import {getComponentName} from '../utilities.js'; + +import {BlendModeMixin} from './blend-mode.js'; export const $updateProperties = Symbol('updateProperties'); export const $effectOptions = Symbol('effectOptions'); @@ -53,7 +55,8 @@ export interface IEffectBaseMixin { effectComposer: MVEffectComposer; } -export const EffectBaseMixin = >(EffectClass: T): Constructor & T => { +export const EffectBaseMixin = >( + EffectClass: T): Constructor&T => { class EffectBaseElement extends EffectClass { [$effectComposer]?: MVEffectComposer; protected effects!: IMVEffect[]; @@ -62,7 +65,11 @@ export const EffectBaseMixin = >(EffectCl * The parent {@link MVEffectComposer} element. */ protected get effectComposer() { - if (!this[$effectComposer]) throw new Error(`${getComponentName(this as any)} must be a child of a component.`); + if (!this[$effectComposer]) { + throw new Error(`${ + getComponentName( + this as any)} must be a child of a component.`); + } return this[$effectComposer]; } @@ -80,7 +87,7 @@ export const EffectBaseMixin = >(EffectCl this.effectComposer.updateEffects(); } } - return EffectBaseElement as Constructor & T; + return EffectBaseElement as Constructor& T; }; export const MVEffectBase = BlendModeMixin(EffectBaseMixin(LitElement)); diff --git a/packages/model-viewer-effects/src/effects/mixins/selective.ts b/packages/model-viewer-effects/src/effects/mixins/selective.ts index 4a92911ad0..5129c9726f 100644 --- a/packages/model-viewer-effects/src/effects/mixins/selective.ts +++ b/packages/model-viewer-effects/src/effects/mixins/selective.ts @@ -13,13 +13,15 @@ * limitations under the License. */ -import { ReactiveElement } from 'lit'; -import { property } from 'lit/decorators.js'; -import { Selection } from 'postprocessing'; -import { $selection, $scene } from '../../effect-composer.js'; -import { Constructor } from '../../utilities.js'; -import { IEffectBaseMixin, IMVEffect } from './effect-base.js'; -import { Object3D } from 'three'; +import {ReactiveElement} from 'lit'; +import {property} from 'lit/decorators.js'; +import {Selection} from 'postprocessing'; +import {Object3D} from 'three'; + +import {$scene, $selection} from '../../effect-composer.js'; +import {Constructor} from '../../utilities.js'; + +import {IEffectBaseMixin, IMVEffect} from './effect-base.js'; export const $setSelection = Symbol('setSelection'); @@ -28,53 +30,64 @@ export interface ISelectionEffect extends IMVEffect { } export interface ISelectiveMixin { - selection: Array; + selection: Array; } -export const SelectiveMixin = >( - EffectClass: T -): Constructor & T => { - class SelectiveEffectElement extends EffectClass { - /** - * The objects to attemp to place into the effect selection. Can be either the 'name' or the actual objects themselves. - * - * Note that since this is an array property, it must be set using the '=' operator in order to properly update. - */ - @property({ type: Array }) - selection: Array = []; +export const SelectiveMixin = + >( + EffectClass: T): Constructor&T => { + class SelectiveEffectElement extends EffectClass { + /** + * The objects to attemp to place into the effect selection. Can be + * either the 'name' or the actual objects themselves. + * + * Note that since this is an array property, it must be set using the + * '=' operator in order to properly update. + */ + @property({type: Array}) selection: Array = []; - connectedCallback() { - super.connectedCallback && super.connectedCallback(); - this[$setSelection](); - this.effectComposer.addEventListener('updated-selection', this[$setSelection]); - } + connectedCallback() { + super.connectedCallback && super.connectedCallback(); + this[$setSelection](); + this.effectComposer.addEventListener( + 'updated-selection', this[$setSelection]); + } - disconnectedCallback(): void { - super.disconnectedCallback && super.disconnectedCallback(); - this.effectComposer.removeEventListener('updated-selection', this[$setSelection]); - } + disconnectedCallback(): void { + super.disconnectedCallback && super.disconnectedCallback(); + this.effectComposer.removeEventListener( + 'updated-selection', this[$setSelection]); + } - updated(changedProperties: Map) { - super.updated(changedProperties); - if (changedProperties.has('selection')) { - this[$setSelection](); - this.effectComposer.queueRender(); - } - } + updated(changedProperties: Map) { + super.updated(changedProperties); + if (changedProperties.has('selection')) { + this[$setSelection](); + this.effectComposer.queueRender(); + } + } - [$setSelection] = () => { - const { effectComposer } = this; - if (!effectComposer) return; + [$setSelection] = () => { + const {effectComposer} = this; + if (!effectComposer) { + return; + } - if (this.selection?.length > 0) { - const selection: Object3D[] = []; - const scene = effectComposer[$scene]; - scene?.traverse((obj) => (this.selection.includes(obj.name) || this.selection.includes(obj)) && selection.push(obj)); - this.effects.forEach((effect: ISelectionEffect) => effect.selection?.set(selection)); - } else { - this.effects.forEach((effect: ISelectionEffect) => effect.selection?.set(effectComposer[$selection].values())); + if (this.selection?.length > 0) { + const selection: Object3D[] = []; + const scene = effectComposer[$scene]; + scene?.traverse( + (obj) => (this.selection.includes(obj.name) || + this.selection.includes(obj)) && + selection.push(obj)); + this.effects.forEach( + (effect: ISelectionEffect) => effect.selection?.set(selection)); + } else { + this.effects.forEach( + (effect: ISelectionEffect) => + effect.selection?.set(effectComposer[$selection].values())); + } + }; } + return SelectiveEffectElement as Constructor& T; }; - } - return SelectiveEffectElement as Constructor & T; -}; diff --git a/packages/model-viewer-effects/src/effects/outline.ts b/packages/model-viewer-effects/src/effects/outline.ts index 0aca17647c..2364be6db7 100644 --- a/packages/model-viewer-effects/src/effects/outline.ts +++ b/packages/model-viewer-effects/src/effects/outline.ts @@ -13,12 +13,13 @@ * limitations under the License. */ -import { property } from 'lit/decorators.js'; -import { BlendFunction, OutlineEffect } from 'postprocessing'; -import { Color, ColorRepresentation } from 'three'; -import { $updateProperties, $effectOptions, MVEffectBase } from './mixins/effect-base.js'; -import { SelectiveMixin } from './mixins/selective.js'; -import { getKernelSize, TEMP_CAMERA } from './utilities.js'; +import {property} from 'lit/decorators.js'; +import {BlendFunction, OutlineEffect} from 'postprocessing'; +import {Color, ColorRepresentation} from 'three'; + +import {$effectOptions, $updateProperties, MVEffectBase} from './mixins/effect-base.js'; +import {SelectiveMixin} from './mixins/selective.js'; +import {getKernelSize, TEMP_CAMERA} from './utilities.js'; export class MVOutlineEffect extends SelectiveMixin(MVEffectBase) { static get is() { @@ -29,26 +30,26 @@ export class MVOutlineEffect extends SelectiveMixin(MVEffectBase) { * String or RGB #-hexadecimal Color. * @default 'white' */ - @property({ type: String || Number, attribute: 'color', reflect: true }) + @property({type: String || Number, attribute: 'color', reflect: true}) color: ColorRepresentation = 'white'; /** * A larger value denotes a thicker edge. * @default 1 */ - @property({ type: Number, attribute: 'strength', reflect: true }) - strength = 1; + @property({type: Number, attribute: 'strength', reflect: true}) strength = 1; /** * Value in the range of (0, 6). Controls the edge blur strength. * @default 1 */ - @property({ type: Number, attribute: 'smoothing', reflect: true }) + @property({type: Number, attribute: 'smoothing', reflect: true}) smoothing = 1; constructor() { super(); - this.effects = [new OutlineEffect(undefined, TEMP_CAMERA, this[$effectOptions])]; + this.effects = + [new OutlineEffect(undefined, TEMP_CAMERA, this[$effectOptions])]; } connectedCallback(): void { @@ -56,9 +57,10 @@ export class MVOutlineEffect extends SelectiveMixin(MVEffectBase) { this[$updateProperties](); } - updated(changedProperties: Map) { + updated(changedProperties: Map) { super.updated(changedProperties); - if (changedProperties.has('color') || changedProperties.has('smoothing') || changedProperties.has('strength')) { + if (changedProperties.has('color') || changedProperties.has('smoothing') || + changedProperties.has('strength')) { this[$updateProperties](); } } @@ -67,12 +69,14 @@ export class MVOutlineEffect extends SelectiveMixin(MVEffectBase) { (this.effects[0] as OutlineEffect).edgeStrength = this.strength; (this.effects[0] as OutlineEffect).visibleEdgeColor = new Color(this.color); (this.effects[0] as OutlineEffect).hiddenEdgeColor = new Color(this.color); - (this.effects[0] as OutlineEffect).blurPass.enabled = Math.round(this.smoothing) > 0; - (this.effects[0] as OutlineEffect).blurPass.kernelSize = getKernelSize(this.smoothing); + (this.effects[0] as OutlineEffect).blurPass.enabled = + Math.round(this.smoothing) > 0; + (this.effects[0] as OutlineEffect).blurPass.kernelSize = + getKernelSize(this.smoothing); this.effectComposer.queueRender(); } - get [$effectOptions]() { + get[$effectOptions]() { return { blendFunction: BlendFunction.SCREEN, edgeStrength: this.strength, diff --git a/packages/model-viewer-effects/src/effects/pixelate.ts b/packages/model-viewer-effects/src/effects/pixelate.ts index 4c9a4bdc77..981bb90a97 100644 --- a/packages/model-viewer-effects/src/effects/pixelate.ts +++ b/packages/model-viewer-effects/src/effects/pixelate.ts @@ -13,9 +13,10 @@ * limitations under the License. */ -import { property } from 'lit/decorators.js'; -import { PixelationEffect } from 'postprocessing'; -import { $updateProperties, MVEffectBase } from './mixins/effect-base.js'; +import {property} from 'lit/decorators.js'; +import {PixelationEffect} from 'postprocessing'; + +import {$updateProperties, MVEffectBase} from './mixins/effect-base.js'; export class MVPixelateEffect extends MVEffectBase { static get is() { @@ -26,7 +27,7 @@ export class MVPixelateEffect extends MVEffectBase { * The pixel granularity. Higher value = lower resolution. * @default 10 */ - @property({ type: Number, attribute: 'granularity', reflect: true }) + @property({type: Number, attribute: 'granularity', reflect: true}) granularity = 10.0; constructor() { @@ -40,7 +41,7 @@ export class MVPixelateEffect extends MVEffectBase { this[$updateProperties](); } - updated(changedProperties: Map) { + updated(changedProperties: Map) { super.updated(changedProperties); if (changedProperties.has('granularity')) { this[$updateProperties](); diff --git a/packages/model-viewer-effects/src/effects/selective-bloom.ts b/packages/model-viewer-effects/src/effects/selective-bloom.ts index cc4b6030b0..3a989ecfa3 100644 --- a/packages/model-viewer-effects/src/effects/selective-bloom.ts +++ b/packages/model-viewer-effects/src/effects/selective-bloom.ts @@ -13,11 +13,12 @@ * limitations under the License. */ -import { property } from 'lit/decorators.js'; -import { BlendFunction, SelectiveBloomEffect } from 'postprocessing'; -import { $updateProperties, $effectOptions, MVEffectBase } from './mixins/effect-base.js'; -import { SelectiveMixin } from './mixins/selective.js'; -import { TEMP_CAMERA } from './utilities.js'; +import {property} from 'lit/decorators.js'; +import {BlendFunction, SelectiveBloomEffect} from 'postprocessing'; + +import {$effectOptions, $updateProperties, MVEffectBase} from './mixins/effect-base.js'; +import {SelectiveMixin} from './mixins/selective.js'; +import {TEMP_CAMERA} from './utilities.js'; export class MVSelectiveBloomEffect extends SelectiveMixin(MVEffectBase) { static get is() { @@ -27,31 +28,31 @@ export class MVSelectiveBloomEffect extends SelectiveMixin(MVEffectBase) { /** * The strength of the bloom effect. */ - @property({ type: Number, attribute: 'strength', reflect: true }) - strength = 1; + @property({type: Number, attribute: 'strength', reflect: true}) strength = 1; /** - * Value in the range of (0, 1). Pixels with a brightness above this will bloom. + * Value in the range of (0, 1). Pixels with a brightness above this will + * bloom. */ - @property({ type: Number, attribute: 'threshold', reflect: true }) + @property({type: Number, attribute: 'threshold', reflect: true}) threshold = 0.85; /** * Value in the range of (0, 1). */ - @property({ type: Number, attribute: 'smoothing', reflect: true }) + @property({type: Number, attribute: 'smoothing', reflect: true}) smoothing = 0.025; /** * Value in the range of (0, 1). */ - @property({ type: Number, attribute: 'radius', reflect: true }) - radius = 0.85; + @property({type: Number, attribute: 'radius', reflect: true}) radius = 0.85; constructor() { super(); - this.effects = [new SelectiveBloomEffect(undefined, TEMP_CAMERA, this[$effectOptions])]; + this.effects = [new SelectiveBloomEffect( + undefined, TEMP_CAMERA, this[$effectOptions])]; } connectedCallback(): void { @@ -59,27 +60,26 @@ export class MVSelectiveBloomEffect extends SelectiveMixin(MVEffectBase) { this[$updateProperties](); } - updated(changedProperties: Map) { + updated(changedProperties: Map) { super.updated(changedProperties); - if ( - changedProperties.has('strength') || - changedProperties.has('threshold') || - changedProperties.has('smoothing') || - changedProperties.has('radius') - ) { + if (changedProperties.has('strength') || + changedProperties.has('threshold') || + changedProperties.has('smoothing') || changedProperties.has('radius')) { this[$updateProperties](); } } [$updateProperties](): void { - (this.effects[0] as SelectiveBloomEffect).luminanceMaterial.threshold = this.threshold; - (this.effects[0] as SelectiveBloomEffect).luminanceMaterial.smoothing = this.smoothing; + (this.effects[0] as SelectiveBloomEffect).luminanceMaterial.threshold = + this.threshold; + (this.effects[0] as SelectiveBloomEffect).luminanceMaterial.smoothing = + this.smoothing; (this.effects[0] as SelectiveBloomEffect).intensity = this.strength; (this.effects[0] as any).mipmapBlurPass.radius = this.radius; this.effectComposer.queueRender(); } - get [$effectOptions]() { + get[$effectOptions]() { return { blendFunction: BlendFunction.ADD, mipmapBlur: true, diff --git a/packages/model-viewer-effects/src/effects/smaa.ts b/packages/model-viewer-effects/src/effects/smaa.ts index ec992f20a9..c9faaed379 100644 --- a/packages/model-viewer-effects/src/effects/smaa.ts +++ b/packages/model-viewer-effects/src/effects/smaa.ts @@ -13,10 +13,12 @@ * limitations under the License. */ -import { property } from 'lit/decorators.js'; -import { SMAAEffect, SMAAPreset } from 'postprocessing'; -import { $updateProperties, MVEffectBase } from './mixins/effect-base.js'; -import { validateLiteralType } from '../utilities.js'; +import {property} from 'lit/decorators.js'; +import {SMAAEffect, SMAAPreset} from 'postprocessing'; + +import {validateLiteralType} from '../utilities.js'; + +import {$updateProperties, MVEffectBase} from './mixins/effect-base.js'; export type SMAAQuality = keyof typeof SMAAPreset; export const SMAA_QUALITIES = Object.keys(SMAAPreset) as SMAAQuality[]; @@ -30,13 +32,13 @@ export class MVSMAAEffect extends MVEffectBase { * `low | medium | high | ultra` * @default 'medium' */ - @property({ type: String, attribute: 'quality', reflect: true }) + @property({type: String, attribute: 'quality', reflect: true}) quality: SMAAQuality = 'MEDIUM'; constructor() { super(); - this.effects = [new SMAAEffect({ preset: SMAAPreset[this.quality] })]; + this.effects = [new SMAAEffect({preset: SMAAPreset[this.quality]})]; } connectedCallback(): void { @@ -44,7 +46,7 @@ export class MVSMAAEffect extends MVEffectBase { this[$updateProperties](); } - updated(changedProperties: Map) { + updated(changedProperties: Map) { super.updated(changedProperties); if (changedProperties.has('quality')) { this[$updateProperties](); diff --git a/packages/model-viewer-effects/src/effects/ssao.ts b/packages/model-viewer-effects/src/effects/ssao.ts index a89ca88549..d5030d522e 100644 --- a/packages/model-viewer-effects/src/effects/ssao.ts +++ b/packages/model-viewer-effects/src/effects/ssao.ts @@ -13,11 +13,12 @@ * limitations under the License. */ -import { SSAOEffect } from 'postprocessing'; -import { $updateProperties, $effectOptions, MVEffectBase } from './mixins/effect-base.js'; -import { property } from 'lit/decorators.js'; -import { TEMP_CAMERA } from './utilities.js'; -import { $setDefaultProperties } from './mixins/blend-mode.js'; +import {property} from 'lit/decorators.js'; +import {SSAOEffect} from 'postprocessing'; + +import {$setDefaultProperties} from './mixins/blend-mode.js'; +import {$effectOptions, $updateProperties, MVEffectBase} from './mixins/effect-base.js'; +import {TEMP_CAMERA} from './utilities.js'; export class MVSSAOEffect extends MVEffectBase { static get is() { @@ -27,12 +28,13 @@ export class MVSSAOEffect extends MVEffectBase { /** * The strength of the shadow occlusions. Higher value means darker shadows. */ - @property({ type: Number, attribute: 'strength', reflect: true }) + @property({type: Number, attribute: 'strength', reflect: true}) strength: number = 2; constructor() { super(); - this.effects = [new SSAOEffect(TEMP_CAMERA, undefined, this[$effectOptions])]; + this.effects = + [new SSAOEffect(TEMP_CAMERA, undefined, this[$effectOptions])]; this.effects[0].requireNormals = true; } @@ -42,7 +44,7 @@ export class MVSSAOEffect extends MVEffectBase { this[$updateProperties](); } - update(changedProperties: Map): void { + update(changedProperties: Map): void { super.update && super.update(changedProperties); if (changedProperties.has('strength')) { this[$updateProperties](); @@ -56,10 +58,11 @@ export class MVSSAOEffect extends MVEffectBase { [$setDefaultProperties]() { super[$setDefaultProperties](); - (this.effects[0] as SSAOEffect).normalBuffer = this.effectComposer.normalBuffer; + (this.effects[0] as SSAOEffect).normalBuffer = + this.effectComposer.normalBuffer; } - get [$effectOptions]() { + get[$effectOptions]() { return { worldDistanceThreshold: 1000, worldDistanceFalloff: 1000, diff --git a/packages/model-viewer-effects/src/effects/utilities.ts b/packages/model-viewer-effects/src/effects/utilities.ts index 2b25e08bbd..c88c2090bb 100644 --- a/packages/model-viewer-effects/src/effects/utilities.ts +++ b/packages/model-viewer-effects/src/effects/utilities.ts @@ -13,10 +13,12 @@ * limitations under the License. */ -import { KernelSize } from 'postprocessing'; -import { PerspectiveCamera } from 'three'; -import { clamp } from '../utilities.js'; -import { MVEffectBase } from './mixins/effect-base.js'; +import {KernelSize} from 'postprocessing'; +import {PerspectiveCamera} from 'three'; + +import {clamp} from '../utilities.js'; + +import {MVEffectBase} from './mixins/effect-base.js'; /** * Helper function for calculating the Kernel Size @@ -24,11 +26,17 @@ import { MVEffectBase } from './mixins/effect-base.js'; * @returns The relative Kernel Size */ export function getKernelSize(n: number): number { - return Math.round(clamp(n + 1, KernelSize.VERY_SMALL, KernelSize.HUGE + 1)) - 1; + return Math.round(clamp(n + 1, KernelSize.VERY_SMALL, KernelSize.HUGE + 1)) - + 1; } export function getComponentName(obj: MVEffectBase): string { - return '<' + obj.constructor.name.replace('MV', '').split(/(?=[A-Z])/).join('-').toLowerCase() + '>'; + return '<' + + obj.constructor.name.replace('MV', '') + .split(/(?=[A-Z])/) + .join('-') + .toLowerCase() + + '>'; } // Used for effects which require a valid Camera for shader instance diff --git a/packages/model-viewer-effects/src/model-viewer-effects.ts b/packages/model-viewer-effects/src/model-viewer-effects.ts index 954c4a103f..5b63cff8e1 100644 --- a/packages/model-viewer-effects/src/model-viewer-effects.ts +++ b/packages/model-viewer-effects/src/model-viewer-effects.ts @@ -13,17 +13,17 @@ * limitations under the License. */ -import { MVBloomEffect } from './effects/bloom.js'; -import { MVColorGradeEffect } from './effects/color-grade.js'; -import { MVGlitchEffect } from './effects/glitch.js'; -import { MVOutlineEffect } from './effects/outline.js'; -import { MVPixelateEffect } from './effects/pixelate.js'; -import { MVSMAAEffect } from './effects/smaa.js'; -import { MVSSAOEffect } from './effects/ssao.js'; -import { MVEffectComposer } from './effect-composer.js'; -import { MVEffectBase } from './effects/mixins/effect-base.js'; -import { SelectiveMixin } from './effects/mixins/selective.js'; -import { MVSelectiveBloomEffect } from './effects/selective-bloom.js'; +import {MVEffectComposer} from './effect-composer.js'; +import {MVBloomEffect} from './effects/bloom.js'; +import {MVColorGradeEffect} from './effects/color-grade.js'; +import {MVGlitchEffect} from './effects/glitch.js'; +import {MVEffectBase} from './effects/mixins/effect-base.js'; +import {SelectiveMixin} from './effects/mixins/selective.js'; +import {MVOutlineEffect} from './effects/outline.js'; +import {MVPixelateEffect} from './effects/pixelate.js'; +import {MVSelectiveBloomEffect} from './effects/selective-bloom.js'; +import {MVSMAAEffect} from './effects/smaa.js'; +import {MVSSAOEffect} from './effects/ssao.js'; customElements.define('effect-composer', MVEffectComposer); customElements.define('pixelate-effect', MVPixelateEffect); @@ -60,5 +60,5 @@ export { MVSMAAEffect as SMAAEffect, MVGlitchEffect as GlitchEffect, MVEffectBase as EffectBase, - SelectiveMixin, + SelectiveMixin, }; diff --git a/packages/model-viewer-effects/src/test/effect-composer-spec.ts b/packages/model-viewer-effects/src/test/effect-composer-spec.ts index a3a8586158..e4ea199630 100644 --- a/packages/model-viewer-effects/src/test/effect-composer-spec.ts +++ b/packages/model-viewer-effects/src/test/effect-composer-spec.ts @@ -70,7 +70,7 @@ suite('MVEffectComposer', () => { suite('userEffects', () => { let pass: EffectPass; - let effects: Effect[] = []; + const effects: Effect[] = []; test('adds grid effect', () => { const effect = new GridEffect(); effects.push(effect); diff --git a/packages/model-viewer-effects/src/test/utilities.ts b/packages/model-viewer-effects/src/test/utilities.ts index 34378106b2..11774596a9 100644 --- a/packages/model-viewer-effects/src/test/utilities.ts +++ b/packages/model-viewer-effects/src/test/utilities.ts @@ -132,8 +132,8 @@ export const spy = let sourcePrototype = object; while (sourcePrototype != null && - !sourcePrototype.hasOwnProperty(property)) { - sourcePrototype = (sourcePrototype as any).__proto__; + !Object.prototype.hasOwnProperty.call(sourcePrototype, property)) { + sourcePrototype = Object.getPrototypeOf(sourcePrototype); } if (sourcePrototype == null) { @@ -204,8 +204,9 @@ const COMPONENTS_PER_PIXEL = 4; export function screenshot(element: ModelViewerElement): Uint8Array { const renderer = getOwnPropertySymbolValue(element, 'renderer'); - if (!renderer) + if (!renderer) { throw new Error('Invalid element provided'); + } const screenshotContext = renderer.threeRenderer.getContext(); const width = screenshotContext.drawingBufferWidth; @@ -227,12 +228,14 @@ export function screenshot(element: ModelViewerElement): Uint8Array { } export function ArraysAreEqual(arr1: TypedArray, arr2: TypedArray): boolean { - if (arr1.length !== arr2.length) + if (arr1.length !== arr2.length) { return false; + } for (let i = 0; i < arr1.length; i++) { - if (arr1[i] !== arr2[i]) + if (arr1[i] !== arr2[i]) { return false; + } } return true; @@ -247,8 +250,9 @@ export function ArraysAreEqual(arr1: TypedArray, arr2: TypedArray): boolean { export function CompareArrays( arr1: TypedArray, arr2: TypedArray): number { if (arr1.length !== arr2.length || - arr1.BYTES_PER_ELEMENT !== arr2.BYTES_PER_ELEMENT) + arr1.BYTES_PER_ELEMENT !== arr2.BYTES_PER_ELEMENT) { return 0; + } const similarity: number[] = []; const max = maxValue(arr1.BYTES_PER_ELEMENT); @@ -305,12 +309,13 @@ function rgbToHsl(r: number, g: number, b: number): HSL { (r /= 255), (g /= 255), (b /= 255); const max = Math.max(r, g, b), min = Math.min(r, g, b); + // eslint-disable-next-line prefer-const let h, s, l = (max + min) / 2; if (max == min) { h = s = 0; // achromatic } else { - var d = max - min; + const d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { diff --git a/packages/model-viewer-effects/src/utilities.ts b/packages/model-viewer-effects/src/utilities.ts index d8bf06b7c9..827d012818 100644 --- a/packages/model-viewer-effects/src/utilities.ts +++ b/packages/model-viewer-effects/src/utilities.ts @@ -13,13 +13,12 @@ * limitations under the License. */ -import { Effect, EffectAttribute, EffectPass, Pass } from 'postprocessing'; -import { ColorRepresentation } from 'three'; +import {Effect, EffectAttribute, EffectPass, Pass} from 'postprocessing'; +import {ColorRepresentation} from 'three'; export type Constructor = { - new (...args: any[]): T; - prototype: T; -} & U; + new (...args: any[]): T; prototype: T; +}&U; /** * Get symbol of given key if exists on object. @@ -27,10 +26,14 @@ export type Constructor = { * @param key Key to search for (case sensitive) * @returns `Symbol(key)` */ -export function getOwnPropertySymbol(object: any, key: string): symbol | undefined { +export function getOwnPropertySymbol(object: any, key: string): symbol| + undefined { while (object) { - const symbol = Object.getOwnPropertySymbols(object).find((symbol) => symbol.description === key); - if (symbol) return symbol; + const symbol = Object.getOwnPropertySymbols(object).find( + (symbol) => symbol.description === key); + if (symbol) { + return symbol; + } // Search further up in prototype chain object = Object.getPrototypeOf(object); } @@ -52,7 +55,8 @@ export function hasOwnPropertySymbol(object: any, key: string): boolean { * @param key Key to search for (case sensitive) * @returns `object[Symbol(key)]` */ -export function getOwnPropertySymbolValue(object: any, key: string): T | undefined { +export function getOwnPropertySymbolValue( + object: any, key: string): T|undefined { const symbol = getOwnPropertySymbol(object, key); return symbol && object[symbol]; } @@ -63,7 +67,8 @@ export function getOwnPropertySymbolValue(object: any, key: string) * @param {Number} upperLimit * @return {Number} value clamped within `lowerLimit - upperLimit` */ -export function clamp(value: number, lowerLimit: number, upperLimit: number): number { +export function clamp( + value: number, lowerLimit: number, upperLimit: number): number { return Math.max(lowerLimit, Math.min(upperLimit, value)); } @@ -81,23 +86,32 @@ export function clampNormal(value: number): number { * @param {Number} upperLimit * @return {Number} wraps value between `lowerLimit - upperLimit` */ -export function wrapClamp(value: number, lowerLimit: number, upperLimit: number): number { - if (value > upperLimit) return lowerLimit; - if (value < lowerLimit) return upperLimit; +export function wrapClamp( + value: number, lowerLimit: number, upperLimit: number): number { + if (value > upperLimit) { + return lowerLimit; + } + if (value < lowerLimit) { + return upperLimit; + } return value; } /** - * Searches through hierarchy of HTMLElement until an element with a non-transparent background is found + * Searches through hierarchy of HTMLElement until an element with a + * non-transparent background is found * @param elem The element background to get * @returns The backgroundColor */ -export function getBackgroundColor(elem: HTMLElement): ColorRepresentation | undefined { - let currElem: HTMLElement | null = elem; +export function getBackgroundColor(elem: HTMLElement): ColorRepresentation| + undefined { + let currElem: HTMLElement|null = elem; while (currElem && isTransparent(getComputedStyle(currElem))) { currElem = currElem.parentElement; } - if (!currElem) return; + if (!currElem) { + return; + } return getComputedStyle(currElem).backgroundColor as ColorRepresentation; } @@ -106,7 +120,8 @@ export function getBackgroundColor(elem: HTMLElement): ColorRepresentation | und * @param style The CSS properties of an Element */ function isTransparent(style: CSSStyleDeclaration): boolean { - return style.backgroundColor === 'transparent' || style.backgroundColor === 'rgba(0, 0, 0, 0)' || !style.backgroundColor; + return style.backgroundColor === 'transparent' || + style.backgroundColor === 'rgba(0, 0, 0, 0)' || !style.backgroundColor; } /** @@ -124,31 +139,36 @@ export function isConvolution(effect: Effect): boolean { export function disposeEffectPass(pass: EffectPass): void { Pass.prototype.dispose.call(pass); - if (!(pass as any).listener) return; + if (!(pass as any).listener) { + return; + } for (const effect of (pass as any).effects) { effect.removeEventListener('change', (pass as any).listener); } } export function getValueOfEnum(Enum: T, key: string): T { - const index = Object.keys(Enum) - .filter((v) => !isNaN(Number(v))) - .indexOf(key); + const index = Object.keys(Enum).filter((v) => !isNaN(Number(v))).indexOf(key); return (Enum as any)[index]; } /** - * Helper function to validate whether a value is in-fact a valid option of a literal type. - * + * Helper function to validate whether a value is in-fact a valid option of a + * literal type. + * * Requires the type to be defined as follows: * @code * `const TOptions = [...] as const;` - * - * `type T = typeof TOptions[number];` + * + * `type T = typeof TOptions[number];` * @param options `TOptions` * @param value `value: T` * @throws TypeError */ -export function validateLiteralType(options: TOptions, value: typeof options[number]): void { - if (!options.includes(value)) throw new TypeError(`Validation Error: ${value} is not a valid value. Expected ${options.join(' | ')}`); +export function validateLiteralType( + options: TOptions, value: typeof options[number]): void { + if (!options.includes(value)) { + throw new TypeError(`Validation Error: ${ + value} is not a valid value. Expected ${options.join(' | ')}`); + } } \ No newline at end of file diff --git a/packages/model-viewer/package.json b/packages/model-viewer/package.json index f0cf30ccd7..f9d9e7eb75 100644 --- a/packages/model-viewer/package.json +++ b/packages/model-viewer/package.json @@ -83,35 +83,36 @@ "3d" ], "dependencies": { - "lit": "^3.2.1", - "@monogrid/gainmap-js": "^3.1.0" + "@monogrid/gainmap-js": "^3.1.0", + "lit": "^3.3.0", + "ua-parser-js": "^2.0.4" }, "peerDependencies": { - "three": "^0.174.0" + "three": "^0.177.0" }, "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.3", - "@rollup/plugin-node-resolve": "^16.0.0", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", + "@rollup/plugin-swc": "^0.4.0", + "@rollup/plugin-terser": "^0.4.4", + "@swc/core": "^1.12.9", "@types/mocha": "^10.0.10", "@types/pngjs": "^6.0.5", - "@types/three": "^0.174.0", + "@types/three": "^0.177.0", "@ungap/event-target": "^0.2.4", - "@web/test-runner": "^0.20.0", - "@rollup/plugin-swc": "^0.4.0", - "@swc/core": "^1.11.8", - "@web/test-runner-playwright": "^0.11.0", + "@web/test-runner": "^0.20.2", + "@web/test-runner-playwright": "^0.11.1", "chai": "^5.2.0", "http-server": "^14.1.1", - "mocha": "^11.1.0", + "mocha": "^11.7.1", "npm-run-all": "^4.1.5", - "rollup": "^4.35.0", + "rollup": "^4.44.1", "rollup-plugin-cleanup": "^3.2.1", - "rollup-plugin-dts": "^6.1.1", + "rollup-plugin-dts": "^6.2.1", "rollup-plugin-polyfill": "^4.2.0", - "@rollup/plugin-terser": "^0.4.4", - "typescript": "5.8.2", - "three": "^0.174.0" + "three": "^0.177.0", + "typescript": "5.8.3" }, "publishConfig": { "access": "public" diff --git a/packages/model-viewer/src/constants.ts b/packages/model-viewer/src/constants.ts index aeb57e1ad3..24fdd13ca8 100644 --- a/packages/model-viewer/src/constants.ts +++ b/packages/model-viewer/src/constants.ts @@ -16,88 +16,51 @@ // NOTE(cdata): The HAS_WEBXR_* constants can be enabled in Chrome by turning on // the appropriate flags. However, just because we have the API does not // guarantee that AR will work. -export const HAS_WEBXR_DEVICE_API = navigator.xr != null && - (self as any).XRSession != null && navigator.xr.isSessionSupported != null; -export const HAS_WEBXR_HIT_TEST_API = HAS_WEBXR_DEVICE_API && - (self as any).XRSession.prototype.requestHitTestSource != null; +import {UAParser} from 'ua-parser-js'; -export const HAS_RESIZE_OBSERVER = self.ResizeObserver != null; +const {browser, os} = UAParser(); -export const HAS_INTERSECTION_OBSERVER = self.IntersectionObserver != null; +export const IS_ANDROID = os.is('android'); +export const IS_IOS = os.is('ios'); +export const IS_CHROMEOS = os.is('chrome os') || os.is('chromium os'); +export const IS_FIREFOX = browser.is('firefox'); +export const IS_SAFARI = browser.is('safari'); +export const IS_OCULUS = browser.is('oculus browser'); +export const IS_IOS_CHROME = IS_IOS && browser.is('chrome'); +export const IS_IOS_SAFARI = IS_IOS && IS_SAFARI; -export const IS_WEBXR_AR_CANDIDATE = HAS_WEBXR_HIT_TEST_API; +export const IS_MOBILE = IS_ANDROID || IS_IOS; -export const IS_MOBILE = (() => { - const userAgent = - navigator.userAgent || navigator.vendor || (self as any).opera; - let check = false; - // eslint-disable-next-line - if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i - .test(userAgent) || - /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i - .test(userAgent.substr(0, 4))) { - check = true; - } - return check; -})(); +export const IS_SCENEVIEWER_CANDIDATE = IS_ANDROID && !IS_FIREFOX && !IS_OCULUS; -export const IS_CHROMEOS = /\bCrOS\b/.test(navigator.userAgent); +export const HAS_WEBXR_DEVICE_API = navigator.xr != null && + (self as any).XRSession != null && navigator.xr.isSessionSupported != null; -export const IS_ANDROID = /android/i.test(navigator.userAgent); +export const HAS_WEBXR_HIT_TEST_API = HAS_WEBXR_DEVICE_API && + (self as any).XRSession.prototype.requestHitTestSource != null; -// Prior to iOS 13, detecting iOS Safari was relatively straight-forward. -// As of iOS 13, Safari on iPad (in its default configuration) reports the same -// user-agent string as Safari on desktop MacOS. Strictly speaking, we only care -// about iOS for the purposes if selecting for cases where Quick Look is known -// to be supported. However, for API correctness purposes, we must rely on -// known, detectable signals to distinguish iOS Safari from MacOS Safari. At the -// time of this writing, there are no non-iOS/iPadOS Apple devices with -// multi-touch displays. -// @see https://stackoverflow.com/questions/57765958/how-to-detect-ipad-and-ipad-os-version-in-ios-13-and-up -// @see https://forums.developer.apple.com/thread/119186 -// @see https://github.com/google/model-viewer/issues/758 -export const IS_IOS = - (/iPad|iPhone|iPod/.test(navigator.userAgent) && !(self as any).MSStream) || - (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1); +export const HAS_RESIZE_OBSERVER = typeof ResizeObserver !== 'undefined'; -// @see https://developer.chrome.com/multidevice/user-agent -export const IS_SAFARI = /Safari\//.test(navigator.userAgent); -export const IS_FIREFOX = /firefox/i.test(navigator.userAgent); -export const IS_OCULUS = /OculusBrowser/.test(navigator.userAgent); -export const IS_IOS_CHROME = IS_IOS && /CriOS\//.test(navigator.userAgent); -export const IS_IOS_SAFARI = IS_IOS && IS_SAFARI; +export const HAS_INTERSECTION_OBSERVER = + typeof IntersectionObserver !== 'undefined'; -export const IS_SCENEVIEWER_CANDIDATE = IS_ANDROID && !IS_FIREFOX && !IS_OCULUS; +export const IS_WEBXR_AR_CANDIDATE = HAS_WEBXR_HIT_TEST_API; -// Extend Window type with webkit property, -// required to check if iOS is running within a WKWebView browser instance. declare global { interface Window { webkit?: any; } } -export const IS_WKWEBVIEW = - Boolean(window.webkit && window.webkit.messageHandlers); +export const IS_WKWEBVIEW = !!(window.webkit && window.webkit.messageHandlers); -// If running in iOS Safari proper, and not within a WKWebView component -// instance, check for ARQL feature support. Otherwise, if running in a -// WKWebView instance, check for known ARQL compatible iOS browsers, including: -// Chrome (CriOS), Edge (EdgiOS), Firefox (FxiOS), Google App (GSA), DuckDuckGo -// (DuckDuckGo). All other iOS browsers / apps will fail by default. export const IS_AR_QUICKLOOK_CANDIDATE = (() => { - if (IS_IOS) { - if (!IS_WKWEBVIEW) { - const tempAnchor = document.createElement('a'); - return Boolean( - tempAnchor.relList && tempAnchor.relList.supports && - tempAnchor.relList.supports('ar')); - } else { - return Boolean(/CriOS\/|EdgiOS\/|FxiOS\/|GSA\/|DuckDuckGo\//.test( - navigator.userAgent)); - } - } else { - return false; + if (IS_IOS && !IS_WKWEBVIEW) { + const tempAnchor = document.createElement('a'); + return Boolean( + tempAnchor.relList && tempAnchor.relList.supports && + tempAnchor.relList.supports('ar')); } -})(); + return false; +})(); \ No newline at end of file diff --git a/packages/model-viewer/src/features/animation.ts b/packages/model-viewer/src/features/animation.ts index e2337ca775..bbc714d082 100644 --- a/packages/model-viewer/src/features/animation.ts +++ b/packages/model-viewer/src/features/animation.ts @@ -32,8 +32,8 @@ interface PlayAnimationOptions { interface AppendAnimationOptions { pingpong: boolean, repetitions: number|null, weight: number, - timeScale: number, fade: boolean|number, warp: boolean|number, - relativeWarp: boolean, time: number|null + timeScale: number, fade: boolean|number, warp: boolean|number, + relativeWarp: boolean, time: number|null } interface DetachAnimationOptions { diff --git a/packages/model-viewer/src/features/ar.ts b/packages/model-viewer/src/features/ar.ts index b7e7fd6eb2..28a1c16bea 100644 --- a/packages/model-viewer/src/features/ar.ts +++ b/packages/model-viewer/src/features/ar.ts @@ -315,8 +315,9 @@ configuration or device capabilities'); const location = self.location.toString(); const locationUrl = new URL(location); const modelUrl = new URL(this.src!, location); - if (modelUrl.hash) + if (modelUrl.hash) { modelUrl.hash = ''; + } const params = new URLSearchParams(modelUrl.search); locationUrl.hash = noArViewerSigil; @@ -412,8 +413,9 @@ configuration or device capabilities'); // attach anchor to shadow DOM to ensure iOS16 ARQL banner click message // event propagation anchor.style.display = 'none'; - if (!anchor.isConnected) + if (!anchor.isConnected) { this.shadowRoot!.appendChild(anchor); + } console.log('Attempting to present in AR with Quick Look...'); anchor.click(); diff --git a/packages/model-viewer/src/features/environment.ts b/packages/model-viewer/src/features/environment.ts index bfac00f53a..f3c6a8b757 100644 --- a/packages/model-viewer/src/features/environment.ts +++ b/packages/model-viewer/src/features/environment.ts @@ -97,8 +97,9 @@ export const EnvironmentMixin = >( ['linear', LinearToneMapping], ['none', NoToneMapping] ]); - - this[$scene].toneMapping = TONE_MAPPING.get(this.toneMapping) ?? NeutralToneMapping; + + this[$scene].toneMapping = + TONE_MAPPING.get(this.toneMapping) ?? NeutralToneMapping; this[$needsRender](); } diff --git a/packages/model-viewer/src/features/loading.ts b/packages/model-viewer/src/features/loading.ts index 44e1ec1a3b..4661b09db4 100644 --- a/packages/model-viewer/src/features/loading.ts +++ b/packages/model-viewer/src/features/loading.ts @@ -295,7 +295,8 @@ export const LoadingMixin = >( parentNode.appendChild(this[$defaultProgressBarElement]); } - this[$defaultProgressBarElement].classList.toggle('hide', progress === 1.0); + this[$defaultProgressBarElement].classList.toggle( + 'hide', progress === 1.0); }); }, PROGRESS_BAR_UPDATE_THRESHOLD); @@ -373,8 +374,8 @@ export const LoadingMixin = >( this[$updateProgressBar](progress); - this.dispatchEvent( - new CustomEvent('progress', {detail: {totalProgress: progress, reason}})); + this.dispatchEvent(new CustomEvent( + 'progress', {detail: {totalProgress: progress, reason}})); }; [$shouldAttemptPreload](): boolean { diff --git a/packages/model-viewer/src/features/scene-graph.ts b/packages/model-viewer/src/features/scene-graph.ts index f7977f70ad..334af9d16b 100644 --- a/packages/model-viewer/src/features/scene-graph.ts +++ b/packages/model-viewer/src/features/scene-graph.ts @@ -230,47 +230,50 @@ export const SceneGraphMixin = >( /** @export */ async exportScene(options?: SceneExportOptions): Promise { const scene = this[$scene]; - return new Promise(async (resolve, reject) => { - // Defaults - const opts = { - binary: true, - onlyVisible: true, - maxTextureSize: Infinity, - includeCustomExtensions: false, - forceIndices: false - } as GLTFExporterOptions; - - Object.assign(opts, options); - // Not configurable - opts.animations = scene.animations; - opts.truncateDrawRange = true; - - const shadow = scene.shadow; - let visible = false; - // Remove shadow from export - if (shadow != null) { - visible = shadow.visible; - shadow.visible = false; - } - await this[$model]![$prepareVariantsForExport](); + // Defaults + const opts = { + binary: true, + onlyVisible: true, + maxTextureSize: Infinity, + includeCustomExtensions: false, + forceIndices: false + } as GLTFExporterOptions; + + Object.assign(opts, options); + // Not configurable + opts.animations = scene.animations; + opts.truncateDrawRange = true; + + const shadow = scene.shadow; + let visible = false; + // Remove shadow from export + if (shadow != null) { + visible = shadow.visible; + shadow.visible = false; + } + // Perform async operation before the Promise + await this[$model]![$prepareVariantsForExport](); + + return new Promise((resolve, reject) => { const exporter = (new GLTFExporter() as any) .register( (writer: any) => new GLTFExporterMaterialsVariantsExtension(writer)); + exporter.parse( scene.model, (gltf: object) => { - return resolve(new Blob( + resolve(new Blob( [opts.binary ? gltf as Blob : JSON.stringify(gltf)], { type: opts.binary ? 'application/octet-stream' : 'application/json' })); }, () => { - return reject('glTF export failed'); + reject(new Error('glTF export failed')); }, opts); diff --git a/packages/model-viewer/src/features/scene-graph/image.ts b/packages/model-viewer/src/features/scene-graph/image.ts index 641960bb36..fe375e1400 100644 --- a/packages/model-viewer/src/features/scene-graph/image.ts +++ b/packages/model-viewer/src/features/scene-graph/image.ts @@ -74,7 +74,7 @@ export class Image extends ThreeDOMElement implements ImageInterface { if (texture && (texture.isCanvasTexture || texture.isVideoTexture)) { return texture.image; } - return; + return undefined; } get animation(): any|undefined { @@ -82,7 +82,7 @@ export class Image extends ThreeDOMElement implements ImageInterface { if (texture && texture.isCanvasTexture && texture.animation) { return texture.animation; } - return; + return undefined; } get type(): 'embedded'|'external' { @@ -128,7 +128,7 @@ export class Image extends ThreeDOMElement implements ImageInterface { imageData.data.set(buffer); blobContext.putImageData(imageData, 0, 0); - return new Promise(async (resolve, reject) => { + return new Promise((resolve, reject) => { blobCanvas.toBlob(blob => { if (!blob) { return reject('Failed to capture thumbnail.'); diff --git a/packages/model-viewer/src/features/scene-graph/material.ts b/packages/model-viewer/src/features/scene-graph/material.ts index 3e2a7d5d59..4856074c69 100644 --- a/packages/model-viewer/src/features/scene-graph/material.ts +++ b/packages/model-viewer/src/features/scene-graph/material.ts @@ -55,7 +55,7 @@ export class Material extends ThreeDOMElement implements MaterialInterface { private[$lazyLoadGLTFInfo]?: LazyLoader; private[$gltfIndex]: number; private[$isActive]: boolean; - public[$variantIndices] = new Set(); + [$variantIndices] = new Set(); private[$name]?: string; readonly[$modelVariants]: Map; private[$pbrTextures] = new Map(); diff --git a/packages/model-viewer/src/features/scene-graph/model.ts b/packages/model-viewer/src/features/scene-graph/model.ts index 7ab2e400ec..bf432202ad 100644 --- a/packages/model-viewer/src/features/scene-graph/model.ts +++ b/packages/model-viewer/src/features/scene-graph/model.ts @@ -352,7 +352,7 @@ export class Model implements ModelInterface { } if (materialIndex < 0 || materialIndex >= this.materials.length) { - console.error(`setMaterialToVariant(): materialIndex is out of bounds.`); + console.error('setMaterialToVariant(): materialIndex is out of bounds.'); return; } diff --git a/packages/model-viewer/src/features/scene-graph/nodes/primitive-node.ts b/packages/model-viewer/src/features/scene-graph/nodes/primitive-node.ts index b995637ca1..1b1b9babf2 100644 --- a/packages/model-viewer/src/features/scene-graph/nodes/primitive-node.ts +++ b/packages/model-viewer/src/features/scene-graph/nodes/primitive-node.ts @@ -33,12 +33,12 @@ export class Node { // Represents a primitive in a glTF mesh. export class PrimitiveNode extends Node { - public mesh: Mesh; + mesh: Mesh; // Maps glTF material index number to a material that this primitive supports. - public materials = new Map(); + materials = new Map(); // Maps variant index to material. private variantToMaterialMap = new Map(); - public initialMaterialIdx = 0; + initialMaterialIdx = 0; private activeMaterialIdx = 0; private modelVariants: Map; private parser: GLTFParser; diff --git a/packages/model-viewer/src/model-viewer-base.ts b/packages/model-viewer/src/model-viewer-base.ts index 3077912a1d..2e84ed22d5 100644 --- a/packages/model-viewer/src/model-viewer-base.ts +++ b/packages/model-viewer/src/model-viewer-base.ts @@ -284,7 +284,7 @@ export default class ModelViewerElementBase extends ReactiveElement { return; } - for (let entry of entries) { + for (const entry of entries) { if (entry.target === this) { this[$updateSize](entry.contentRect); } @@ -294,7 +294,7 @@ export default class ModelViewerElementBase extends ReactiveElement { if (HAS_INTERSECTION_OBSERVER) { this[$intersectionObserver] = new IntersectionObserver(entries => { - for (let entry of entries) { + for (const entry of entries) { if (entry.target === this) { const oldVisibility = this.modelIsVisible; this[$isElementInViewport] = entry.isIntersecting; @@ -446,7 +446,7 @@ export default class ModelViewerElementBase extends ReactiveElement { blobCanvas.width = outputWidth; blobCanvas.height = outputHeight; try { - return new Promise(async (resolve, reject) => { + return new Promise((resolve, reject) => { blobCanvas.getContext('2d')!.drawImage( this[$renderer].displayCanvas(this[$scene]), offsetX, @@ -462,13 +462,12 @@ export default class ModelViewerElementBase extends ReactiveElement { if (!blob) { return reject(new Error('Unable to retrieve canvas blob')); } - resolve(blob); }, mimeType, qualityArgument); }); } finally { this[$updateSize]({width, height}); - }; + } } /** diff --git a/packages/model-viewer/src/model-viewer.ts b/packages/model-viewer/src/model-viewer.ts index c2a353a617..f0fca5a328 100644 --- a/packages/model-viewer/src/model-viewer.ts +++ b/packages/model-viewer/src/model-viewer.ts @@ -28,7 +28,7 @@ import ModelViewerElementBase from './model-viewer-base.js'; export {CanvasTexture, FileLoader, Loader, NearestFilter} from 'three'; export const ModelViewerElement = -AnnotationMixin(SceneGraphMixin(StagingMixin(EnvironmentMixin(ControlsMixin( + AnnotationMixin(SceneGraphMixin(StagingMixin(EnvironmentMixin(ControlsMixin( ARMixin(LoadingMixin(AnimationMixin(ModelViewerElementBase)))))))); export type ModelViewerElement = InstanceType; diff --git a/packages/model-viewer/src/styles/deserializers.ts b/packages/model-viewer/src/styles/deserializers.ts index b2f403b2de..b980a015d5 100644 --- a/packages/model-viewer/src/styles/deserializers.ts +++ b/packages/model-viewer/src/styles/deserializers.ts @@ -49,6 +49,10 @@ export const enumerationDeserializer = (allowedNames: T[]) => return new Set(names); } catch (_error) { + // If parsing fails, we return an empty set. This is to ensure that + // deserializers are robust against malformed input. + console.warn( + `Failed to parse enumeration from "${valueString}". Returning empty set.`); } return new Set(); }; \ No newline at end of file diff --git a/packages/model-viewer/src/styles/evaluators.ts b/packages/model-viewer/src/styles/evaluators.ts index 632c7551c3..94f1852687 100644 --- a/packages/model-viewer/src/styles/evaluators.ts +++ b/packages/model-viewer/src/styles/evaluators.ts @@ -307,7 +307,7 @@ export class EnvEvaluator extends Evaluator { [$evaluate](): NumberNode { if (this[$identNode] != null) { switch (this[$identNode]!.value) { - case 'window-scroll-y': + case 'window-scroll-y': { const verticalScrollPosition = window.pageYOffset; const verticalScrollMax = Math.max( document.body.scrollHeight, @@ -320,6 +320,7 @@ export class EnvEvaluator extends Evaluator { 0; return {type: 'number', number: scrollY, unit: null}; + } } } @@ -328,7 +329,7 @@ export class EnvEvaluator extends Evaluator { } -const IS_MULTIPLICATION_RE = /[\*\/]/; +const IS_MULTIPLICATION_RE = /[*/]/; const $evaluator = Symbol('evaluator'); /** diff --git a/packages/model-viewer/src/styles/parsers.ts b/packages/model-viewer/src/styles/parsers.ts index aa9cbc7164..ebb225d615 100644 --- a/packages/model-viewer/src/styles/parsers.ts +++ b/packages/model-viewer/src/styles/parsers.ts @@ -137,8 +137,11 @@ export const parseExpressions = (() => { * next comma, or between the parens of a function invocation. */ const parseExpression = (() => { + // eslint-disable-next-line no-useless-escape const IS_IDENT_RE = /^(\-\-|[a-z\u0240-\uffff])/i; + // eslint-disable-next-line no-useless-escape const IS_OPERATOR_RE = /^([\*\+\/]|[\-]\s)/i; + // eslint-disable-next-line no-useless-escape const IS_EXPRESSION_END_RE = /^[\),]/; const FUNCTION_ARGUMENTS_FIRST_TOKEN = '('; const HEX_FIRST_TOKEN = '#'; @@ -224,7 +227,7 @@ const parseIdent = (() => { */ const parseNumber = (() => { // @see https://www.w3.org/TR/css-syntax/#number-token-diagram - const VALUE_RE = /[\+\-]?(\d+[\.]\d+|\d+|[\.]\d+)([eE][\+\-]?\d+)?/; + const VALUE_RE = /[+-]?(\d+\.\d+|\d+|\.\d+)([eE][+-]?\d+)?/; const UNIT_RE = /^[a-z%]+/i; const ALLOWED_UNITS = /^(m|mm|cm|rad|deg|[%])$/; diff --git a/packages/model-viewer/src/test/features/animation-spec.ts b/packages/model-viewer/src/test/features/animation-spec.ts index 0c840e2bb0..21e12b521b 100644 --- a/packages/model-viewer/src/test/features/animation-spec.ts +++ b/packages/model-viewer/src/test/features/animation-spec.ts @@ -105,6 +105,7 @@ suite('Animation', () => { expect(animationIsPlaying(element)).to.be.false; }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('has a current time close to the delay', () => { expect(element.currentTime) .to.be.closeTo(delaySeconds, TOLERANCE_SEC); @@ -130,6 +131,7 @@ suite('Animation', () => { expect(element.duration).to.be.greaterThan(0); }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('has a current time close to the delay', () => { expect(element.currentTime) .to.be.closeTo(delaySeconds, TOLERANCE_SEC); @@ -147,6 +149,7 @@ suite('Animation', () => { await animationsPlay; }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('plays forward, backward, and stops', async () => { await timePasses(element.duration * 0.8 * 1000); expect(animationIsPlaying(element), 'failed to start playing!') diff --git a/packages/model-viewer/src/test/features/annotation-spec.ts b/packages/model-viewer/src/test/features/annotation-spec.ts index 43f377722f..b435060044 100644 --- a/packages/model-viewer/src/test/features/annotation-spec.ts +++ b/packages/model-viewer/src/test/features/annotation-spec.ts @@ -95,12 +95,13 @@ suite('Annotation', () => { expect(sceneContainsHotspot(scene, hotspot)).to.be.true; }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('querying it returns valid data', () => { // to test querying, place hotspot in the center and verify the screen // position is half the default width and height (300 x 150) with a depth // value of ~1. const defaultDimensions = {width: 300, height: 150}; - element.updateHotspot({name: 'hotspot-1', position: `0m 0m 0m`}); + element.updateHotspot({name: 'hotspot-1', position: '0m 0m 0m'}); const hotspotData = element.queryHotspot('hotspot-1'); @@ -211,7 +212,7 @@ suite('Annotation', () => { let rect: DOMRect; setup(async () => { - element.setAttribute('style', `width: 200px; height: 300px`); + element.setAttribute('style', 'width: 200px; height: 300px'); rect = element.getBoundingClientRect(); element.cameraOrbit = '0deg 90deg 2m'; element.jumpCameraToGoal(); diff --git a/packages/model-viewer/src/test/features/ar-spec.ts b/packages/model-viewer/src/test/features/ar-spec.ts index 245fb32f58..4f872fe37c 100644 --- a/packages/model-viewer/src/test/features/ar-spec.ts +++ b/packages/model-viewer/src/test/features/ar-spec.ts @@ -200,6 +200,7 @@ suite('AR', () => { }); // This only works on a physical iOS device, not an emulated one. + // eslint-disable-next-line mocha/no-pending-tests test.skip('with an ios-src on iOS', async () => { element.iosSrc = assetPath('models/Astronaut.usdz'); await rafPasses(); diff --git a/packages/model-viewer/src/test/features/controls-spec.ts b/packages/model-viewer/src/test/features/controls-spec.ts index 4516c0b312..b52bd771d5 100644 --- a/packages/model-viewer/src/test/features/controls-spec.ts +++ b/packages/model-viewer/src/test/features/controls-spec.ts @@ -211,7 +211,7 @@ suite('Controls', () => { test('changes FOV basis when aspect ratio changes', async () => { const fov = element.getFieldOfView(); - expect(fov).to.be.closeTo(DEFAULT_FOV_DEG, .001); + expect(fov).to.be.closeTo(DEFAULT_FOV_DEG, 0.001); element.setAttribute('style', 'width: 200px; height: 300px'); await rafPasses(); await rafPasses(); @@ -244,7 +244,7 @@ suite('Controls', () => { suite('getCameraOrbit', () => { setup(async () => { - element.cameraOrbit = `1rad 1rad 2.5m`; + element.cameraOrbit = '1rad 1rad 2.5m'; element.jumpCameraToGoal(); await element.updateComplete; }); @@ -257,7 +257,7 @@ suite('Controls', () => { }); test('jumpCameraToGoal updates instantly', async () => { - const cameraOrbit = `0.5rad 1.5rad 2.2m`; + const cameraOrbit = '0.5rad 1.5rad 2.2m'; element.cameraOrbit = cameraOrbit; const fieldOfView = 30; element.fieldOfView = `${fieldOfView}deg`; @@ -266,7 +266,7 @@ suite('Controls', () => { await rafPasses(); expect(element.getFieldOfView()).to.be.closeTo(fieldOfView, 0.00001); - let orbit = element.getCameraOrbit(); + const orbit = element.getCameraOrbit(); // round to nearest 0.0001 orbit.theta = Math.round(orbit.theta * 10000) / 10000; expect(`${orbit.theta}rad ${orbit.phi}rad ${orbit.radius}m`) @@ -276,7 +276,7 @@ suite('Controls', () => { suite('min/max extents', () => { setup(async () => { - element.cameraOrbit = `0deg 90deg 2.5m`; + element.cameraOrbit = '0deg 90deg 2.5m'; element.jumpCameraToGoal(); await element.updateComplete; }); @@ -289,7 +289,7 @@ suite('Controls', () => { }); test('jumps to maxCameraOrbit when outside', async () => { - element.maxCameraOrbit = `-2rad 1rad 2m`; + element.maxCameraOrbit = '-2rad 1rad 2m'; await timePasses(); const orbit = element.getCameraOrbit(); expect(`${orbit.theta}rad ${orbit.phi}rad ${orbit.radius}m`) @@ -297,7 +297,7 @@ suite('Controls', () => { }); test('jumps to minCameraOrbit when outside', async () => { - element.minCameraOrbit = `2rad 2rad 3m`; + element.minCameraOrbit = '2rad 2rad 3m'; await timePasses(); const orbit = element.getCameraOrbit(); expect(`${orbit.theta}rad ${orbit.phi}rad ${orbit.radius}m`) @@ -305,14 +305,14 @@ suite('Controls', () => { }); test('jumps to maxFieldOfView when outside', async () => { - element.maxFieldOfView = `30deg`; + element.maxFieldOfView = '30deg'; await timePasses(); const fov = Math.round(element.getFieldOfView()); expect(`${fov}deg`).to.equal(element.maxFieldOfView); }); test('jumps to minFieldOfView when outside', async () => { - element.minFieldOfView = `60deg`; + element.minFieldOfView = '60deg'; await timePasses(); const fov = Math.round(element.getFieldOfView()); expect(`${fov}deg`).to.equal(element.minFieldOfView); @@ -565,6 +565,7 @@ suite('Controls', () => { }; }; + // eslint-disable-next-line mocha/no-pending-tests test.skip('one finger rotates', async () => { const orbit = element.getCameraOrbit(); @@ -597,6 +598,7 @@ suite('Controls', () => { expect(newOrbit.radius).to.eq(orbit.radius, 'radius'); }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('two fingers pan', async () => { element.cameraOrbit = '0deg 90deg auto'; element.jumpCameraToGoal(); @@ -667,6 +669,7 @@ suite('Controls', () => { expect(stopped).to.be.true; }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('tap moves the model and re-centers', async () => { element.cameraOrbit = '0deg 90deg auto'; element.jumpCameraToGoal(); @@ -717,6 +720,7 @@ suite('Controls', () => { expect(newTarget.z).to.be.eq(target.z, 'Z'); }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('camera-orbit cancels synthetic interaction', async () => { const canceled = waitForEvent( element, @@ -729,6 +733,7 @@ suite('Controls', () => { await canceled; }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('user interaction cancels synthetic interaction', async () => { const canceled = waitForEvent( element, @@ -743,6 +748,7 @@ suite('Controls', () => { await canceled; }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('second interaction does not interrupt the first', async () => { const target = element.getCameraTarget(); const orbit = element.getCameraOrbit(); diff --git a/packages/model-viewer/src/test/features/scene-graph-spec.ts b/packages/model-viewer/src/test/features/scene-graph-spec.ts index fd4e854eaa..c5657bec46 100644 --- a/packages/model-viewer/src/test/features/scene-graph-spec.ts +++ b/packages/model-viewer/src/test/features/scene-graph-spec.ts @@ -293,6 +293,7 @@ suite('SceneGraph', () => { }); }); + // eslint-disable-next-line mocha/no-pending-tests test.skip( 'When loading a new JPEG texture from an ObjectURL, the GLB does not export PNG', async () => { diff --git a/packages/model-viewer/src/test/features/scene-graph/model-spec.ts b/packages/model-viewer/src/test/features/scene-graph/model-spec.ts index 7a6403af90..cf6b7bb7f5 100644 --- a/packages/model-viewer/src/test/features/scene-graph/model-spec.ts +++ b/packages/model-viewer/src/test/features/scene-graph/model-spec.ts @@ -41,6 +41,7 @@ suite('scene-graph/model', () => { expect(model.materials[0].name).to.be.eq('Default'); }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('exposes a list of materials in the scene', async () => { // TODO: This test is skipped because [$correlatedObjects] can contain // unused materials, because it can contain a base material and the diff --git a/packages/model-viewer/src/test/features/staging-spec.ts b/packages/model-viewer/src/test/features/staging-spec.ts index c9d50c8636..0fc73520d5 100644 --- a/packages/model-viewer/src/test/features/staging-spec.ts +++ b/packages/model-viewer/src/test/features/staging-spec.ts @@ -56,6 +56,7 @@ suite('Staging', () => { await timePasses(); }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('causes the model to rotate after a delay', async () => { const {turntableRotation} = element; await rafPasses(); @@ -90,6 +91,7 @@ suite('Staging', () => { .to.be.greaterThan(turntableRotation); }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('pauses rotate after user interaction', async () => { const {turntableRotation} = element; await timePasses(AUTO_ROTATE_DELAY); diff --git a/packages/model-viewer/src/test/helpers.ts b/packages/model-viewer/src/test/helpers.ts index d3bee952cc..99ca523d27 100644 --- a/packages/model-viewer/src/test/helpers.ts +++ b/packages/model-viewer/src/test/helpers.ts @@ -124,8 +124,8 @@ export const spy = let sourcePrototype = object; while (sourcePrototype != null && - !sourcePrototype.hasOwnProperty(property)) { - sourcePrototype = (sourcePrototype as any).__proto__; + !Object.prototype.hasOwnProperty.call(sourcePrototype, property)) { + sourcePrototype = Object.getPrototypeOf(sourcePrototype); } if (sourcePrototype == null) { diff --git a/packages/model-viewer/src/test/model-viewer-base-spec.ts b/packages/model-viewer/src/test/model-viewer-base-spec.ts index 2db6684192..7b9bd44b71 100644 --- a/packages/model-viewer/src/test/model-viewer-base-spec.ts +++ b/packages/model-viewer/src/test/model-viewer-base-spec.ts @@ -157,7 +157,7 @@ suite('ModelViewerElementBase', () => { suite('toDataURL', () => { test('produces a URL-compatible string', () => { - const dataUrlMatcher = /^data\:image\//; + const dataUrlMatcher = /^data:image\//; expect(dataUrlMatcher.test(element.toDataURL())).to.be.true; }); }); @@ -171,7 +171,7 @@ suite('ModelViewerElementBase', () => { test('can convert blob to object URL', async () => { const blob = await element.toBlob(); const objectUrl = URL.createObjectURL(blob); - const objectUrlMatcher = /^blob\:/; + const objectUrlMatcher = /^blob:/; expect(objectUrlMatcher.test(objectUrl)).to.be.true; }); @@ -180,6 +180,7 @@ suite('ModelViewerElementBase', () => { expect(blob.size).to.be.greaterThan(0); }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('idealAspect gives the proper blob dimensions', async () => { const basicBlob = await element.toBlob(); const idealBlob = await element.toBlob({idealAspect: true}); @@ -195,14 +196,14 @@ suite('ModelViewerElementBase', () => { }); suite('orchestrates rendering', () => { - let elements: Array = []; + const elements: Array = []; setup(async () => { elements.push(new ModelViewerElement()); elements.push(new ModelViewerElement()); elements.push(new ModelViewerElement()); - for (let element of elements) { + for (const element of elements) { element.style.position = 'relative'; element.style.marginBottom = '100vh'; element.src = assetPath('models/cube.gltf'); @@ -224,6 +225,7 @@ suite('ModelViewerElementBase', () => { expect(elements[2].modelIsVisible).to.be.true; }); + // eslint-disable-next-line mocha/no-pending-tests test.skip('only models visible in the viewport', async () => { // IntersectionObserver needs to set appropriate // visibility on the scene, lots of timing issues when diff --git a/packages/model-viewer/src/test/three-components/ARRenderer-spec.ts b/packages/model-viewer/src/test/three-components/ARRenderer-spec.ts index 4e7e027d39..3932f1d2a6 100644 --- a/packages/model-viewer/src/test/three-components/ARRenderer-spec.ts +++ b/packages/model-viewer/src/test/three-components/ARRenderer-spec.ts @@ -96,7 +96,7 @@ suite('ARRenderer', () => { const stubWebXrInterface = (arRenderer: ARRenderer) => { arRenderer.resolveARSession = async () => { class FakeSession extends EventTarget implements XRSession { - public renderState: XRRenderState = { + renderState: XRRenderState = { baseLayer: { getViewport: () => { return {x: 0, y: 0, width: 320, height: 240} as XRViewport @@ -104,8 +104,7 @@ suite('ARRenderer', () => { } as unknown as XRLayer } as XRRenderState; - public hitTestSources: Set = - new Set(); + hitTestSources: Set = new Set(); async updateRenderState(_object: any) { } diff --git a/packages/model-viewer/src/test/three-components/ModelScene-spec.ts b/packages/model-viewer/src/test/three-components/ModelScene-spec.ts index 4d96fc8853..77a90979b1 100644 --- a/packages/model-viewer/src/test/three-components/ModelScene-spec.ts +++ b/packages/model-viewer/src/test/three-components/ModelScene-spec.ts @@ -44,7 +44,7 @@ suite('ModelScene', () => { suite('with a model', () => { setup(async () => { - await scene.setSource(assetPath('models/Astronaut.glb')); + await scene.setSource(assetPath('models/soldier.glb')); }); suite('setShadowIntensity', () => { @@ -63,6 +63,23 @@ suite('ModelScene', () => { expect(scene.shadow).to.be.ok; }); }); + + test('can append and play an animation', () => { + expect(scene.animationNames.length).to.be.greaterThan(0); + const animationName = scene.animationNames[0]; + scene.appendAnimation(animationName); + expect(scene.appendedAnimations).to.include(animationName); + }); + + test('can detach an appended animation', () => { + expect(scene.animationNames.length).to.be.greaterThan(0); + const animationName = scene.animationNames[0]; + scene.appendAnimation(animationName); + expect(scene.appendedAnimations).to.include(animationName); + scene.detachAnimation( + animationName, false); + expect(scene.appendedAnimations).to.not.include(animationName); + }); }); suite('setSize', () => { diff --git a/packages/model-viewer/src/test/three-components/Renderer-spec.ts b/packages/model-viewer/src/test/three-components/Renderer-spec.ts index 3fb5945817..310f51fa7a 100644 --- a/packages/model-viewer/src/test/three-components/Renderer-spec.ts +++ b/packages/model-viewer/src/test/three-components/Renderer-spec.ts @@ -154,6 +154,7 @@ suite('Renderer with two scenes', () => { }); }); + // eslint-disable-next-line mocha/no-pending-tests suite.skip('with two loaded scenes', () => { setup(async () => { const sceneVisible = waitForEvent(scene.element, 'poster-dismissed'); diff --git a/packages/model-viewer/src/test/three-components/TextureUtils-spec.ts b/packages/model-viewer/src/test/three-components/TextureUtils-spec.ts index 1f8e78b07f..2a232ec443 100644 --- a/packages/model-viewer/src/test/three-components/TextureUtils-spec.ts +++ b/packages/model-viewer/src/test/three-components/TextureUtils-spec.ts @@ -56,14 +56,14 @@ suite('TextureUtils', () => { suite('load', () => { test('loads a valid texture from URL', async () => { - let texture = await textureUtils.loadEquirect(EQUI_URL); + const texture = await textureUtils.loadEquirect(EQUI_URL); texture.dispose(); expect(texture.isTexture).to.be.ok; expect(texture.name).to.be.eq(EQUI_URL); expect(texture.mapping).to.be.eq(EquirectangularReflectionMapping); }); test('loads a valid HDR texture from URL', async () => { - let texture = await textureUtils.loadEquirect(HDR_EQUI_URL); + const texture = await textureUtils.loadEquirect(HDR_EQUI_URL); texture.dispose(); expect(texture.isTexture).to.be.ok; expect(texture.name).to.be.eq(HDR_EQUI_URL); diff --git a/packages/model-viewer/src/three-components/ARRenderer.ts b/packages/model-viewer/src/three-components/ARRenderer.ts index 4154298611..3c7c943c98 100644 --- a/packages/model-viewer/src/three-components/ARRenderer.ts +++ b/packages/model-viewer/src/three-components/ARRenderer.ts @@ -124,9 +124,9 @@ export type XRMode = typeof XRMode[keyof typeof XRMode]; export class ARRenderer extends EventDispatcher< {status: {status: ARStatus}, tracking: {status: ARTracking}}> { - public threeRenderer: WebGLRenderer; - public currentSession: XRSession|null = null; - public placeOnWall = false; + threeRenderer: WebGLRenderer; + currentSession: XRSession|null = null; + placeOnWall = false; private placementBox: PlacementBox|null = null; private menuPanel: XRMenuPanel|null = null; @@ -246,7 +246,7 @@ export class ARRenderer extends EventDispatcher< console.warn('Cannot present while a model is already presenting'); } - let waitForAnimationFrame = new Promise((resolve, _reject) => { + const waitForAnimationFrame = new Promise((resolve, _reject) => { requestAnimationFrame(() => resolve()); }); @@ -315,8 +315,7 @@ export class ARRenderer extends EventDispatcher< new DOMPoint(0, 0, 0), {x: 0, y: -Math.sin(radians), z: -Math.cos(radians)}); currentSession - .requestHitTestSource! - ({space: viewerRefSpace, offsetRay: ray})!.then(hitTestSource => { + .requestHitTestSource!({space: viewerRefSpace, offsetRay: ray})!.then(hitTestSource => { this.initialHitSource = hitTestSource; }); @@ -800,8 +799,7 @@ export class ARRenderer extends EventDispatcher< session.addEventListener('selectstart', this.onSelectStart); session.addEventListener('selectend', this.onSelectEnd); session - .requestHitTestSourceForTransientInput! - ({profile: 'generic-touchscreen'})!.then(hitTestSource => { + .requestHitTestSourceForTransientInput!({profile: 'generic-touchscreen'})!.then(hitTestSource => { this.transientHitTestSource = hitTestSource; }); } @@ -809,12 +807,12 @@ export class ARRenderer extends EventDispatcher< private getTouchLocation(): Vector3|null { const {axes} = this.inputSource!.gamepad!; - let location = this.placementBox!.getExpandedHit( + const location = this.placementBox!.getExpandedHit( this.presentedScene!, axes[0], axes[1]); if (location != null) { vector3.copy(location).sub(this.presentedScene!.getCamera().position); if (vector3.length() > MAX_DISTANCE) - return null; + {return null;} } return location; } @@ -1191,8 +1189,8 @@ export class ARRenderer extends EventDispatcher< private applyXRControllerRotations(pivot: Object3D) { if (!this.isTwoHandInteraction) { - if (this.xrController1) this.applyXRControllerRotation(this.xrController1, pivot); - if (this.xrController2) this.applyXRControllerRotation(this.xrController2, pivot); + if (this.xrController1) {this.applyXRControllerRotation(this.xrController1, pivot);} + if (this.xrController2) {this.applyXRControllerRotation(this.xrController2, pivot);} } } @@ -1249,7 +1247,7 @@ export class ARRenderer extends EventDispatcher< /** * Only public to make it testable. */ - public onWebXRFrame(time: number, frame: XRFrame) { + onWebXRFrame(time: number, frame: XRFrame) { if (this.xrMode !== XRMode.SCREEN_SPACE) { this.updateXRControllerHover(); } diff --git a/packages/model-viewer/src/three-components/CachingGLTFLoader.ts b/packages/model-viewer/src/three-components/CachingGLTFLoader.ts index 0f8aabc119..eceae97bc0 100644 --- a/packages/model-viewer/src/three-components/CachingGLTFLoader.ts +++ b/packages/model-viewer/src/three-components/CachingGLTFLoader.ts @@ -38,8 +38,7 @@ export const loadWithLoader = progressCallback: ProgressCallback = () => {}) => { const onProgress = (event: ProgressEvent) => { const fraction = event.loaded / event.total; - progressCallback! - (Math.max(0, Math.min(1, isFinite(fraction) ? fraction : 1))); + progressCallback!(Math.max(0, Math.min(1, isFinite(fraction) ? fraction : 1))); }; return new Promise((resolve, reject) => { loader.load(url, resolve, onProgress, reject); diff --git a/packages/model-viewer/src/three-components/Hotspot.ts b/packages/model-viewer/src/three-components/Hotspot.ts index b15bc94adb..7bcc11f386 100644 --- a/packages/model-viewer/src/three-components/Hotspot.ts +++ b/packages/model-viewer/src/three-components/Hotspot.ts @@ -50,11 +50,11 @@ const quat = new Quaternion(); * it should be removed from the tree so it can be garbage-collected. */ export class Hotspot extends CSS2DObject { - public normal: Vector3 = new Vector3(0, 1, 0); - public surface?: string; - public mesh?: Mesh; - public tri?: Vector3; - public bary?: Vector3; + normal: Vector3 = new Vector3(0, 1, 0); + surface?: string; + mesh?: Mesh; + tri?: Vector3; + bary?: Vector3; private initialized = false; private referenceCount = 1; private pivot = document.createElement('div'); @@ -120,8 +120,9 @@ export class Hotspot extends CSS2DObject { * as the data-position attribute. */ updatePosition(position?: string) { - if (position == null) + if (position == null) { return; + } const positionNodes = parseExpressions(position)[0].terms; for (let i = 0; i < 3; ++i) { this.position.setComponent( @@ -135,8 +136,9 @@ export class Hotspot extends CSS2DObject { * data-normal attribute. */ updateNormal(normal?: string) { - if (normal == null) + if (normal == null) { return; + } const normalNodes = parseExpressions(normal)[0].terms; for (let i = 0; i < 3; ++i) { this.normal.setComponent(i, (normalNodes[i] as NumberNode).number); diff --git a/packages/model-viewer/src/three-components/ModelScene.ts b/packages/model-viewer/src/three-components/ModelScene.ts index ebfcf8526b..e6886a5d36 100644 --- a/packages/model-viewer/src/three-components/ModelScene.ts +++ b/packages/model-viewer/src/three-components/ModelScene.ts @@ -69,43 +69,43 @@ const ndc = new Vector2(); * Provides lights and cameras to be used in a renderer. */ export class ModelScene extends Scene { - public element: ModelViewerElement; - public canvas: HTMLCanvasElement; - public annotationRenderer = new CSS2DRenderer(); - public effectRenderer: EffectComposerInterface|null = null; - public schemaElement = document.createElement('script'); - public width = 1; - public height = 1; - public aspect = 1; - public scaleStep = 0; - public renderCount = 0; - public externalRenderer: RendererInterface|null = null; - public appendedAnimations: Array = []; - public markedAnimations: Array = []; + element: ModelViewerElement; + canvas: HTMLCanvasElement; + annotationRenderer = new CSS2DRenderer(); + effectRenderer: EffectComposerInterface|null = null; + schemaElement = document.createElement('script'); + width = 1; + height = 1; + aspect = 1; + scaleStep = 0; + renderCount = 0; + externalRenderer: RendererInterface|null = null; + appendedAnimations: Array = []; + markedAnimations: Array = []; // These default camera values are never used, as they are reset once the // model is loaded and framing is computed. - public camera = new PerspectiveCamera(45, 1, 0.1, 100); - public xrCamera: Camera|null = null; - - public url: string|null = null; - public pivot = new Object3D(); - public target = new Object3D(); - public animationNames: Array = []; - public boundingBox = new Box3(); - public boundingSphere = new Sphere(); - public size = new Vector3(); - public idealAspect = 0; - public framedFoVDeg = 0; - - public shadow: Shadow|null = null; - public shadowIntensity = 0; - public shadowSoftness = 1; - public bakedShadows = new Set(); - - public exposure = 1; - public toneMapping: ToneMapping = NeutralToneMapping; - public canScale = true; + camera = new PerspectiveCamera(45, 1, 0.1, 100); + xrCamera: Camera|null = null; + + url: string|null = null; + pivot = new Object3D(); + target = new Object3D(); + animationNames: Array = []; + boundingBox = new Box3(); + boundingSphere = new Sphere(); + size = new Vector3(); + idealAspect = 0; + framedFoVDeg = 0; + + shadow: Shadow|null = null; + shadowIntensity = 0; + shadowSoftness = 1; + bakedShadows = new Set(); + + exposure = 1; + toneMapping: ToneMapping = NeutralToneMapping; + canScale = true; private isDirty = false; @@ -232,17 +232,19 @@ export class ModelScene extends Scene { let gltf: ModelViewerGLTFInstance; try { - gltf = await new Promise( - async (resolve, reject) => { - this.cancelPendingSourceChange = () => reject(); - try { - const result = await this.element[$renderer].loader.load( - url, this.element, progressCallback); - resolve(result); - } catch (error) { - reject(error); - } - }); + gltf = await new Promise((resolve, reject) => { + this.cancelPendingSourceChange = () => reject(); + + (async () => { + try { + const result = await this.element[$renderer].loader.load( + url, this.element, progressCallback); + resolve(result); + } catch (error) { + reject(error); + } + })(); + }); } catch (error) { if (error == null) { // Loading was cancelled, so silently return @@ -252,6 +254,7 @@ export class ModelScene extends Scene { throw error; } + this.cancelPendingSourceChange = null; this.reset(); this.url = url; @@ -753,11 +756,6 @@ export class ModelScene extends Scene { const action = this.mixer.clipAction(animationClip, this); - // Reset animationAction timeScale - if (action.timeScale != this.element.timeScale) { - action.timeScale = this.element.timeScale; - } - this.currentAnimationAction = action; if (this.element.paused) { @@ -787,9 +785,9 @@ export class ModelScene extends Scene { appendAnimation( name: string = '', loopMode: AnimationActionLoopStyles = LoopRepeat, repetitionCount: number = Infinity, weight: number = 1, - timeScale: number = 1, fade: boolean|number = false, - warp: boolean|number = false, relativeWarp: boolean = true, - time: null|number = null, needsToStop: boolean = false) { + timeScale: number = 1, fade: boolean|number|string = false, + warp: boolean|number|string = false, relativeWarp: boolean = true, + time: null|number|string = null, needsToStop: boolean = false) { if (this._currentGLTF == null || name === this.element.animationName) { return; } @@ -798,85 +796,58 @@ export class ModelScene extends Scene { return; } - let animationClip = null; - const defaultFade = 1.25; - - if (name) { - animationClip = this.animationsByName.get(name); - } - + const animationClip = name ? this.animationsByName.get(name) : null; if (animationClip == null) { return; } - // validate function parameters + // validate and normalize parameters if (typeof repetitionCount === 'string') { - if (!isNaN(repetitionCount)) { - repetitionCount = Math.max(parseInt(repetitionCount), 1); - } else { - repetitionCount = Infinity; - console.warn( - 'Invalid repetitionCount value, repetitionCount is set to Infinity'); - } + repetitionCount = !isNaN(parseFloat(repetitionCount)) ? + Math.max(parseInt(repetitionCount), 1) : + Infinity; } else if (typeof repetitionCount === 'number' && repetitionCount < 1) { repetitionCount = 1; } if (repetitionCount === 1 && loopMode !== LoopOnce) { - loopMode = LoopOnce + loopMode = LoopOnce; } if (typeof weight === 'string') { - if (!isNaN(weight)) { - weight = parseFloat(weight); - } else { - weight = 1; - console.warn('Invalid weight value, weight is set to 1'); - } + weight = !isNaN(parseFloat(weight)) ? parseFloat(weight) : 1; } if (typeof timeScale === 'string') { - if (!isNaN(timeScale)) { - timeScale = parseFloat(timeScale); - } else { - timeScale = 1; - console.warn('Invalid timeScale value, timeScale is set to 1'); - } + timeScale = !isNaN(parseFloat(timeScale)) ? parseFloat(timeScale) : 1; } - if (typeof fade === 'string') { - // @ts-ignore: Unreachable code error - if (fade.toLowerCase().trim() === 'true') { - fade = true; - // @ts-ignore: Unreachable code error - } else if (fade.toLowerCase().trim() === 'false') { - fade = false; - } else if (!isNaN(fade)) { - fade = parseFloat(fade); - } else { - fade = false; - console.warn('Invalid fade value, fade is set to false'); - } + if (typeof time === 'string') { + time = !isNaN(parseFloat(time)) ? parseFloat(time) : null; } - if (typeof warp === 'string') { - // @ts-ignore: Unreachable code error + const {shouldFade, duration: fadeDuration} = + this.parseFadeValue(fade, false, 1.25); + + const defaultWarpDuration = 1.25; + let shouldWarp = false; + let warpDuration = 0; + + if (typeof warp === 'boolean') { + shouldWarp = warp; + warpDuration = warp ? defaultWarpDuration : 0; + } else if (typeof warp === 'number') { + shouldWarp = warp > 0; + warpDuration = Math.max(warp, 0); + } else if (typeof warp === 'string') { if (warp.toLowerCase().trim() === 'true') { - warp = true; - // @ts-ignore: Unreachable code error + shouldWarp = true; + warpDuration = defaultWarpDuration; } else if (warp.toLowerCase().trim() === 'false') { - warp = false; - } else if (!isNaN(warp)) { - warp = parseFloat(warp); - } else { - warp = false; - console.warn('Invalid warp value, warp is set to false'); - } - } - - if (typeof time === 'string') { - if (!isNaN(time)) { - time = parseFloat(time); + shouldWarp = false; + } else if (!isNaN(parseFloat(warp))) { + warpDuration = Math.max(parseFloat(warp), 0); + shouldWarp = warpDuration > 0; } } @@ -896,22 +867,15 @@ export class ModelScene extends Scene { action.time = Math.min(Math.max(time, 0), animationClip.duration); } - if (typeof fade === 'boolean' && fade) { - action.fadeIn(defaultFade); - } else if (typeof fade === 'number') { - action.fadeIn(Math.max(fade, 0)); - } else { - if (weight >= 0) { - action.weight = Math.min(Math.max(weight, 0), 1); - } + if (shouldFade) { + action.fadeIn(fadeDuration); + } else if (weight >= 0) { + action.weight = Math.min(Math.max(weight, 0), 1); } - if (typeof warp === 'boolean' && warp) { - action.warp( - relativeWarp ? currentTimeScale : 0, timeScale, defaultFade); - } else if (typeof warp === 'number') { + if (shouldWarp) { action.warp( - relativeWarp ? currentTimeScale : 0, timeScale, Math.max(warp, 0)); + relativeWarp ? currentTimeScale : 0, timeScale, warpDuration); } else { action.timeScale = timeScale; } @@ -935,7 +899,49 @@ export class ModelScene extends Scene { } } - detachAnimation(name: string = '', fade: boolean|number = true) { + /** + * Helper function to parse fade parameter values + */ + private parseFadeValue( + fade: boolean|number|string, defaultValue: boolean = true, + defaultDuration: number = 1.5): {shouldFade: boolean, duration: number} { + const normalizeString = (str: string) => str.toLowerCase().trim(); + + if (typeof fade === 'boolean') { + return {shouldFade: fade, duration: fade ? defaultDuration : 0}; + } + + if (typeof fade === 'number') { + const duration = Math.max(fade, 0); + return {shouldFade: duration > 0, duration}; + } + + if (typeof fade === 'string') { + const normalized = normalizeString(fade); + + if (normalized === 'true') { + return {shouldFade: true, duration: defaultDuration}; + } + + if (normalized === 'false') { + return {shouldFade: false, duration: 0}; + } + + const parsed = parseFloat(normalized); + if (!isNaN(parsed)) { + const duration = Math.max(parsed, 0); + return {shouldFade: duration > 0, duration}; + } + } + + console.warn(`Invalid fade value: ${fade}. Using default: ${defaultValue}`); + return { + shouldFade: defaultValue, + duration: defaultValue ? defaultDuration : 0 + }; + } + + detachAnimation(name: string = '', fade: boolean|number|string = true) { if (this._currentGLTF == null || name === this.element.animationName) { return; } @@ -944,47 +950,25 @@ export class ModelScene extends Scene { return; } - let animationClip = null; - const defaultFade = 1.5; - - if (name) { - animationClip = this.animationsByName.get(name); - } - + const animationClip = name ? this.animationsByName.get(name) : null; if (animationClip == null) { return; } - if (typeof fade === 'string') { - // @ts-ignore: Unreachable code error - if (fade.toLowerCase().trim() === 'true') { - fade = true; - // @ts-ignore: Unreachable code error - } else if (fade.toLowerCase().trim() === 'false') { - fade = false; - } else if (!isNaN(fade)) { - fade = parseFloat(fade); - } else { - fade = true; - console.warn('Invalid fade value, fade is set to true'); - } - } + const {shouldFade, duration} = this.parseFadeValue(fade, true, 1.5); try { const action = this.mixer.existingAction(animationClip) || this.mixer.clipAction(animationClip, this); - if (typeof fade === 'boolean' && fade) { - action.fadeOut(defaultFade); - } else if (typeof fade === 'number') { - action.fadeOut(Math.max(fade, 0)); + if (shouldFade) { + action.fadeOut(duration); } else { action.stop(); } - const result = + this.element[$scene].appendedAnimations = this.element[$scene].appendedAnimations.filter(i => i !== name); - this.element[$scene].appendedAnimations = result; } catch (error) { console.error(error); } diff --git a/packages/model-viewer/src/three-components/Renderer.ts b/packages/model-viewer/src/three-components/Renderer.ts index 014fa2c226..53db482b9f 100644 --- a/packages/model-viewer/src/three-components/Renderer.ts +++ b/packages/model-viewer/src/three-components/Renderer.ts @@ -94,14 +94,14 @@ export class Renderer extends } } - public threeRenderer!: WebGLRenderer; - public canvas3D: HTMLCanvasElement; - public textureUtils: TextureUtils|null; - public arRenderer: ARRenderer; - public loader = new CachingGLTFLoader(ModelViewerGLTFInstance); - public width = 0; - public height = 0; - public dpr = 1; + threeRenderer!: WebGLRenderer; + canvas3D: HTMLCanvasElement; + textureUtils: TextureUtils|null; + arRenderer: ARRenderer; + loader = new CachingGLTFLoader(ModelViewerGLTFInstance); + width = 0; + height = 0; + dpr = 1; private scenes: Set = new Set(); private multipleScenesVisible = false; diff --git a/packages/model-viewer/src/three-components/Shadow.ts b/packages/model-viewer/src/three-components/Shadow.ts index 06b7d588b9..1901dddfbe 100644 --- a/packages/model-viewer/src/three-components/Shadow.ts +++ b/packages/model-viewer/src/three-components/Shadow.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import {BackSide, DoubleSide, Box3, Material, Mesh, MeshBasicMaterial, MeshDepthMaterial, Object3D, OrthographicCamera, PlaneGeometry, RenderTargetOptions, RGBAFormat, Scene, ShaderMaterial, Vector3, WebGLRenderer, WebGLRenderTarget} from 'three'; +import {BackSide, Box3, DoubleSide, Material, Mesh, MeshBasicMaterial, MeshDepthMaterial, Object3D, OrthographicCamera, PlaneGeometry, RenderTargetOptions, RGBAFormat, Scene, ShaderMaterial, Vector3, WebGLRenderer, WebGLRenderTarget} from 'three'; import {HorizontalBlurShader} from 'three/examples/jsm/shaders/HorizontalBlurShader.js'; import {VerticalBlurShader} from 'three/examples/jsm/shaders/VerticalBlurShader.js'; import {lerp} from 'three/src/math/MathUtils.js'; @@ -65,7 +65,7 @@ export class Shadow extends Object3D { private size = new Vector3; private maxDimension = 0; private isAnimated = false; - public needsUpdate = false; + needsUpdate = false; constructor(scene: ModelScene, softness: number, side: Side) { super(); diff --git a/packages/model-viewer/src/three-components/SmoothControls.ts b/packages/model-viewer/src/three-components/SmoothControls.ts index ee0bd05cee..2ee9a4941d 100644 --- a/packages/model-viewer/src/three-components/SmoothControls.ts +++ b/packages/model-viewer/src/three-components/SmoothControls.ts @@ -130,11 +130,11 @@ export class SmoothControls extends EventDispatcher<{ 'pointer-change-start': {}, 'pointer-change-end': {} }> { - public orbitSensitivity = 1; - public zoomSensitivity = 1; - public panSensitivity = 1; - public inputSensitivity = 1; - public changeSource = ChangeSource.NONE; + orbitSensitivity = 1; + zoomSensitivity = 1; + panSensitivity = 1; + inputSensitivity = 1; + changeSource = ChangeSource.NONE; private _interactionEnabled: boolean = false; private _options: SmoothControlsOptions; @@ -142,8 +142,8 @@ export class SmoothControls extends EventDispatcher<{ private isUserPointing = false; // Pan state - public enablePan = true; - public enableTap = true; + enablePan = true; + enableTap = true; private panProjection = new Matrix3(); private panPerPixel = 0; @@ -690,6 +690,8 @@ export class SmoothControls extends EventDispatcher<{ try { element.setPointerCapture(event.pointerId); } catch { + // setPointerCapture is not supported in all browsers, so we ignore + // errors here. } this.pointers.push( {clientX: event.clientX, clientY: event.clientY, id: event.pointerId}); diff --git a/packages/model-viewer/src/three-components/TextureUtils.ts b/packages/model-viewer/src/three-components/TextureUtils.ts index 5fc078bb22..f5be30ed2e 100644 --- a/packages/model-viewer/src/three-components/TextureUtils.ts +++ b/packages/model-viewer/src/three-components/TextureUtils.ts @@ -34,7 +34,7 @@ const MAX_SAMPLES = 20; const HDR_FILE_RE = /\.hdr(\.js)?$/; export default class TextureUtils { - public lottieLoaderUrl = ''; + lottieLoaderUrl = ''; private _ldrLoader: TextureLoader|null = null; private _imageLoader: HDRJPGLoader|null = null; @@ -172,16 +172,16 @@ export default class TextureUtils { let environmentMapLoads: Promise; // If we have a skybox URL, attempt to load it as a cubemap - if (!!skyboxUrl) { + if (skyboxUrl) { skyboxLoads = this.loadEquirectFromUrl( skyboxUrl, withCredentials, progressCallback); } - if (!!environmentMapUrl) { + if (environmentMapUrl) { // We have an available environment map URL environmentMapLoads = this.loadEquirectFromUrl( environmentMapUrl, withCredentials, progressCallback); - } else if (!!skyboxUrl) { + } else if (skyboxUrl) { // Fallback to deriving the environment map from an available skybox environmentMapLoads = this.loadEquirectFromUrl( skyboxUrl, withCredentials, progressCallback); diff --git a/packages/model-viewer/src/three-components/XRMenuPanel.ts b/packages/model-viewer/src/three-components/XRMenuPanel.ts index 3a38e67d16..11ddd6e1ca 100644 --- a/packages/model-viewer/src/three-components/XRMenuPanel.ts +++ b/packages/model-viewer/src/three-components/XRMenuPanel.ts @@ -297,7 +297,7 @@ export class XRMenuPanel extends Object3D { this.traverse((child) => { if (child instanceof Mesh) { const mat = child.material as MeshBasicMaterial; - if (mat.transparent) mat.opacity = newOpacity; + if (mat.transparent) {mat.opacity = newOpacity;} } }); this.visible = newOpacity > 0; diff --git a/packages/model-viewer/src/three-components/gltf-instance/VariantMaterialExporterPlugin.ts b/packages/model-viewer/src/three-components/gltf-instance/VariantMaterialExporterPlugin.ts index 61a03113e3..9970d4e4d5 100644 --- a/packages/model-viewer/src/three-components/gltf-instance/VariantMaterialExporterPlugin.ts +++ b/packages/model-viewer/src/three-components/gltf-instance/VariantMaterialExporterPlugin.ts @@ -41,8 +41,8 @@ import {UserDataVariantMapping} from './VariantMaterialLoaderPlugin.js'; const compatibleObject = (object: Object3D) => { // @TODO: Need properer variantMaterials format validation? return (object as Mesh).material !== - undefined && // easier than (!object.isMesh && !object.isLine && - // !object.isPoints) + undefined && // easier than (!object.isMesh && !object.isLine && + // !object.isPoints) object.userData && // just in case object.userData.variantMaterials && // Is this line costly? @@ -65,7 +65,7 @@ const compatibleMaterial = (material: Material|null) => { export default class GLTFExporterMaterialsVariantsExtension implements GLTFExporterPlugin { writer: any; // @TODO: Replace with GLTFWriter when GLTFExporter plugin TS - // declaration is ready + // declaration is ready name: string; variantNames: string[]; @@ -115,7 +115,7 @@ export default class GLTFExporterMaterialsVariantsExtension implements const variantMaterials = userData.variantMaterials as Map; const variantDataMap = userData.variantData as Map; - const mappingTable = + const mappingTable = new Map(); // Removes gaps in the variant indices list (caused by deleting variants). diff --git a/packages/model-viewer/src/three-components/gltf-instance/VariantMaterialLoaderPlugin.ts b/packages/model-viewer/src/three-components/gltf-instance/VariantMaterialLoaderPlugin.ts index 77bd848c71..5eda4e0907 100644 --- a/packages/model-viewer/src/three-components/gltf-instance/VariantMaterialLoaderPlugin.ts +++ b/packages/model-viewer/src/three-components/gltf-instance/VariantMaterialLoaderPlugin.ts @@ -26,8 +26,7 @@ */ import {Material as ThreeMaterial, Mesh} from 'three'; -import {GLTFReference} from 'three/examples/jsm/loaders/GLTFLoader.js'; -import {GLTF, GLTFLoaderPlugin, GLTFParser} from 'three/examples/jsm/loaders/GLTFLoader.js'; +import {GLTF, GLTFLoaderPlugin, GLTFParser, GLTFReference} from 'three/examples/jsm/loaders/GLTFLoader.js'; export interface UserDataVariantMapping { diff --git a/packages/model-viewer/src/three-components/gltf-instance/utilities.ts b/packages/model-viewer/src/three-components/gltf-instance/utilities.ts index 9ddc3433a3..239611bd06 100644 --- a/packages/model-viewer/src/three-components/gltf-instance/utilities.ts +++ b/packages/model-viewer/src/three-components/gltf-instance/utilities.ts @@ -111,9 +111,9 @@ export class GLTFTreeVisitor { visit(gltf: GLTF, options: VisitOptions = {}): void { const allScenes = !!options.allScenes; const sparse = !!options.sparse; - const scenes = allScenes ? - gltf.scenes || [] : - (gltf.scenes && gltf.scene != null) ? [gltf.scenes[gltf.scene]] : []; + const scenes = allScenes ? gltf.scenes || [] : + (gltf.scenes && gltf.scene != null) ? [gltf.scenes[gltf.scene]] : + []; const state: VisitorTraversalState = {hierarchy: [], visited: new Set(), sparse, gltf}; diff --git a/packages/model-viewer/src/utilities/animation.ts b/packages/model-viewer/src/utilities/animation.ts index 38581e2c72..25fd7ca976 100644 --- a/packages/model-viewer/src/utilities/animation.ts +++ b/packages/model-viewer/src/utilities/animation.ts @@ -17,7 +17,7 @@ import {clamp} from '../utilities.js'; // Adapted from https://gist.github.com/gre/1650294 export const easeInOutQuad: TimingFunction = (t: number) => - t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t; + t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; /** * A TimingFunction accepts a value from 0-1 and returns a corresponding diff --git a/packages/model-viewer/src/utilities/progress-tracker.ts b/packages/model-viewer/src/utilities/progress-tracker.ts index 71324a6409..6566024833 100644 --- a/packages/model-viewer/src/utilities/progress-tracker.ts +++ b/packages/model-viewer/src/utilities/progress-tracker.ts @@ -99,9 +99,8 @@ export class ProgressTracker extends EventTarget { } return (progress: number): number => { - let nextProgress: number; - - nextProgress = Math.max(clamp(progress, 0, 1), activity.progress); + const nextProgress: number = + Math.max(clamp(progress, 0, 1), activity.progress); if (nextProgress !== activity.progress) { this.announceTotalProgress(activity, nextProgress, reason); @@ -116,8 +115,9 @@ export class ProgressTracker extends EventTarget { let progressLeft = 0; let completedActivities = 0; - if (nextProgress == 1.0) + if (nextProgress == 1.0) { updatedActivity.completed = true; + } for (const activity of this.ongoingActivities) { const {progress} = activity; @@ -141,7 +141,7 @@ export class ProgressTracker extends EventTarget { this.totalProgress; this.dispatchEvent(new CustomEvent( - 'progress', {detail: {totalProgress, reason }})); + 'progress', {detail: {totalProgress, reason}})); if (completedActivities === this.ongoingActivityCount) { this.totalProgress = 0.0; diff --git a/packages/modelviewer.dev/data/docs.json b/packages/modelviewer.dev/data/docs.json index 2648e19ca0..accd066064 100644 --- a/packages/modelviewer.dev/data/docs.json +++ b/packages/modelviewer.dev/data/docs.json @@ -136,7 +136,7 @@ { "name": "lottieLoaderLocation", "htmlName": "lottieLoaderLocation", - "description": "This static, writable property sets <model-viewer>'s LottieLoader location URL. The default URL is https://cdn.jsdelivr.net/npm/three@0.174.0/examples/jsm/loaders/LottieLoader.js. It will also require the server to provide the lottie canvas module at ../libs/lottie_canvas.module.js." + "description": "This static, writable property sets <model-viewer>'s LottieLoader location URL. The default URL is https://cdn.jsdelivr.net/npm/three@{{THREEJS_VERSION}}/examples/jsm/loaders/LottieLoader.js. It will also require the server to provide the lottie canvas module at ../libs/lottie_canvas.module.js." }, { "name": "minimumRenderScale", diff --git a/packages/modelviewer.dev/data/faq.json b/packages/modelviewer.dev/data/faq.json index 084d461fb2..75bf9478fb 100644 --- a/packages/modelviewer.dev/data/faq.json +++ b/packages/modelviewer.dev/data/faq.json @@ -86,7 +86,7 @@ { "name": "How should I access <model-viewer>?", "htmlName": "cdn", - "description": "If you control your own hosting, the safest option is always to host model-viewer.min.js yourself on the same server as your site. For smaller sites and blogs, it is often more convenient to use one of various free CDNs - Google provides <model-viewer> as one of its hosted libraries, which we recommend as it is a fast and reliable CDN. Simply specify your desired version in the URL: https://ajax.googleapis.com/ajax/libs/model-viewer/4.0.0/model-viewer.min.js. We used to recommend unpkg, but it has had several serious outages recently. It can automatically pick the most recent version, but this is not a good practice as it slows loading (two requests) and ideally you should test when updating to ensure no bugs have been introduced. Another good option is jsDelivr.", + "description": "If you control your own hosting, the safest option is always to host model-viewer.min.js yourself on the same server as your site. For smaller sites and blogs, it is often more convenient to use one of various free CDNs - Google provides <model-viewer> as one of its hosted libraries, which we recommend as it is a fast and reliable CDN. Simply specify your desired version in the URL: https://ajax.googleapis.com/ajax/libs/model-viewer/{{MODELVIEWER_VERSION}}/model-viewer.min.js. We used to recommend unpkg, but it has had several serious outages recently. It can automatically pick the most recent version, but this is not a good practice as it slows loading (two requests) and ideally you should test when updating to ensure no bugs have been introduced. Another good option is jsDelivr.", "links": [ "Google Hosted Libraries", "jsDelivr" diff --git a/packages/modelviewer.dev/docs/faq.html b/packages/modelviewer.dev/docs/faq.html index 017fe4caaa..31979fc1ca 100644 --- a/packages/modelviewer.dev/docs/faq.html +++ b/packages/modelviewer.dev/docs/faq.html @@ -28,7 +28,7 @@ diff --git a/packages/modelviewer.dev/index.html b/packages/modelviewer.dev/index.html index f960356408..c05cc16871 100644 --- a/packages/modelviewer.dev/index.html +++ b/packages/modelviewer.dev/index.html @@ -16,27 +16,30 @@ --> + <model-viewer> - - - - - - - - + + + + + + + + - + + @@ -75,22 +82,24 @@

Quick Start

- - Min Zip - - - Latest Release - - - NPM Package - -
- - follow on Twitter - - - Github Discussions - + + Min Zip + + + Latest Release + + + NPM Package + +
+ + follow on Twitter + + + Github Discussions +

Getting Started

@@ -152,11 +161,12 @@

Browser Support

-

<model-viewer> is supported on the last two major versions of all evergreen +

<model-viewer> is supported on the last two major versions + of all evergreen desktop and mobile browsers, plus the last two versions of Safari (on MacOS and iOS).

These browser features are - only needed if you wish to use webxr in ar-modes:

+ only needed if you wish to use webxr in ar-modes:

@@ -198,10 +208,18 @@

Browser Support

Feature
-
icon-check
Natively supported
-
icon-warning
Available with polyfill
-
icon-flag
Behind a flag, unstable
-
icon-na
Not available
+
icon-check +
Natively supported
+
+
icon-warning +
Available with polyfill
+
+
icon-flag +
Behind a flag, unstable
+
+
icon-na +
Not available
+
@@ -214,29 +232,31 @@

Browser Support

- - - + + \ No newline at end of file diff --git a/packages/modelviewer.dev/package.json b/packages/modelviewer.dev/package.json index 33304962dd..d7b4908a19 100644 --- a/packages/modelviewer.dev/package.json +++ b/packages/modelviewer.dev/package.json @@ -26,18 +26,18 @@ }, "dependencies": { "@google/model-viewer": "^4.1.0", - "@google/model-viewer-effects": "^1.4.0", + "@google/model-viewer-effects": "^1.5.0", "@types/prismjs": "^1.26.5", "focus-visible": "^5.2.1", - "lit": "^3.2.1", + "lit": "^3.3.0", "prismjs": "^1.30.0" }, "devDependencies": { - "rollup": "^4.35.0", - "@rollup/plugin-node-resolve": "^16.0.0", + "rollup": "^4.44.1", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-swc": "^0.4.0", - "@swc/core": "^1.11.8", + "@swc/core": "^1.12.9", "@rollup/plugin-replace": "^6.0.2", - "typescript": "5.8.2" + "typescript": "5.8.3" } } \ No newline at end of file diff --git a/packages/modelviewer.dev/scripts/ci-before-deploy.sh b/packages/modelviewer.dev/scripts/ci-before-deploy.sh index 2cc39e433e..daf62ac6ab 100755 --- a/packages/modelviewer.dev/scripts/ci-before-deploy.sh +++ b/packages/modelviewer.dev/scripts/ci-before-deploy.sh @@ -75,13 +75,11 @@ function copyToDeployRoot { if [ -d "${path}" ]; then cp -r $path/* "$DEPLOY_ROOT/$path" + elif [ -f "${path}" ]; then + cp $path "$DEPLOY_ROOT/$path" else - if [ -f "${path}" ]; then - cp $path "$DEPLOY_ROOT/$path" - else - echo "Path not found: $path" - exit 1 - fi + echo "Path not found: $path" + exit 1 fi } @@ -122,19 +120,21 @@ cp -r ../../node_modules/web-animations-js/* $DEPLOY_ROOT/node_modules/web-anima FILES_TO_PATCH_WITH_MINIFIED_BUNDLE=($(find $DEPLOY_ROOT \( -type d -name node_modules -prune \) -o -type f | grep \.html)) for file_to_patch in "${FILES_TO_PATCH_WITH_MINIFIED_BUNDLE[@]}"; do - sed -i.bak 's model-viewer.js model-viewer.min.js g' $file_to_patch - rm $file_to_patch.bak - sed -i.bak 's model-viewer-module.js model-viewer-module.min.js g' $file_to_patch - rm $file_to_patch.bak - sed -i.bak 's model-viewer-effects.js model-viewer-effects.min.js g' $file_to_patch - rm $file_to_patch.bak - sed -i.bak 's ../../node_modules/ node_modules/ g' $file_to_patch - rm $file_to_patch.bak + sed -i.bak 's/model-viewer.js/model-viewer.min.js/g' "$file_to_patch" + rm "$file_to_patch.bak" + sed -i.bak 's/model-viewer-module.js/model-viewer-module.min.js/g' "$file_to_patch" + rm "$file_to_patch.bak" + sed -i.bak 's/model-viewer-effects.js/model-viewer-effects.min.js/g' "$file_to_patch" + rm "$file_to_patch.bak" + sed -i.bak 's|\.\./\.\./node_modules/|node_modules/|g' "$file_to_patch" + rm "$file_to_patch.bak" done # Add a "VERSION" file containing the last git commit message git log -n 1 > $DEPLOY_ROOT/VERSION +node scripts/update-versions.js + git status --ignored popd diff --git a/packages/modelviewer.dev/scripts/update-versions.js b/packages/modelviewer.dev/scripts/update-versions.js new file mode 100644 index 0000000000..99b905533d --- /dev/null +++ b/packages/modelviewer.dev/scripts/update-versions.js @@ -0,0 +1,126 @@ +#!/usr/bin/env node +/* eslint-disable no-undef */ + +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import chalk from 'chalk'; + +// Resolve __dirname and __filename in ESM +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +// Colored logging helpers +const printSuccess = (message) => console.log(chalk.green(`✓ ${message}`)); +const printError = (message) => console.log(chalk.red(`✗ ${message}`)); +const printWarning = (message) => console.log(chalk.yellow(`⚠ ${message}`)); +const printInfo = (message) => console.log(chalk.blue(`ℹ ${message}`)); + +// Path to the target package.json +const packageJsonPath = path.resolve(__dirname, '../../model-viewer/package.json'); + +if (!fs.existsSync(packageJsonPath)) { + printError(`package.json not found at ${packageJsonPath}`); + process.exit(1); +} + +let threeVersion = ''; +let modelviewerVersion = ''; + +try { + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + + // Extract versions from dependencies or devDependencies + if (packageJson.dependencies?.three) { + threeVersion = packageJson.dependencies.three; + } else if (packageJson.devDependencies?.three) { + threeVersion = packageJson.devDependencies.three; + } + + modelviewerVersion = packageJson.version || ''; +} catch (e) { + printError(`Error reading or parsing package.json: ${e.message}`); + process.exit(1); +} + +if (!threeVersion || !modelviewerVersion) { + printError('Could not find three.js or model-viewer version!'); + process.exit(1); +} + +// Remove any leading symbols (e.g., ^ or ~) from version +threeVersion = threeVersion.replace(/^[^\d]*/, ''); + +printInfo(`three.js version: ${threeVersion}`); +printInfo(`model-viewer version: ${modelviewerVersion}`); + +// Placeholders to be replaced +const PLACEHOLDERS = { + '{{MODELVIEWER_VERSION}}': modelviewerVersion, + '{{THREEJS_VERSION}}': threeVersion, +}; + +// Target files to update +const TARGET_FILES = [ + path.resolve(__dirname, '../dist/index.html'), + path.resolve(__dirname, '../dist/data/faq.json'), + path.resolve(__dirname, '../dist/data/docs.json'), +]; + +// Function to replace version placeholders in a file +const replaceVersionInFile = (file) => { + if (!fs.existsSync(file)) { + printWarning(`File ${file} does not exist - skipped`); + return false; + } + + let content = fs.readFileSync(file, 'utf8'); + let replaced = false; + + for (const [placeholder, value] of Object.entries(PLACEHOLDERS)) { + if (content.includes(placeholder)) { + content = content.split(placeholder).join(value); + replaced = true; + } else { + printWarning(`Placeholder ${placeholder} not found in ${file} - skipped`); + } + } + + if (replaced) { + try { + fs.writeFileSync(file, content, 'utf8'); + printSuccess(`File ${file} updated successfully`); + return true; + } catch (e) { + printError(`Error writing to file ${file}: ${e.message}`); + return false; + } + } else { + return false; + } +}; + +// Entry point +const main = () => { + printInfo('Starting version replacement...'); + console.log(''); + + let successCount = 0; + + for (const file of TARGET_FILES) { + if (replaceVersionInFile(file)) { + successCount++; + } + } + + console.log(''); + if (successCount === TARGET_FILES.length) { + printSuccess('All files updated successfully!'); + } else if (successCount > 0) { + printWarning(`${successCount} out of ${TARGET_FILES.length} files updated`); + } else { + printError('No files were updated!'); + } +}; + +main(); diff --git a/packages/modelviewer.dev/src/components/example-snippet.ts b/packages/modelviewer.dev/src/components/example-snippet.ts index cc07c4db71..274214aad0 100644 --- a/packages/modelviewer.dev/src/components/example-snippet.ts +++ b/packages/modelviewer.dev/src/components/example-snippet.ts @@ -15,13 +15,13 @@ import 'prismjs'; -import {property} from 'lit/decorators.js'; import {ReactiveElement} from 'lit'; +import {property} from 'lit/decorators.js'; // Silence tsc since prismjs isn't a proper module -declare var Prism: any; +declare let Prism: any; -const EMPTY_ATTRIBUTE_RE = /([\w-]+)=\"\"/g; +const EMPTY_ATTRIBUTE_RE = /([\w-]+)=""/g; export type RootNode = Document|ShadowRoot; @@ -73,7 +73,7 @@ export class ExampleSnippet extends ReactiveElement { readonly stamped: boolean = false; - public stamp() { + stamp() { if (this.template == null) { return; } diff --git a/packages/modelviewer.dev/src/docs-and-examples/create-html.ts b/packages/modelviewer.dev/src/docs-and-examples/create-html.ts index a46b55102b..ab9b856844 100644 --- a/packages/modelviewer.dev/src/docs-and-examples/create-html.ts +++ b/packages/modelviewer.dev/src/docs-and-examples/create-html.ts @@ -45,7 +45,7 @@ const CategoryConstant: Category = { }; function getCurrentDocs() { - const click = `onclick="switchPages('docs', 'examples')"`; + const click = 'onclick="switchPages(\'docs\', \'examples\')"'; return `
DOCUMENTATION
@@ -85,13 +85,17 @@ export function starterSidebar(docsOrExample: string) { const isExample = inputList[0] === 'examples'; const docsExamples = isExample ? getCurrentExample(category) : getCurrentDocs(); - const isPostprocesssing = docsOrExample === 'mve' || category === 'postprocessing'; + const isPostprocesssing = + docsOrExample === 'mve' || category === 'postprocessing'; const href = isExample ? '../../' : '../'; nav.innerHTML = ` @@ -166,7 +170,8 @@ function createSidebar(category: Category) { const container = document.getElementById('sidebar-category-container'); const lowerCaseTitle = category.htmlName; let subcategories = Object.keys(category); - subcategories = subcategories.filter(k => k !== 'Title' && k !== 'htmlName' && k !== 'Description'); + subcategories = subcategories.filter( + k => k !== 'Title' && k !== 'htmlName' && k !== 'Description'); // Link category href (Loading) to first subcategory (Loading, Attributes) let lowerKey = ''; @@ -249,7 +254,7 @@ function createLinks( for (const link of entry.links) { linksEntry += `
${link}
`; } - linksEntry += `
`; + linksEntry += '
'; return linksEntry; } @@ -295,7 +300,8 @@ function createSubcategory(

- ${subcategory === 'Questions' || subcategory === 'Mixin' ? '' : subcategory} + ${ + subcategory === 'Questions' || subcategory === 'Mixin' ? '' : subcategory}

diff --git a/packages/modelviewer.dev/src/docs-and-examples/sidebar.ts b/packages/modelviewer.dev/src/docs-and-examples/sidebar.ts index 6b0a155b97..d586b66d6b 100644 --- a/packages/modelviewer.dev/src/docs-and-examples/sidebar.ts +++ b/packages/modelviewer.dev/src/docs-and-examples/sidebar.ts @@ -16,7 +16,7 @@ let globalCurrentView: string[] = []; let previouslyActive: string = ''; let toRemove = ''; -let order = new Map(); +const order = new Map(); let isSideBarClick = false; let isFirstOpen = true; // is true on the first observation of all entries @@ -63,7 +63,15 @@ function removeDeactiveCategory(sidebarIds: SidebarIds) { ?.classList.remove('de-active'); } -const identicalCategories = ['loading', 'augmentedreality', 'stagingandcameras', 'annotations', 'lightingandenv', 'animation', 'scenegraph']; +const identicalCategories = [ + 'loading', + 'augmentedreality', + 'stagingandcameras', + 'annotations', + 'lightingandenv', + 'animation', + 'scenegraph' +]; export function getSidebarCategoryForNewPage(): string { const category = previouslyActive.split('-')[0]; @@ -77,8 +85,8 @@ export function getSidebarCategoryForNewPage(): string { function getSidebarIdsFromSidebarName(name: string): SidebarIds { const sb = 'sidebar'; const sidebarName = name; - let sidebarSub = sidebarName.split('-').slice(0, 2); - let sidebarCat = sidebarName.split('-').slice(0, 1); + const sidebarSub = sidebarName.split('-').slice(0, 2); + const sidebarCat = sidebarName.split('-').slice(0, 1); sidebarSub.push(sb); const sidebarSubcategory = sidebarSub.join('-'); sidebarCat.push(sb); @@ -93,8 +101,8 @@ function getSidebarIdsFromSidebarName(name: string): SidebarIds { function getSidebarIdsFromId(id: string): SidebarIds { const sb = 'sidebar'; const sidebarName = id.split('-').slice(1, 10).join('-'); - let sidebarSub = id.split('-').slice(1, 3); - let sidebarCat = id.split('-').slice(1, 2); + const sidebarSub = id.split('-').slice(1, 3); + const sidebarCat = id.split('-').slice(1, 2); sidebarSub.push(sb); const sidebarSubcategory = sidebarSub.join('-'); sidebarCat.push(sb); @@ -261,12 +269,12 @@ function handlePageJump(entries: IntersectionObserverEntry[]) { previouslyActive = sidebarIds.name; } -let intersectionRatios = new Map(); +const intersectionRatios = new Map(); function handleExamples(entries: IntersectionObserverEntry[], _observer: any) { if (isFirstOpen) { everyEntry = entries; isFirstOpen = false; - document.querySelector(`h3[id="active-container-sidebar"`)!.classList.add( + document.querySelector('h3[id="active-container-sidebar"')!.classList.add( 'active'); } diff --git a/packages/modelviewer.dev/src/docs-and-examples/utils.ts b/packages/modelviewer.dev/src/docs-and-examples/utils.ts index 873c9aef64..07f1254dbc 100644 --- a/packages/modelviewer.dev/src/docs-and-examples/utils.ts +++ b/packages/modelviewer.dev/src/docs-and-examples/utils.ts @@ -125,7 +125,9 @@ export function init(docsOrExample: string) { (self as any).initFooterLinks = initFooterLinks; function handleSideBarClickToggle(event: any) { - if (!(event.target.classList.contains('sidebar') || event.target.closest(".sidebar")) && !event.target.classList.contains("hamburgerInput")) { + if (!(event.target.classList.contains('sidebar') || + event.target.closest('.sidebar')) && + !event.target.classList.contains('hamburgerInput')) { if (event.target.classList.contains('tab')) { document.getElementById('sidenav')?.classList.toggle('active'); } else { diff --git a/packages/modelviewer.dev/styles/examples.css b/packages/modelviewer.dev/styles/examples.css index ca107128f4..7a1d387f60 100644 --- a/packages/modelviewer.dev/styles/examples.css +++ b/packages/modelviewer.dev/styles/examples.css @@ -64,6 +64,7 @@ select { } .sidebar { + width: var(--sidebar-width); margin: 0; padding: 0; background-color: #f6f6f6; diff --git a/packages/render-fidelity-tools/package.json b/packages/render-fidelity-tools/package.json index e647dfcd49..f243a221e7 100644 --- a/packages/render-fidelity-tools/package.json +++ b/packages/render-fidelity-tools/package.json @@ -29,22 +29,23 @@ "@polymer/paper-slider": "^3.0.1", "@types/http-server": "^0.12.4", "@types/pngjs": "^6.0.5", + "get-east-asian-width": "^1.3.0", "http-server": "^14.1.1", - "lit": "^3.2.1", + "lit": "^3.3.0", "mkdirp": "^3.0.1", "pngjs": "^7.0.0", - "puppeteer": "^24.4.0", + "puppeteer": "^24.11.1", "rimraf": "^6.0.1", - "yargs": "^17.7.2" + "yargs": "^18.0.0" }, "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.3", - "@rollup/plugin-node-resolve": "^16.0.0", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@types/yargs": "^17.0.33", "polymer-build": "^3.1.4", - "rollup": "^4.35.0", + "rollup": "^4.44.1", "rollup-plugin-external-globals": "^0.13.0", - "typescript": "5.8.2" + "typescript": "5.8.3" } -} \ No newline at end of file +} diff --git a/packages/render-fidelity-tools/src/artifact-creator.ts b/packages/render-fidelity-tools/src/artifact-creator.ts index b11bebf510..9a4c7a35df 100644 --- a/packages/render-fidelity-tools/src/artifact-creator.ts +++ b/packages/render-fidelity-tools/src/artifact-creator.ts @@ -120,7 +120,7 @@ export class ArtifactCreator { } const scenarioRecord = {analysisResults, scenario}; - console.log(`\n💾 Recording analysis`); + console.log('\n💾 Recording analysis'); await fs.writeFile( join(outputDirectory, scenarioName, 'analysis.json'), JSON.stringify(scenarioRecord)); @@ -299,9 +299,13 @@ export class ArtifactCreator { } if (this.browser == null) { - console.log(`🚀 Launching browser`); - // no-sandbox and disable-setuid-sandbox args to resolve puppeteer browser run error in fidelity tests - this.browser = await puppeteer.launch({headless: quiet, args:['--no-sandbox', '--disable-setuid-sandbox']}); + console.log('🚀 Launching browser'); + // no-sandbox and disable-setuid-sandbox args to resolve puppeteer browser + // run error in fidelity tests + this.browser = await puppeteer.launch({ + headless: quiet, + args: ['--no-sandbox', '--disable-setuid-sandbox'] + }); } const page = await this.browser.newPage(); @@ -324,7 +328,7 @@ export class ArtifactCreator { await Promise.all(message.args().map((arg: any) => arg.jsonValue())); if (args.length) { - console.log(`➡️`, ...args); + console.log('➡️', ...args); } }); @@ -373,7 +377,7 @@ export class ArtifactCreator { throw new Error(evaluateError); } - console.log(`🖼 Capturing screenshot`); + console.log('🖼 Capturing screenshot'); try { await fs.mkdir(this.outputDirectory); diff --git a/packages/render-fidelity-tools/src/common.ts b/packages/render-fidelity-tools/src/common.ts index 80cd4908fc..c64c9ded95 100644 --- a/packages/render-fidelity-tools/src/common.ts +++ b/packages/render-fidelity-tools/src/common.ts @@ -109,13 +109,8 @@ export interface ScenarioConfig { } export interface RendererConfig { - name: string, - description: string, - scripts?: {setup: string}, - command?: { - executable?: string, - args?: string[] - } + name: string, description: string, scripts?: {setup: string}, + command?: {executable?: string, args?: string[]} } export interface GoldenConfig extends RendererConfig { diff --git a/packages/render-fidelity-tools/src/components/magnifying-glass.ts b/packages/render-fidelity-tools/src/components/magnifying-glass.ts index dc8a1e11c3..3f46d3b05c 100644 --- a/packages/render-fidelity-tools/src/components/magnifying-glass.ts +++ b/packages/render-fidelity-tools/src/components/magnifying-glass.ts @@ -86,7 +86,8 @@ export class MagnifyingGlass extends LitElement { return this.direction === 'horizontal' ? x < (width / 2) ? 'right' : 'left' : - y < (height / 2) ? 'bottom' : 'top'; + y < (height / 2) ? 'bottom' : + 'top'; } render() { diff --git a/packages/render-fidelity-tools/src/image-comparison-worker.ts b/packages/render-fidelity-tools/src/image-comparison-worker.ts index 1154348d04..626c48fbf2 100644 --- a/packages/render-fidelity-tools/src/image-comparison-worker.ts +++ b/packages/render-fidelity-tools/src/image-comparison-worker.ts @@ -90,7 +90,7 @@ class ImageComparisonWorker { const {analyzer} = this; if (analyzer == null) { - console.warn(`Analyzer not created!`); + console.warn('Analyzer not created!'); return; } diff --git a/packages/render-fidelity-tools/src/third_party/pixelmatch/color-delta.ts b/packages/render-fidelity-tools/src/third_party/pixelmatch/color-delta.ts index 59ebee2b3b..e8774fa3db 100644 --- a/packages/render-fidelity-tools/src/third_party/pixelmatch/color-delta.ts +++ b/packages/render-fidelity-tools/src/third_party/pixelmatch/color-delta.ts @@ -15,21 +15,22 @@ export function colorDelta( k: number, m: number, yOnly: boolean = false): number { - var a1 = img1[k + 3] / 255, a2 = img2[m + 3] / 255, + const a1 = img1[k + 3] / 255, a2 = img2[m + 3] / 255, - r1 = blend(img1[k + 0], a1), g1 = blend(img1[k + 1], a1), - b1 = blend(img1[k + 2], a1), + r1 = blend(img1[k + 0], a1), g1 = blend(img1[k + 1], a1), + b1 = blend(img1[k + 2], a1), - r2 = blend(img2[m + 0], a2), g2 = blend(img2[m + 1], a2), - b2 = blend(img2[m + 2], a2), + r2 = blend(img2[m + 0], a2), g2 = blend(img2[m + 1], a2), + b2 = blend(img2[m + 2], a2), - y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2); + y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2); - if (yOnly) - return y; // brightness difference only + if (yOnly) { + return y; + } // brightness difference only - var i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2), - q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2); + const i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2), + q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2); return 0.5053 * y * y + 0.299 * i * i + 0.1957 * q * q; } diff --git a/packages/render-fidelity-tools/src/workflows/compare-results.ts b/packages/render-fidelity-tools/src/workflows/compare-results.ts index 7b8fd1c7e6..8bfecae8d9 100644 --- a/packages/render-fidelity-tools/src/workflows/compare-results.ts +++ b/packages/render-fidelity-tools/src/workflows/compare-results.ts @@ -21,7 +21,7 @@ const [candidateResultsDirectory, goldenResultsDirectory] = const warn = (message: string) => console.warn(`🚨 ${message}`); const exit = () => { - console.log(`📋 Fidelity result comparison concluded`); + console.log('📋 Fidelity result comparison concluded'); process.exit(0); }; diff --git a/packages/render-fidelity-tools/src/workflows/render-goldens.ts b/packages/render-fidelity-tools/src/workflows/render-goldens.ts index 5596e39bc7..f0ffa5d86a 100644 --- a/packages/render-fidelity-tools/src/workflows/render-goldens.ts +++ b/packages/render-fidelity-tools/src/workflows/render-goldens.ts @@ -105,7 +105,7 @@ async function main() { const warn = (message: string) => console.warn(`🚨 ${message}`); const exit = (code = 0) => { - console.log(`📋 Screenshot updates concluded`); + console.log('📋 Screenshot updates concluded'); process.exit(code); }; @@ -183,7 +183,7 @@ async function main() { const updateScreenshots = async (config: ImageComparisonConfig) => { const {scenarios} = config; - console.log(`🆙 Updating screenshots`); + console.log('🆙 Updating screenshots'); try { await fs.mkdir(goldensDirectory); @@ -266,7 +266,7 @@ async function main() { if (args.dryRun) { process.stdout.write( - rendererName + `: Rendering ` + scenarioName + + rendererName + ': Rendering ' + scenarioName + '... -- skipping, dry-run'); continue; } diff --git a/packages/render-fidelity-tools/src/workflows/test-fidelity.ts b/packages/render-fidelity-tools/src/workflows/test-fidelity.ts index bf6bfd4214..7cbea2d8db 100644 --- a/packages/render-fidelity-tools/src/workflows/test-fidelity.ts +++ b/packages/render-fidelity-tools/src/workflows/test-fidelity.ts @@ -175,7 +175,8 @@ async function main() { } if (fidelityRegressionWarningCount > 0) { - console.log(`Warnings on ${fidelityRegressionWarningCount} scenarios❗️`); + console.log( + `Warnings on ${fidelityRegressionWarningCount} scenarios❗️`); console.log('\n🔍 Logging warning scenarios: '); for (const warning of fidelityRegressionWarnings) { console.log(warning); diff --git a/packages/space-opera/package.json b/packages/space-opera/package.json index e8b76bc3d7..a52bd60b4c 100644 --- a/packages/space-opera/package.json +++ b/packages/space-opera/package.json @@ -35,9 +35,9 @@ "Chris George " ], "devDependencies": { - "@gltf-transform/core": "^4.1.2", - "@gltf-transform/extensions": "^4.1.2", - "@gltf-transform/functions": "^4.1.2", + "@gltf-transform/core": "^4.2.0", + "@gltf-transform/extensions": "^4.2.0", + "@gltf-transform/functions": "^4.2.0", "@google/model-viewer": "^4.1.0", "@material/mwc-button": "^0.27.0", "@material/mwc-checkbox": "^0.27.0", @@ -52,30 +52,30 @@ "@polymer/paper-item": "^3.0.1", "@polymer/paper-listbox": "^3.0.1", "@polymer/paper-slider": "^3.0.1", - "@reduxjs/toolkit": "^2.6.1", - "@rollup/plugin-commonjs": "^28.0.3", - "@rollup/plugin-node-resolve": "^16.0.0", + "@reduxjs/toolkit": "^2.8.2", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-swc": "^0.4.0", - "@swc/core": "^1.11.8", + "@swc/core": "^1.12.9", "@types/js-beautify": "^1.14.3", "@types/remote-redux-devtools": "^0.5.8", - "@web/test-runner": "^0.20.0", - "@web/test-runner-playwright": "^0.11.0", + "@web/test-runner": "^0.20.2", + "@web/test-runner-playwright": "^0.11.1", "chai": "^5.2.0", "gltf-validator": "^2.0.0-dev.3.10", "http-server": "^14.1.1", "js-beautify": "^1.15.4", "jszip": "^3.10.1", - "lit": "^3.2.1", + "lit": "^3.3.0", "npm-run-all": "^4.1.5", "pwa-helpers": "^0.9.1", "qrious": "^4.0.2", "redux": "^5.0.1", "remote-redux-devtools": "^0.5.16", - "rollup": "^4.35.0", + "rollup": "^4.44.1", "simple-dropzone": "^0.8.3", "ts-closure-library": "^2022.502.5", - "typescript": "5.8.2", + "typescript": "5.8.3", "web-animations-js": "^2.3.2" } } diff --git a/packages/space-opera/src/components/animation_controls/animation_controls.ts b/packages/space-opera/src/components/animation_controls/animation_controls.ts index e4928f4dd2..8af2e92425 100644 --- a/packages/space-opera/src/components/animation_controls/animation_controls.ts +++ b/packages/space-opera/src/components/animation_controls/animation_controls.ts @@ -21,7 +21,7 @@ import '../shared/checkbox/checkbox.js'; import '@polymer/paper-item'; import {html} from 'lit'; -import {customElement, state, query} from 'lit/decorators.js'; +import {customElement, query, state} from 'lit/decorators.js'; import {reduxStore} from '../../space_opera_base.js'; import {State} from '../../types.js'; diff --git a/packages/space-opera/src/components/best_practices/best_practices.ts b/packages/space-opera/src/components/best_practices/best_practices.ts index ad67ed657a..4c2c1e1fc5 100644 --- a/packages/space-opera/src/components/best_practices/best_practices.ts +++ b/packages/space-opera/src/components/best_practices/best_practices.ts @@ -16,11 +16,13 @@ */ import {html} from 'lit'; -import {customElement, state, query} from 'lit/decorators.js'; +import {customElement, query, state} from 'lit/decorators.js'; + import {reduxStore} from '../../space_opera_base'; import {BestPracticesState, State} from '../../types'; import {ConnectedLitElement} from '../connected_lit_element/connected_lit_element'; import {CheckboxElement} from '../shared/checkbox/checkbox'; + import {dispatchSetARButton, dispatchSetARPrompt, dispatchSetProgressBar, getBestPractices} from './reducer'; /** diff --git a/packages/space-opera/src/components/best_practices/constants.ts b/packages/space-opera/src/components/best_practices/constants.ts index bd140fd1a6..6147dd0ab8 100644 --- a/packages/space-opera/src/components/best_practices/constants.ts +++ b/packages/space-opera/src/components/best_practices/constants.ts @@ -32,7 +32,7 @@ export const modelViewerTemplate = ` `; -export const scriptTemplate = ` `; +export const scriptTemplate = ' '; export const progressBar = `// Handles loading the events for 's slotted progress bar diff --git a/packages/space-opera/src/components/best_practices/render_best_practices.ts b/packages/space-opera/src/components/best_practices/render_best_practices.ts index 01b4c710ab..082c05af8a 100644 --- a/packages/space-opera/src/components/best_practices/render_best_practices.ts +++ b/packages/space-opera/src/components/best_practices/render_best_practices.ts @@ -35,8 +35,9 @@ export function renderProgressBar(isEditor) { export const onProgress = (event) => { const progressBar = event.target.querySelector('.progress-bar'); const updatingBar = event.target.querySelector('.update-bar'); - if (!progressBar || !updatingBar) + if (!progressBar || !updatingBar) { return; + } updatingBar.style.width = `${event.detail.totalProgress * 100}%`; if (event.detail.totalProgress === 1) { progressBar.classList.add('hide'); diff --git a/packages/space-opera/src/components/camera_settings/components/limits_base.ts b/packages/space-opera/src/components/camera_settings/components/limits_base.ts index 78c580f7f6..2a29c6e0d8 100644 --- a/packages/space-opera/src/components/camera_settings/components/limits_base.ts +++ b/packages/space-opera/src/components/camera_settings/components/limits_base.ts @@ -22,7 +22,7 @@ import '../../shared/slider_with_input/slider_with_input.js'; import '../../shared/checkbox/checkbox.js'; import {html} from 'lit'; -import {state, query} from 'lit/decorators.js'; +import {query, state} from 'lit/decorators.js'; import {Limits} from '../../config/types.js'; import {ConnectedLitElement} from '../../connected_lit_element/connected_lit_element.js'; @@ -130,8 +130,9 @@ export abstract class LimitsBase extends ConnectedLitElement { } renderLimits() { - if (!this.limitsProperty?.enabled || !getModelViewer()) + if (!this.limitsProperty?.enabled || !getModelViewer()) { return html``; + } return html` diff --git a/packages/space-opera/src/components/config/reducer.ts b/packages/space-opera/src/components/config/reducer.ts index 379f4799ac..4174d75df7 100644 --- a/packages/space-opera/src/components/config/reducer.ts +++ b/packages/space-opera/src/components/config/reducer.ts @@ -205,7 +205,7 @@ export function configReducer( return {...state, cameraControls: action.payload}; case SET_AUTO_ROTATE: return {...state, autoRotate: action.payload}; - case SET_CAMERA_TARGET: + case SET_CAMERA_TARGET: { const target = action.payload; const cameraTarget = target == null ? undefined : @@ -213,20 +213,23 @@ export function configReducer( roundToDigits( target.y, DIGITS)}m ${roundToDigits(target.z, DIGITS)}m`; return {...state, cameraTarget}; - case SAVE_CAMERA_ORBIT: + } + case SAVE_CAMERA_ORBIT: { const orbit = action.payload; const cameraOrbit = orbit == null ? undefined : getOrbitString(orbit); return {...state, cameraOrbit}; - case SAVE_CAMERA_FOV: + } + case SAVE_CAMERA_FOV: { const fieldOfView = action.payload == null ? undefined : `${roundToDigits(action.payload, DIGITS)}deg`; return {...state, fieldOfView}; + } case SET_CAMERA_FOV_LIMITS: return { ...state, minFov: getMinString(action.payload, 'deg'), - maxFov: getMaxString(action.payload, 'deg') + maxFov: getMaxString(action.payload, 'deg'), }; case SET_CAMERA_PITCH_LIMITS: return {...state, ...getUpdatedLimits(state, action.payload, 1)}; @@ -234,13 +237,13 @@ export function configReducer( return {...state, ...getUpdatedLimits(state, action.payload, 2)}; case SET_CAMERA_YAW_LIMITS: return {...state, ...getUpdatedLimits(state, action.payload, 0)}; - case SET_MIN_ZOOM: + case SET_MIN_ZOOM: { const orbitLimits = getUpdatedLimits( state, { enabled: action.payload.fov != null, min: action.payload.radius, - max: -1 + max: -1, }, 2); @@ -248,15 +251,16 @@ export function configReducer( { enabled: action.payload.fov != null, min: action.payload.fov, - max: -1 + max: -1, }, 'deg'); return { ...state, minCameraOrbit: orbitLimits.minCameraOrbit, - minFov: minFov === 'auto' ? undefined : minFov + minFov: minFov === 'auto' ? undefined : minFov, }; + } default: return state; } diff --git a/packages/space-opera/src/components/hotspot_panel/hotspot_editor.ts b/packages/space-opera/src/components/hotspot_panel/hotspot_editor.ts index 329990398d..0fd46780fa 100644 --- a/packages/space-opera/src/components/hotspot_panel/hotspot_editor.ts +++ b/packages/space-opera/src/components/hotspot_panel/hotspot_editor.ts @@ -23,8 +23,8 @@ import {html, LitElement, PropertyValues} from 'lit'; import {customElement, property, query} from 'lit/decorators.js'; import {reduxStore} from '../../space_opera_base.js'; - import {hotspotEditorStyles} from '../../styles.css.js'; + import {dispatchRemoveHotspot, dispatchUpdateHotspot} from './reducer.js'; import {HotspotConfig} from './types.js'; @@ -43,8 +43,9 @@ export class HotspotEditorElement extends LitElement { } render() { - if (!this.config) + if (!this.config) { return html``; + } return html` @@ -58,8 +59,9 @@ export class HotspotEditorElement extends LitElement { } onAnnotationInput() { - if (!this.annotationInput) + if (!this.annotationInput) { return; + } const newConfig = { ...this.config, annotation: this.annotationInput.value diff --git a/packages/space-opera/src/components/materials_panel/materials_panel.ts b/packages/space-opera/src/components/materials_panel/materials_panel.ts index b04acdc28b..2ec9492d41 100644 --- a/packages/space-opera/src/components/materials_panel/materials_panel.ts +++ b/packages/space-opera/src/components/materials_panel/materials_panel.ts @@ -431,7 +431,7 @@ export class MaterialPanel extends ConnectedLitElement { (value: string, nativeValidity: ValidityState) => { // Validates length. if (value.length < 1) { - textField.validationMessage = `Invalid input.`; + textField.validationMessage = 'Invalid input.'; return {valid: false} as ValidityState; } @@ -452,7 +452,7 @@ export class MaterialPanel extends ConnectedLitElement { isValidInput(_value: string): {valid: boolean, validationMessage: string} { // Validates length. if (_value.length < 1) { - return {valid: false, validationMessage: `Invalid input.`}; + return {valid: false, validationMessage: 'Invalid input.'}; } // Verifies name is unique. diff --git a/packages/space-opera/src/components/mobile_view/components/mobile_modal.ts b/packages/space-opera/src/components/mobile_view/components/mobile_modal.ts index 2670eb00fe..e438a2eded 100644 --- a/packages/space-opera/src/components/mobile_view/components/mobile_modal.ts +++ b/packages/space-opera/src/components/mobile_view/components/mobile_modal.ts @@ -16,7 +16,7 @@ */ import {html} from 'lit'; -import {customElement, state, property, query} from 'lit/decorators.js'; +import {customElement, property, query, state} from 'lit/decorators.js'; // @ts-ignore, the qrious package isn't typed import QRious from 'qrious'; @@ -42,6 +42,7 @@ export class MobileModal extends ConnectedLitElement { open() { if (this.isNewQRCode) { + // eslint-disable-next-line no-new new QRious({element: this.canvasQR, value: this.viewableSite, size: 200}); this.isNewQRCode = false } diff --git a/packages/space-opera/src/components/mobile_view/open_mobile_view.ts b/packages/space-opera/src/components/mobile_view/open_mobile_view.ts index 26c4254f04..cd7d82a309 100644 --- a/packages/space-opera/src/components/mobile_view/open_mobile_view.ts +++ b/packages/space-opera/src/components/mobile_view/open_mobile_view.ts @@ -216,7 +216,7 @@ export class OpenMobileView extends ConnectedLitElement { // If any of the sessions are stale, we want to prepare the relavent blobs // to POST before we loop through the sessions let haveStale = false; - for (let session of this.sessionList) { + for (const session of this.sessionList) { haveStale = haveStale || session.isStale; } @@ -240,7 +240,7 @@ export class OpenMobileView extends ConnectedLitElement { // Iterate through the list of active mobile sessions, and allow them to // post their information asynchronously. - for (let session of sessionList) { + for (const session of sessionList) { this.sendSessionContentHolder( session, updatedContent, posterBlob, gltfBlob, envBlob); } diff --git a/packages/space-opera/src/components/model_viewer_preview/model_viewer_preview.ts b/packages/space-opera/src/components/model_viewer_preview/model_viewer_preview.ts index f10f4f5aef..1bc97d21a0 100644 --- a/packages/space-opera/src/components/model_viewer_preview/model_viewer_preview.ts +++ b/packages/space-opera/src/components/model_viewer_preview/model_viewer_preview.ts @@ -110,8 +110,7 @@ export class ModelViewerPreview extends ConnectedLitElement { const hasModel = !!editedConfig.src; - const refreshMobileButton = this.refreshButtonIsReady === true ? html - ` Refresh Mobile `: html``; @@ -124,8 +123,7 @@ export class ModelViewerPreview extends ConnectedLitElement { childElements.push(refreshMobileButton); if (!hasModel) { childElements.push( - html - `
Drag a glTF or GLB here!
+ html`
Drag a glTF or GLB here!
Groups, folders, and Zip archives supported
Drop an HDR for lighting
`); } @@ -155,7 +153,7 @@ export class ModelViewerPreview extends ConnectedLitElement { private async onModelLoaded() { reduxStore.dispatch(await dispatchModel()); if (this.modelViewer.availableAnimations.length > 0) { - reduxStore.dispatch(dispatchAutoplayEnabled(true)); + reduxStore.dispatch(dispatchAutoplayEnabled(true)); } const config = getConfig(reduxStore.getState()); reduxStore.dispatch(dispatchConfig({...config})); @@ -168,35 +166,36 @@ export class ModelViewerPreview extends ConnectedLitElement { private addHotspot(event: MouseEvent) { if (getModelViewer().availableAnimations.length > 0) { - const surface = - this.modelViewer.surfaceFromPoint(event.clientX, event.clientY); - if (!surface) { - console.log('Click was not on model, no hotspot added.'); - return; - } - reduxStore.dispatch(dispatchAddHotspot({ - name: generateUniqueHotspotName(), - surface, - })); + const surface = + this.modelViewer.surfaceFromPoint(event.clientX, event.clientY); + if (!surface) { + console.log('Click was not on model, no hotspot added.'); + return; + } + reduxStore.dispatch(dispatchAddHotspot({ + name: generateUniqueHotspotName(), + surface, + })); } else { - const point = this.modelViewer.positionAndNormalFromPoint( - event.clientX, event.clientY); - if (!point) { - console.log('Click was not on model, no hotspot added.'); - return; - } - reduxStore.dispatch(dispatchAddHotspot({ - name: generateUniqueHotspotName(), - position: point.position.toString(), - normal: point.normal.toString() - })); + const point = this.modelViewer.positionAndNormalFromPoint( + event.clientX, event.clientY); + if (!point) { + console.log('Click was not on model, no hotspot added.'); + return; + } + reduxStore.dispatch(dispatchAddHotspot({ + name: generateUniqueHotspotName(), + position: point.position.toString(), + normal: point.normal.toString() + })); } reduxStore.dispatch(dispatchUpdateHotspotMode(false)); } private onDragover(event: DragEvent) { - if (!event.dataTransfer) - return; + if (!event.dataTransfer) { + return; + } event.stopPropagation(); event.preventDefault(); @@ -207,26 +206,26 @@ export class ModelViewerPreview extends ConnectedLitElement { event.preventDefault(); if (event.dataTransfer && event.dataTransfer.items[0].kind === 'file') { - const file = event.dataTransfer.items[0].getAsFile(); - if (!file) - return; - if (file.name.match(/\.(glb|gltf)$/i)) { - const arrayBuffer = await file.arrayBuffer(); - reduxStore.dispatch(dispatchSetModelName(file.name)); - const url = - createSafeObjectUrlFromArrayBuffer(arrayBuffer).unsafeUrl; - reduxStore.dispatch(dispatchGltfUrl(url)); - dispatchConfig(extractStagingConfig(this.config)); - reduxStore.dispatch(dispatchCameraControlsEnabled(true)); - reduxStore.dispatch(dispatchSetHotspots([])); - } - if (file.name.match(/\.(hdr|png|jpg|jpeg)$/i)) { - const unsafeUrl = await createBlobUrlFromEnvironmentImage(file); - reduxStore.dispatch( - dispatchAddEnvironmentImage({uri: unsafeUrl, name: file.name})); - reduxStore.dispatch(dispatchEnvironmentImage(unsafeUrl)); - reduxStore.dispatch(dispatchSetEnvironmentName(file.name)); - } + const file = event.dataTransfer.items[0].getAsFile(); + if (!file) { + return; + } + if (file.name.match(/\.(glb|gltf)$/i)) { + const arrayBuffer = await file.arrayBuffer(); + reduxStore.dispatch(dispatchSetModelName(file.name)); + const url = createSafeObjectUrlFromArrayBuffer(arrayBuffer).unsafeUrl; + reduxStore.dispatch(dispatchGltfUrl(url)); + dispatchConfig(extractStagingConfig(this.config)); + reduxStore.dispatch(dispatchCameraControlsEnabled(true)); + reduxStore.dispatch(dispatchSetHotspots([])); + } + if (file.name.match(/\.(hdr|png|jpg|jpeg)$/i)) { + const unsafeUrl = await createBlobUrlFromEnvironmentImage(file); + reduxStore.dispatch( + dispatchAddEnvironmentImage({uri: unsafeUrl, name: file.name})); + reduxStore.dispatch(dispatchEnvironmentImage(unsafeUrl)); + reduxStore.dispatch(dispatchSetEnvironmentName(file.name)); + } } } } diff --git a/packages/space-opera/src/components/model_viewer_preview/reducer.ts b/packages/space-opera/src/components/model_viewer_preview/reducer.ts index 9ef90c5e37..b0d2ffa9a5 100644 --- a/packages/space-opera/src/components/model_viewer_preview/reducer.ts +++ b/packages/space-opera/src/components/model_viewer_preview/reducer.ts @@ -96,7 +96,8 @@ export async function pushThumbnail( async function createThumbnails(): Promise> { const thumbnailsById = new Map(); - for (const material of getModelViewer()!.model?.materials!) { + const materials = getModelViewer()?.model?.materials ?? []; + for (const material of materials) { await material.ensureLoaded(); const { pbrMetallicRoughness, diff --git a/packages/space-opera/src/components/model_viewer_snippet/components/download_button.ts b/packages/space-opera/src/components/model_viewer_snippet/components/download_button.ts index 6802b0e43b..c45da496bb 100644 --- a/packages/space-opera/src/components/model_viewer_snippet/components/download_button.ts +++ b/packages/space-opera/src/components/model_viewer_snippet/components/download_button.ts @@ -58,8 +58,9 @@ class GenericDownloadButton extends ConnectedLitElement { // side-effects anyway, so nothing bad can happen. async onDownloadClick() { const payload = await this.preparePayload!(); - if (!payload) + if (!payload) { return; + } await safeDownloadCallback(payload.blob, payload.filename)(); } @@ -85,7 +86,7 @@ async function preparePosterPayload(posterName: string): Promise { function beautify_snippet(snippetList: string[]): string { let snippet = ''; let i = 0; - for (let line of snippetList) { + for (const line of snippetList) { if (i == 0) { snippet = `${line}\n`; } else if (i !== 0 && line.includes('model-viewer')) { diff --git a/packages/space-opera/src/components/model_viewer_snippet/components/open_button.ts b/packages/space-opera/src/components/model_viewer_snippet/components/open_button.ts index 511bd92615..0067085feb 100644 --- a/packages/space-opera/src/components/model_viewer_snippet/components/open_button.ts +++ b/packages/space-opera/src/components/model_viewer_snippet/components/open_button.ts @@ -65,8 +65,9 @@ export class OpenModal extends ConnectedLitElement { async handleSubmitSnippet(value?: string) { const textArea = this.snippetViewer.snippet; - if (!textArea) + if (!textArea) { return; + } this.errors = []; let inputText: string = ''; if (value === undefined) { diff --git a/packages/space-opera/src/components/model_viewer_snippet/components/parsing.ts b/packages/space-opera/src/components/model_viewer_snippet/components/parsing.ts index ae082b90f4..9535af4ecc 100644 --- a/packages/space-opera/src/components/model_viewer_snippet/components/parsing.ts +++ b/packages/space-opera/src/components/model_viewer_snippet/components/parsing.ts @@ -50,7 +50,7 @@ export function parseExtraAttributes(snippet: string): string { // Parse snippet and extract attributes from model-viewer const parsedInput = new DOMParser().parseFromString(snippet, 'text/html'); const modelViewer = parsedInput.body.getElementsByTagName('model-viewer')[0]; - let extraAttributes: any = {}; + const extraAttributes: any = {}; const attributes = modelViewer.attributes; // Loop through every attribute, only add the attributes to extraAttributes diff --git a/packages/space-opera/src/components/model_viewer_snippet/components/validation.ts b/packages/space-opera/src/components/model_viewer_snippet/components/validation.ts index f75096830f..f66d496cd0 100644 --- a/packages/space-opera/src/components/model_viewer_snippet/components/validation.ts +++ b/packages/space-opera/src/components/model_viewer_snippet/components/validation.ts @@ -169,7 +169,7 @@ export class Validation extends ConnectedLitElement { if (originalGltf != null && gltfUrl != null && this.originalGltf !== originalGltf) { - if (this.severityTitle = 'Converted') { + if (this.severityTitle === 'Converted') { URL.revokeObjectURL(this.gltfUrl!); } @@ -233,7 +233,7 @@ export class Validation extends ConnectedLitElement { this.severityColor = '#8bc34a'; this.severityTitle = 'Converted'; } - if (!!this.report.info?.extensionsUsed?.find( + if (this.report.info?.extensionsUsed?.find( (e) => e == 'KHR_materials_pbrSpecularGlossiness')) { this.severityColor = '#f9a825'; this.severityTitle = 'Converting'; diff --git a/packages/space-opera/src/components/model_viewer_snippet/components/validation_utils.ts b/packages/space-opera/src/components/model_viewer_snippet/components/validation_utils.ts index cc501f0d17..3f7a61e7d2 100644 --- a/packages/space-opera/src/components/model_viewer_snippet/components/validation_utils.ts +++ b/packages/space-opera/src/components/model_viewer_snippet/components/validation_utils.ts @@ -131,18 +131,21 @@ function groupMessages(report) { }; report.errors.forEach((message) => { - if (!CODES[message.code]) + if (!CODES[message.code]) { return; + } if (!CODES[message.code].pointerCounts[message.pointer]) { CODES[message.code].pointerCounts[message.pointer] = 0; } CODES[message.code].pointerCounts[message.pointer]++; }); report.errors = report.errors.filter((message) => { - if (!CODES[message.code]) + if (!CODES[message.code]) { return true; - if (!CODES[message.code].pointerCounts[message.pointer]) + } + if (!CODES[message.code].pointerCounts[message.pointer]) { return true; + } return CODES[message.code].pointerCounts[message.pointer] < 2; }); Object.keys(CODES).forEach((code) => { diff --git a/packages/space-opera/src/components/model_viewer_snippet/model_viewer_snippet.ts b/packages/space-opera/src/components/model_viewer_snippet/model_viewer_snippet.ts index e4164fe575..9657399c81 100644 --- a/packages/space-opera/src/components/model_viewer_snippet/model_viewer_snippet.ts +++ b/packages/space-opera/src/components/model_viewer_snippet/model_viewer_snippet.ts @@ -23,7 +23,7 @@ import '../shared/snippet_viewer/snippet_viewer.js'; import '../shared/expandable_content/expandable_tab.js'; import {html} from 'lit'; -import {customElement, state, property, query} from 'lit/decorators.js'; +import {customElement, property, query, state} from 'lit/decorators.js'; import {reduxStore} from '../../space_opera_base.js'; import {ArConfigState, BestPracticesState, ImageType, INITIAL_STATE, ModelViewerConfig, RelativeFilePathsState, State} from '../../types.js'; diff --git a/packages/space-opera/src/components/model_viewer_snippet/parse_hotspot_config.ts b/packages/space-opera/src/components/model_viewer_snippet/parse_hotspot_config.ts index db997c6ba3..c472580500 100644 --- a/packages/space-opera/src/components/model_viewer_snippet/parse_hotspot_config.ts +++ b/packages/space-opera/src/components/model_viewer_snippet/parse_hotspot_config.ts @@ -60,7 +60,9 @@ function parseHotspotConfig(element: HTMLElement): HotspotConfig { throw new Error(`no surface or position for hotspot at slot "${ element.getAttribute('slot')}"`); } - const annotation = (element.querySelector('.HotspotAnnotation') as HTMLElement)?.innerText || undefined; // Update here + const annotation = + (element.querySelector('.HotspotAnnotation') as HTMLElement)?.innerText || + undefined; // Update here return {name, surface, position, normal, annotation}; } diff --git a/packages/space-opera/src/components/shared/checkbox/checkbox.ts b/packages/space-opera/src/components/shared/checkbox/checkbox.ts index 4ab1c05134..72e809e73c 100644 --- a/packages/space-opera/src/components/shared/checkbox/checkbox.ts +++ b/packages/space-opera/src/components/shared/checkbox/checkbox.ts @@ -16,8 +16,8 @@ */ import '@material/mwc-checkbox'; -import {Checkbox} from '@material/mwc-checkbox'; +import {Checkbox} from '@material/mwc-checkbox'; import {html, LitElement} from 'lit'; import {customElement, property, query} from 'lit/decorators.js'; diff --git a/packages/space-opera/src/components/shared/expandable_content/expandable_switch.ts b/packages/space-opera/src/components/shared/expandable_content/expandable_switch.ts index 441d6adb00..8cf0b05577 100644 --- a/packages/space-opera/src/components/shared/expandable_content/expandable_switch.ts +++ b/packages/space-opera/src/components/shared/expandable_content/expandable_switch.ts @@ -17,8 +17,8 @@ import '@material/mwc-switch'; import './expandable_section.js'; -import {Switch} from '@material/mwc-switch'; +import {Switch} from '@material/mwc-switch'; import {html, LitElement} from 'lit'; import {customElement, property} from 'lit/decorators.js'; diff --git a/packages/space-opera/src/components/shared/mv_link/mv_link.ts b/packages/space-opera/src/components/shared/mv_link/mv_link.ts index e3f63ef446..6732a01a1f 100644 --- a/packages/space-opera/src/components/shared/mv_link/mv_link.ts +++ b/packages/space-opera/src/components/shared/mv_link/mv_link.ts @@ -17,6 +17,7 @@ import {html, LitElement} from 'lit'; import {customElement} from 'lit/decorators.js'; + import {styles} from './styles.css.js'; /** diff --git a/packages/space-opera/src/components/shared/radio_group/radio_group.ts b/packages/space-opera/src/components/shared/radio_group/radio_group.ts index 2f1aa566ac..e19a21063d 100644 --- a/packages/space-opera/src/components/shared/radio_group/radio_group.ts +++ b/packages/space-opera/src/components/shared/radio_group/radio_group.ts @@ -20,6 +20,7 @@ import '@polymer/paper-radio-group'; import {html, LitElement} from 'lit'; import {customElement, property} from 'lit/decorators.js'; + import {styles} from './radio_group.css.js'; /** diff --git a/packages/space-opera/src/components/shared/section_row/section_row.ts b/packages/space-opera/src/components/shared/section_row/section_row.ts index 34df2d2b40..68612ca87d 100644 --- a/packages/space-opera/src/components/shared/section_row/section_row.ts +++ b/packages/space-opera/src/components/shared/section_row/section_row.ts @@ -17,6 +17,7 @@ import {html, LitElement} from 'lit'; import {customElement, property} from 'lit/decorators.js'; + import {styles} from './section_row.css.js'; /** diff --git a/packages/space-opera/src/components/shared/snippet_viewer/snippet_viewer.ts b/packages/space-opera/src/components/shared/snippet_viewer/snippet_viewer.ts index 8f986dfda3..a12f996575 100644 --- a/packages/space-opera/src/components/shared/snippet_viewer/snippet_viewer.ts +++ b/packages/space-opera/src/components/shared/snippet_viewer/snippet_viewer.ts @@ -92,7 +92,7 @@ export class SnippetViewer extends LitElement { ${css_beautify(this.renderedStyle)} ` : - ``; + ''; } get formattedHtml() { diff --git a/packages/space-opera/src/components/shared/tabs/tabs.ts b/packages/space-opera/src/components/shared/tabs/tabs.ts index 85d1c97fef..840373a0b7 100644 --- a/packages/space-opera/src/components/shared/tabs/tabs.ts +++ b/packages/space-opera/src/components/shared/tabs/tabs.ts @@ -16,12 +16,12 @@ */ import '@material/mwc-tab-bar'; +import './tab'; import {html, LitElement} from 'lit'; import {customElement, property} from 'lit/decorators.js'; import {styles} from './styles.css.js'; -import './tab'; /** * A tabbed panel. diff --git a/packages/space-opera/src/components/utils/spread_directive.ts b/packages/space-opera/src/components/utils/spread_directive.ts index e70e960952..e65a554af0 100644 --- a/packages/space-opera/src/components/utils/spread_directive.ts +++ b/packages/space-opera/src/components/utils/spread_directive.ts @@ -12,14 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - directive, - Directive, - DirectiveParameters, - ElementPart, - PartInfo, - PartType, -} from 'lit/directive.js'; +import {directive, Directive, DirectiveParameters, ElementPart, PartInfo, PartType,} from 'lit/directive.js'; const Binding = { ATTRIBUTE: 'ATTRIBUTE' as 'ATTRIBUTE', @@ -31,23 +24,23 @@ const Binding = { type Binding = keyof typeof Binding; class Spread extends Directive { - oldBinds: { [bind: string]: unknown } = {}; + oldBinds: {[bind: string]: unknown} = {}; constructor(info: PartInfo) { super(info); if (info.type !== PartType.ELEMENT) { - throw new Error(`spread directive can only be used on element parts.`); + throw new Error('spread directive can only be used on element parts.'); } } update(part: ElementPart, [binds]: DirectiveParameters) { const newEntires = Object.entries(binds); - this.oldBinds.hasOwnProperty('$spread'); + Object.prototype.hasOwnProperty.call(this.oldBinds, '$spread'); for (const [bind, value] of newEntires) { const [bindKind, bindName] = this.parseBind(bind); - if (this.oldBinds.hasOwnProperty(bind)) { + if (Object.prototype.hasOwnProperty.call(this.oldBinds, bind)) { this.handleExistingBind(part, bind, bindName, value, bindKind); } else { this.handleNewBind(part, bindName, value, bindKind); @@ -58,7 +51,7 @@ class Spread extends Directive { for (const [bind, value] of oldEntries) { const [bindKind, bindName] = this.parseBind(bind); - if (!binds.hasOwnProperty(bind)) { + if (!Object.prototype.hasOwnProperty.call(binds, bind)) { this.handleRemovedBind(part, bindName, value, bindKind); } } @@ -67,12 +60,8 @@ class Spread extends Directive { } handleExistingBind( - part: ElementPart, - bind: string, - bindName: string, - value: unknown, - bindKind: Binding - ) { + part: ElementPart, bind: string, bindName: string, value: unknown, + bindKind: Binding) { const hasBindChanged = this.oldBinds[bind] !== value; if (!hasBindChanged) { @@ -81,9 +70,7 @@ class Spread extends Directive { if (bindKind === Binding.EVENT) { part.element.removeEventListener( - bindName, - this.oldBinds[bind] as EventListener - ); + bindName, this.oldBinds[bind] as EventListener); } this.handleNewBind(part, bindName, value, bindKind); @@ -92,11 +79,7 @@ class Spread extends Directive { } handleNewBind( - part: ElementPart, - bindName: string, - value: unknown, - bindKind: Binding - ) { + part: ElementPart, bindName: string, value: unknown, bindKind: Binding) { switch (bindKind) { case Binding.ATTRIBUTE: part.element.setAttribute(bindName, value as string); @@ -114,11 +97,7 @@ class Spread extends Directive { } handleRemovedBind( - part: ElementPart, - bindName: string, - value: unknown, - bindKind: Binding - ) { + part: ElementPart, bindName: string, value: unknown, bindKind: Binding) { switch (bindKind) { case Binding.ATTRIBUTE: case Binding.BOOLEAN_ATTRIBUTE: @@ -146,10 +125,10 @@ class Spread extends Directive { } } - render(binds: { [bind: string]: unknown }) { + render(binds: {[bind: string]: unknown}) { this.oldBinds = {...binds}; } } export const spread = directive(Spread); -export type { Spread }; +export type{Spread}; diff --git a/packages/space-opera/src/test/hotspot_panel/reducer_test.ts b/packages/space-opera/src/test/hotspot_panel/reducer_test.ts index c04c5cfdfb..1a3144704c 100644 --- a/packages/space-opera/src/test/hotspot_panel/reducer_test.ts +++ b/packages/space-opera/src/test/hotspot_panel/reducer_test.ts @@ -70,7 +70,7 @@ suite('hotspot dispatchers test', () => { }); test( - 'throws an error when dispatchUpdateHotspot is called with configs with \ non - existing hotspot names', + 'throws an error when dispatchUpdateHotspot is called with configs with \\ non - existing hotspot names', () => { expect(() => { reduxStore.dispatch(dispatchUpdateHotspot(config)); @@ -103,7 +103,7 @@ suite('hotspot dispatchers test', () => { }); test( - 'throws an error when dispatchRemoveHotspot is called with configs with \ non - existing hotspot names', + 'throws an error when dispatchRemoveHotspot is called with configs with \\ non - existing hotspot names', () => { reduxStore.dispatch(dispatchAddHotspot(config)); diff --git a/packages/space-opera/src/test/model_viewer_snippet/parse_hotspot_config_test.ts b/packages/space-opera/src/test/model_viewer_snippet/parse_hotspot_config_test.ts index d8ce4bff10..b12411ac80 100644 --- a/packages/space-opera/src/test/model_viewer_snippet/parse_hotspot_config_test.ts +++ b/packages/space-opera/src/test/model_viewer_snippet/parse_hotspot_config_test.ts @@ -50,7 +50,7 @@ suite('parse hotspot config test', () => { test( 'throws an error when given an invalid config without model-viewer tag', () => { - const snippet = ``; + const snippet = ''; expect(() => { parseHotspotsFromSnippet(snippet); }).to.throw; diff --git a/packages/space-opera/src/test/utils/test_utils.ts b/packages/space-opera/src/test/utils/test_utils.ts index 0b3df235fc..d3faef4f96 100644 --- a/packages/space-opera/src/test/utils/test_utils.ts +++ b/packages/space-opera/src/test/utils/test_utils.ts @@ -77,7 +77,7 @@ export async function generatePngBlob( return new Promise((resolve, reject) => { canvas.toBlob(blob => { if (!blob) { - reject(`Failed to get the PNG blob`); + reject('Failed to get the PNG blob'); } else { resolve(blob); } @@ -89,13 +89,15 @@ export async function generatePngBlob( * Returns true if two ArrayBuffers are equal, byte for byte. */ export function areBuffersEqual(buffer0: ArrayBuffer, buffer1: ArrayBuffer) { - if (buffer0.byteLength !== buffer1.byteLength) + if (buffer0.byteLength !== buffer1.byteLength) { return false; + } const view0 = new Uint8Array(buffer0); const view1 = new Uint8Array(buffer1); for (let i = 0; i < view0.length; i++) { - if (view0[i] !== view1[i]) + if (view0[i] !== view1[i]) { return false; + } } return true; }