diff --git a/.prettierignore b/.prettierignore index a3fd3e65b..0a39840d3 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,3 @@ # Prettier-only ignores. CHANGELOG.md +src/third_party/lighthouse-devtools-mcp-bundle.js \ No newline at end of file diff --git a/README.md b/README.md index e32db77e0..31e9e9ba2 100644 --- a/README.md +++ b/README.md @@ -442,9 +442,10 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles - **Network** (2 tools) - [`get_network_request`](docs/tool-reference.md#get_network_request) - [`list_network_requests`](docs/tool-reference.md#list_network_requests) -- **Debugging** (5 tools) +- **Debugging** (6 tools) - [`evaluate_script`](docs/tool-reference.md#evaluate_script) - [`get_console_message`](docs/tool-reference.md#get_console_message) + - [`lighthouse_audit`](docs/tool-reference.md#lighthouse_audit) - [`list_console_messages`](docs/tool-reference.md#list_console_messages) - [`take_screenshot`](docs/tool-reference.md#take_screenshot) - [`take_snapshot`](docs/tool-reference.md#take_snapshot) diff --git a/docs/tool-reference.md b/docs/tool-reference.md index 874e814de..8c33310db 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -1,6 +1,6 @@ -# Chrome DevTools MCP Tool Reference (~7084 cl100k_base tokens) +# Chrome DevTools MCP Tool Reference (~7324 cl100k_base tokens) - **[Input automation](#input-automation)** (9 tools) - [`click`](#click) @@ -30,9 +30,10 @@ - **[Network](#network)** (2 tools) - [`get_network_request`](#get_network_request) - [`list_network_requests`](#list_network_requests) -- **[Debugging](#debugging)** (5 tools) +- **[Debugging](#debugging)** (6 tools) - [`evaluate_script`](#evaluate_script) - [`get_console_message`](#get_console_message) + - [`lighthouse_audit`](#lighthouse_audit) - [`list_console_messages`](#list_console_messages) - [`take_screenshot`](#take_screenshot) - [`take_snapshot`](#take_snapshot) @@ -345,6 +346,18 @@ so returned values have to be JSON-serializable. --- +### `lighthouse_audit` + +**Description:** Get Lighthouse score and reports for accessibility, SEO and best practices. + +**Parameters:** + +- **device** (enum: "desktop", "mobile") _(optional)_: Device to [`emulate`](#emulate). +- **mode** (enum: "navigation", "snapshot") _(optional)_: "navigation" reloads & audits. "snapshot" analyzes current state. +- **outputDirPath** (string) _(optional)_: Directory for reports. If omitted, uses temporary files. + +--- + ### `list_console_messages` **Description:** List all console messages for the currently selected page since the last navigation. diff --git a/eslint.config.mjs b/eslint.config.mjs index 2c1cd0214..f4790ca78 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -14,7 +14,12 @@ import tseslint from 'typescript-eslint'; import localPlugin from './scripts/eslint_rules/local-plugin.js'; export default defineConfig([ - globalIgnores(['**/node_modules', '**/build/', 'tests/tools/fixtures/']), + globalIgnores([ + '**/node_modules', + '**/build/', + 'tests/tools/fixtures/', + 'src/third_party/lighthouse-devtools-mcp-bundle.js', + ]), importPlugin.flatConfigs.typescript, { languageOptions: { diff --git a/package-lock.json b/package-lock.json index 94dad7359..58dc1f61c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-import": "^2.32.0", "globals": "^17.0.0", + "lighthouse": "13.0.2", "prettier": "^3.6.2", "puppeteer": "24.37.5", "rollup": "4.59.0", @@ -322,6 +323,62 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz", + "integrity": "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/intl-localematcher": "0.6.2", + "decimal.js": "^10.4.3", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz", + "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz", + "integrity": "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/icu-skeleton-parser": "1.8.16", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz", + "integrity": "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz", + "integrity": "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@google/genai": { "version": "1.42.0", "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.42.0.tgz", @@ -570,6 +627,590 @@ "@tybys/wasm-util": "^0.10.0" } }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz", + "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.46.1.tgz", + "integrity": "sha512-AyXVnlCf/xV3K/rNumzKxZqsULyITJH6OVLiW6730JPRqWA7Zc9bvYoVNpN6iOpTU8CasH34SU/ksVJmObFibQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.43.1.tgz", + "integrity": "sha512-ht7YGWQuV5BopMcw5Q2hXn3I8eG8TH0J/kc/GMcW4CuNTgiP6wCu44BOnucJWL3CmFWaRHI//vWyAhaC8BwePw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.16.1.tgz", + "integrity": "sha512-K/qU4CjnzOpNkkKO4DfCLSQshejRNAJtd4esgigo/50nxCB6XCyi1dhAblUHM9jG5dRm8eu0FB+t87nIo99LYQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.47.1.tgz", + "integrity": "sha512-QNXPTWteDclR2B4pDFpz0TNghgB33UMjUt14B+BZPmtH1MwUFAfLHBaP5If0Z5NZC+jaH8oF2glgYjrmhZWmSw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.19.1.tgz", + "integrity": "sha512-6g0FhB3B9UobAR60BGTcXg4IHZ6aaYJzp0Ki5FhnxyAPt8Ns+9SSvgcrnsN2eGmk3RWG5vYycUGOEApycQL24A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.43.1.tgz", + "integrity": "sha512-M6qGYsp1cURtvVLGDrPPZemMFEbuMmCXgQYTReC/IbimV5sGrLBjB+/hANUpRZjX67nGLdKSVLZuQQAiNz+sww==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.47.1.tgz", + "integrity": "sha512-EGQRWMGqwiuVma8ZLAZnExQ7sBvbOx0N/AE/nlafISPs8S+QtXX+Viy6dcQwVWwYHQPAcuY3bFt3xgoAwb4ZNQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.45.2.tgz", + "integrity": "sha512-7Ehow/7Wp3aoyCrZwQpU7a2CnoMq0XhIcioFuKjBb0PLYfBfmTsFTUyatlHu0fRxhwcRsSQRTvEhmZu8CppBpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.57.2.tgz", + "integrity": "sha512-1Uz5iJ9ZAlFOiPuwYg29Bf7bJJc/GeoeJIFKJYQf67nTVKFe8RHbEtxgkOmK4UGZNHKXcpW4P8cWBYzBn1USpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/instrumentation": "0.57.2", + "@opentelemetry/semantic-conventions": "1.28.0", + "forwarded-parse": "2.1.2", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.47.1.tgz", + "integrity": "sha512-OtFGSN+kgk/aoKgdkKQnBsQFDiG8WdCxu+UrHr0bXScdAmtSzLSraLo7wFIb25RVHfRWvzI5kZomqJYEg/l1iA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.7.1.tgz", + "integrity": "sha512-OtjaKs8H7oysfErajdYr1yuWSjMAectT7Dwr+axIoZqT9lmEOkD/H/3rgAs8h/NIuEi2imSXD+vL4MZtOuJfqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.44.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.44.1.tgz", + "integrity": "sha512-U4dQxkNhvPexffjEmGwCq68FuftFK15JgUF05y/HlK3M6W/G2iEaACIfXdSnwVNe9Qh0sPfw8LbOPxrWzGWGMQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.47.1.tgz", + "integrity": "sha512-l/c+Z9F86cOiPJUllUCt09v+kICKvT+Vg1vOAJHtHPsJIzurGayucfCMq2acd/A/yxeNWunl9d9eqZ0G+XiI6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.44.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.44.1.tgz", + "integrity": "sha512-5MPkYCvG2yw7WONEjYj5lr5JFehTobW7wX+ZUFy81oF2lr9IPfZk9qO+FTaM0bGEiymwfLwKe6jE15nHn1nmHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.52.0.tgz", + "integrity": "sha512-1xmAqOtRUQGR7QfJFfGV/M2kC7wmI2WgZdpru8hJl3S0r4hW0n3OQpEHlSGXJAaNFyvT+ilnwkT+g5L4ljHR6g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.46.1.tgz", + "integrity": "sha512-3kINtW1LUTPkiXFRSSBmva1SXzS/72we/jL22N+BnF3DFcoewkdkHPYOIdAAk9gSicJ4d5Ojtt1/HeibEc5OQg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.45.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.45.1.tgz", + "integrity": "sha512-TKp4hQ8iKQsY7vnp/j0yJJ4ZsP109Ht6l4RHTj0lNEG1TfgTrIH5vJMbgmoYXWzNHAqBH2e7fncN12p3BP8LFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/mysql": "2.15.26" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.45.2.tgz", + "integrity": "sha512-h6Ad60FjCYdJZ5DTz1Lk2VmQsShiViKe0G7sYikb0GHI0NVvApp2XQNRHNjEMz87roFttGPLHOYVPlfy+yVIhQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.40.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.51.1.tgz", + "integrity": "sha512-QxgjSrxyWZc7Vk+qGSfsejPVFL1AgAJdSBMYZdDUbwg730D09ub3PXScB9d04vIqPriZ+0dqzjmQx0yWKiCi2Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.26.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.40.1", + "@types/pg": "8.6.1", + "@types/pg-pool": "2.0.6" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis-4": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis-4/-/instrumentation-redis-4-0.46.1.tgz", + "integrity": "sha512-UMqleEoabYMsWoTkqyt9WAzXwZ4BlFZHO40wr3d5ZvtjKCHlD4YXLm+6OLCeIi/HkX7EXvQaz8gtAwkwwSEvcQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.18.1.tgz", + "integrity": "sha512-5Cuy/nj0HBaH+ZJ4leuD7RjgvA844aY2WW+B5uLcWtxGjRZl3MNLuxnNg5DYWZNPO+NafSSnra0q49KWAHsKBg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.10.1.tgz", + "integrity": "sha512-rkOGikPEyRpMCmNu9AQuV5dtRlDmJp2dK5sw8roVshAGoB6hH/3QjDtRhdwd75SsJwgynWUNRUYe0wAkTo16tQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz", + "integrity": "sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", + "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.40.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.1.tgz", + "integrity": "sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.1.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "node_modules/@paulirish/trace_engine": { + "version": "0.0.61", + "resolved": "https://registry.npmjs.org/@paulirish/trace_engine/-/trace_engine-0.0.61.tgz", + "integrity": "sha512-/O08DwmUqIlJjUSPSZbNF8lWnlxaMsIOV6sS+uDKCxBd5i1psAmjEoG3JAqR6+nHD8X+YY474NW7SxUH/K+/kQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "legacy-javascript": "latest", + "third-party-web": "latest" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -581,6 +1222,19 @@ "node": ">=14" } }, + "node_modules/@prisma/instrumentation": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-6.11.1.tgz", + "integrity": "sha512-mrZOev24EDhnefmnZX7WVVT7v+r9LttPRqf54ONvj6re4XMF7wFTpK2tLJi4XHB7fFp/6xhYbgRel8YV7gQiyA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.8" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -1237,6 +1891,107 @@ "dev": true, "license": "MIT" }, + "node_modules/@sentry/core": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.47.1.tgz", + "integrity": "sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-9.47.1.tgz", + "integrity": "sha512-CDbkasBz3fnWRKSFs6mmaRepM2pa+tbZkrqhPWifFfIkJDidtVW40p6OnquTvPXyPAszCnDZRnZT14xyvNmKPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1", + "@opentelemetry/core": "^1.30.1", + "@opentelemetry/instrumentation": "^0.57.2", + "@opentelemetry/instrumentation-amqplib": "^0.46.1", + "@opentelemetry/instrumentation-connect": "0.43.1", + "@opentelemetry/instrumentation-dataloader": "0.16.1", + "@opentelemetry/instrumentation-express": "0.47.1", + "@opentelemetry/instrumentation-fs": "0.19.1", + "@opentelemetry/instrumentation-generic-pool": "0.43.1", + "@opentelemetry/instrumentation-graphql": "0.47.1", + "@opentelemetry/instrumentation-hapi": "0.45.2", + "@opentelemetry/instrumentation-http": "0.57.2", + "@opentelemetry/instrumentation-ioredis": "0.47.1", + "@opentelemetry/instrumentation-kafkajs": "0.7.1", + "@opentelemetry/instrumentation-knex": "0.44.1", + "@opentelemetry/instrumentation-koa": "0.47.1", + "@opentelemetry/instrumentation-lru-memoizer": "0.44.1", + "@opentelemetry/instrumentation-mongodb": "0.52.0", + "@opentelemetry/instrumentation-mongoose": "0.46.1", + "@opentelemetry/instrumentation-mysql": "0.45.1", + "@opentelemetry/instrumentation-mysql2": "0.45.2", + "@opentelemetry/instrumentation-pg": "0.51.1", + "@opentelemetry/instrumentation-redis-4": "0.46.1", + "@opentelemetry/instrumentation-tedious": "0.18.1", + "@opentelemetry/instrumentation-undici": "0.10.1", + "@opentelemetry/resources": "^1.30.1", + "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@prisma/instrumentation": "6.11.1", + "@sentry/core": "9.47.1", + "@sentry/node-core": "9.47.1", + "@sentry/opentelemetry": "9.47.1", + "import-in-the-middle": "^1.14.2", + "minimatch": "^9.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node-core": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-9.47.1.tgz", + "integrity": "sha512-7TEOiCGkyShJ8CKtsri9lbgMCbB+qNts2Xq37itiMPN2m+lIukK3OX//L8DC5nfKYZlgikrefS63/vJtm669hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/core": "9.47.1", + "@sentry/opentelemetry": "9.47.1", + "import-in-the-middle": "^1.14.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0", + "@opentelemetry/core": "^1.30.1 || ^2.0.0", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/resources": "^1.30.1 || ^2.0.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0", + "@opentelemetry/semantic-conventions": "^1.34.0" + } + }, + "node_modules/@sentry/opentelemetry": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-9.47.1.tgz", + "integrity": "sha512-STtFpjF7lwzeoedDJV+5XA6P89BfmFwFftmHSGSe3UTI8z8IoiR5yB6X2vCjSPvXlfeOs13qCNNCEZyznxM8Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/core": "9.47.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0", + "@opentelemetry/core": "^1.30.1 || ^2.0.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0", + "@opentelemetry/semantic-conventions": "^1.34.0" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -1317,6 +2072,16 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -1372,6 +2137,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mysql": { + "version": "2.15.26", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz", + "integrity": "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "25.3.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz", @@ -1382,6 +2157,28 @@ "undici-types": "~7.18.0" } }, + "node_modules/@types/pg": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", + "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -1396,6 +2193,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/shimmer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", + "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/sinon": { "version": "21.0.0", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz", @@ -1413,6 +2217,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { "version": "17.0.35", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", @@ -1970,6 +2784,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -2049,6 +2873,16 @@ "dev": true, "license": "MIT" }, + "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-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", @@ -2240,6 +3074,17 @@ "node": ">= 0.4" } }, + "node_modules/atomically": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.1.1.tgz", + "integrity": "sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "stubborn-fs": "^2.0.0", + "when-exit": "^2.1.4" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2256,6 +3101,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axe-core": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz", + "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, "node_modules/b4a": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", @@ -2563,6 +3418,25 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/chrome-launcher": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.2.1.tgz", + "integrity": "sha512-qmFR5PLMzHyuNJHwOloHPAHhbaNglkfeV/xDtt5b7xiFFyU1I+AZZX0PYseMuhenJSSirgxELYIbswcoc+5H4A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^2.0.1" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.cjs" + }, + "engines": { + "node": ">=12.13.0" + } + }, "node_modules/chromium-bidi": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-14.0.0.tgz", @@ -2577,6 +3451,13 @@ "devtools-protocol": "*" } }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, "node_modules/cliui": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", @@ -2633,6 +3514,25 @@ "dev": true, "license": "MIT" }, + "node_modules/configstore": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-7.1.0.tgz", + "integrity": "sha512-N4oog6YJWbR9kGyXvS7jEykLDXIE2C0ILYqNBZBp9iwiJpoCBWYsuAdW6PPFn6w06jjnC+3JstVvWHO4cZqvRg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "atomically": "^2.0.3", + "dot-prop": "^9.0.0", + "graceful-fs": "^4.2.11", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/content-disposition": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", @@ -2745,6 +3645,13 @@ "node": ">= 8" } }, + "node_modules/csp_evaluator": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/csp_evaluator/-/csp_evaluator-1.1.5.tgz", + "integrity": "sha512-EL/iN9etCTzw/fBnp0/uj0f5BOOGvZut2mzsiiBZ/FdT6gFQCKRO/tmcKOxn5drWZ2Ndm/xBb1SI4zwWbGtmIw==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", @@ -2827,6 +3734,13 @@ } } }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2862,6 +3776,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/define-properties": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", @@ -2935,6 +3859,22 @@ "node": ">=0.10.0" } }, + "node_modules/dot-prop": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz", + "integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^4.18.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -3001,6 +3941,43 @@ "once": "^1.4.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/enquirer/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/enquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -3989,6 +4966,13 @@ "node": ">= 0.6" } }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "dev": true, + "license": "MIT" + }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", @@ -4326,6 +5310,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/gtoken": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", @@ -4465,6 +5456,16 @@ "url": "https://opencollective.com/express" } }, + "node_modules/http-link-header": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/http-link-header/-/http-link-header-1.1.3.tgz", + "integrity": "sha512-3cZ0SRL8fb9MUlU3mKM61FcQvPfXx2dBrZW3Vbg5CXa8jFlK8OaEpePenLe1oEXQduhz8b0QjsqfS59QP4AJDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -4520,6 +5521,13 @@ "node": ">= 4" } }, + "node_modules/image-ssim": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/image-ssim/-/image-ssim-0.2.0.tgz", + "integrity": "sha512-W7+sO6/yhxy83L0G7xR8YAc5Z5QFtYEXXRV6EaE8tuYBZJnA3gVgp3q7X7muhLZVodeb9UfvjSbwt9VJwjIYAg==", + "dev": true, + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -4537,6 +5545,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4569,6 +5590,19 @@ "node": ">= 0.4" } }, + "node_modules/intl-messageformat": { + "version": "10.7.18", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.18.tgz", + "integrity": "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/icu-messageformat-parser": "2.11.4", + "tslib": "^2.8.0" + } + }, "node_modules/ip-address": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", @@ -4741,6 +5775,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5022,6 +6072,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", @@ -5062,6 +6125,13 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/js-cleanup": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.2.0.tgz", @@ -5087,6 +6157,16 @@ "sourcemap-codec": "^1.4.8" } }, + "node_modules/js-library-detector": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/js-library-detector/-/js-library-detector-6.7.0.tgz", + "integrity": "sha512-c80Qupofp43y4cJ7+8TTDN/AsDwLi5oOm/plBrWI+iQt485vKXCco+yVmOwEgdo9VOdsYTuV0UlTeetVPTriXA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5138,78 +6218,281 @@ "dev": true, "license": "MIT" }, - "node_modules/json-schema-typed": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", - "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/legacy-javascript": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/legacy-javascript/-/legacy-javascript-0.0.1.tgz", + "integrity": "sha512-lPyntS4/aS7jpuvOlitZDFifBCb4W8L/3QU0PLbUTUj+zYah8rfVjYic88yG7ZKTxhS5h9iz7duT8oUXKszLhg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lighthouse": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/lighthouse/-/lighthouse-13.0.2.tgz", + "integrity": "sha512-n0gdiopYHdTugNMeysuO/1jAUTDVNk/rfybvbbetzdn1po82a+V1vI7JB0yv3SIJM8yTRb+1EFEHJqQmKK8crA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@paulirish/trace_engine": "0.0.61", + "@sentry/node": "^9.28.1", + "axe-core": "^4.11.0", + "chrome-launcher": "^1.2.1", + "configstore": "^7.0.0", + "csp_evaluator": "1.1.5", + "devtools-protocol": "0.0.1527314", + "enquirer": "^2.3.6", + "http-link-header": "^1.1.1", + "intl-messageformat": "^10.5.3", + "jpeg-js": "^0.4.4", + "js-library-detector": "^6.7.0", + "lighthouse-logger": "^2.0.2", + "lighthouse-stack-packs": "1.12.3", + "lodash-es": "^4.17.21", + "lookup-closest-locale": "6.2.0", + "open": "^8.4.0", + "puppeteer-core": "^24.23.0", + "robots-parser": "^3.0.1", + "speedline-core": "^1.4.3", + "third-party-web": "^0.27.0", + "tldts-icann": "^7.0.17", + "ws": "^7.0.0", + "yargs": "^17.3.1", + "yargs-parser": "^21.0.0" + }, + "bin": { + "chrome-debug": "core/scripts/manual-chrome-launcher.js", + "lighthouse": "cli/index.js", + "smokehouse": "cli/test/smokehouse/frontends/smokehouse-bin.js" + }, + "engines": { + "node": ">=22.19" + } + }, + "node_modules/lighthouse-logger": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.2.tgz", + "integrity": "sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.1", + "marky": "^1.2.2" + } + }, + "node_modules/lighthouse-stack-packs": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/lighthouse-stack-packs/-/lighthouse-stack-packs-1.12.3.tgz", + "integrity": "sha512-d8IsOpE83kbANgnM+Tp8+x6HcMpX9o2ITBiUERssgzAIFdZCQzs/f4k6D0DLQTE59enml9mbAOU52Wu35exWtg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/lighthouse/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lighthouse/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/lighthouse/node_modules/devtools-protocol": { + "version": "0.0.1527314", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1527314.tgz", + "integrity": "sha512-UohCFOlzpPPD/IcsxM0k4lVZp/GfhPVJ6l2No5XX+LknpGisPWJe17oOHQhZTHf6ThUFIMwHO6bSEZUq/6oP7w==", "dev": true, - "license": "BSD-2-Clause" + "license": "BSD-3-Clause" }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "node_modules/lighthouse/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "node_modules/lighthouse/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { - "minimist": "^1.2.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "bin": { - "json5": "lib/cli.js" + "engines": { + "node": ">=8" } }, - "node_modules/jwa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "node_modules/lighthouse/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/jws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", - "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "node_modules/lighthouse/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { - "jwa": "^2.0.1", - "safe-buffer": "^5.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "node_modules/lighthouse/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/lighthouse/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=12" + } + }, + "node_modules/lighthouse/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" } }, "node_modules/lines-and-columns": { @@ -5242,6 +6525,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5256,6 +6546,13 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/lookup-closest-locale": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/lookup-closest-locale/-/lookup-closest-locale-6.2.0.tgz", + "integrity": "sha512-/c2kL+Vnp1jnV6K6RpDTHK3dgg0Tu2VVp+elEiJpjfS1UyY7AjOYHohRug6wT0OpoX2qFgNORndE9RqesfVxWQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -5276,6 +6573,13 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/marky": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz", + "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -5379,6 +6683,13 @@ "dev": true, "license": "MIT" }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "dev": true, + "license": "MIT" + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -5619,6 +6930,24 @@ "wrappy": "1" } }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -5876,6 +7205,40 @@ "node": ">=6.14" } }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz", + "integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==", + "dev": true, + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -5916,6 +7279,49 @@ "node": ">= 0.4" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6186,6 +7592,21 @@ "node": ">=0.10.0" } }, + "node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -6253,6 +7674,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robots-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/robots-parser/-/robots-parser-3.0.1.tgz", + "integrity": "sha512-s+pyvQeIKIZ0dx5iJiQk1tPLJAWln39+MI5jtM8wnyws+G5azk+dMnMX0qfbqNetKKNgcWWOdi0sfm+FbQbgdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/rollup": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", @@ -6594,6 +8025,13 @@ "node": ">=8" } }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -6837,6 +8275,21 @@ "spdx-ranges": "^2.0.0" } }, + "node_modules/speedline-core": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/speedline-core/-/speedline-core-1.4.3.tgz", + "integrity": "sha512-DI7/OuAUD+GMpR6dmu8lliO2Wg5zfeh+/xsdyJZCzd8o5JgFUjCeLsBDuZjIQJdwXS3J0L/uZYrELKYqx+PXog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "image-ssim": "^0.2.0", + "jpeg-js": "^0.4.1" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/stable-hash-x": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", @@ -7069,6 +8522,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stubborn-fs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-2.0.0.tgz", + "integrity": "sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "stubborn-utils": "^1.0.1" + } + }, + "node_modules/stubborn-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stubborn-utils/-/stubborn-utils-1.0.2.tgz", + "integrity": "sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==", + "dev": true, + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7143,6 +8613,13 @@ "b4a": "^1.6.4" } }, + "node_modules/third-party-web": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/third-party-web/-/third-party-web-0.27.0.tgz", + "integrity": "sha512-h0JYX+dO2Zr3abCQpS6/uFjujaOjA1DyDzGQ41+oFn9VW/ARiq9g5ln7qEP9+BTzDpOMyIfsfj4OvfgXAsMUSA==", + "dev": true, + "license": "MIT" + }, "node_modules/tiktoken": { "version": "1.0.22", "resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.22.tgz", @@ -7167,6 +8644,23 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tldts-core": { + "version": "7.0.23", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.23.tgz", + "integrity": "sha512-0g9vrtDQLrNIiCj22HSe9d4mLVG3g5ph5DZ8zCKBr4OtrspmNB6ss7hVyzArAeE88ceZocIEGkyW1Ime7fxPtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tldts-icann": { + "version": "7.0.23", + "resolved": "https://registry.npmjs.org/tldts-icann/-/tldts-icann-7.0.23.tgz", + "integrity": "sha512-LMc6V1KOHFjKDU8wyDsIEJdV8o2bpc2OaYw2NxncJB2oZxJMPpiNVAbiu1HnqsUy81fkK1QWwFztVqY81hUFEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.23" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -7233,6 +8727,19 @@ "node": ">=4" } }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", @@ -7479,6 +8986,13 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/when-exit": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.5.tgz", + "integrity": "sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==", + "dev": true, + "license": "MIT" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7718,6 +9232,29 @@ } } }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 65554fb8e..447e0e1ad 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "main": "./build/src/server.js", "scripts": { "clean": "node -e \"require('fs').rmSync('build', {recursive: true, force: true})\"", - "bundle": "npm run clean && npm run build && rollup -c rollup.config.mjs && node -e \"require('fs').rmSync('build/node_modules', {recursive: true, force: true})\"", + "bundle": "npm run clean && npm run build && rollup -c rollup.config.mjs && node -e \"require('fs').rmSync('build/node_modules', {recursive: true, force: true})\" && node --experimental-strip-types scripts/append-lighthouse-notices.ts", "build": "tsc && node --experimental-strip-types --no-warnings=ExperimentalWarning scripts/post-build.ts", "typecheck": "tsc --noEmit", "format": "eslint --cache --fix . && prettier --write --cache .", @@ -22,6 +22,7 @@ "test:update-snapshots": "npm run build && node scripts/test.mjs --test-update-snapshots", "prepare": "node --experimental-strip-types scripts/prepare.ts", "verify-server-json-version": "node --experimental-strip-types scripts/verify-server-json-version.ts", + "update-lighthouse": "node --experimental-strip-types scripts/update-lighthouse.ts", "verify-npm-package": "node scripts/verify-npm-package.mjs", "eval": "npm run build && node --experimental-strip-types scripts/eval_gemini.ts", "count-tokens": "node --experimental-strip-types scripts/count_tokens.ts" @@ -61,6 +62,7 @@ "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-import": "^2.32.0", "globals": "^17.0.0", + "lighthouse": "13.0.2", "prettier": "^3.6.2", "puppeteer": "24.37.5", "rollup": "4.59.0", diff --git a/rollup.config.mjs b/rollup.config.mjs index b6904824c..3a241bafc 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -107,7 +107,8 @@ function listBundledDeps() { Object.entries(devDependencies).filter( ([name]) => aggregatedStats.bundledPackages.has(name) || - name === 'chrome-devtools-frontend', + name === 'chrome-devtools-frontend' || + name === 'lighthouse', ), ); @@ -210,6 +211,22 @@ const bundleDependency = ( ); } + // Add chrome-devtools-frontend main license + const lighthouseLicensePath = path.join( + process.cwd(), + 'node_modules/lighthouse/LICENSE', + ); + if (fs.existsSync(lighthouseLicensePath)) { + manualLicenses.push( + [ + 'Name: lighthouse', + 'License: Apache-2.0', + '', + fs.readFileSync(lighthouseLicensePath, 'utf-8'), + ].join('\n'), + ); + } + for (const thirdPartyDir of thirdPartyDirectories) { const fullPath = path.join(process.cwd(), thirdPartyDir); const licenseFile = path.join(fullPath, 'LICENSE'); @@ -260,11 +277,15 @@ export default [ return true; } - const existingExternals = ['./bidi.js', '../bidi/bidi.js']; + const existingExternals = [ + './bidi.js', + '../bidi/bidi.js', + './lighthouse-devtools-mcp-bundle.js', + ]; + if (existingExternals.includes(source)) { return true; } - return false; }, ), diff --git a/scripts/append-lighthouse-notices.ts b/scripts/append-lighthouse-notices.ts new file mode 100644 index 000000000..2c6d1ba89 --- /dev/null +++ b/scripts/append-lighthouse-notices.ts @@ -0,0 +1,32 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const ROOT_DIR = process.cwd(); +const TARGET_DIR = path.join(ROOT_DIR, 'build/src/third_party'); +const SOURCE_DIR = path.join(ROOT_DIR, 'src/third_party'); + +function main() { + const lighthouseNotices = fs.readFileSync( + path.join(SOURCE_DIR, 'LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES'), + 'utf8', + ); + const bundledNotices = fs.readFileSync( + path.join(TARGET_DIR, 'THIRD_PARTY_NOTICES'), + 'utf8', + ); + fs.writeFileSync( + path.join(TARGET_DIR, 'THIRD_PARTY_NOTICES'), + bundledNotices + + '\n\n-------------------- DEPENDENCY DIVIDER --------------------\n\n' + + lighthouseNotices, + ); + console.log('Done.'); +} + +main(); diff --git a/scripts/eval_scenarios/lighthouse_a11y_test.ts b/scripts/eval_scenarios/lighthouse_a11y_test.ts new file mode 100644 index 000000000..cf0a0e67a --- /dev/null +++ b/scripts/eval_scenarios/lighthouse_a11y_test.ts @@ -0,0 +1,21 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import assert from 'node:assert'; + +import type {TestScenario} from '../eval_gemini.ts'; + +export const scenario: TestScenario = { + prompt: 'Check a11y issues on the current page', + maxTurns: 1, + expectations: calls => { + assert.strictEqual(calls.length, 1); + assert.ok( + calls[0].name === 'lighthouse_audit', + 'First call should be lighthouse_audit', + ); + }, +}; diff --git a/scripts/eval_scenarios/lighthouse_best_practices_test.ts b/scripts/eval_scenarios/lighthouse_best_practices_test.ts new file mode 100644 index 000000000..54aed3b8f --- /dev/null +++ b/scripts/eval_scenarios/lighthouse_best_practices_test.ts @@ -0,0 +1,21 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import assert from 'node:assert'; + +import type {TestScenario} from '../eval_gemini.ts'; + +export const scenario: TestScenario = { + prompt: 'Check for best practices on the current page', + maxTurns: 1, + expectations: calls => { + assert.strictEqual(calls.length, 1); + assert.ok( + calls[0].name === 'lighthouse_audit', + 'First call should be lighthouse_audit', + ); + }, +}; diff --git a/scripts/prepare.ts b/scripts/prepare.ts index dc7756dea..0a51226d7 100644 --- a/scripts/prepare.ts +++ b/scripts/prepare.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import {readFileSync, writeFileSync} from 'node:fs'; import {rm} from 'node:fs/promises'; import {resolve} from 'node:path'; @@ -15,6 +16,31 @@ const filesToRemove = [ 'node_modules/chrome-devtools-frontend/front_end/third_party/intl-messageformat/package/package.json', ]; +/** + * Removes the conflicting global HTMLElementEventMap declaration from + * @paulirish/trace_engine/models/trace/ModelImpl.d.ts to avoid TS2717 error + * when both chrome-devtools-frontend and @paulirish/trace_engine declare + * the same property. + */ +function removeConflictingGlobalDeclaration(): void { + const filePath = resolve( + projectRoot, + 'node_modules/@paulirish/trace_engine/models/trace/ModelImpl.d.ts', + ); + console.log( + 'Removing conflicting global declaration from @paulirish/trace_engine...', + ); + const content = readFileSync(filePath, 'utf-8'); + // Remove the declare global block using regex + // Matches: declare global { ... interface HTMLElementEventMap { ... } ... } + const newContent = content.replace( + /declare global\s*\{\s*interface HTMLElementEventMap\s*\{[^}]*\[ModelUpdateEvent\.eventName\]:\s*ModelUpdateEvent;\s*\}\s*\}/s, + '', + ); + writeFileSync(filePath, newContent, 'utf-8'); + console.log('Successfully removed conflicting global declaration.'); +} + async function main() { console.log('Running prepare script to clean up chrome-devtools-frontend...'); for (const file of filesToRemove) { @@ -28,6 +54,8 @@ async function main() { } } console.log('Clean up of chrome-devtools-frontend complete.'); + + removeConflictingGlobalDeclaration(); } void main(); diff --git a/scripts/update-lighthouse.ts b/scripts/update-lighthouse.ts new file mode 100644 index 000000000..9a08b07ac --- /dev/null +++ b/scripts/update-lighthouse.ts @@ -0,0 +1,54 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import {execSync} from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; + +const ROOT_DIR = process.cwd(); +const LIGHTHOUSE_DIR = path.resolve(ROOT_DIR, '../lighthouse'); +const DEST_DIR = path.join(ROOT_DIR, 'src/third_party'); + +function main() { + if (!fs.existsSync(LIGHTHOUSE_DIR)) { + console.error(`Lighthouse directory not found at ${LIGHTHOUSE_DIR}`); + process.exit(1); + } + + console.log('Running yarn in lighthouse directory...'); + execSync('yarn', {cwd: LIGHTHOUSE_DIR, stdio: 'inherit'}); + + console.log('Building lighthouse-devtools-mcp bundle...'); + execSync('yarn build-devtools-mcp', {cwd: LIGHTHOUSE_DIR, stdio: 'inherit'}); + + const bundlePath = path.join( + LIGHTHOUSE_DIR, + 'dist', + 'lighthouse-devtools-mcp-bundle.js', + ); + + console.log(`Copying bundle from ${bundlePath} to ${DEST_DIR}...`); + fs.copyFileSync( + bundlePath, + path.join(DEST_DIR, 'lighthouse-devtools-mcp-bundle.js'), + ); + + const noticesPath = path.join( + LIGHTHOUSE_DIR, + 'dist', + 'LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES', + ); + + console.log(`Copying notices from ${noticesPath} to ${DEST_DIR}...`); + fs.copyFileSync( + noticesPath, + path.join(DEST_DIR, 'LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES'), + ); + + console.log('Done.'); +} + +main(); diff --git a/src/McpContext.ts b/src/McpContext.ts index cf5597b39..09a339db0 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -93,18 +93,6 @@ function getNetworkMultiplierFromString(condition: string | null): number { return 1; } -function getExtensionFromMimeType(mimeType: string) { - switch (mimeType) { - case 'image/png': - return 'png'; - case 'image/jpeg': - return 'jpeg'; - case 'image/webp': - return 'webp'; - } - throw new Error(`No mapping for Mime type ${mimeType}.`); -} - export class McpContext implements Context { browser: Browser; logger: Debugger; @@ -334,6 +322,13 @@ export class McpContext implements Context { return this.#networkCollector.getById(this.#resolveTargetPage(), reqid); } + async restoreEmulation(targetPage?: Page) { + const page = targetPage ?? this.getSelectedPage(); + const mcpPage = this.#getMcpPage(page); + const currentSetting = mcpPage.emulationSettings; + await this.emulate(currentSetting, targetPage); + } + async emulate( options: { networkConditions?: string | null; @@ -1002,22 +997,19 @@ export class McpContext implements Context { async saveTemporaryFile( data: Uint8Array, - mimeType: 'image/png' | 'image/jpeg' | 'image/webp', - ): Promise<{filename: string}> { + filename: string, + ): Promise<{filepath: string}> { try { const dir = await fs.mkdtemp( path.join(os.tmpdir(), 'chrome-devtools-mcp-'), ); - const filename = path.join( - dir, - `screenshot.${getExtensionFromMimeType(mimeType)}`, - ); - await fs.writeFile(filename, data); - return {filename}; + const filepath = path.join(dir, filename); + await fs.writeFile(filepath, data); + return {filepath}; } catch (err) { this.logger(err); - throw new Error('Could not save a screenshot to a file', {cause: err}); + throw new Error('Could not save a file', {cause: err}); } } async saveFile( @@ -1026,11 +1018,12 @@ export class McpContext implements Context { ): Promise<{filename: string}> { try { const filePath = path.resolve(filename); + await fs.mkdir(path.dirname(filePath), {recursive: true}); await fs.writeFile(filePath, data); - return {filename}; + return {filename: filePath}; } catch (err) { this.logger(err); - throw new Error('Could not save a screenshot to a file', {cause: err}); + throw new Error('Could not save a file', {cause: err}); } } diff --git a/src/McpResponse.ts b/src/McpResponse.ts index 33f631d1e..d53f4da25 100644 --- a/src/McpResponse.ts +++ b/src/McpResponse.ts @@ -22,6 +22,7 @@ import {handleDialog} from './tools/pages.js'; import type { DevToolsData, ImageContentData, + LighthouseData, Response, SnapshotParams, } from './tools/ToolDefinition.js'; @@ -49,6 +50,7 @@ export class McpResponse implements Response { #attachedConsoleMessageId?: number; #attachedTraceSummary?: TraceResult; #attachedTraceInsight?: TraceInsightData; + #attachedLighthouseResult?: LighthouseData; #textResponseLines: string[] = []; #images: ImageContentData[] = []; #networkRequestsOptions?: { @@ -181,6 +183,10 @@ export class McpResponse implements Response { }; } + attachLighthouseResult(result: LighthouseData): void { + this.#attachedLighthouseResult = result; + } + get includePages(): boolean { return this.#includePages; } @@ -193,6 +199,10 @@ export class McpResponse implements Response { return this.#attachedTraceInsight; } + get attachedLighthouseResult(): LighthouseData | undefined { + return this.#attachedLighthouseResult; + } + get includeNetworkRequests(): boolean { return this.#networkRequestsOptions?.include ?? false; } @@ -412,6 +422,7 @@ export class McpResponse implements Response { traceInsight: this.#attachedTraceInsight, traceSummary: this.#attachedTraceSummary, extensions, + lighthouseResult: this.#attachedLighthouseResult, }); } @@ -427,6 +438,7 @@ export class McpResponse implements Response { traceSummary?: TraceResult; traceInsight?: TraceInsightData; extensions?: InstalledExtension[]; + lighthouseResult?: LighthouseData; }, ): {content: Array; structuredContent: object} { const structuredContent: { @@ -439,6 +451,7 @@ export class McpResponse implements Response { consoleMessages?: object[]; traceSummary?: string; traceInsights?: Array<{insightName: string; insightKey: string}>; + lighthouseResult?: object; extensions?: object[]; message?: string; networkConditions?: string; @@ -601,6 +614,29 @@ Call ${handleDialog.name} to handle it before continuing.`); } } + if (data.lighthouseResult) { + structuredContent.lighthouseResult = data.lighthouseResult; + const {summary, reports} = data.lighthouseResult; + response.push('## Lighthouse Audit Results'); + response.push(`Mode: ${summary.mode}`); + response.push(`Device: ${summary.device}`); + response.push(`URL: ${summary.url}`); + response.push('### Category Scores'); + for (const score of summary.scores) { + response.push( + `- ${score.title}: ${(score.score ?? 0) * 100} (${score.id})`, + ); + } + response.push('### Audit Summary'); + response.push(`Passed: ${summary.audits.passed}`); + response.push(`Failed: ${summary.audits.failed}`); + response.push(`Total Timing: ${summary.timing.total}ms`); + response.push('### Reports'); + for (const report of reports) { + response.push(`- ${report}`); + } + } + if (data.snapshot) { if (typeof data.snapshot === 'string') { response.push(`Saved snapshot to ${data.snapshot}.`); diff --git a/src/third_party/LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES b/src/third_party/LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES new file mode 100644 index 000000000..c99dde397 --- /dev/null +++ b/src/third_party/LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES @@ -0,0 +1,1033 @@ +Name: ms +URL: N/A +Version: 2.1.2 +License: MIT + +The MIT License (MIT) + +Copyright (c) 2016 Zeit, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: debug +URL: git://github.com/debug-js/debug.git +Version: 4.3.4 +License: MIT + +(The MIT License) + +Copyright (c) 2014-2017 TJ Holowaychuk +Copyright (c) 2018-2021 Josh Junon + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the 'Software'), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: marky +URL: N/A +Version: 1.2.2 +License: Apache-2.0 + +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of + fifty percent (50%) or more of the outstanding shares, or (iii) beneficial + ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, + and configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to + other media types. + + "Work" shall mean the work of authorship, whether in Source or Object + form, made available under the License, as indicated by a copyright notice + that is included in or attached to the work (an example is provided in the + Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, + as a whole, an original work of authorship. For the purposes of this + License, Derivative Works shall not include works that remain separable + from, or merely link (or bind by name) to the interfaces of, the Work and + Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or + Legal Entity authorized to submit on behalf of the copyright owner. + For the purposes of this definition, "submitted" means any form of + electronic, verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems + that are managed by, or on behalf of, the Licensor for the purpose of + discussing and improving the Work, but excluding communication that is + conspicuously marked or otherwise designated in writing by the copyright + owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. + + Subject to the terms and conditions of this License, each Contributor + hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, + royalty-free, irrevocable copyright license to reproduce, prepare + Derivative Works of, publicly display, publicly perform, sublicense, + and distribute the Work and such Derivative Works in + Source or Object form. + +3. Grant of Patent License. + + Subject to the terms and conditions of this License, each Contributor + hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, + royalty-free, irrevocable (except as stated in this section) patent + license to make, have made, use, offer to sell, sell, import, and + otherwise transfer the Work, where such license applies only to those + patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or + contributory patent infringement, then any patent licenses granted to + You under this License for that Work shall terminate as of the date such + litigation is filed. + +4. Redistribution. + + You may reproduce and distribute copies of the Work or Derivative Works + thereof in any medium, with or without modifications, and in Source or + Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + + 3. You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain + to any part of the Derivative Works; and + + 4. If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, + in at least one of the following places: within a NOTICE text file + distributed as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, within a + display generated by the Derivative Works, if and wherever such + third-party notices normally appear. The contents of the NOTICE file are + for informational purposes only and do not modify the License. + You may add Your own attribution notices within Derivative Works that You + distribute, alongside or as an addendum to the NOTICE text from the Work, + provided that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions + stated in this License. + +5. Submission of Contributions. + + Unless You explicitly state otherwise, any Contribution intentionally + submitted for inclusion in the Work by You to the Licensor shall be under + the terms and conditions of this License, without any additional + terms or conditions. Notwithstanding the above, nothing herein shall + supersede or modify the terms of any separate license agreement you may + have executed with Licensor regarding such Contributions. + +6. Trademarks. + + This License does not grant permission to use the trade names, trademarks, + service marks, or product names of the Licensor, except as required for + reasonable and customary use in describing the origin of the Work and + reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + + Unless required by applicable law or agreed to in writing, Licensor + provides the Work (and each Contributor provides its Contributions) + on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied, including, without limitation, any warranties + or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS + FOR A PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + + In no event and under no legal theory, whether in tort + (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed + to in writing, shall any Contributor be liable to You for damages, + including any direct, indirect, special, incidental, or consequential + damages of any character arising as a result of this License or out of + the use or inability to use the Work (including but not limited to damages + for loss of goodwill, work stoppage, computer failure or malfunction, + or any and all other commercial damages or losses), even if such + Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + + While redistributing the Work or Derivative Works thereof, You may choose + to offer, and charge a fee for, acceptance of support, warranty, + indemnity, or other liability obligations and/or rights consistent with + this License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf of any + other Contributor, and only if You agree to indemnify, defend, and hold + each Contributor harmless for any liability incurred by, or claims + asserted against, such Contributor by reason of your accepting any such + warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + + To apply the Apache License to your work, attach the following boilerplate + notice, with the fields enclosed by brackets "[]" replaced with your own + identifying information. (Don't include the brackets!) The text should be + enclosed in the appropriate comment syntax for the file format. We also + recommend that a file or class name and description of purpose be included + on the same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 Nolan Lawson + + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the License for the specific language governing + permissions and limitations under the License. + + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: lodash-es +URL: N/A +Version: 4.17.21 +License: MIT + +Copyright OpenJS Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: tslib +URL: N/A +Version: 2.6.2 +License: 0BSD + +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: @formatjs/icu-messageformat-parser +URL: https://github.com/formatjs/formatjs.git +Version: 2.6.2 +License: MIT + +MIT License + +Copyright (c) 2021 FormatJS + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: @formatjs/icu-skeleton-parser +URL: https://github.com/formatjs/formatjs.git +Version: 1.6.2 +License: MIT + +MIT License + +Copyright (c) 2021 FormatJS + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: @formatjs/fast-memoize +URL: N/A +Version: 2.2.0 +License: MIT + +MIT License + +Copyright (c) 2021 FormatJS + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: intl-messageformat +URL: N/A +Version: 10.5.3 +License: BSD-3-Clause + +Copyright (c) 2021, Oath Inc. + +Licensed under the terms of the New BSD license. See below for terms. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +- Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +- Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +- Neither the name of Oath Inc. nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Oath Inc. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: lighthouse-stack-packs +URL: N/A +Version: 1.12.3 +License: Apache-2.0 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: lookup-closest-locale +URL: N/A +Version: 6.2.0 +License: MIT + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: @paulirish/trace_engine +URL: N/A +Version: 0.0.61 +License: BSD-3-Clause + +// Copyright 2014 The Chromium Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: third-party-web +URL: https://github.com/patrickhulce/third-party-web.git +Version: 0.26.2 +License: MIT + +The MIT License (MIT) +Copyright (c) 2019 Patrick Hulce + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: legacy-javascript +URL: N/A +Version: 0.0.1 +License: Apache-2.0 + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: tldts-icann +URL: N/A +Version: 7.0.17 +License: MIT + +Copyright (c) 2017 Thomas Parisot, 2018 Rémi Berson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: http-link-header +URL: N/A +Version: 1.1.1 +License: MIT + +# The MIT License (MIT) +Copyright (c) 2016 Jonas Hermsmeier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: csp_evaluator +URL: N/A +Version: 1.1.5 +License: Apache-2.0 + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: robots-parser +URL: N/A +Version: 3.0.1 +License: MIT + +The MIT License (MIT) + +Copyright (c) 2014 Sam Clarke + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: lighthouse-plugin-soft-navigation +URL: N/A +Version: 1.1.0 +License: ISC \ No newline at end of file diff --git a/src/third_party/index.ts b/src/third_party/index.ts index 862227871..a3d96ef18 100644 --- a/src/third_party/index.ts +++ b/src/third_party/index.ts @@ -8,6 +8,11 @@ import 'core-js/modules/es.promise.with-resolvers.js'; import 'core-js/modules/es.set.union.v2.js'; import 'core-js/proposals/iterator-helpers.js'; +import type {Flags, OutputMode, Result, RunnerResult} from 'lighthouse'; +import type {Page} from 'puppeteer-core'; + +export type {Flags, Result, RunnerResult, OutputMode}; + export type {Options as YargsOptions} from 'yargs'; export {default as yargs} from 'yargs'; export {hideBin} from 'yargs/helpers'; @@ -39,4 +44,24 @@ export { type ChromeReleaseChannel as BrowsersChromeReleaseChannel, } from '@puppeteer/browsers'; +import { + snapshot as snapshotImpl, + navigation as navigationImpl, + generateReport as generateReportImpl, +} from './lighthouse-devtools-mcp-bundle.js'; + +export const snapshot = snapshotImpl as ( + page: Page, + options: {flags?: Flags}, +) => Promise; +export const navigation = navigationImpl as ( + page: Page, + url: string, + options: {flags?: Flags}, +) => Promise; +export const generateReport = generateReportImpl as ( + lhr: Result, + format: string, +) => string; + export * as DevTools from '../../node_modules/chrome-devtools-frontend/mcp/mcp.js'; diff --git a/src/third_party/lighthouse-devtools-mcp-bundle.js b/src/third_party/lighthouse-devtools-mcp-bundle.js new file mode 100644 index 000000000..ea30c6836 --- /dev/null +++ b/src/third_party/lighthouse-devtools-mcp-bundle.js @@ -0,0 +1,54649 @@ +/** + * Lighthouse v13.0.3-4-ga9dfea556 (Feb 23 2026) + * + * Automated auditing, performance metrics, and best practices for the web. + * + * @homepage https://github.com/GoogleChrome/lighthouse#readme + * @author Copyright 2026 Google LLC + * @license Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); +var __esm = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; +}; +var __commonJS = (cb, mod2) => function __require() { + return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; +}; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, + mod2 +)); +var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2); + +// build/process-global.js +import process2 from "process"; +var init_process_global = __esm({ + "build/process-global.js"() { + "use strict"; + globalThis.process = process2; + } +}); + +// types/lh.js +var init_lh = __esm({ + "types/lh.js"() { + "use strict"; + init_process_global(); + /** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + } +}); + +// core/gather/base-gatherer.js +var BaseGatherer, base_gatherer_default; +var init_base_gatherer = __esm({ + "core/gather/base-gatherer.js"() { + "use strict"; + init_process_global(); + init_lh(); + /** + * @license + * Copyright 2021 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + BaseGatherer = class { + static { + __name(this, "BaseGatherer"); + } + /** @type {LH.Gatherer.GathererMeta} */ + meta = { supportedModes: [] }; + /** + * Method to start observing a page for an arbitrary period of time. + * @param {LH.Gatherer.Context} passContext + * @return {Promise|void} + */ + startInstrumentation(passContext) { + } + /** + * Method to start observing a page when the measurements are very sensitive and + * should observe as little Lighthouse-induced work as possible. + * @param {LH.Gatherer.Context} passContext + * @return {Promise|void} + */ + startSensitiveInstrumentation(passContext) { + } + /** + * Method to stop observing a page when the measurements are very sensitive and + * should observe as little Lighthouse-induced work as possible. + * + * @param {LH.Gatherer.Context} passContext + * @return {Promise|void} + */ + stopSensitiveInstrumentation(passContext) { + } + /** + * Method to end observing a page after an arbitrary period of time. + * @param {LH.Gatherer.Context} passContext + * @return {Promise|void} + */ + stopInstrumentation(passContext) { + } + /** + * Method to gather results about a page. + * @param {LH.Gatherer.Context} passContext + * @return {LH.Gatherer.PhaseResult} + */ + getArtifact(passContext) { + } + }; + base_gatherer_default = BaseGatherer; + } +}); + +// lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/trace.js +var trace_exports = {}; +__export(trace_exports, { + default: () => trace_default +}); +var ShimGatherer, trace_default; +var init_trace = __esm({ + "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/trace.js"() { + init_process_global(); + init_base_gatherer(); + ShimGatherer = class extends base_gatherer_default { + static { + __name(this, "ShimGatherer"); + } + meta = { supportedModes: ["navigation", "timespan", "snapshot"] }; + static getDefaultTraceCategories() { + return []; + } + getArtifact() { + return void 0; + } + }; + trace_default = ShimGatherer; + } +}); + +// node_modules/debug/node_modules/ms/index.js +var require_ms = __commonJS({ + "node_modules/debug/node_modules/ms/index.js"(exports2, module2) { + init_process_global(); + var s = 1e3; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var w = d * 7; + var y = d * 365.25; + module2.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === "string" && val.length > 0) { + return parse(val); + } else if (type === "number" && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) + ); + }; + function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || "ms").toLowerCase(); + switch (type) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return n * y; + case "weeks": + case "week": + case "w": + return n * w; + case "days": + case "day": + case "d": + return n * d; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return n * h; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return n * m; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return n * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return n; + default: + return void 0; + } + } + __name(parse, "parse"); + function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + "d"; + } + if (msAbs >= h) { + return Math.round(ms / h) + "h"; + } + if (msAbs >= m) { + return Math.round(ms / m) + "m"; + } + if (msAbs >= s) { + return Math.round(ms / s) + "s"; + } + return ms + "ms"; + } + __name(fmtShort, "fmtShort"); + function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, "day"); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, "hour"); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, "minute"); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, "second"); + } + return ms + " ms"; + } + __name(fmtLong, "fmtLong"); + function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + " " + name + (isPlural ? "s" : ""); + } + __name(plural, "plural"); + } +}); + +// node_modules/debug/src/common.js +var require_common = __commonJS({ + "node_modules/debug/src/common.js"(exports2, module2) { + init_process_global(); + function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = require_ms(); + createDebug.destroy = destroy; + Object.keys(env).forEach((key) => { + createDebug[key] = env[key]; + }); + createDebug.names = []; + createDebug.skips = []; + createDebug.formatters = {}; + function selectColor(namespace) { + let hash = 0; + for (let i = 0; i < namespace.length; i++) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + __name(selectColor, "selectColor"); + createDebug.selectColor = selectColor; + function createDebug(namespace) { + let prevTime; + let enableOverride = null; + let namespacesCache; + let enabledCache; + function debug2(...args) { + if (!debug2.enabled) { + return; + } + const self2 = debug2; + const curr = Number(/* @__PURE__ */ new Date()); + const ms = curr - (prevTime || curr); + self2.diff = ms; + self2.prev = prevTime; + self2.curr = curr; + prevTime = curr; + args[0] = createDebug.coerce(args[0]); + if (typeof args[0] !== "string") { + args.unshift("%O"); + } + let index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + if (match === "%%") { + return "%"; + } + index++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === "function") { + const val = args[index]; + match = formatter.call(self2, val); + args.splice(index, 1); + index--; + } + return match; + }); + createDebug.formatArgs.call(self2, args); + const logFn = self2.log || createDebug.log; + logFn.apply(self2, args); + } + __name(debug2, "debug"); + debug2.namespace = namespace; + debug2.useColors = createDebug.useColors(); + debug2.color = createDebug.selectColor(namespace); + debug2.extend = extend; + debug2.destroy = createDebug.destroy; + Object.defineProperty(debug2, "enabled", { + enumerable: true, + configurable: false, + get: /* @__PURE__ */ __name(() => { + if (enableOverride !== null) { + return enableOverride; + } + if (namespacesCache !== createDebug.namespaces) { + namespacesCache = createDebug.namespaces; + enabledCache = createDebug.enabled(namespace); + } + return enabledCache; + }, "get"), + set: /* @__PURE__ */ __name((v) => { + enableOverride = v; + }, "set") + }); + if (typeof createDebug.init === "function") { + createDebug.init(debug2); + } + return debug2; + } + __name(createDebug, "createDebug"); + function extend(namespace, delimiter) { + const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + __name(extend, "extend"); + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.namespaces = namespaces; + createDebug.names = []; + createDebug.skips = []; + let i; + const split = (typeof namespaces === "string" ? namespaces : "").split(/[\s,]+/); + const len = split.length; + for (i = 0; i < len; i++) { + if (!split[i]) { + continue; + } + namespaces = split[i].replace(/\*/g, ".*?"); + if (namespaces[0] === "-") { + createDebug.skips.push(new RegExp("^" + namespaces.slice(1) + "$")); + } else { + createDebug.names.push(new RegExp("^" + namespaces + "$")); + } + } + } + __name(enable, "enable"); + function disable() { + const namespaces = [ + ...createDebug.names.map(toNamespace), + ...createDebug.skips.map(toNamespace).map((namespace) => "-" + namespace) + ].join(","); + createDebug.enable(""); + return namespaces; + } + __name(disable, "disable"); + function enabled(name) { + if (name[name.length - 1] === "*") { + return true; + } + let i; + let len; + for (i = 0, len = createDebug.skips.length; i < len; i++) { + if (createDebug.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = createDebug.names.length; i < len; i++) { + if (createDebug.names[i].test(name)) { + return true; + } + } + return false; + } + __name(enabled, "enabled"); + function toNamespace(regexp) { + return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, "*"); + } + __name(toNamespace, "toNamespace"); + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } + __name(coerce, "coerce"); + function destroy() { + console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + } + __name(destroy, "destroy"); + createDebug.enable(createDebug.load()); + return createDebug; + } + __name(setup, "setup"); + module2.exports = setup; + } +}); + +// node_modules/debug/src/browser.js +var require_browser = __commonJS({ + "node_modules/debug/src/browser.js"(exports2, module2) { + init_process_global(); + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.storage = localstorage(); + exports2.destroy = /* @__PURE__ */ (() => { + let warned = false; + return () => { + if (!warned) { + warned = true; + console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + } + }; + })(); + exports2.colors = [ + "#0000CC", + "#0000FF", + "#0033CC", + "#0033FF", + "#0066CC", + "#0066FF", + "#0099CC", + "#0099FF", + "#00CC00", + "#00CC33", + "#00CC66", + "#00CC99", + "#00CCCC", + "#00CCFF", + "#3300CC", + "#3300FF", + "#3333CC", + "#3333FF", + "#3366CC", + "#3366FF", + "#3399CC", + "#3399FF", + "#33CC00", + "#33CC33", + "#33CC66", + "#33CC99", + "#33CCCC", + "#33CCFF", + "#6600CC", + "#6600FF", + "#6633CC", + "#6633FF", + "#66CC00", + "#66CC33", + "#9900CC", + "#9900FF", + "#9933CC", + "#9933FF", + "#99CC00", + "#99CC33", + "#CC0000", + "#CC0033", + "#CC0066", + "#CC0099", + "#CC00CC", + "#CC00FF", + "#CC3300", + "#CC3333", + "#CC3366", + "#CC3399", + "#CC33CC", + "#CC33FF", + "#CC6600", + "#CC6633", + "#CC9900", + "#CC9933", + "#CCCC00", + "#CCCC33", + "#FF0000", + "#FF0033", + "#FF0066", + "#FF0099", + "#FF00CC", + "#FF00FF", + "#FF3300", + "#FF3333", + "#FF3366", + "#FF3399", + "#FF33CC", + "#FF33FF", + "#FF6600", + "#FF6633", + "#FF9900", + "#FF9933", + "#FFCC00", + "#FFCC33" + ]; + function useColors() { + if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) { + return true; + } + if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + __name(useColors, "useColors"); + function formatArgs(args) { + args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module2.exports.humanize(this.diff); + if (!this.useColors) { + return; + } + const c = "color: " + this.color; + args.splice(1, 0, c, "color: inherit"); + let index = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, (match) => { + if (match === "%%") { + return; + } + index++; + if (match === "%c") { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + __name(formatArgs, "formatArgs"); + exports2.log = console.debug || console.log || (() => { + }); + function save(namespaces) { + try { + if (namespaces) { + exports2.storage.setItem("debug", namespaces); + } else { + exports2.storage.removeItem("debug"); + } + } catch (error) { + } + } + __name(save, "save"); + function load() { + let r; + try { + r = exports2.storage.getItem("debug"); + } catch (error) { + } + if (!r && typeof process !== "undefined" && "env" in process) { + r = process.env.DEBUG; + } + return r; + } + __name(load, "load"); + function localstorage() { + try { + return localStorage; + } catch (error) { + } + } + __name(localstorage, "localstorage"); + module2.exports = require_common()(exports2); + var { formatters } = module2.exports; + formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (error) { + return "[UnexpectedJSONParseError]: " + error.message; + } + }; + } +}); + +// node_modules/marky/lib/marky.cjs.js +var require_marky_cjs = __commonJS({ + "node_modules/marky/lib/marky.cjs.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + var perf = typeof performance !== "undefined" && performance; + var nowForNode; + { + hrtime = process.hrtime; + getNanoSeconds = /* @__PURE__ */ __name(function() { + var hr = hrtime(); + return hr[0] * 1e9 + hr[1]; + }, "getNanoSeconds"); + loadTime = getNanoSeconds(); + nowForNode = /* @__PURE__ */ __name(function() { + return (getNanoSeconds() - loadTime) / 1e6; + }, "nowForNode"); + } + var hrtime; + var getNanoSeconds; + var loadTime; + var now = nowForNode; + function throwIfEmpty(name) { + if (!name) { + throw new Error("name must be non-empty"); + } + } + __name(throwIfEmpty, "throwIfEmpty"); + function insertSorted(arr, item) { + var low = 0; + var high = arr.length; + var mid; + while (low < high) { + mid = low + high >>> 1; + if (arr[mid].startTime < item.startTime) { + low = mid + 1; + } else { + high = mid; + } + } + arr.splice(low, 0, item); + } + __name(insertSorted, "insertSorted"); + exports2.mark = void 0; + exports2.stop = void 0; + exports2.getEntries = void 0; + exports2.clear = void 0; + if (perf && perf.mark && perf.getEntriesByName && perf.getEntriesByType && perf.clearMeasures) { + exports2.mark = function(name) { + throwIfEmpty(name); + perf.mark("start " + name); + }; + exports2.stop = function(name) { + throwIfEmpty(name); + perf.mark("end " + name); + perf.measure(name, "start " + name, "end " + name); + var entries2 = perf.getEntriesByName(name); + return entries2[entries2.length - 1]; + }; + exports2.getEntries = function() { + return perf.getEntriesByType("measure"); + }; + exports2.clear = function() { + perf.clearMarks(); + perf.clearMeasures(); + }; + } else { + marks = {}; + entries = []; + exports2.mark = function(name) { + throwIfEmpty(name); + var startTime = now(); + marks["$" + name] = startTime; + }; + exports2.stop = function(name) { + throwIfEmpty(name); + var endTime = now(); + var startTime = marks["$" + name]; + if (!startTime) { + throw new Error("no known mark: " + name); + } + var entry = { + startTime, + name, + duration: endTime - startTime, + entryType: "measure" + }; + insertSorted(entries, entry); + return entry; + }; + exports2.getEntries = function() { + return entries; + }; + exports2.clear = function() { + marks = {}; + entries = []; + }; + } + var marks; + var entries; + } +}); + +// lighthouse-logger/index.js +import process3 from "process"; +import { EventEmitter } from "events"; +var import_debug, marky, isWindows, isBrowser, colors, Emitter, loggersByTitle, loggingBufferColumns, level_, Log, lighthouse_logger_default; +var init_lighthouse_logger = __esm({ + "lighthouse-logger/index.js"() { + "use strict"; + init_process_global(); + import_debug = __toESM(require_browser(), 1); + marky = __toESM(require_marky_cjs(), 1); + /** + * @license + * Copyright 2016 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + isWindows = process3.platform === "win32"; + isBrowser = process3.browser; + colors = { + red: isBrowser ? "crimson" : 1, + yellow: isBrowser ? "gold" : 3, + cyan: isBrowser ? "darkturquoise" : 6, + green: isBrowser ? "forestgreen" : 2, + blue: isBrowser ? "steelblue" : 4, + magenta: isBrowser ? "palevioletred" : 5 + }; + import_debug.default.colors = [colors.cyan, colors.green, colors.blue, colors.magenta]; + Emitter = class extends EventEmitter { + static { + __name(this, "Emitter"); + } + // yarn build-types fails without this! + // https://github.com/microsoft/TypeScript/issues/41672#issuecomment-2303803072 + constructor(options) { + super(options); + } + /** + * Fires off all status updates. Listen with + * `require('lib/log').events.addListener('status', callback)` + * @param {string} title + * @param {!Array<*>} argsArray + */ + issueStatus(title, argsArray) { + if (title === "status" || title === "statusEnd") { + this.emit(title, [title, ...argsArray]); + } + } + /** + * Fires off all warnings. Listen with + * `require('lib/log').events.addListener('warning', callback)` + * @param {string} title + * @param {!Array<*>} argsArray + */ + issueWarning(title, argsArray) { + this.emit("warning", [title, ...argsArray]); + } + }; + loggersByTitle = {}; + loggingBufferColumns = 25; + Log = class _Log { + static { + __name(this, "Log"); + } + static _logToStdErr(title, argsArray) { + const log = _Log.loggerfn(title); + log(...argsArray); + } + /** + * @param {string} title + */ + static loggerfn(title) { + title = `LH:${title}`; + let log = loggersByTitle[title]; + if (!log) { + log = (0, import_debug.default)(title); + loggersByTitle[title] = log; + if (title.endsWith("error")) { + log.color = colors.red; + } else if (title.endsWith("warn")) { + log.color = colors.yellow; + } + } + return log; + } + /** + * @param {string} level + */ + static setLevel(level) { + level_ = level; + switch (level) { + case "silent": + import_debug.default.enable("-LH:*"); + break; + case "verbose": + import_debug.default.enable("LH:*"); + break; + case "warn": + import_debug.default.enable("-LH:*, LH:*:warn, LH:*:error"); + break; + case "error": + import_debug.default.enable("-LH:*, LH:*:error"); + break; + default: + import_debug.default.enable("LH:*, -LH:*:verbose"); + } + } + /** + * A simple formatting utility for event logging. + * @param {string} prefix + * @param {!Object} data A JSON-serializable object of event data to log. + * @param {string=} level Optional logging level. Defaults to 'log'. + */ + static formatProtocol(prefix, data31, level) { + const columns = !process3 || process3.browser ? Infinity : process3.stdout.columns; + const method = data31.method || "?????"; + const maxLength = columns - method.length - prefix.length - loggingBufferColumns; + const snippet = data31.params && method !== "IO.read" ? JSON.stringify(data31.params).substr(0, maxLength) : ""; + _Log._logToStdErr(`${prefix}:${level || ""}`, [method, snippet]); + } + /** + * @return {boolean} + */ + static isVerbose() { + return level_ === "verbose"; + } + /** + * @param {{msg: string, id: string, args?: any[]}} status + * @param {string} level + */ + static time({ msg, id, args = [] }, level = "log") { + marky.mark(id); + _Log[level]("status", msg, ...args); + } + /** + * @param {{msg: string, id: string, args?: any[]}} status + * @param {string} level + */ + static timeEnd({ msg, id, args = [] }, level = "verbose") { + _Log[level]("statusEnd", msg, ...args); + marky.stop(id); + } + /** + * @param {string} title + * @param {...any} args + */ + static log(title, ...args) { + _Log.events.issueStatus(title, args); + return _Log._logToStdErr(title, args); + } + /** + * @param {string} title + * @param {...any} args + */ + static warn(title, ...args) { + _Log.events.issueWarning(title, args); + return _Log._logToStdErr(`${title}:warn`, args); + } + /** + * @param {string} title + * @param {...any} args + */ + static error(title, ...args) { + return _Log._logToStdErr(`${title}:error`, args); + } + /** + * @param {string} title + * @param {...any} args + */ + static verbose(title, ...args) { + _Log.events.issueStatus(title, args); + return _Log._logToStdErr(`${title}:verbose`, args); + } + /** + * Add surrounding escape sequences to turn a string green when logged. + * @param {string} str + * @return {string} + */ + static greenify(str) { + return `${_Log.green}${str}${_Log.reset}`; + } + /** + * Add surrounding escape sequences to turn a string red when logged. + * @param {string} str + * @return {string} + */ + static redify(str) { + return `${_Log.red}${str}${_Log.reset}`; + } + static get green() { + return "\x1B[32m"; + } + static get red() { + return "\x1B[31m"; + } + static get yellow() { + return "\x1B[33m"; + } + static get purple() { + return "\x1B[95m"; + } + static get reset() { + return "\x1B[0m"; + } + static get bold() { + return "\x1B[1m"; + } + static get dim() { + return "\x1B[2m"; + } + static get tick() { + return isWindows ? "√" : "✓"; + } + static get cross() { + return isWindows ? "×" : "✘"; + } + static get whiteSmallSquare() { + return isWindows ? "·" : "▫"; + } + static get heavyHorizontal() { + return isWindows ? "─" : "━"; + } + static get heavyVertical() { + return isWindows ? "│ " : "┃ "; + } + static get heavyUpAndRight() { + return isWindows ? "└" : "┗"; + } + static get heavyVerticalAndRight() { + return isWindows ? "├" : "┣"; + } + static get heavyDownAndHorizontal() { + return isWindows ? "┬" : "┳"; + } + static get doubleLightHorizontal() { + return "──"; + } + }; + Log.events = new Emitter(); + Log.takeTimeEntries = () => { + const entries = marky.getEntries(); + marky.clear(); + return entries; + }; + Log.getTimeEntries = () => marky.getEntries(); + lighthouse_logger_default = Log; + } +}); + +// node_modules/lodash-es/_freeGlobal.js +var freeGlobal, freeGlobal_default; +var init_freeGlobal = __esm({ + "node_modules/lodash-es/_freeGlobal.js"() { + init_process_global(); + freeGlobal = typeof global == "object" && global && global.Object === Object && global; + freeGlobal_default = freeGlobal; + } +}); + +// node_modules/lodash-es/_root.js +var freeSelf, root, root_default; +var init_root = __esm({ + "node_modules/lodash-es/_root.js"() { + init_process_global(); + init_freeGlobal(); + freeSelf = typeof self == "object" && self && self.Object === Object && self; + root = freeGlobal_default || freeSelf || Function("return this")(); + root_default = root; + } +}); + +// node_modules/lodash-es/_Symbol.js +var Symbol2, Symbol_default; +var init_Symbol = __esm({ + "node_modules/lodash-es/_Symbol.js"() { + init_process_global(); + init_root(); + Symbol2 = root_default.Symbol; + Symbol_default = Symbol2; + } +}); + +// node_modules/lodash-es/_getRawTag.js +function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; + try { + value[symToStringTag] = void 0; + var unmasked = true; + } catch (e) { + } + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; +} +var objectProto, hasOwnProperty, nativeObjectToString, symToStringTag, getRawTag_default; +var init_getRawTag = __esm({ + "node_modules/lodash-es/_getRawTag.js"() { + init_process_global(); + init_Symbol(); + objectProto = Object.prototype; + hasOwnProperty = objectProto.hasOwnProperty; + nativeObjectToString = objectProto.toString; + symToStringTag = Symbol_default ? Symbol_default.toStringTag : void 0; + __name(getRawTag, "getRawTag"); + getRawTag_default = getRawTag; + } +}); + +// node_modules/lodash-es/_objectToString.js +function objectToString(value) { + return nativeObjectToString2.call(value); +} +var objectProto2, nativeObjectToString2, objectToString_default; +var init_objectToString = __esm({ + "node_modules/lodash-es/_objectToString.js"() { + init_process_global(); + objectProto2 = Object.prototype; + nativeObjectToString2 = objectProto2.toString; + __name(objectToString, "objectToString"); + objectToString_default = objectToString; + } +}); + +// node_modules/lodash-es/_baseGetTag.js +function baseGetTag(value) { + if (value == null) { + return value === void 0 ? undefinedTag : nullTag; + } + return symToStringTag2 && symToStringTag2 in Object(value) ? getRawTag_default(value) : objectToString_default(value); +} +var nullTag, undefinedTag, symToStringTag2, baseGetTag_default; +var init_baseGetTag = __esm({ + "node_modules/lodash-es/_baseGetTag.js"() { + init_process_global(); + init_Symbol(); + init_getRawTag(); + init_objectToString(); + nullTag = "[object Null]"; + undefinedTag = "[object Undefined]"; + symToStringTag2 = Symbol_default ? Symbol_default.toStringTag : void 0; + __name(baseGetTag, "baseGetTag"); + baseGetTag_default = baseGetTag; + } +}); + +// node_modules/lodash-es/isObjectLike.js +function isObjectLike(value) { + return value != null && typeof value == "object"; +} +var isObjectLike_default; +var init_isObjectLike = __esm({ + "node_modules/lodash-es/isObjectLike.js"() { + init_process_global(); + __name(isObjectLike, "isObjectLike"); + isObjectLike_default = isObjectLike; + } +}); + +// node_modules/lodash-es/isArray.js +var isArray, isArray_default; +var init_isArray = __esm({ + "node_modules/lodash-es/isArray.js"() { + init_process_global(); + isArray = Array.isArray; + isArray_default = isArray; + } +}); + +// node_modules/lodash-es/isObject.js +function isObject(value) { + var type = typeof value; + return value != null && (type == "object" || type == "function"); +} +var isObject_default; +var init_isObject = __esm({ + "node_modules/lodash-es/isObject.js"() { + init_process_global(); + __name(isObject, "isObject"); + isObject_default = isObject; + } +}); + +// node_modules/lodash-es/isFunction.js +function isFunction(value) { + if (!isObject_default(value)) { + return false; + } + var tag = baseGetTag_default(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; +} +var asyncTag, funcTag, genTag, proxyTag, isFunction_default; +var init_isFunction = __esm({ + "node_modules/lodash-es/isFunction.js"() { + init_process_global(); + init_baseGetTag(); + init_isObject(); + asyncTag = "[object AsyncFunction]"; + funcTag = "[object Function]"; + genTag = "[object GeneratorFunction]"; + proxyTag = "[object Proxy]"; + __name(isFunction, "isFunction"); + isFunction_default = isFunction; + } +}); + +// node_modules/lodash-es/_coreJsData.js +var coreJsData, coreJsData_default; +var init_coreJsData = __esm({ + "node_modules/lodash-es/_coreJsData.js"() { + init_process_global(); + init_root(); + coreJsData = root_default["__core-js_shared__"]; + coreJsData_default = coreJsData; + } +}); + +// node_modules/lodash-es/_isMasked.js +function isMasked(func) { + return !!maskSrcKey && maskSrcKey in func; +} +var maskSrcKey, isMasked_default; +var init_isMasked = __esm({ + "node_modules/lodash-es/_isMasked.js"() { + init_process_global(); + init_coreJsData(); + maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData_default && coreJsData_default.keys && coreJsData_default.keys.IE_PROTO || ""); + return uid ? "Symbol(src)_1." + uid : ""; + })(); + __name(isMasked, "isMasked"); + isMasked_default = isMasked; + } +}); + +// node_modules/lodash-es/_toSource.js +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) { + } + try { + return func + ""; + } catch (e) { + } + } + return ""; +} +var funcProto, funcToString, toSource_default; +var init_toSource = __esm({ + "node_modules/lodash-es/_toSource.js"() { + init_process_global(); + funcProto = Function.prototype; + funcToString = funcProto.toString; + __name(toSource, "toSource"); + toSource_default = toSource; + } +}); + +// node_modules/lodash-es/_baseIsNative.js +function baseIsNative(value) { + if (!isObject_default(value) || isMasked_default(value)) { + return false; + } + var pattern = isFunction_default(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource_default(value)); +} +var reRegExpChar, reIsHostCtor, funcProto2, objectProto3, funcToString2, hasOwnProperty2, reIsNative, baseIsNative_default; +var init_baseIsNative = __esm({ + "node_modules/lodash-es/_baseIsNative.js"() { + init_process_global(); + init_isFunction(); + init_isMasked(); + init_isObject(); + init_toSource(); + reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + reIsHostCtor = /^\[object .+?Constructor\]$/; + funcProto2 = Function.prototype; + objectProto3 = Object.prototype; + funcToString2 = funcProto2.toString; + hasOwnProperty2 = objectProto3.hasOwnProperty; + reIsNative = RegExp( + "^" + funcToString2.call(hasOwnProperty2).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$" + ); + __name(baseIsNative, "baseIsNative"); + baseIsNative_default = baseIsNative; + } +}); + +// node_modules/lodash-es/_getValue.js +function getValue(object, key) { + return object == null ? void 0 : object[key]; +} +var getValue_default; +var init_getValue = __esm({ + "node_modules/lodash-es/_getValue.js"() { + init_process_global(); + __name(getValue, "getValue"); + getValue_default = getValue; + } +}); + +// node_modules/lodash-es/_getNative.js +function getNative(object, key) { + var value = getValue_default(object, key); + return baseIsNative_default(value) ? value : void 0; +} +var getNative_default; +var init_getNative = __esm({ + "node_modules/lodash-es/_getNative.js"() { + init_process_global(); + init_baseIsNative(); + init_getValue(); + __name(getNative, "getNative"); + getNative_default = getNative; + } +}); + +// node_modules/lodash-es/_WeakMap.js +var WeakMap2, WeakMap_default; +var init_WeakMap = __esm({ + "node_modules/lodash-es/_WeakMap.js"() { + init_process_global(); + init_getNative(); + init_root(); + WeakMap2 = getNative_default(root_default, "WeakMap"); + WeakMap_default = WeakMap2; + } +}); + +// node_modules/lodash-es/_isIndex.js +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && (type == "number" || type != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length); +} +var MAX_SAFE_INTEGER, reIsUint, isIndex_default; +var init_isIndex = __esm({ + "node_modules/lodash-es/_isIndex.js"() { + init_process_global(); + MAX_SAFE_INTEGER = 9007199254740991; + reIsUint = /^(?:0|[1-9]\d*)$/; + __name(isIndex, "isIndex"); + isIndex_default = isIndex; + } +}); + +// node_modules/lodash-es/eq.js +function eq(value, other) { + return value === other || value !== value && other !== other; +} +var eq_default; +var init_eq = __esm({ + "node_modules/lodash-es/eq.js"() { + init_process_global(); + __name(eq, "eq"); + eq_default = eq; + } +}); + +// node_modules/lodash-es/isLength.js +function isLength(value) { + return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER2; +} +var MAX_SAFE_INTEGER2, isLength_default; +var init_isLength = __esm({ + "node_modules/lodash-es/isLength.js"() { + init_process_global(); + MAX_SAFE_INTEGER2 = 9007199254740991; + __name(isLength, "isLength"); + isLength_default = isLength; + } +}); + +// node_modules/lodash-es/isArrayLike.js +function isArrayLike(value) { + return value != null && isLength_default(value.length) && !isFunction_default(value); +} +var isArrayLike_default; +var init_isArrayLike = __esm({ + "node_modules/lodash-es/isArrayLike.js"() { + init_process_global(); + init_isFunction(); + init_isLength(); + __name(isArrayLike, "isArrayLike"); + isArrayLike_default = isArrayLike; + } +}); + +// node_modules/lodash-es/_isPrototype.js +function isPrototype(value) { + var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto4; + return value === proto; +} +var objectProto4, isPrototype_default; +var init_isPrototype = __esm({ + "node_modules/lodash-es/_isPrototype.js"() { + init_process_global(); + objectProto4 = Object.prototype; + __name(isPrototype, "isPrototype"); + isPrototype_default = isPrototype; + } +}); + +// node_modules/lodash-es/_baseTimes.js +function baseTimes(n, iteratee) { + var index = -1, result = Array(n); + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} +var baseTimes_default; +var init_baseTimes = __esm({ + "node_modules/lodash-es/_baseTimes.js"() { + init_process_global(); + __name(baseTimes, "baseTimes"); + baseTimes_default = baseTimes; + } +}); + +// node_modules/lodash-es/_baseIsArguments.js +function baseIsArguments(value) { + return isObjectLike_default(value) && baseGetTag_default(value) == argsTag; +} +var argsTag, baseIsArguments_default; +var init_baseIsArguments = __esm({ + "node_modules/lodash-es/_baseIsArguments.js"() { + init_process_global(); + init_baseGetTag(); + init_isObjectLike(); + argsTag = "[object Arguments]"; + __name(baseIsArguments, "baseIsArguments"); + baseIsArguments_default = baseIsArguments; + } +}); + +// node_modules/lodash-es/isArguments.js +var objectProto5, hasOwnProperty3, propertyIsEnumerable, isArguments, isArguments_default; +var init_isArguments = __esm({ + "node_modules/lodash-es/isArguments.js"() { + init_process_global(); + init_baseIsArguments(); + init_isObjectLike(); + objectProto5 = Object.prototype; + hasOwnProperty3 = objectProto5.hasOwnProperty; + propertyIsEnumerable = objectProto5.propertyIsEnumerable; + isArguments = baseIsArguments_default(/* @__PURE__ */ (function() { + return arguments; + })()) ? baseIsArguments_default : function(value) { + return isObjectLike_default(value) && hasOwnProperty3.call(value, "callee") && !propertyIsEnumerable.call(value, "callee"); + }; + isArguments_default = isArguments; + } +}); + +// node_modules/lodash-es/stubFalse.js +function stubFalse() { + return false; +} +var stubFalse_default; +var init_stubFalse = __esm({ + "node_modules/lodash-es/stubFalse.js"() { + init_process_global(); + __name(stubFalse, "stubFalse"); + stubFalse_default = stubFalse; + } +}); + +// node_modules/lodash-es/isBuffer.js +var freeExports, freeModule, moduleExports, Buffer2, nativeIsBuffer, isBuffer, isBuffer_default; +var init_isBuffer = __esm({ + "node_modules/lodash-es/isBuffer.js"() { + init_process_global(); + init_root(); + init_stubFalse(); + freeExports = typeof exports == "object" && exports && !exports.nodeType && exports; + freeModule = freeExports && typeof module == "object" && module && !module.nodeType && module; + moduleExports = freeModule && freeModule.exports === freeExports; + Buffer2 = moduleExports ? root_default.Buffer : void 0; + nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : void 0; + isBuffer = nativeIsBuffer || stubFalse_default; + isBuffer_default = isBuffer; + } +}); + +// node_modules/lodash-es/_baseIsTypedArray.js +function baseIsTypedArray(value) { + return isObjectLike_default(value) && isLength_default(value.length) && !!typedArrayTags[baseGetTag_default(value)]; +} +var argsTag2, arrayTag, boolTag, dateTag, errorTag, funcTag2, mapTag, numberTag, objectTag, regexpTag, setTag, stringTag, weakMapTag, arrayBufferTag, dataViewTag, float32Tag, float64Tag, int8Tag, int16Tag, int32Tag, uint8Tag, uint8ClampedTag, uint16Tag, uint32Tag, typedArrayTags, baseIsTypedArray_default; +var init_baseIsTypedArray = __esm({ + "node_modules/lodash-es/_baseIsTypedArray.js"() { + init_process_global(); + init_baseGetTag(); + init_isLength(); + init_isObjectLike(); + argsTag2 = "[object Arguments]"; + arrayTag = "[object Array]"; + boolTag = "[object Boolean]"; + dateTag = "[object Date]"; + errorTag = "[object Error]"; + funcTag2 = "[object Function]"; + mapTag = "[object Map]"; + numberTag = "[object Number]"; + objectTag = "[object Object]"; + regexpTag = "[object RegExp]"; + setTag = "[object Set]"; + stringTag = "[object String]"; + weakMapTag = "[object WeakMap]"; + arrayBufferTag = "[object ArrayBuffer]"; + dataViewTag = "[object DataView]"; + float32Tag = "[object Float32Array]"; + float64Tag = "[object Float64Array]"; + int8Tag = "[object Int8Array]"; + int16Tag = "[object Int16Array]"; + int32Tag = "[object Int32Array]"; + uint8Tag = "[object Uint8Array]"; + uint8ClampedTag = "[object Uint8ClampedArray]"; + uint16Tag = "[object Uint16Array]"; + uint32Tag = "[object Uint32Array]"; + typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag2] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag2] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + __name(baseIsTypedArray, "baseIsTypedArray"); + baseIsTypedArray_default = baseIsTypedArray; + } +}); + +// node_modules/lodash-es/_baseUnary.js +function baseUnary(func) { + return function(value) { + return func(value); + }; +} +var baseUnary_default; +var init_baseUnary = __esm({ + "node_modules/lodash-es/_baseUnary.js"() { + init_process_global(); + __name(baseUnary, "baseUnary"); + baseUnary_default = baseUnary; + } +}); + +// node_modules/lodash-es/_nodeUtil.js +var freeExports2, freeModule2, moduleExports2, freeProcess, nodeUtil, nodeUtil_default; +var init_nodeUtil = __esm({ + "node_modules/lodash-es/_nodeUtil.js"() { + init_process_global(); + init_freeGlobal(); + freeExports2 = typeof exports == "object" && exports && !exports.nodeType && exports; + freeModule2 = freeExports2 && typeof module == "object" && module && !module.nodeType && module; + moduleExports2 = freeModule2 && freeModule2.exports === freeExports2; + freeProcess = moduleExports2 && freeGlobal_default.process; + nodeUtil = (function() { + try { + var types = freeModule2 && freeModule2.require && freeModule2.require("util").types; + if (types) { + return types; + } + return freeProcess && freeProcess.binding && freeProcess.binding("util"); + } catch (e) { + } + })(); + nodeUtil_default = nodeUtil; + } +}); + +// node_modules/lodash-es/isTypedArray.js +var nodeIsTypedArray, isTypedArray, isTypedArray_default; +var init_isTypedArray = __esm({ + "node_modules/lodash-es/isTypedArray.js"() { + init_process_global(); + init_baseIsTypedArray(); + init_baseUnary(); + init_nodeUtil(); + nodeIsTypedArray = nodeUtil_default && nodeUtil_default.isTypedArray; + isTypedArray = nodeIsTypedArray ? baseUnary_default(nodeIsTypedArray) : baseIsTypedArray_default; + isTypedArray_default = isTypedArray; + } +}); + +// node_modules/lodash-es/_arrayLikeKeys.js +function arrayLikeKeys(value, inherited) { + var isArr = isArray_default(value), isArg = !isArr && isArguments_default(value), isBuff = !isArr && !isArg && isBuffer_default(value), isType = !isArr && !isArg && !isBuff && isTypedArray_default(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes_default(value.length, String) : [], length = result.length; + for (var key in value) { + if ((inherited || hasOwnProperty4.call(value, key)) && !(skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode. + (key == "length" || // Node.js 0.10 has enumerable non-index properties on buffers. + isBuff && (key == "offset" || key == "parent") || // PhantomJS 2 has enumerable non-index properties on typed arrays. + isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || // Skip index properties. + isIndex_default(key, length)))) { + result.push(key); + } + } + return result; +} +var objectProto6, hasOwnProperty4, arrayLikeKeys_default; +var init_arrayLikeKeys = __esm({ + "node_modules/lodash-es/_arrayLikeKeys.js"() { + init_process_global(); + init_baseTimes(); + init_isArguments(); + init_isArray(); + init_isBuffer(); + init_isIndex(); + init_isTypedArray(); + objectProto6 = Object.prototype; + hasOwnProperty4 = objectProto6.hasOwnProperty; + __name(arrayLikeKeys, "arrayLikeKeys"); + arrayLikeKeys_default = arrayLikeKeys; + } +}); + +// node_modules/lodash-es/_overArg.js +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} +var overArg_default; +var init_overArg = __esm({ + "node_modules/lodash-es/_overArg.js"() { + init_process_global(); + __name(overArg, "overArg"); + overArg_default = overArg; + } +}); + +// node_modules/lodash-es/_nativeKeys.js +var nativeKeys, nativeKeys_default; +var init_nativeKeys = __esm({ + "node_modules/lodash-es/_nativeKeys.js"() { + init_process_global(); + init_overArg(); + nativeKeys = overArg_default(Object.keys, Object); + nativeKeys_default = nativeKeys; + } +}); + +// node_modules/lodash-es/_baseKeys.js +function baseKeys(object) { + if (!isPrototype_default(object)) { + return nativeKeys_default(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty5.call(object, key) && key != "constructor") { + result.push(key); + } + } + return result; +} +var objectProto7, hasOwnProperty5, baseKeys_default; +var init_baseKeys = __esm({ + "node_modules/lodash-es/_baseKeys.js"() { + init_process_global(); + init_isPrototype(); + init_nativeKeys(); + objectProto7 = Object.prototype; + hasOwnProperty5 = objectProto7.hasOwnProperty; + __name(baseKeys, "baseKeys"); + baseKeys_default = baseKeys; + } +}); + +// node_modules/lodash-es/keys.js +function keys(object) { + return isArrayLike_default(object) ? arrayLikeKeys_default(object) : baseKeys_default(object); +} +var keys_default; +var init_keys = __esm({ + "node_modules/lodash-es/keys.js"() { + init_process_global(); + init_arrayLikeKeys(); + init_baseKeys(); + init_isArrayLike(); + __name(keys, "keys"); + keys_default = keys; + } +}); + +// node_modules/lodash-es/_nativeCreate.js +var nativeCreate, nativeCreate_default; +var init_nativeCreate = __esm({ + "node_modules/lodash-es/_nativeCreate.js"() { + init_process_global(); + init_getNative(); + nativeCreate = getNative_default(Object, "create"); + nativeCreate_default = nativeCreate; + } +}); + +// node_modules/lodash-es/_hashClear.js +function hashClear() { + this.__data__ = nativeCreate_default ? nativeCreate_default(null) : {}; + this.size = 0; +} +var hashClear_default; +var init_hashClear = __esm({ + "node_modules/lodash-es/_hashClear.js"() { + init_process_global(); + init_nativeCreate(); + __name(hashClear, "hashClear"); + hashClear_default = hashClear; + } +}); + +// node_modules/lodash-es/_hashDelete.js +function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; +} +var hashDelete_default; +var init_hashDelete = __esm({ + "node_modules/lodash-es/_hashDelete.js"() { + init_process_global(); + __name(hashDelete, "hashDelete"); + hashDelete_default = hashDelete; + } +}); + +// node_modules/lodash-es/_hashGet.js +function hashGet(key) { + var data31 = this.__data__; + if (nativeCreate_default) { + var result = data31[key]; + return result === HASH_UNDEFINED ? void 0 : result; + } + return hasOwnProperty6.call(data31, key) ? data31[key] : void 0; +} +var HASH_UNDEFINED, objectProto8, hasOwnProperty6, hashGet_default; +var init_hashGet = __esm({ + "node_modules/lodash-es/_hashGet.js"() { + init_process_global(); + init_nativeCreate(); + HASH_UNDEFINED = "__lodash_hash_undefined__"; + objectProto8 = Object.prototype; + hasOwnProperty6 = objectProto8.hasOwnProperty; + __name(hashGet, "hashGet"); + hashGet_default = hashGet; + } +}); + +// node_modules/lodash-es/_hashHas.js +function hashHas(key) { + var data31 = this.__data__; + return nativeCreate_default ? data31[key] !== void 0 : hasOwnProperty7.call(data31, key); +} +var objectProto9, hasOwnProperty7, hashHas_default; +var init_hashHas = __esm({ + "node_modules/lodash-es/_hashHas.js"() { + init_process_global(); + init_nativeCreate(); + objectProto9 = Object.prototype; + hasOwnProperty7 = objectProto9.hasOwnProperty; + __name(hashHas, "hashHas"); + hashHas_default = hashHas; + } +}); + +// node_modules/lodash-es/_hashSet.js +function hashSet(key, value) { + var data31 = this.__data__; + this.size += this.has(key) ? 0 : 1; + data31[key] = nativeCreate_default && value === void 0 ? HASH_UNDEFINED2 : value; + return this; +} +var HASH_UNDEFINED2, hashSet_default; +var init_hashSet = __esm({ + "node_modules/lodash-es/_hashSet.js"() { + init_process_global(); + init_nativeCreate(); + HASH_UNDEFINED2 = "__lodash_hash_undefined__"; + __name(hashSet, "hashSet"); + hashSet_default = hashSet; + } +}); + +// node_modules/lodash-es/_Hash.js +function Hash(entries) { + var index = -1, length = entries == null ? 0 : entries.length; + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} +var Hash_default; +var init_Hash = __esm({ + "node_modules/lodash-es/_Hash.js"() { + init_process_global(); + init_hashClear(); + init_hashDelete(); + init_hashGet(); + init_hashHas(); + init_hashSet(); + __name(Hash, "Hash"); + Hash.prototype.clear = hashClear_default; + Hash.prototype["delete"] = hashDelete_default; + Hash.prototype.get = hashGet_default; + Hash.prototype.has = hashHas_default; + Hash.prototype.set = hashSet_default; + Hash_default = Hash; + } +}); + +// node_modules/lodash-es/_listCacheClear.js +function listCacheClear() { + this.__data__ = []; + this.size = 0; +} +var listCacheClear_default; +var init_listCacheClear = __esm({ + "node_modules/lodash-es/_listCacheClear.js"() { + init_process_global(); + __name(listCacheClear, "listCacheClear"); + listCacheClear_default = listCacheClear; + } +}); + +// node_modules/lodash-es/_assocIndexOf.js +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq_default(array[length][0], key)) { + return length; + } + } + return -1; +} +var assocIndexOf_default; +var init_assocIndexOf = __esm({ + "node_modules/lodash-es/_assocIndexOf.js"() { + init_process_global(); + init_eq(); + __name(assocIndexOf, "assocIndexOf"); + assocIndexOf_default = assocIndexOf; + } +}); + +// node_modules/lodash-es/_listCacheDelete.js +function listCacheDelete(key) { + var data31 = this.__data__, index = assocIndexOf_default(data31, key); + if (index < 0) { + return false; + } + var lastIndex = data31.length - 1; + if (index == lastIndex) { + data31.pop(); + } else { + splice.call(data31, index, 1); + } + --this.size; + return true; +} +var arrayProto, splice, listCacheDelete_default; +var init_listCacheDelete = __esm({ + "node_modules/lodash-es/_listCacheDelete.js"() { + init_process_global(); + init_assocIndexOf(); + arrayProto = Array.prototype; + splice = arrayProto.splice; + __name(listCacheDelete, "listCacheDelete"); + listCacheDelete_default = listCacheDelete; + } +}); + +// node_modules/lodash-es/_listCacheGet.js +function listCacheGet(key) { + var data31 = this.__data__, index = assocIndexOf_default(data31, key); + return index < 0 ? void 0 : data31[index][1]; +} +var listCacheGet_default; +var init_listCacheGet = __esm({ + "node_modules/lodash-es/_listCacheGet.js"() { + init_process_global(); + init_assocIndexOf(); + __name(listCacheGet, "listCacheGet"); + listCacheGet_default = listCacheGet; + } +}); + +// node_modules/lodash-es/_listCacheHas.js +function listCacheHas(key) { + return assocIndexOf_default(this.__data__, key) > -1; +} +var listCacheHas_default; +var init_listCacheHas = __esm({ + "node_modules/lodash-es/_listCacheHas.js"() { + init_process_global(); + init_assocIndexOf(); + __name(listCacheHas, "listCacheHas"); + listCacheHas_default = listCacheHas; + } +}); + +// node_modules/lodash-es/_listCacheSet.js +function listCacheSet(key, value) { + var data31 = this.__data__, index = assocIndexOf_default(data31, key); + if (index < 0) { + ++this.size; + data31.push([key, value]); + } else { + data31[index][1] = value; + } + return this; +} +var listCacheSet_default; +var init_listCacheSet = __esm({ + "node_modules/lodash-es/_listCacheSet.js"() { + init_process_global(); + init_assocIndexOf(); + __name(listCacheSet, "listCacheSet"); + listCacheSet_default = listCacheSet; + } +}); + +// node_modules/lodash-es/_ListCache.js +function ListCache(entries) { + var index = -1, length = entries == null ? 0 : entries.length; + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} +var ListCache_default; +var init_ListCache = __esm({ + "node_modules/lodash-es/_ListCache.js"() { + init_process_global(); + init_listCacheClear(); + init_listCacheDelete(); + init_listCacheGet(); + init_listCacheHas(); + init_listCacheSet(); + __name(ListCache, "ListCache"); + ListCache.prototype.clear = listCacheClear_default; + ListCache.prototype["delete"] = listCacheDelete_default; + ListCache.prototype.get = listCacheGet_default; + ListCache.prototype.has = listCacheHas_default; + ListCache.prototype.set = listCacheSet_default; + ListCache_default = ListCache; + } +}); + +// node_modules/lodash-es/_Map.js +var Map2, Map_default; +var init_Map = __esm({ + "node_modules/lodash-es/_Map.js"() { + init_process_global(); + init_getNative(); + init_root(); + Map2 = getNative_default(root_default, "Map"); + Map_default = Map2; + } +}); + +// node_modules/lodash-es/_mapCacheClear.js +function mapCacheClear() { + this.size = 0; + this.__data__ = { + "hash": new Hash_default(), + "map": new (Map_default || ListCache_default)(), + "string": new Hash_default() + }; +} +var mapCacheClear_default; +var init_mapCacheClear = __esm({ + "node_modules/lodash-es/_mapCacheClear.js"() { + init_process_global(); + init_Hash(); + init_ListCache(); + init_Map(); + __name(mapCacheClear, "mapCacheClear"); + mapCacheClear_default = mapCacheClear; + } +}); + +// node_modules/lodash-es/_isKeyable.js +function isKeyable(value) { + var type = typeof value; + return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null; +} +var isKeyable_default; +var init_isKeyable = __esm({ + "node_modules/lodash-es/_isKeyable.js"() { + init_process_global(); + __name(isKeyable, "isKeyable"); + isKeyable_default = isKeyable; + } +}); + +// node_modules/lodash-es/_getMapData.js +function getMapData(map, key) { + var data31 = map.__data__; + return isKeyable_default(key) ? data31[typeof key == "string" ? "string" : "hash"] : data31.map; +} +var getMapData_default; +var init_getMapData = __esm({ + "node_modules/lodash-es/_getMapData.js"() { + init_process_global(); + init_isKeyable(); + __name(getMapData, "getMapData"); + getMapData_default = getMapData; + } +}); + +// node_modules/lodash-es/_mapCacheDelete.js +function mapCacheDelete(key) { + var result = getMapData_default(this, key)["delete"](key); + this.size -= result ? 1 : 0; + return result; +} +var mapCacheDelete_default; +var init_mapCacheDelete = __esm({ + "node_modules/lodash-es/_mapCacheDelete.js"() { + init_process_global(); + init_getMapData(); + __name(mapCacheDelete, "mapCacheDelete"); + mapCacheDelete_default = mapCacheDelete; + } +}); + +// node_modules/lodash-es/_mapCacheGet.js +function mapCacheGet(key) { + return getMapData_default(this, key).get(key); +} +var mapCacheGet_default; +var init_mapCacheGet = __esm({ + "node_modules/lodash-es/_mapCacheGet.js"() { + init_process_global(); + init_getMapData(); + __name(mapCacheGet, "mapCacheGet"); + mapCacheGet_default = mapCacheGet; + } +}); + +// node_modules/lodash-es/_mapCacheHas.js +function mapCacheHas(key) { + return getMapData_default(this, key).has(key); +} +var mapCacheHas_default; +var init_mapCacheHas = __esm({ + "node_modules/lodash-es/_mapCacheHas.js"() { + init_process_global(); + init_getMapData(); + __name(mapCacheHas, "mapCacheHas"); + mapCacheHas_default = mapCacheHas; + } +}); + +// node_modules/lodash-es/_mapCacheSet.js +function mapCacheSet(key, value) { + var data31 = getMapData_default(this, key), size = data31.size; + data31.set(key, value); + this.size += data31.size == size ? 0 : 1; + return this; +} +var mapCacheSet_default; +var init_mapCacheSet = __esm({ + "node_modules/lodash-es/_mapCacheSet.js"() { + init_process_global(); + init_getMapData(); + __name(mapCacheSet, "mapCacheSet"); + mapCacheSet_default = mapCacheSet; + } +}); + +// node_modules/lodash-es/_MapCache.js +function MapCache(entries) { + var index = -1, length = entries == null ? 0 : entries.length; + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} +var MapCache_default; +var init_MapCache = __esm({ + "node_modules/lodash-es/_MapCache.js"() { + init_process_global(); + init_mapCacheClear(); + init_mapCacheDelete(); + init_mapCacheGet(); + init_mapCacheHas(); + init_mapCacheSet(); + __name(MapCache, "MapCache"); + MapCache.prototype.clear = mapCacheClear_default; + MapCache.prototype["delete"] = mapCacheDelete_default; + MapCache.prototype.get = mapCacheGet_default; + MapCache.prototype.has = mapCacheHas_default; + MapCache.prototype.set = mapCacheSet_default; + MapCache_default = MapCache; + } +}); + +// node_modules/lodash-es/_arrayPush.js +function arrayPush(array, values) { + var index = -1, length = values.length, offset = array.length; + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} +var arrayPush_default; +var init_arrayPush = __esm({ + "node_modules/lodash-es/_arrayPush.js"() { + init_process_global(); + __name(arrayPush, "arrayPush"); + arrayPush_default = arrayPush; + } +}); + +// node_modules/lodash-es/_stackClear.js +function stackClear() { + this.__data__ = new ListCache_default(); + this.size = 0; +} +var stackClear_default; +var init_stackClear = __esm({ + "node_modules/lodash-es/_stackClear.js"() { + init_process_global(); + init_ListCache(); + __name(stackClear, "stackClear"); + stackClear_default = stackClear; + } +}); + +// node_modules/lodash-es/_stackDelete.js +function stackDelete(key) { + var data31 = this.__data__, result = data31["delete"](key); + this.size = data31.size; + return result; +} +var stackDelete_default; +var init_stackDelete = __esm({ + "node_modules/lodash-es/_stackDelete.js"() { + init_process_global(); + __name(stackDelete, "stackDelete"); + stackDelete_default = stackDelete; + } +}); + +// node_modules/lodash-es/_stackGet.js +function stackGet(key) { + return this.__data__.get(key); +} +var stackGet_default; +var init_stackGet = __esm({ + "node_modules/lodash-es/_stackGet.js"() { + init_process_global(); + __name(stackGet, "stackGet"); + stackGet_default = stackGet; + } +}); + +// node_modules/lodash-es/_stackHas.js +function stackHas(key) { + return this.__data__.has(key); +} +var stackHas_default; +var init_stackHas = __esm({ + "node_modules/lodash-es/_stackHas.js"() { + init_process_global(); + __name(stackHas, "stackHas"); + stackHas_default = stackHas; + } +}); + +// node_modules/lodash-es/_stackSet.js +function stackSet(key, value) { + var data31 = this.__data__; + if (data31 instanceof ListCache_default) { + var pairs = data31.__data__; + if (!Map_default || pairs.length < LARGE_ARRAY_SIZE - 1) { + pairs.push([key, value]); + this.size = ++data31.size; + return this; + } + data31 = this.__data__ = new MapCache_default(pairs); + } + data31.set(key, value); + this.size = data31.size; + return this; +} +var LARGE_ARRAY_SIZE, stackSet_default; +var init_stackSet = __esm({ + "node_modules/lodash-es/_stackSet.js"() { + init_process_global(); + init_ListCache(); + init_Map(); + init_MapCache(); + LARGE_ARRAY_SIZE = 200; + __name(stackSet, "stackSet"); + stackSet_default = stackSet; + } +}); + +// node_modules/lodash-es/_Stack.js +function Stack(entries) { + var data31 = this.__data__ = new ListCache_default(entries); + this.size = data31.size; +} +var Stack_default; +var init_Stack = __esm({ + "node_modules/lodash-es/_Stack.js"() { + init_process_global(); + init_ListCache(); + init_stackClear(); + init_stackDelete(); + init_stackGet(); + init_stackHas(); + init_stackSet(); + __name(Stack, "Stack"); + Stack.prototype.clear = stackClear_default; + Stack.prototype["delete"] = stackDelete_default; + Stack.prototype.get = stackGet_default; + Stack.prototype.has = stackHas_default; + Stack.prototype.set = stackSet_default; + Stack_default = Stack; + } +}); + +// node_modules/lodash-es/_arrayFilter.js +function arrayFilter(array, predicate) { + var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} +var arrayFilter_default; +var init_arrayFilter = __esm({ + "node_modules/lodash-es/_arrayFilter.js"() { + init_process_global(); + __name(arrayFilter, "arrayFilter"); + arrayFilter_default = arrayFilter; + } +}); + +// node_modules/lodash-es/stubArray.js +function stubArray() { + return []; +} +var stubArray_default; +var init_stubArray = __esm({ + "node_modules/lodash-es/stubArray.js"() { + init_process_global(); + __name(stubArray, "stubArray"); + stubArray_default = stubArray; + } +}); + +// node_modules/lodash-es/_getSymbols.js +var objectProto10, propertyIsEnumerable2, nativeGetSymbols, getSymbols, getSymbols_default; +var init_getSymbols = __esm({ + "node_modules/lodash-es/_getSymbols.js"() { + init_process_global(); + init_arrayFilter(); + init_stubArray(); + objectProto10 = Object.prototype; + propertyIsEnumerable2 = objectProto10.propertyIsEnumerable; + nativeGetSymbols = Object.getOwnPropertySymbols; + getSymbols = !nativeGetSymbols ? stubArray_default : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter_default(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable2.call(object, symbol); + }); + }; + getSymbols_default = getSymbols; + } +}); + +// node_modules/lodash-es/_baseGetAllKeys.js +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray_default(object) ? result : arrayPush_default(result, symbolsFunc(object)); +} +var baseGetAllKeys_default; +var init_baseGetAllKeys = __esm({ + "node_modules/lodash-es/_baseGetAllKeys.js"() { + init_process_global(); + init_arrayPush(); + init_isArray(); + __name(baseGetAllKeys, "baseGetAllKeys"); + baseGetAllKeys_default = baseGetAllKeys; + } +}); + +// node_modules/lodash-es/_getAllKeys.js +function getAllKeys(object) { + return baseGetAllKeys_default(object, keys_default, getSymbols_default); +} +var getAllKeys_default; +var init_getAllKeys = __esm({ + "node_modules/lodash-es/_getAllKeys.js"() { + init_process_global(); + init_baseGetAllKeys(); + init_getSymbols(); + init_keys(); + __name(getAllKeys, "getAllKeys"); + getAllKeys_default = getAllKeys; + } +}); + +// node_modules/lodash-es/_DataView.js +var DataView, DataView_default; +var init_DataView = __esm({ + "node_modules/lodash-es/_DataView.js"() { + init_process_global(); + init_getNative(); + init_root(); + DataView = getNative_default(root_default, "DataView"); + DataView_default = DataView; + } +}); + +// node_modules/lodash-es/_Promise.js +var Promise2, Promise_default; +var init_Promise = __esm({ + "node_modules/lodash-es/_Promise.js"() { + init_process_global(); + init_getNative(); + init_root(); + Promise2 = getNative_default(root_default, "Promise"); + Promise_default = Promise2; + } +}); + +// node_modules/lodash-es/_Set.js +var Set2, Set_default; +var init_Set = __esm({ + "node_modules/lodash-es/_Set.js"() { + init_process_global(); + init_getNative(); + init_root(); + Set2 = getNative_default(root_default, "Set"); + Set_default = Set2; + } +}); + +// node_modules/lodash-es/_getTag.js +var mapTag2, objectTag2, promiseTag, setTag2, weakMapTag2, dataViewTag2, dataViewCtorString, mapCtorString, promiseCtorString, setCtorString, weakMapCtorString, getTag, getTag_default; +var init_getTag = __esm({ + "node_modules/lodash-es/_getTag.js"() { + init_process_global(); + init_DataView(); + init_Map(); + init_Promise(); + init_Set(); + init_WeakMap(); + init_baseGetTag(); + init_toSource(); + mapTag2 = "[object Map]"; + objectTag2 = "[object Object]"; + promiseTag = "[object Promise]"; + setTag2 = "[object Set]"; + weakMapTag2 = "[object WeakMap]"; + dataViewTag2 = "[object DataView]"; + dataViewCtorString = toSource_default(DataView_default); + mapCtorString = toSource_default(Map_default); + promiseCtorString = toSource_default(Promise_default); + setCtorString = toSource_default(Set_default); + weakMapCtorString = toSource_default(WeakMap_default); + getTag = baseGetTag_default; + if (DataView_default && getTag(new DataView_default(new ArrayBuffer(1))) != dataViewTag2 || Map_default && getTag(new Map_default()) != mapTag2 || Promise_default && getTag(Promise_default.resolve()) != promiseTag || Set_default && getTag(new Set_default()) != setTag2 || WeakMap_default && getTag(new WeakMap_default()) != weakMapTag2) { + getTag = /* @__PURE__ */ __name(function(value) { + var result = baseGetTag_default(value), Ctor = result == objectTag2 ? value.constructor : void 0, ctorString = Ctor ? toSource_default(Ctor) : ""; + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: + return dataViewTag2; + case mapCtorString: + return mapTag2; + case promiseCtorString: + return promiseTag; + case setCtorString: + return setTag2; + case weakMapCtorString: + return weakMapTag2; + } + } + return result; + }, "getTag"); + } + getTag_default = getTag; + } +}); + +// node_modules/lodash-es/_Uint8Array.js +var Uint8Array2, Uint8Array_default; +var init_Uint8Array = __esm({ + "node_modules/lodash-es/_Uint8Array.js"() { + init_process_global(); + init_root(); + Uint8Array2 = root_default.Uint8Array; + Uint8Array_default = Uint8Array2; + } +}); + +// node_modules/lodash-es/_setCacheAdd.js +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED3); + return this; +} +var HASH_UNDEFINED3, setCacheAdd_default; +var init_setCacheAdd = __esm({ + "node_modules/lodash-es/_setCacheAdd.js"() { + init_process_global(); + HASH_UNDEFINED3 = "__lodash_hash_undefined__"; + __name(setCacheAdd, "setCacheAdd"); + setCacheAdd_default = setCacheAdd; + } +}); + +// node_modules/lodash-es/_setCacheHas.js +function setCacheHas(value) { + return this.__data__.has(value); +} +var setCacheHas_default; +var init_setCacheHas = __esm({ + "node_modules/lodash-es/_setCacheHas.js"() { + init_process_global(); + __name(setCacheHas, "setCacheHas"); + setCacheHas_default = setCacheHas; + } +}); + +// node_modules/lodash-es/_SetCache.js +function SetCache(values) { + var index = -1, length = values == null ? 0 : values.length; + this.__data__ = new MapCache_default(); + while (++index < length) { + this.add(values[index]); + } +} +var SetCache_default; +var init_SetCache = __esm({ + "node_modules/lodash-es/_SetCache.js"() { + init_process_global(); + init_MapCache(); + init_setCacheAdd(); + init_setCacheHas(); + __name(SetCache, "SetCache"); + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd_default; + SetCache.prototype.has = setCacheHas_default; + SetCache_default = SetCache; + } +}); + +// node_modules/lodash-es/_arraySome.js +function arraySome(array, predicate) { + var index = -1, length = array == null ? 0 : array.length; + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} +var arraySome_default; +var init_arraySome = __esm({ + "node_modules/lodash-es/_arraySome.js"() { + init_process_global(); + __name(arraySome, "arraySome"); + arraySome_default = arraySome; + } +}); + +// node_modules/lodash-es/_cacheHas.js +function cacheHas(cache, key) { + return cache.has(key); +} +var cacheHas_default; +var init_cacheHas = __esm({ + "node_modules/lodash-es/_cacheHas.js"() { + init_process_global(); + __name(cacheHas, "cacheHas"); + cacheHas_default = cacheHas; + } +}); + +// node_modules/lodash-es/_equalArrays.js +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array.length, othLength = other.length; + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, result = true, seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache_default() : void 0; + stack.set(array, other); + stack.set(other, array); + while (++index < arrLength) { + var arrValue = array[index], othValue = other[index]; + if (customizer) { + var compared = isPartial ? customizer(othValue, arrValue, index, other, array, stack) : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== void 0) { + if (compared) { + continue; + } + result = false; + break; + } + if (seen) { + if (!arraySome_default(other, function(othValue2, othIndex) { + if (!cacheHas_default(seen, othIndex) && (arrValue === othValue2 || equalFunc(arrValue, othValue2, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + result = false; + break; + } + } + stack["delete"](array); + stack["delete"](other); + return result; +} +var COMPARE_PARTIAL_FLAG, COMPARE_UNORDERED_FLAG, equalArrays_default; +var init_equalArrays = __esm({ + "node_modules/lodash-es/_equalArrays.js"() { + init_process_global(); + init_SetCache(); + init_arraySome(); + init_cacheHas(); + COMPARE_PARTIAL_FLAG = 1; + COMPARE_UNORDERED_FLAG = 2; + __name(equalArrays, "equalArrays"); + equalArrays_default = equalArrays; + } +}); + +// node_modules/lodash-es/_mapToArray.js +function mapToArray(map) { + var index = -1, result = Array(map.size); + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} +var mapToArray_default; +var init_mapToArray = __esm({ + "node_modules/lodash-es/_mapToArray.js"() { + init_process_global(); + __name(mapToArray, "mapToArray"); + mapToArray_default = mapToArray; + } +}); + +// node_modules/lodash-es/_setToArray.js +function setToArray(set) { + var index = -1, result = Array(set.size); + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} +var setToArray_default; +var init_setToArray = __esm({ + "node_modules/lodash-es/_setToArray.js"() { + init_process_global(); + __name(setToArray, "setToArray"); + setToArray_default = setToArray; + } +}); + +// node_modules/lodash-es/_equalByTag.js +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag3: + if (object.byteLength != other.byteLength || object.byteOffset != other.byteOffset) { + return false; + } + object = object.buffer; + other = other.buffer; + case arrayBufferTag2: + if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array_default(object), new Uint8Array_default(other))) { + return false; + } + return true; + case boolTag2: + case dateTag2: + case numberTag2: + return eq_default(+object, +other); + case errorTag2: + return object.name == other.name && object.message == other.message; + case regexpTag2: + case stringTag2: + return object == other + ""; + case mapTag3: + var convert = mapToArray_default; + case setTag3: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG2; + convert || (convert = setToArray_default); + if (object.size != other.size && !isPartial) { + return false; + } + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG2; + stack.set(object, other); + var result = equalArrays_default(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack["delete"](object); + return result; + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} +var COMPARE_PARTIAL_FLAG2, COMPARE_UNORDERED_FLAG2, boolTag2, dateTag2, errorTag2, mapTag3, numberTag2, regexpTag2, setTag3, stringTag2, symbolTag, arrayBufferTag2, dataViewTag3, symbolProto, symbolValueOf, equalByTag_default; +var init_equalByTag = __esm({ + "node_modules/lodash-es/_equalByTag.js"() { + init_process_global(); + init_Symbol(); + init_Uint8Array(); + init_eq(); + init_equalArrays(); + init_mapToArray(); + init_setToArray(); + COMPARE_PARTIAL_FLAG2 = 1; + COMPARE_UNORDERED_FLAG2 = 2; + boolTag2 = "[object Boolean]"; + dateTag2 = "[object Date]"; + errorTag2 = "[object Error]"; + mapTag3 = "[object Map]"; + numberTag2 = "[object Number]"; + regexpTag2 = "[object RegExp]"; + setTag3 = "[object Set]"; + stringTag2 = "[object String]"; + symbolTag = "[object Symbol]"; + arrayBufferTag2 = "[object ArrayBuffer]"; + dataViewTag3 = "[object DataView]"; + symbolProto = Symbol_default ? Symbol_default.prototype : void 0; + symbolValueOf = symbolProto ? symbolProto.valueOf : void 0; + __name(equalByTag, "equalByTag"); + equalByTag_default = equalByTag; + } +}); + +// node_modules/lodash-es/_equalObjects.js +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG3, objProps = getAllKeys_default(object), objLength = objProps.length, othProps = getAllKeys_default(other), othLength = othProps.length; + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty8.call(other, key))) { + return false; + } + } + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], othValue = other[key]; + if (customizer) { + var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); + } + if (!(compared === void 0 ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack) : compared)) { + result = false; + break; + } + skipCtor || (skipCtor = key == "constructor"); + } + if (result && !skipCtor) { + var objCtor = object.constructor, othCtor = other.constructor; + if (objCtor != othCtor && ("constructor" in object && "constructor" in other) && !(typeof objCtor == "function" && objCtor instanceof objCtor && typeof othCtor == "function" && othCtor instanceof othCtor)) { + result = false; + } + } + stack["delete"](object); + stack["delete"](other); + return result; +} +var COMPARE_PARTIAL_FLAG3, objectProto11, hasOwnProperty8, equalObjects_default; +var init_equalObjects = __esm({ + "node_modules/lodash-es/_equalObjects.js"() { + init_process_global(); + init_getAllKeys(); + COMPARE_PARTIAL_FLAG3 = 1; + objectProto11 = Object.prototype; + hasOwnProperty8 = objectProto11.hasOwnProperty; + __name(equalObjects, "equalObjects"); + equalObjects_default = equalObjects; + } +}); + +// node_modules/lodash-es/_baseIsEqualDeep.js +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray_default(object), othIsArr = isArray_default(other), objTag = objIsArr ? arrayTag2 : getTag_default(object), othTag = othIsArr ? arrayTag2 : getTag_default(other); + objTag = objTag == argsTag3 ? objectTag3 : objTag; + othTag = othTag == argsTag3 ? objectTag3 : othTag; + var objIsObj = objTag == objectTag3, othIsObj = othTag == objectTag3, isSameTag = objTag == othTag; + if (isSameTag && isBuffer_default(object)) { + if (!isBuffer_default(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack_default()); + return objIsArr || isTypedArray_default(object) ? equalArrays_default(object, other, bitmask, customizer, equalFunc, stack) : equalByTag_default(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG4)) { + var objIsWrapped = objIsObj && hasOwnProperty9.call(object, "__wrapped__"), othIsWrapped = othIsObj && hasOwnProperty9.call(other, "__wrapped__"); + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, othUnwrapped = othIsWrapped ? other.value() : other; + stack || (stack = new Stack_default()); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack_default()); + return equalObjects_default(object, other, bitmask, customizer, equalFunc, stack); +} +var COMPARE_PARTIAL_FLAG4, argsTag3, arrayTag2, objectTag3, objectProto12, hasOwnProperty9, baseIsEqualDeep_default; +var init_baseIsEqualDeep = __esm({ + "node_modules/lodash-es/_baseIsEqualDeep.js"() { + init_process_global(); + init_Stack(); + init_equalArrays(); + init_equalByTag(); + init_equalObjects(); + init_getTag(); + init_isArray(); + init_isBuffer(); + init_isTypedArray(); + COMPARE_PARTIAL_FLAG4 = 1; + argsTag3 = "[object Arguments]"; + arrayTag2 = "[object Array]"; + objectTag3 = "[object Object]"; + objectProto12 = Object.prototype; + hasOwnProperty9 = objectProto12.hasOwnProperty; + __name(baseIsEqualDeep, "baseIsEqualDeep"); + baseIsEqualDeep_default = baseIsEqualDeep; + } +}); + +// node_modules/lodash-es/_baseIsEqual.js +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || !isObjectLike_default(value) && !isObjectLike_default(other)) { + return value !== value && other !== other; + } + return baseIsEqualDeep_default(value, other, bitmask, customizer, baseIsEqual, stack); +} +var baseIsEqual_default; +var init_baseIsEqual = __esm({ + "node_modules/lodash-es/_baseIsEqual.js"() { + init_process_global(); + init_baseIsEqualDeep(); + init_isObjectLike(); + __name(baseIsEqual, "baseIsEqual"); + baseIsEqual_default = baseIsEqual; + } +}); + +// node_modules/lodash-es/isEqual.js +function isEqual(value, other) { + return baseIsEqual_default(value, other); +} +var isEqual_default; +var init_isEqual = __esm({ + "node_modules/lodash-es/isEqual.js"() { + init_process_global(); + init_baseIsEqual(); + __name(isEqual, "isEqual"); + isEqual_default = isEqual; + } +}); + +// node_modules/lodash-es/lodash.js +var init_lodash = __esm({ + "node_modules/lodash-es/lodash.js"() { + init_process_global(); + init_isEqual(); + /** + * @license + * Lodash (Custom Build) + * Build: `lodash modularize exports="es" -o ./` + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + } +}); + +// core/lib/lh-env.js +import process4 from "process"; +var isUnderTest; +var init_lh_env = __esm({ + "core/lib/lh-env.js"() { + "use strict"; + init_process_global(); + /** + * @license + * Copyright 2020 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + isUnderTest = !!process4.env.CI || process4.env.NODE_ENV === "test"; + } +}); + +// shared/statistics.js +function erf(x) { + const sign = Math.sign(x); + x = Math.abs(x); + const a1 = 0.254829592; + const a2 = -0.284496736; + const a3 = 1.421413741; + const a4 = -1.453152027; + const a5 = 1.061405429; + const p = 0.3275911; + const t = 1 / (1 + p * x); + const y = t * (a1 + t * (a2 + t * (a3 + t * (a4 + t * a5)))); + return sign * (1 - y * Math.exp(-x * x)); +} +function getLogNormalScore({ median, p10 }, value) { + if (median <= 0) throw new Error("median must be greater than zero"); + if (p10 <= 0) throw new Error("p10 must be greater than zero"); + if (p10 >= median) throw new Error("p10 must be less than the median"); + if (value <= 0) return 1; + const INVERSE_ERFC_ONE_FIFTH = 0.9061938024368232; + const xRatio = Math.max(Number.MIN_VALUE, value / median); + const xLogRatio = Math.log(xRatio); + const p10Ratio = Math.max(Number.MIN_VALUE, p10 / median); + const p10LogRatio = -Math.log(p10Ratio); + const standardizedX = xLogRatio * INVERSE_ERFC_ONE_FIFTH / p10LogRatio; + const complementaryPercentile = (1 - erf(standardizedX)) / 2; + let score; + if (value <= p10) { + score = Math.max(MIN_PASSING_SCORE, Math.min(1, complementaryPercentile)); + } else if (value <= median) { + score = Math.max(MIN_AVERAGE_SCORE, Math.min(MAX_AVERAGE_SCORE, complementaryPercentile)); + } else { + score = Math.max(0, Math.min(MAX_FAILING_SCORE, complementaryPercentile)); + } + return score; +} +var MIN_PASSING_SCORE, MAX_AVERAGE_SCORE, MIN_AVERAGE_SCORE, MAX_FAILING_SCORE; +var init_statistics = __esm({ + "shared/statistics.js"() { + "use strict"; + init_process_global(); + /** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + MIN_PASSING_SCORE = 0.9; + MAX_AVERAGE_SCORE = 0.8999999999999999; + MIN_AVERAGE_SCORE = 0.5; + MAX_FAILING_SCORE = 0.49999999999999994; + __name(erf, "erf"); + __name(getLogNormalScore, "getLogNormalScore"); + } +}); + +// shared/util.js +var ELLIPSIS, NBSP, PASS_THRESHOLD, RATINGS, listOfTlds, Util; +var init_util = __esm({ + "shared/util.js"() { + "use strict"; + init_process_global(); + init_statistics(); + /** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + ELLIPSIS = "…"; + NBSP = " "; + PASS_THRESHOLD = 0.9; + RATINGS = { + PASS: { label: "pass", minScore: PASS_THRESHOLD }, + AVERAGE: { label: "average", minScore: 0.5 }, + FAIL: { label: "fail" }, + ERROR: { label: "error" } + }; + listOfTlds = [ + "com", + "co", + "gov", + "edu", + "ac", + "org", + "go", + "gob", + "or", + "net", + "in", + "ne", + "nic", + "gouv", + "web", + "spb", + "blog", + "jus", + "kiev", + "mil", + "wi", + "qc", + "ca", + "bel", + "on" + ]; + Util = class _Util { + static { + __name(this, "Util"); + } + static get RATINGS() { + return RATINGS; + } + static get PASS_THRESHOLD() { + return PASS_THRESHOLD; + } + static get MS_DISPLAY_VALUE() { + return `%10d${NBSP}ms`; + } + /** + * If LHR is older than 10.0 it will not have the `finalDisplayedUrl` property. + * Old LHRs should have the `finalUrl` property which will work fine for the report. + * + * @param {LH.Result} lhr + */ + static getFinalDisplayedUrl(lhr) { + if (lhr.finalDisplayedUrl) return lhr.finalDisplayedUrl; + if (lhr.finalUrl) return lhr.finalUrl; + throw new Error("Could not determine final displayed URL"); + } + /** + * If LHR is older than 10.0 it will not have the `mainDocumentUrl` property. + * Old LHRs should have the `finalUrl` property which is the same as `mainDocumentUrl`. + * + * @param {LH.Result} lhr + */ + static getMainDocumentUrl(lhr) { + return lhr.mainDocumentUrl || lhr.finalUrl; + } + /** + * @param {LH.Result} lhr + * @return {LH.Result.FullPageScreenshot=} + */ + static getFullPageScreenshot(lhr) { + if (lhr.fullPageScreenshot) { + return lhr.fullPageScreenshot; + } + const details = ( + /** @type {LH.Result.FullPageScreenshot=} */ + lhr.audits["full-page-screenshot"]?.details + ); + return details; + } + /** + * Given the entity classification dataset and a URL, identify the entity. + * @param {string} url + * @param {LH.Result.Entities=} entities + * @return {LH.Result.LhrEntity|string} + */ + static getEntityFromUrl(url, entities) { + if (!entities) { + return _Util.getPseudoRootDomain(url); + } + const entity = entities.find((e) => e.origins.find((origin) => url.startsWith(origin))); + return entity || _Util.getPseudoRootDomain(url); + } + /** + * Split a string by markdown code spans (enclosed in `backticks`), splitting + * into segments that were enclosed in backticks (marked as `isCode === true`) + * and those that outside the backticks (`isCode === false`). + * @param {string} text + * @return {Array<{isCode: true, text: string}|{isCode: false, text: string}>} + */ + static splitMarkdownCodeSpans(text) { + const segments = []; + const parts = text.split(/`(.*?)`/g); + for (let i = 0; i < parts.length; i++) { + const text2 = parts[i]; + if (!text2) continue; + const isCode = i % 2 !== 0; + segments.push({ + isCode, + text: text2 + }); + } + return segments; + } + /** + * Split a string on markdown links (e.g. [some link](https://...)) into + * segments of plain text that weren't part of a link (marked as + * `isLink === false`), and segments with text content and a URL that did make + * up a link (marked as `isLink === true`). + * @param {string} text + * @return {Array<{isLink: true, text: string, linkHref: string}|{isLink: false, text: string}>} + */ + static splitMarkdownLink(text) { + const segments = []; + const parts = text.split(/\[([^\]]+?)\]\((https?:\/\/.*?)\)/g); + while (parts.length) { + const [preambleText, linkText, linkHref] = parts.splice(0, 3); + if (preambleText) { + segments.push({ + isLink: false, + text: preambleText + }); + } + if (linkText && linkHref) { + segments.push({ + isLink: true, + text: linkText, + linkHref + }); + } + } + return segments; + } + /** + * @param {string} string + * @param {number} characterLimit + * @param {string} ellipseSuffix + */ + static truncate(string, characterLimit, ellipseSuffix = "…") { + if (string.length <= characterLimit) { + return string; + } + const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" }); + const iterator = segmenter.segment(string)[Symbol.iterator](); + let lastSegmentIndex = 0; + for (let i = 0; i <= characterLimit - ellipseSuffix.length; i++) { + const result = iterator.next(); + if (result.done) { + return string; + } + lastSegmentIndex = result.value.index; + } + for (let i = 0; i < ellipseSuffix.length; i++) { + if (iterator.next().done) { + return string; + } + } + return string.slice(0, lastSegmentIndex) + ellipseSuffix; + } + /** + * @param {URL} parsedUrl + * @param {{numPathParts?: number, preserveQuery?: boolean, preserveHost?: boolean}=} options + * @return {string} + */ + static getURLDisplayName(parsedUrl, options) { + options = options || { + numPathParts: void 0, + preserveQuery: void 0, + preserveHost: void 0 + }; + const numPathParts = options.numPathParts !== void 0 ? options.numPathParts : 2; + const preserveQuery = options.preserveQuery !== void 0 ? options.preserveQuery : true; + const preserveHost = options.preserveHost || false; + let name; + if (parsedUrl.protocol === "about:" || parsedUrl.protocol === "data:") { + name = parsedUrl.href; + } else { + name = parsedUrl.pathname; + const parts = name.split("/").filter((part) => part.length); + if (numPathParts && parts.length > numPathParts) { + name = ELLIPSIS + parts.slice(-1 * numPathParts).join("/"); + } + if (preserveHost) { + name = `${parsedUrl.host}/${name.replace(/^\//, "")}`; + } + if (preserveQuery) { + name = `${name}${parsedUrl.search}`; + } + } + const MAX_LENGTH = 64; + if (parsedUrl.protocol !== "data:") { + name = name.slice(0, 200); + name = name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, `$1${ELLIPSIS}`); + name = name.replace( + /([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g, + `$1${ELLIPSIS}` + ); + name = name.replace(/(\d{3})\d{6,}/g, `$1${ELLIPSIS}`); + name = name.replace(/\u2026+/g, ELLIPSIS); + if (name.length > MAX_LENGTH && name.includes("?")) { + name = name.replace(/\?([^=]*)(=)?.*/, `?$1$2${ELLIPSIS}`); + if (name.length > MAX_LENGTH) { + name = name.replace(/\?.*/, `?${ELLIPSIS}`); + } + } + } + if (name.length > MAX_LENGTH) { + const dotIndex = name.lastIndexOf("."); + if (dotIndex >= 0) { + name = name.slice(0, MAX_LENGTH - 1 - (name.length - dotIndex)) + // Show file extension + `${ELLIPSIS}${name.slice(dotIndex)}`; + } else { + name = name.slice(0, MAX_LENGTH - 1) + ELLIPSIS; + } + } + return name; + } + /** + * Returns the origin portion of a Chrome extension URL. + * @param {string} url + * @return {string} + */ + static getChromeExtensionOrigin(url) { + const parsedUrl = new URL(url); + return parsedUrl.protocol + "//" + parsedUrl.host; + } + /** + * Split a URL into a file, hostname and origin for easy display. + * @param {string} url + * @return {{file: string, hostname: string, origin: string}} + */ + static parseURL(url) { + const parsedUrl = new URL(url); + return { + file: _Util.getURLDisplayName(parsedUrl), + hostname: parsedUrl.hostname, + // Node's URL parsing behavior is different than Chrome and returns 'null' + // for chrome-extension:// URLs. See https://github.com/nodejs/node/issues/21955. + origin: parsedUrl.protocol === "chrome-extension:" ? _Util.getChromeExtensionOrigin(url) : parsedUrl.origin + }; + } + /** + * @param {string|URL} value + * @return {!URL} + */ + static createOrReturnURL(value) { + if (value instanceof URL) { + return value; + } + return new URL(value); + } + /** + * Gets the tld of a domain + * This function is used only while rendering pre-10.0 LHRs. + * + * @param {string} hostname + * @return {string} tld + */ + static getPseudoTld(hostname) { + const tlds = hostname.split(".").slice(-2); + if (!listOfTlds.includes(tlds[0])) { + return `.${tlds[tlds.length - 1]}`; + } + return `.${tlds.join(".")}`; + } + /** + * Returns a primary domain for provided hostname (e.g. www.example.com -> example.com). + * As it doesn't consult the Public Suffix List, it can sometimes lose detail. + * See the `listOfTlds` comment above for more. + * This function is used only while rendering pre-10.0 LHRs. See UrlUtils.getRootDomain + * for the current method that makes use of PSL. + * @param {string|URL} url hostname or URL object + * @return {string} + */ + static getPseudoRootDomain(url) { + const hostname = _Util.createOrReturnURL(url).hostname; + const tld = _Util.getPseudoTld(hostname); + const splitTld = tld.split("."); + return hostname.split(".").slice(-splitTld.length).join("."); + } + /** + * Returns only lines that are near a message, or the first few lines if there are + * no line messages. + * @param {SnippetValue['lines']} lines + * @param {SnippetValue['lineMessages']} lineMessages + * @param {number} surroundingLineCount Number of lines to include before and after + * the message. If this is e.g. 2 this function might return 5 lines. + */ + static filterRelevantLines(lines, lineMessages, surroundingLineCount) { + if (lineMessages.length === 0) { + return lines.slice(0, surroundingLineCount * 2 + 1); + } + const minGapSize = 3; + const lineNumbersToKeep = /* @__PURE__ */ new Set(); + lineMessages = lineMessages.sort((a, b) => (a.lineNumber || 0) - (b.lineNumber || 0)); + lineMessages.forEach(({ lineNumber }) => { + let firstSurroundingLineNumber = lineNumber - surroundingLineCount; + let lastSurroundingLineNumber = lineNumber + surroundingLineCount; + while (firstSurroundingLineNumber < 1) { + firstSurroundingLineNumber++; + lastSurroundingLineNumber++; + } + if (lineNumbersToKeep.has(firstSurroundingLineNumber - minGapSize - 1)) { + firstSurroundingLineNumber -= minGapSize; + } + for (let i = firstSurroundingLineNumber; i <= lastSurroundingLineNumber; i++) { + const surroundingLineNumber = i; + lineNumbersToKeep.add(surroundingLineNumber); + } + }); + return lines.filter((line) => lineNumbersToKeep.has(line.lineNumber)); + } + /** + * Computes a score between 0 and 1 based on the measured `value`. Score is determined by + * considering a log-normal distribution governed by two control points (the 10th + * percentile value and the median value) and represents the percentage of sites that are + * greater than `value`. + * + * Score characteristics: + * - within [0, 1] + * - rounded to two digits + * - value must meet or beat a controlPoint value to meet or exceed its percentile score: + * - value > median will give a score < 0.5; value ≤ median will give a score ≥ 0.5. + * - value > p10 will give a score < 0.9; value ≤ p10 will give a score ≥ 0.9. + * - values < p10 will get a slight boost so a score of 1 is achievable by a + * `value` other than those close to 0. Scores of > ~0.99524 end up rounded to 1. + * @param {{median: number, p10: number}} controlPoints + * @param {number} value + * @return {number} + */ + static computeLogNormalScore(controlPoints, value) { + let percentile = getLogNormalScore(controlPoints, value); + if (percentile > 0.9) { + percentile += 0.05 * (percentile - 0.9); + } + return Math.floor(percentile * 100) / 100; + } + }; + } +}); + +// core/audits/audit.js +var METRIC_SAVINGS_PRECISION, clampTo2Decimals, Audit; +var init_audit = __esm({ + "core/audits/audit.js"() { + "use strict"; + init_process_global(); + init_lh(); + init_lh_env(); + init_util(); + /** + * @license + * Copyright 2016 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + METRIC_SAVINGS_PRECISION = { + FCP: 50, + LCP: 50, + INP: 50, + TBT: 50, + CLS: 1e-3 + }; + clampTo2Decimals = /* @__PURE__ */ __name((val) => Math.round(val * 100) / 100, "clampTo2Decimals"); + Audit = class _Audit { + static { + __name(this, "Audit"); + } + /** + * @return {LH.Audit.ScoreDisplayModes} + */ + static get SCORING_MODES() { + return { + NUMERIC: "numeric", + METRIC_SAVINGS: "metricSavings", + BINARY: "binary", + MANUAL: "manual", + INFORMATIVE: "informative", + NOT_APPLICABLE: "notApplicable", + ERROR: "error" + }; + } + /** + * @return {LH.Audit.Meta} + */ + static get meta() { + throw new Error("Audit meta information must be overridden."); + } + /** + * @return {Object} + */ + static get defaultOptions() { + return {}; + } + /* eslint-disable no-unused-vars */ + /** + * + * @param {LH.Artifacts} artifacts + * @param {LH.Audit.Context} context + * @return {LH.Audit.Product|Promise} + */ + static audit(artifacts, context) { + throw new Error("audit() method must be overridden"); + } + /* eslint-enable no-unused-vars */ + /** + * Computes a score between 0 and 1 based on the measured `value`. Score is determined by + * considering a log-normal distribution governed by two control points (the 10th + * percentile value and the median value) and represents the percentage of sites that are + * greater than `value`. + * + * Score characteristics: + * - within [0, 1] + * - rounded to two digits + * - value must meet or beat a controlPoint value to meet or exceed its percentile score: + * - value > median will give a score < 0.5; value ≤ median will give a score ≥ 0.5. + * - value > p10 will give a score < 0.9; value ≤ p10 will give a score ≥ 0.9. + * - values < p10 will get a slight boost so a score of 1 is achievable by a + * `value` other than those close to 0. Scores of > ~0.99524 end up rounded to 1. + * @param {{median: number, p10: number}} controlPoints + * @param {number} value + * @return {number} + */ + static computeLogNormalScore(controlPoints, value) { + return Util.computeLogNormalScore(controlPoints, value); + } + /** + * This catches typos in the `key` property of a heading definition of table/opportunity details. + * Throws an error if any of keys referenced by headings don't exist in at least one of the items. + * + * @param {LH.Audit.Details.Table['headings']|LH.Audit.Details.Opportunity['headings']} headings + * @param {LH.Audit.Details.Opportunity['items']|LH.Audit.Details.Table['items']} items + */ + static assertHeadingKeysExist(headings, items) { + if (!items.length) return; + if (!isUnderTest) return; + for (const heading of headings) { + if (heading.key === null) continue; + const key = heading.key; + if (items.some((item) => key in item)) continue; + throw new Error(`"${heading.key}" is missing from items`); + } + } + /** + * @param {LH.Audit.Details.Checklist['items']} items + * @return {LH.Audit.Details.Checklist} + */ + static makeChecklistDetails(items) { + return { + type: "checklist", + items + }; + } + /** + * @param {LH.Audit.Details.Table['headings']} headings + * @param {LH.Audit.Details.Table['items']} results + * @param {TableOptions=} options + * @return {LH.Audit.Details.Table} + */ + static makeTableDetails(headings, results, options = {}) { + const { wastedBytes, wastedMs, sortedBy, skipSumming, isEntityGrouped } = options; + const summary = wastedBytes || wastedMs ? { wastedBytes, wastedMs } : void 0; + if (results.length === 0) { + return { + type: "table", + headings, + items: [], + summary + }; + } + _Audit.assertHeadingKeysExist(headings, results); + return { + type: "table", + headings, + items: results, + summary, + sortedBy, + skipSumming, + isEntityGrouped + }; + } + /** + * @param {LH.Audit.Details.List['items']} items + * @return {LH.Audit.Details.List} + */ + static makeListDetails(items) { + return { + type: "list", + items + }; + } + /** + * @param {LH.IcuMessage | string=} title + * @param {LH.IcuMessage | string=} description + * @param {LH.Audit.Details.ListableDetail} value + * @return {LH.Audit.Details.ListSectionItem} + */ + static makeListDetailSectionItem(value, title, description) { + return { + type: "list-section", + title, + description, + value + }; + } + /** @typedef {{ + * content: string; + * title: string; + * lineMessages: LH.Audit.Details.SnippetValue['lineMessages']; + * generalMessages: LH.Audit.Details.SnippetValue['generalMessages']; + * node?: LH.Audit.Details.NodeValue; + * maxLineLength?: number; + * maxLinesAroundMessage?: number; + * }} SnippetInfo */ + /** + * @param {SnippetInfo} snippetInfo + * @return {LH.Audit.Details.SnippetValue} + */ + static makeSnippetDetails({ + content, + title, + lineMessages, + generalMessages, + node, + maxLineLength = 200, + maxLinesAroundMessage = 20 + }) { + const allLines = _Audit._makeSnippetLinesArray(content, maxLineLength); + const lines = Util.filterRelevantLines(allLines, lineMessages, maxLinesAroundMessage); + return { + type: "snippet", + lines, + title, + lineMessages, + generalMessages, + lineCount: allLines.length, + node + }; + } + /** + * @param {string} content + * @param {number} maxLineLength + * @return {LH.Audit.Details.SnippetValue['lines']} + */ + static _makeSnippetLinesArray(content, maxLineLength) { + return content.split("\n").map((line, lineIndex) => { + const lineNumber = lineIndex + 1; + const lineDetail = { + content: Util.truncate(line, maxLineLength), + lineNumber + }; + if (line.length > maxLineLength) { + lineDetail.truncated = true; + } + return lineDetail; + }); + } + /** + * @param {LH.Audit.Details.Opportunity['headings']} headings + * @param {LH.Audit.Details.Opportunity['items']} items + * @param {OpportunityOptions} options + * @return {LH.Audit.Details.Opportunity} + */ + static makeOpportunityDetails(headings, items, options) { + _Audit.assertHeadingKeysExist(headings, items); + const { overallSavingsMs, overallSavingsBytes, sortedBy, skipSumming, isEntityGrouped } = options; + return { + type: "opportunity", + headings: items.length === 0 ? [] : headings, + items, + overallSavingsMs, + overallSavingsBytes, + sortedBy, + skipSumming, + isEntityGrouped + }; + } + /** + * @param {LH.Artifacts.NodeDetails} node + * @return {LH.Audit.Details.NodeValue} + */ + static makeNodeItem(node) { + return { + type: "node", + lhId: node.lhId, + path: node.devtoolsNodePath, + selector: node.selector, + boundingRect: node.boundingRect, + snippet: node.snippet, + nodeLabel: node.nodeLabel + }; + } + /** + * @param {LH.Artifacts.Bundle} bundle + * @param {number} generatedLine + * @param {number} generatedColumn + * @return {LH.Audit.Details.SourceLocationValue['original']} + */ + static _findOriginalLocation(bundle, generatedLine, generatedColumn) { + const entry = bundle?.map.findEntry(generatedLine, generatedColumn); + if (!entry) return; + return { + file: entry.sourceURL || "", + line: entry.sourceLineNumber || 0, + column: entry.sourceColumnNumber || 0 + }; + } + /** + * @param {string} url + * @param {number} line 0-indexed + * @param {number} column 0-indexed + * @param {LH.Artifacts.Bundle=} bundle + * @return {LH.Audit.Details.SourceLocationValue} + */ + static makeSourceLocation(url, line, column, bundle) { + return { + type: "source-location", + url, + urlProvider: "network", + line, + column, + original: bundle && this._findOriginalLocation(bundle, line, column) + }; + } + /** + * @param {LH.Artifacts.ConsoleMessage} entry + * @param {LH.Artifacts.Bundle=} bundle + * @return {LH.Audit.Details.SourceLocationValue | undefined} + */ + static makeSourceLocationFromConsoleMessage(entry, bundle) { + if (!entry.url) return; + const line = entry.lineNumber || 0; + const column = entry.columnNumber || 0; + return this.makeSourceLocation(entry.url, line, column, bundle); + } + /** + * @param {number|null} score + * @param {LH.Audit.ScoreDisplayMode} scoreDisplayMode + * @param {string} auditId + * @return {number|null} + */ + static _normalizeAuditScore(score, scoreDisplayMode, auditId) { + if (scoreDisplayMode === _Audit.SCORING_MODES.INFORMATIVE) { + return 1; + } + if (scoreDisplayMode !== _Audit.SCORING_MODES.BINARY && scoreDisplayMode !== _Audit.SCORING_MODES.NUMERIC && scoreDisplayMode !== _Audit.SCORING_MODES.METRIC_SAVINGS) { + return null; + } + if (score === null || !Number.isFinite(score)) { + throw new Error(`Invalid score for ${auditId}: ${score}`); + } + if (score > 1) throw new Error(`Audit score for ${auditId} is > 1`); + if (score < 0) throw new Error(`Audit score for ${auditId} is < 0`); + score = clampTo2Decimals(score); + return score; + } + /** + * @param {LH.Audit.ProductMetricSavings|undefined} metricSavings + * @return {LH.Audit.ProductMetricSavings|undefined} + */ + static _quantizeMetricSavings(metricSavings) { + if (!metricSavings) return; + const normalizedMetricSavings = { ...metricSavings }; + for ( + const key of + /** @type {Array} */ + Object.keys(metricSavings) + ) { + let value = metricSavings[key]; + if (value === void 0) continue; + value = Math.max(value, 0); + const precision = METRIC_SAVINGS_PRECISION[key]; + if (precision !== void 0) { + value = Math.round(value / precision) * precision; + } + normalizedMetricSavings[key] = value; + } + return normalizedMetricSavings; + } + /** + * @param {typeof Audit} audit + * @param {string | LH.IcuMessage} errorMessage + * @param {string=} errorStack + * @return {LH.RawIcu} + */ + static generateErrorAuditResult(audit, errorMessage, errorStack) { + return _Audit.generateAuditResult(audit, { + score: null, + errorMessage, + errorStack + }); + } + /** + * @param {typeof Audit} audit + * @param {LH.Audit.Product} product + * @return {LH.RawIcu} + */ + static generateAuditResult(audit, product) { + if (product.score === void 0) { + throw new Error("generateAuditResult requires a score"); + } + let scoreDisplayMode = audit.meta.scoreDisplayMode || _Audit.SCORING_MODES.BINARY; + let score = product.score; + if (product.errorMessage !== void 0) { + scoreDisplayMode = _Audit.SCORING_MODES.ERROR; + } else if (product.notApplicable) { + scoreDisplayMode = _Audit.SCORING_MODES.NOT_APPLICABLE; + } else if (product.scoreDisplayMode) { + scoreDisplayMode = product.scoreDisplayMode; + } + const metricSavings = _Audit._quantizeMetricSavings(product.metricSavings); + const hasSomeSavings = Object.values(metricSavings || {}).some((v) => v); + if (scoreDisplayMode === _Audit.SCORING_MODES.METRIC_SAVINGS) { + if (score && score >= Util.PASS_THRESHOLD) { + score = 1; + } else if (hasSomeSavings) { + score = 0; + } else { + score = 0.5; + } + } + score = _Audit._normalizeAuditScore(score, scoreDisplayMode, audit.meta.id); + let auditTitle = audit.meta.title; + if (audit.meta.failureTitle) { + if (score !== null && score < Util.PASS_THRESHOLD) { + auditTitle = audit.meta.failureTitle; + } + } + const numericProduct = "numericUnit" in product ? product : void 0; + return { + id: audit.meta.id, + title: auditTitle, + description: audit.meta.description, + score, + scoreDisplayMode, + numericValue: numericProduct?.numericValue, + numericUnit: numericProduct?.numericUnit, + displayValue: product.displayValue, + explanation: product.explanation, + errorMessage: product.errorMessage, + errorStack: product.errorStack, + warnings: product.warnings, + scoringOptions: product.scoringOptions, + metricSavings, + details: product.details, + guidanceLevel: audit.meta.guidanceLevel + }; + } + /** + * @param {LH.Artifacts} artifacts + * @param {LH.Audit.Context} context + * @returns {LH.Artifacts.MetricComputationDataInput} + */ + static makeMetricComputationDataInput(artifacts, context) { + const trace = artifacts.Trace; + const devtoolsLog = artifacts.DevtoolsLog; + const gatherContext = artifacts.GatherContext; + const { URL: URL3, HostDPR, SourceMaps: SourceMaps2 } = artifacts; + return { trace, devtoolsLog, gatherContext, settings: context.settings, URL: URL3, SourceMaps: SourceMaps2, HostDPR, simulator: null }; + } + }; + } +}); + +// core/scoring.js +var clampTo2Decimals2, ReportScoring; +var init_scoring = __esm({ + "core/scoring.js"() { + "use strict"; + init_process_global(); + init_audit(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + clampTo2Decimals2 = /* @__PURE__ */ __name((val) => Math.round(val * 100) / 100, "clampTo2Decimals"); + ReportScoring = class _ReportScoring { + static { + __name(this, "ReportScoring"); + } + /** + * Computes the weighted-average of the score of the list of items. + * @param {Array<{score: number|null, weight: number}>} items + * @return {number|null} + */ + static arithmeticMean(items) { + items = items.filter((item) => item.weight > 0); + if (items.some((item) => item.score === null)) return null; + const results = items.reduce( + (result, item) => { + const score = item.score; + const weight = item.weight; + return { + weight: result.weight + weight, + sum: result.sum + /** @type {number} */ + score * weight + }; + }, + { weight: 0, sum: 0 } + ); + return clampTo2Decimals2(results.sum / results.weight || 0); + } + /** + * Returns the report JSON object with computed scores. + * @param {Object} configCategories + * @param {Object>} resultsByAuditId + * @return {Object>} + */ + static scoreAllCategories(configCategories, resultsByAuditId) { + const scoredCategories = {}; + for (const [categoryId, configCategory] of Object.entries(configCategories)) { + const auditRefs = configCategory.auditRefs.map((configMember) => { + const member = { ...configMember }; + const result = resultsByAuditId[member.id]; + if (result.scoreDisplayMode === Audit.SCORING_MODES.NOT_APPLICABLE || result.scoreDisplayMode === Audit.SCORING_MODES.INFORMATIVE || result.scoreDisplayMode === Audit.SCORING_MODES.MANUAL) { + member.weight = 0; + } + return member; + }); + const scores = auditRefs.map((auditRef) => ({ + score: resultsByAuditId[auditRef.id].score, + weight: auditRef.weight + })); + const score = _ReportScoring.arithmeticMean(scores); + scoredCategories[categoryId] = { + ...configCategory, + auditRefs, + id: categoryId, + score + }; + } + return scoredCategories; + } + }; + } +}); + +// node_modules/intl-messageformat/node_modules/tslib/tslib.es6.mjs +var tslib_es6_exports = {}; +__export(tslib_es6_exports, { + __addDisposableResource: () => __addDisposableResource, + __assign: () => __assign, + __asyncDelegator: () => __asyncDelegator, + __asyncGenerator: () => __asyncGenerator, + __asyncValues: () => __asyncValues, + __await: () => __await, + __awaiter: () => __awaiter, + __classPrivateFieldGet: () => __classPrivateFieldGet, + __classPrivateFieldIn: () => __classPrivateFieldIn, + __classPrivateFieldSet: () => __classPrivateFieldSet, + __createBinding: () => __createBinding, + __decorate: () => __decorate, + __disposeResources: () => __disposeResources, + __esDecorate: () => __esDecorate, + __exportStar: () => __exportStar, + __extends: () => __extends, + __generator: () => __generator, + __importDefault: () => __importDefault, + __importStar: () => __importStar, + __makeTemplateObject: () => __makeTemplateObject, + __metadata: () => __metadata, + __param: () => __param, + __propKey: () => __propKey, + __read: () => __read, + __rest: () => __rest, + __runInitializers: () => __runInitializers, + __setFunctionName: () => __setFunctionName, + __spread: () => __spread, + __spreadArray: () => __spreadArray, + __spreadArrays: () => __spreadArrays, + __values: () => __values, + default: () => tslib_es6_default +}); +function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { + this.constructor = d; + } + __name(__, "__"); + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} +function __param(paramIndex, decorator) { + return function(target, key) { + decorator(target, key, paramIndex); + }; +} +function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { + if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); + return f; + } + __name(accept, "accept"); + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function(f) { + if (done) throw new TypeError("Cannot add initializers after decoration has completed"); + extraInitializers.push(accept(f || null)); + }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +} +function __runInitializers(thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +} +function __propKey(x) { + return typeof x === "symbol" ? x : "".concat(x); +} +function __setFunctionName(f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +} +function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + __name(adopt, "adopt"); + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + __name(fulfilled, "fulfilled"); + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + __name(rejected, "rejected"); + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + __name(step, "step"); + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} +function __generator(thisArg, body) { + var _ = { label: 0, sent: /* @__PURE__ */ __name(function() { + if (t[0] & 1) throw t[1]; + return t[1]; + }, "sent"), trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { + return this; + }), g; + function verb(n) { + return function(v) { + return step([n, v]); + }; + } + __name(verb, "verb"); + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + __name(step, "step"); +} +function __exportStar(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); +} +function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: /* @__PURE__ */ __name(function() { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + }, "next") + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { error }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + return ar; +} +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; +} +function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +} +function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +} +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i; + function verb(n) { + if (g[n]) i[n] = function(v) { + return new Promise(function(a, b) { + q.push([n, v, a, b]) > 1 || resume(n, v); + }); + }; + } + __name(verb, "verb"); + function resume(n, v) { + try { + step(g[n](v)); + } catch (e) { + settle(q[0][3], e); + } + } + __name(resume, "resume"); + function step(r) { + r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); + } + __name(step, "step"); + function fulfill(value) { + resume("next", value); + } + __name(fulfill, "fulfill"); + function reject(value) { + resume("throw", value); + } + __name(reject, "reject"); + function settle(f, v) { + if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); + } + __name(settle, "settle"); +} +function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function(e) { + throw e; + }), verb("return"), i[Symbol.iterator] = function() { + return this; + }, i; + function verb(n, f) { + i[n] = o[n] ? function(v) { + return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; + } : f; + } + __name(verb, "verb"); +} +function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i); + function verb(n) { + i[n] = o[n] && function(v) { + return new Promise(function(resolve, reject) { + v = o[n](v), settle(resolve, reject, v.done, v.value); + }); + }; + } + __name(verb, "verb"); + function settle(resolve, reject, d, v) { + Promise.resolve(v).then(function(v2) { + resolve({ value: v2, done: d }); + }, reject); + } + __name(settle, "settle"); +} +function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { + Object.defineProperty(cooked, "raw", { value: raw }); + } else { + cooked.raw = raw; + } + return cooked; +} +function __importStar(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; +} +function __importDefault(mod2) { + return mod2 && mod2.__esModule ? mod2 : { default: mod2 }; +} +function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +} +function __classPrivateFieldSet(receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; +} +function __classPrivateFieldIn(state, receiver) { + if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function") throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); +} +function __addDisposableResource(env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value, dispose, async }); + } else if (async) { + env.stack.push({ async: true }); + } + return value; +} +function __disposeResources(env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + __name(fail, "fail"); + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { + fail(e); + return next(); + }); + } catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + __name(next, "next"); + return next(); +} +var extendStatics, __assign, __createBinding, __setModuleDefault, _SuppressedError, tslib_es6_default; +var init_tslib_es6 = __esm({ + "node_modules/intl-messageformat/node_modules/tslib/tslib.es6.mjs"() { + init_process_global(); + extendStatics = /* @__PURE__ */ __name(function(d, b) { + extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { + d2.__proto__ = b2; + } || function(d2, b2) { + for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p]; + }; + return extendStatics(d, b); + }, "extendStatics"); + __name(__extends, "__extends"); + __assign = /* @__PURE__ */ __name(function() { + __assign = Object.assign || /* @__PURE__ */ __name(function __assign4(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }, "__assign"); + return __assign.apply(this, arguments); + }, "__assign"); + __name(__rest, "__rest"); + __name(__decorate, "__decorate"); + __name(__param, "__param"); + __name(__esDecorate, "__esDecorate"); + __name(__runInitializers, "__runInitializers"); + __name(__propKey, "__propKey"); + __name(__setFunctionName, "__setFunctionName"); + __name(__metadata, "__metadata"); + __name(__awaiter, "__awaiter"); + __name(__generator, "__generator"); + __createBinding = Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: /* @__PURE__ */ __name(function() { + return m[k]; + }, "get") }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + __name(__exportStar, "__exportStar"); + __name(__values, "__values"); + __name(__read, "__read"); + __name(__spread, "__spread"); + __name(__spreadArrays, "__spreadArrays"); + __name(__spreadArray, "__spreadArray"); + __name(__await, "__await"); + __name(__asyncGenerator, "__asyncGenerator"); + __name(__asyncDelegator, "__asyncDelegator"); + __name(__asyncValues, "__asyncValues"); + __name(__makeTemplateObject, "__makeTemplateObject"); + __setModuleDefault = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }; + __name(__importStar, "__importStar"); + __name(__importDefault, "__importDefault"); + __name(__classPrivateFieldGet, "__classPrivateFieldGet"); + __name(__classPrivateFieldSet, "__classPrivateFieldSet"); + __name(__classPrivateFieldIn, "__classPrivateFieldIn"); + __name(__addDisposableResource, "__addDisposableResource"); + _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + __name(__disposeResources, "__disposeResources"); + tslib_es6_default = { + __extends, + __assign, + __rest, + __decorate, + __param, + __metadata, + __awaiter, + __generator, + __createBinding, + __exportStar, + __values, + __read, + __spread, + __spreadArrays, + __spreadArray, + __await, + __asyncGenerator, + __asyncDelegator, + __asyncValues, + __makeTemplateObject, + __importStar, + __importDefault, + __classPrivateFieldGet, + __classPrivateFieldSet, + __classPrivateFieldIn, + __addDisposableResource, + __disposeResources + }; + } +}); + +// node_modules/@formatjs/icu-messageformat-parser/node_modules/tslib/tslib.es6.mjs +var tslib_es6_exports2 = {}; +__export(tslib_es6_exports2, { + __addDisposableResource: () => __addDisposableResource2, + __assign: () => __assign2, + __asyncDelegator: () => __asyncDelegator2, + __asyncGenerator: () => __asyncGenerator2, + __asyncValues: () => __asyncValues2, + __await: () => __await2, + __awaiter: () => __awaiter2, + __classPrivateFieldGet: () => __classPrivateFieldGet2, + __classPrivateFieldIn: () => __classPrivateFieldIn2, + __classPrivateFieldSet: () => __classPrivateFieldSet2, + __createBinding: () => __createBinding2, + __decorate: () => __decorate2, + __disposeResources: () => __disposeResources2, + __esDecorate: () => __esDecorate2, + __exportStar: () => __exportStar2, + __extends: () => __extends2, + __generator: () => __generator2, + __importDefault: () => __importDefault2, + __importStar: () => __importStar2, + __makeTemplateObject: () => __makeTemplateObject2, + __metadata: () => __metadata2, + __param: () => __param2, + __propKey: () => __propKey2, + __read: () => __read2, + __rest: () => __rest2, + __runInitializers: () => __runInitializers2, + __setFunctionName: () => __setFunctionName2, + __spread: () => __spread2, + __spreadArray: () => __spreadArray2, + __spreadArrays: () => __spreadArrays2, + __values: () => __values2, + default: () => tslib_es6_default2 +}); +function __extends2(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics2(d, b); + function __() { + this.constructor = d; + } + __name(__, "__"); + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} +function __rest2(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} +function __decorate2(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} +function __param2(paramIndex, decorator) { + return function(target, key) { + decorator(target, key, paramIndex); + }; +} +function __esDecorate2(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { + if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); + return f; + } + __name(accept, "accept"); + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function(f) { + if (done) throw new TypeError("Cannot add initializers after decoration has completed"); + extraInitializers.push(accept(f || null)); + }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +} +function __runInitializers2(thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +} +function __propKey2(x) { + return typeof x === "symbol" ? x : "".concat(x); +} +function __setFunctionName2(f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +} +function __metadata2(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} +function __awaiter2(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + __name(adopt, "adopt"); + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + __name(fulfilled, "fulfilled"); + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + __name(rejected, "rejected"); + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + __name(step, "step"); + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} +function __generator2(thisArg, body) { + var _ = { label: 0, sent: /* @__PURE__ */ __name(function() { + if (t[0] & 1) throw t[1]; + return t[1]; + }, "sent"), trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { + return this; + }), g; + function verb(n) { + return function(v) { + return step([n, v]); + }; + } + __name(verb, "verb"); + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + __name(step, "step"); +} +function __exportStar2(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding2(o, m, p); +} +function __values2(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: /* @__PURE__ */ __name(function() { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + }, "next") + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} +function __read2(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { error }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + return ar; +} +function __spread2() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read2(arguments[i])); + return ar; +} +function __spreadArrays2() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +} +function __spreadArray2(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +} +function __await2(v) { + return this instanceof __await2 ? (this.v = v, this) : new __await2(v); +} +function __asyncGenerator2(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i; + function verb(n) { + if (g[n]) i[n] = function(v) { + return new Promise(function(a, b) { + q.push([n, v, a, b]) > 1 || resume(n, v); + }); + }; + } + __name(verb, "verb"); + function resume(n, v) { + try { + step(g[n](v)); + } catch (e) { + settle(q[0][3], e); + } + } + __name(resume, "resume"); + function step(r) { + r.value instanceof __await2 ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); + } + __name(step, "step"); + function fulfill(value) { + resume("next", value); + } + __name(fulfill, "fulfill"); + function reject(value) { + resume("throw", value); + } + __name(reject, "reject"); + function settle(f, v) { + if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); + } + __name(settle, "settle"); +} +function __asyncDelegator2(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function(e) { + throw e; + }), verb("return"), i[Symbol.iterator] = function() { + return this; + }, i; + function verb(n, f) { + i[n] = o[n] ? function(v) { + return (p = !p) ? { value: __await2(o[n](v)), done: false } : f ? f(v) : v; + } : f; + } + __name(verb, "verb"); +} +function __asyncValues2(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values2 === "function" ? __values2(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i); + function verb(n) { + i[n] = o[n] && function(v) { + return new Promise(function(resolve, reject) { + v = o[n](v), settle(resolve, reject, v.done, v.value); + }); + }; + } + __name(verb, "verb"); + function settle(resolve, reject, d, v) { + Promise.resolve(v).then(function(v2) { + resolve({ value: v2, done: d }); + }, reject); + } + __name(settle, "settle"); +} +function __makeTemplateObject2(cooked, raw) { + if (Object.defineProperty) { + Object.defineProperty(cooked, "raw", { value: raw }); + } else { + cooked.raw = raw; + } + return cooked; +} +function __importStar2(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding2(result, mod2, k); + } + __setModuleDefault2(result, mod2); + return result; +} +function __importDefault2(mod2) { + return mod2 && mod2.__esModule ? mod2 : { default: mod2 }; +} +function __classPrivateFieldGet2(receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +} +function __classPrivateFieldSet2(receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; +} +function __classPrivateFieldIn2(state, receiver) { + if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function") throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); +} +function __addDisposableResource2(env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value, dispose, async }); + } else if (async) { + env.stack.push({ async: true }); + } + return value; +} +function __disposeResources2(env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError2(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + __name(fail, "fail"); + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { + fail(e); + return next(); + }); + } catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + __name(next, "next"); + return next(); +} +var extendStatics2, __assign2, __createBinding2, __setModuleDefault2, _SuppressedError2, tslib_es6_default2; +var init_tslib_es62 = __esm({ + "node_modules/@formatjs/icu-messageformat-parser/node_modules/tslib/tslib.es6.mjs"() { + init_process_global(); + extendStatics2 = /* @__PURE__ */ __name(function(d, b) { + extendStatics2 = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { + d2.__proto__ = b2; + } || function(d2, b2) { + for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p]; + }; + return extendStatics2(d, b); + }, "extendStatics"); + __name(__extends2, "__extends"); + __assign2 = /* @__PURE__ */ __name(function() { + __assign2 = Object.assign || /* @__PURE__ */ __name(function __assign4(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }, "__assign"); + return __assign2.apply(this, arguments); + }, "__assign"); + __name(__rest2, "__rest"); + __name(__decorate2, "__decorate"); + __name(__param2, "__param"); + __name(__esDecorate2, "__esDecorate"); + __name(__runInitializers2, "__runInitializers"); + __name(__propKey2, "__propKey"); + __name(__setFunctionName2, "__setFunctionName"); + __name(__metadata2, "__metadata"); + __name(__awaiter2, "__awaiter"); + __name(__generator2, "__generator"); + __createBinding2 = Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: /* @__PURE__ */ __name(function() { + return m[k]; + }, "get") }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + __name(__exportStar2, "__exportStar"); + __name(__values2, "__values"); + __name(__read2, "__read"); + __name(__spread2, "__spread"); + __name(__spreadArrays2, "__spreadArrays"); + __name(__spreadArray2, "__spreadArray"); + __name(__await2, "__await"); + __name(__asyncGenerator2, "__asyncGenerator"); + __name(__asyncDelegator2, "__asyncDelegator"); + __name(__asyncValues2, "__asyncValues"); + __name(__makeTemplateObject2, "__makeTemplateObject"); + __setModuleDefault2 = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }; + __name(__importStar2, "__importStar"); + __name(__importDefault2, "__importDefault"); + __name(__classPrivateFieldGet2, "__classPrivateFieldGet"); + __name(__classPrivateFieldSet2, "__classPrivateFieldSet"); + __name(__classPrivateFieldIn2, "__classPrivateFieldIn"); + __name(__addDisposableResource2, "__addDisposableResource"); + _SuppressedError2 = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + __name(__disposeResources2, "__disposeResources"); + tslib_es6_default2 = { + __extends: __extends2, + __assign: __assign2, + __rest: __rest2, + __decorate: __decorate2, + __param: __param2, + __metadata: __metadata2, + __awaiter: __awaiter2, + __generator: __generator2, + __createBinding: __createBinding2, + __exportStar: __exportStar2, + __values: __values2, + __read: __read2, + __spread: __spread2, + __spreadArrays: __spreadArrays2, + __spreadArray: __spreadArray2, + __await: __await2, + __asyncGenerator: __asyncGenerator2, + __asyncDelegator: __asyncDelegator2, + __asyncValues: __asyncValues2, + __makeTemplateObject: __makeTemplateObject2, + __importStar: __importStar2, + __importDefault: __importDefault2, + __classPrivateFieldGet: __classPrivateFieldGet2, + __classPrivateFieldSet: __classPrivateFieldSet2, + __classPrivateFieldIn: __classPrivateFieldIn2, + __addDisposableResource: __addDisposableResource2, + __disposeResources: __disposeResources2 + }; + } +}); + +// node_modules/@formatjs/icu-messageformat-parser/error.js +var require_error = __commonJS({ + "node_modules/@formatjs/icu-messageformat-parser/error.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ErrorKind = void 0; + var ErrorKind; + (function(ErrorKind2) { + ErrorKind2[ErrorKind2["EXPECT_ARGUMENT_CLOSING_BRACE"] = 1] = "EXPECT_ARGUMENT_CLOSING_BRACE"; + ErrorKind2[ErrorKind2["EMPTY_ARGUMENT"] = 2] = "EMPTY_ARGUMENT"; + ErrorKind2[ErrorKind2["MALFORMED_ARGUMENT"] = 3] = "MALFORMED_ARGUMENT"; + ErrorKind2[ErrorKind2["EXPECT_ARGUMENT_TYPE"] = 4] = "EXPECT_ARGUMENT_TYPE"; + ErrorKind2[ErrorKind2["INVALID_ARGUMENT_TYPE"] = 5] = "INVALID_ARGUMENT_TYPE"; + ErrorKind2[ErrorKind2["EXPECT_ARGUMENT_STYLE"] = 6] = "EXPECT_ARGUMENT_STYLE"; + ErrorKind2[ErrorKind2["INVALID_NUMBER_SKELETON"] = 7] = "INVALID_NUMBER_SKELETON"; + ErrorKind2[ErrorKind2["INVALID_DATE_TIME_SKELETON"] = 8] = "INVALID_DATE_TIME_SKELETON"; + ErrorKind2[ErrorKind2["EXPECT_NUMBER_SKELETON"] = 9] = "EXPECT_NUMBER_SKELETON"; + ErrorKind2[ErrorKind2["EXPECT_DATE_TIME_SKELETON"] = 10] = "EXPECT_DATE_TIME_SKELETON"; + ErrorKind2[ErrorKind2["UNCLOSED_QUOTE_IN_ARGUMENT_STYLE"] = 11] = "UNCLOSED_QUOTE_IN_ARGUMENT_STYLE"; + ErrorKind2[ErrorKind2["EXPECT_SELECT_ARGUMENT_OPTIONS"] = 12] = "EXPECT_SELECT_ARGUMENT_OPTIONS"; + ErrorKind2[ErrorKind2["EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE"] = 13] = "EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE"; + ErrorKind2[ErrorKind2["INVALID_PLURAL_ARGUMENT_OFFSET_VALUE"] = 14] = "INVALID_PLURAL_ARGUMENT_OFFSET_VALUE"; + ErrorKind2[ErrorKind2["EXPECT_SELECT_ARGUMENT_SELECTOR"] = 15] = "EXPECT_SELECT_ARGUMENT_SELECTOR"; + ErrorKind2[ErrorKind2["EXPECT_PLURAL_ARGUMENT_SELECTOR"] = 16] = "EXPECT_PLURAL_ARGUMENT_SELECTOR"; + ErrorKind2[ErrorKind2["EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT"] = 17] = "EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT"; + ErrorKind2[ErrorKind2["EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT"] = 18] = "EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT"; + ErrorKind2[ErrorKind2["INVALID_PLURAL_ARGUMENT_SELECTOR"] = 19] = "INVALID_PLURAL_ARGUMENT_SELECTOR"; + ErrorKind2[ErrorKind2["DUPLICATE_PLURAL_ARGUMENT_SELECTOR"] = 20] = "DUPLICATE_PLURAL_ARGUMENT_SELECTOR"; + ErrorKind2[ErrorKind2["DUPLICATE_SELECT_ARGUMENT_SELECTOR"] = 21] = "DUPLICATE_SELECT_ARGUMENT_SELECTOR"; + ErrorKind2[ErrorKind2["MISSING_OTHER_CLAUSE"] = 22] = "MISSING_OTHER_CLAUSE"; + ErrorKind2[ErrorKind2["INVALID_TAG"] = 23] = "INVALID_TAG"; + ErrorKind2[ErrorKind2["INVALID_TAG_NAME"] = 25] = "INVALID_TAG_NAME"; + ErrorKind2[ErrorKind2["UNMATCHED_CLOSING_TAG"] = 26] = "UNMATCHED_CLOSING_TAG"; + ErrorKind2[ErrorKind2["UNCLOSED_TAG"] = 27] = "UNCLOSED_TAG"; + })(ErrorKind = exports2.ErrorKind || (exports2.ErrorKind = {})); + } +}); + +// node_modules/@formatjs/icu-messageformat-parser/types.js +var require_types = __commonJS({ + "node_modules/@formatjs/icu-messageformat-parser/types.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createNumberElement = exports2.createLiteralElement = exports2.isDateTimeSkeleton = exports2.isNumberSkeleton = exports2.isTagElement = exports2.isPoundElement = exports2.isPluralElement = exports2.isSelectElement = exports2.isTimeElement = exports2.isDateElement = exports2.isNumberElement = exports2.isArgumentElement = exports2.isLiteralElement = exports2.SKELETON_TYPE = exports2.TYPE = void 0; + var TYPE2; + (function(TYPE3) { + TYPE3[TYPE3["literal"] = 0] = "literal"; + TYPE3[TYPE3["argument"] = 1] = "argument"; + TYPE3[TYPE3["number"] = 2] = "number"; + TYPE3[TYPE3["date"] = 3] = "date"; + TYPE3[TYPE3["time"] = 4] = "time"; + TYPE3[TYPE3["select"] = 5] = "select"; + TYPE3[TYPE3["plural"] = 6] = "plural"; + TYPE3[TYPE3["pound"] = 7] = "pound"; + TYPE3[TYPE3["tag"] = 8] = "tag"; + })(TYPE2 = exports2.TYPE || (exports2.TYPE = {})); + var SKELETON_TYPE; + (function(SKELETON_TYPE2) { + SKELETON_TYPE2[SKELETON_TYPE2["number"] = 0] = "number"; + SKELETON_TYPE2[SKELETON_TYPE2["dateTime"] = 1] = "dateTime"; + })(SKELETON_TYPE = exports2.SKELETON_TYPE || (exports2.SKELETON_TYPE = {})); + function isLiteralElement(el) { + return el.type === TYPE2.literal; + } + __name(isLiteralElement, "isLiteralElement"); + exports2.isLiteralElement = isLiteralElement; + function isArgumentElement(el) { + return el.type === TYPE2.argument; + } + __name(isArgumentElement, "isArgumentElement"); + exports2.isArgumentElement = isArgumentElement; + function isNumberElement(el) { + return el.type === TYPE2.number; + } + __name(isNumberElement, "isNumberElement"); + exports2.isNumberElement = isNumberElement; + function isDateElement(el) { + return el.type === TYPE2.date; + } + __name(isDateElement, "isDateElement"); + exports2.isDateElement = isDateElement; + function isTimeElement(el) { + return el.type === TYPE2.time; + } + __name(isTimeElement, "isTimeElement"); + exports2.isTimeElement = isTimeElement; + function isSelectElement(el) { + return el.type === TYPE2.select; + } + __name(isSelectElement, "isSelectElement"); + exports2.isSelectElement = isSelectElement; + function isPluralElement(el) { + return el.type === TYPE2.plural; + } + __name(isPluralElement, "isPluralElement"); + exports2.isPluralElement = isPluralElement; + function isPoundElement(el) { + return el.type === TYPE2.pound; + } + __name(isPoundElement, "isPoundElement"); + exports2.isPoundElement = isPoundElement; + function isTagElement(el) { + return el.type === TYPE2.tag; + } + __name(isTagElement, "isTagElement"); + exports2.isTagElement = isTagElement; + function isNumberSkeleton(el) { + return !!(el && typeof el === "object" && el.type === SKELETON_TYPE.number); + } + __name(isNumberSkeleton, "isNumberSkeleton"); + exports2.isNumberSkeleton = isNumberSkeleton; + function isDateTimeSkeleton(el) { + return !!(el && typeof el === "object" && el.type === SKELETON_TYPE.dateTime); + } + __name(isDateTimeSkeleton, "isDateTimeSkeleton"); + exports2.isDateTimeSkeleton = isDateTimeSkeleton; + function createLiteralElement(value) { + return { + type: TYPE2.literal, + value + }; + } + __name(createLiteralElement, "createLiteralElement"); + exports2.createLiteralElement = createLiteralElement; + function createNumberElement(value, style) { + return { + type: TYPE2.number, + value, + style + }; + } + __name(createNumberElement, "createNumberElement"); + exports2.createNumberElement = createNumberElement; + } +}); + +// node_modules/@formatjs/icu-messageformat-parser/regex.generated.js +var require_regex_generated = __commonJS({ + "node_modules/@formatjs/icu-messageformat-parser/regex.generated.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.WHITE_SPACE_REGEX = exports2.SPACE_SEPARATOR_REGEX = void 0; + exports2.SPACE_SEPARATOR_REGEX = /[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/; + exports2.WHITE_SPACE_REGEX = /[\t-\r \x85\u200E\u200F\u2028\u2029]/; + } +}); + +// node_modules/@formatjs/icu-skeleton-parser/node_modules/tslib/tslib.es6.mjs +var tslib_es6_exports3 = {}; +__export(tslib_es6_exports3, { + __addDisposableResource: () => __addDisposableResource3, + __assign: () => __assign3, + __asyncDelegator: () => __asyncDelegator3, + __asyncGenerator: () => __asyncGenerator3, + __asyncValues: () => __asyncValues3, + __await: () => __await3, + __awaiter: () => __awaiter3, + __classPrivateFieldGet: () => __classPrivateFieldGet3, + __classPrivateFieldIn: () => __classPrivateFieldIn3, + __classPrivateFieldSet: () => __classPrivateFieldSet3, + __createBinding: () => __createBinding3, + __decorate: () => __decorate3, + __disposeResources: () => __disposeResources3, + __esDecorate: () => __esDecorate3, + __exportStar: () => __exportStar3, + __extends: () => __extends3, + __generator: () => __generator3, + __importDefault: () => __importDefault3, + __importStar: () => __importStar3, + __makeTemplateObject: () => __makeTemplateObject3, + __metadata: () => __metadata3, + __param: () => __param3, + __propKey: () => __propKey3, + __read: () => __read3, + __rest: () => __rest3, + __runInitializers: () => __runInitializers3, + __setFunctionName: () => __setFunctionName3, + __spread: () => __spread3, + __spreadArray: () => __spreadArray3, + __spreadArrays: () => __spreadArrays3, + __values: () => __values3, + default: () => tslib_es6_default3 +}); +function __extends3(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics3(d, b); + function __() { + this.constructor = d; + } + __name(__, "__"); + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} +function __rest3(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} +function __decorate3(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} +function __param3(paramIndex, decorator) { + return function(target, key) { + decorator(target, key, paramIndex); + }; +} +function __esDecorate3(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { + if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); + return f; + } + __name(accept, "accept"); + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function(f) { + if (done) throw new TypeError("Cannot add initializers after decoration has completed"); + extraInitializers.push(accept(f || null)); + }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +} +function __runInitializers3(thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +} +function __propKey3(x) { + return typeof x === "symbol" ? x : "".concat(x); +} +function __setFunctionName3(f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +} +function __metadata3(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} +function __awaiter3(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + __name(adopt, "adopt"); + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + __name(fulfilled, "fulfilled"); + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + __name(rejected, "rejected"); + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + __name(step, "step"); + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} +function __generator3(thisArg, body) { + var _ = { label: 0, sent: /* @__PURE__ */ __name(function() { + if (t[0] & 1) throw t[1]; + return t[1]; + }, "sent"), trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { + return this; + }), g; + function verb(n) { + return function(v) { + return step([n, v]); + }; + } + __name(verb, "verb"); + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + __name(step, "step"); +} +function __exportStar3(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding3(o, m, p); +} +function __values3(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: /* @__PURE__ */ __name(function() { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + }, "next") + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} +function __read3(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { error }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + return ar; +} +function __spread3() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read3(arguments[i])); + return ar; +} +function __spreadArrays3() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +} +function __spreadArray3(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +} +function __await3(v) { + return this instanceof __await3 ? (this.v = v, this) : new __await3(v); +} +function __asyncGenerator3(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i; + function verb(n) { + if (g[n]) i[n] = function(v) { + return new Promise(function(a, b) { + q.push([n, v, a, b]) > 1 || resume(n, v); + }); + }; + } + __name(verb, "verb"); + function resume(n, v) { + try { + step(g[n](v)); + } catch (e) { + settle(q[0][3], e); + } + } + __name(resume, "resume"); + function step(r) { + r.value instanceof __await3 ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); + } + __name(step, "step"); + function fulfill(value) { + resume("next", value); + } + __name(fulfill, "fulfill"); + function reject(value) { + resume("throw", value); + } + __name(reject, "reject"); + function settle(f, v) { + if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); + } + __name(settle, "settle"); +} +function __asyncDelegator3(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function(e) { + throw e; + }), verb("return"), i[Symbol.iterator] = function() { + return this; + }, i; + function verb(n, f) { + i[n] = o[n] ? function(v) { + return (p = !p) ? { value: __await3(o[n](v)), done: false } : f ? f(v) : v; + } : f; + } + __name(verb, "verb"); +} +function __asyncValues3(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values3 === "function" ? __values3(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i); + function verb(n) { + i[n] = o[n] && function(v) { + return new Promise(function(resolve, reject) { + v = o[n](v), settle(resolve, reject, v.done, v.value); + }); + }; + } + __name(verb, "verb"); + function settle(resolve, reject, d, v) { + Promise.resolve(v).then(function(v2) { + resolve({ value: v2, done: d }); + }, reject); + } + __name(settle, "settle"); +} +function __makeTemplateObject3(cooked, raw) { + if (Object.defineProperty) { + Object.defineProperty(cooked, "raw", { value: raw }); + } else { + cooked.raw = raw; + } + return cooked; +} +function __importStar3(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding3(result, mod2, k); + } + __setModuleDefault3(result, mod2); + return result; +} +function __importDefault3(mod2) { + return mod2 && mod2.__esModule ? mod2 : { default: mod2 }; +} +function __classPrivateFieldGet3(receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +} +function __classPrivateFieldSet3(receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; +} +function __classPrivateFieldIn3(state, receiver) { + if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function") throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); +} +function __addDisposableResource3(env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + env.stack.push({ value, dispose, async }); + } else if (async) { + env.stack.push({ async: true }); + } + return value; +} +function __disposeResources3(env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError3(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + __name(fail, "fail"); + function next() { + while (env.stack.length) { + var rec = env.stack.pop(); + try { + var result = rec.dispose && rec.dispose.call(rec.value); + if (rec.async) return Promise.resolve(result).then(next, function(e) { + fail(e); + return next(); + }); + } catch (e) { + fail(e); + } + } + if (env.hasError) throw env.error; + } + __name(next, "next"); + return next(); +} +var extendStatics3, __assign3, __createBinding3, __setModuleDefault3, _SuppressedError3, tslib_es6_default3; +var init_tslib_es63 = __esm({ + "node_modules/@formatjs/icu-skeleton-parser/node_modules/tslib/tslib.es6.mjs"() { + init_process_global(); + extendStatics3 = /* @__PURE__ */ __name(function(d, b) { + extendStatics3 = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { + d2.__proto__ = b2; + } || function(d2, b2) { + for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p]; + }; + return extendStatics3(d, b); + }, "extendStatics"); + __name(__extends3, "__extends"); + __assign3 = /* @__PURE__ */ __name(function() { + __assign3 = Object.assign || /* @__PURE__ */ __name(function __assign4(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }, "__assign"); + return __assign3.apply(this, arguments); + }, "__assign"); + __name(__rest3, "__rest"); + __name(__decorate3, "__decorate"); + __name(__param3, "__param"); + __name(__esDecorate3, "__esDecorate"); + __name(__runInitializers3, "__runInitializers"); + __name(__propKey3, "__propKey"); + __name(__setFunctionName3, "__setFunctionName"); + __name(__metadata3, "__metadata"); + __name(__awaiter3, "__awaiter"); + __name(__generator3, "__generator"); + __createBinding3 = Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: /* @__PURE__ */ __name(function() { + return m[k]; + }, "get") }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + __name(__exportStar3, "__exportStar"); + __name(__values3, "__values"); + __name(__read3, "__read"); + __name(__spread3, "__spread"); + __name(__spreadArrays3, "__spreadArrays"); + __name(__spreadArray3, "__spreadArray"); + __name(__await3, "__await"); + __name(__asyncGenerator3, "__asyncGenerator"); + __name(__asyncDelegator3, "__asyncDelegator"); + __name(__asyncValues3, "__asyncValues"); + __name(__makeTemplateObject3, "__makeTemplateObject"); + __setModuleDefault3 = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }; + __name(__importStar3, "__importStar"); + __name(__importDefault3, "__importDefault"); + __name(__classPrivateFieldGet3, "__classPrivateFieldGet"); + __name(__classPrivateFieldSet3, "__classPrivateFieldSet"); + __name(__classPrivateFieldIn3, "__classPrivateFieldIn"); + __name(__addDisposableResource3, "__addDisposableResource"); + _SuppressedError3 = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + __name(__disposeResources3, "__disposeResources"); + tslib_es6_default3 = { + __extends: __extends3, + __assign: __assign3, + __rest: __rest3, + __decorate: __decorate3, + __param: __param3, + __metadata: __metadata3, + __awaiter: __awaiter3, + __generator: __generator3, + __createBinding: __createBinding3, + __exportStar: __exportStar3, + __values: __values3, + __read: __read3, + __spread: __spread3, + __spreadArrays: __spreadArrays3, + __spreadArray: __spreadArray3, + __await: __await3, + __asyncGenerator: __asyncGenerator3, + __asyncDelegator: __asyncDelegator3, + __asyncValues: __asyncValues3, + __makeTemplateObject: __makeTemplateObject3, + __importStar: __importStar3, + __importDefault: __importDefault3, + __classPrivateFieldGet: __classPrivateFieldGet3, + __classPrivateFieldSet: __classPrivateFieldSet3, + __classPrivateFieldIn: __classPrivateFieldIn3, + __addDisposableResource: __addDisposableResource3, + __disposeResources: __disposeResources3 + }; + } +}); + +// node_modules/@formatjs/icu-skeleton-parser/date-time.js +var require_date_time = __commonJS({ + "node_modules/@formatjs/icu-skeleton-parser/date-time.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.parseDateTimeSkeleton = void 0; + var DATE_TIME_REGEX = /(?:[Eec]{1,6}|G{1,5}|[Qq]{1,5}|(?:[yYur]+|U{1,5})|[ML]{1,5}|d{1,2}|D{1,3}|F{1}|[abB]{1,5}|[hkHK]{1,2}|w{1,2}|W{1}|m{1,2}|s{1,2}|[zZOvVxX]{1,4})(?=([^']*'[^']*')*[^']*$)/g; + function parseDateTimeSkeleton(skeleton) { + var result = {}; + skeleton.replace(DATE_TIME_REGEX, function(match) { + var len = match.length; + switch (match[0]) { + // Era + case "G": + result.era = len === 4 ? "long" : len === 5 ? "narrow" : "short"; + break; + // Year + case "y": + result.year = len === 2 ? "2-digit" : "numeric"; + break; + case "Y": + case "u": + case "U": + case "r": + throw new RangeError("`Y/u/U/r` (year) patterns are not supported, use `y` instead"); + // Quarter + case "q": + case "Q": + throw new RangeError("`q/Q` (quarter) patterns are not supported"); + // Month + case "M": + case "L": + result.month = ["numeric", "2-digit", "short", "long", "narrow"][len - 1]; + break; + // Week + case "w": + case "W": + throw new RangeError("`w/W` (week) patterns are not supported"); + case "d": + result.day = ["numeric", "2-digit"][len - 1]; + break; + case "D": + case "F": + case "g": + throw new RangeError("`D/F/g` (day) patterns are not supported, use `d` instead"); + // Weekday + case "E": + result.weekday = len === 4 ? "short" : len === 5 ? "narrow" : "short"; + break; + case "e": + if (len < 4) { + throw new RangeError("`e..eee` (weekday) patterns are not supported"); + } + result.weekday = ["short", "long", "narrow", "short"][len - 4]; + break; + case "c": + if (len < 4) { + throw new RangeError("`c..ccc` (weekday) patterns are not supported"); + } + result.weekday = ["short", "long", "narrow", "short"][len - 4]; + break; + // Period + case "a": + result.hour12 = true; + break; + case "b": + // am, pm, noon, midnight + case "B": + throw new RangeError("`b/B` (period) patterns are not supported, use `a` instead"); + // Hour + case "h": + result.hourCycle = "h12"; + result.hour = ["numeric", "2-digit"][len - 1]; + break; + case "H": + result.hourCycle = "h23"; + result.hour = ["numeric", "2-digit"][len - 1]; + break; + case "K": + result.hourCycle = "h11"; + result.hour = ["numeric", "2-digit"][len - 1]; + break; + case "k": + result.hourCycle = "h24"; + result.hour = ["numeric", "2-digit"][len - 1]; + break; + case "j": + case "J": + case "C": + throw new RangeError("`j/J/C` (hour) patterns are not supported, use `h/H/K/k` instead"); + // Minute + case "m": + result.minute = ["numeric", "2-digit"][len - 1]; + break; + // Second + case "s": + result.second = ["numeric", "2-digit"][len - 1]; + break; + case "S": + case "A": + throw new RangeError("`S/A` (second) patterns are not supported, use `s` instead"); + // Zone + case "z": + result.timeZoneName = len < 4 ? "short" : "long"; + break; + case "Z": + // 1..3, 4, 5: The ISO8601 varios formats + case "O": + // 1, 4: miliseconds in day short, long + case "v": + // 1, 4: generic non-location format + case "V": + // 1, 2, 3, 4: time zone ID or city + case "X": + // 1, 2, 3, 4: The ISO8601 varios formats + case "x": + throw new RangeError("`Z/O/v/V/X/x` (timeZone) patterns are not supported, use `z` instead"); + } + return ""; + }); + return result; + } + __name(parseDateTimeSkeleton, "parseDateTimeSkeleton"); + exports2.parseDateTimeSkeleton = parseDateTimeSkeleton; + } +}); + +// node_modules/@formatjs/icu-skeleton-parser/regex.generated.js +var require_regex_generated2 = __commonJS({ + "node_modules/@formatjs/icu-skeleton-parser/regex.generated.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.WHITE_SPACE_REGEX = void 0; + exports2.WHITE_SPACE_REGEX = /[\t-\r \x85\u200E\u200F\u2028\u2029]/i; + } +}); + +// node_modules/@formatjs/icu-skeleton-parser/number.js +var require_number = __commonJS({ + "node_modules/@formatjs/icu-skeleton-parser/number.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.parseNumberSkeleton = exports2.parseNumberSkeletonFromString = void 0; + var tslib_1 = (init_tslib_es63(), __toCommonJS(tslib_es6_exports3)); + var regex_generated_1 = require_regex_generated2(); + function parseNumberSkeletonFromString(skeleton) { + if (skeleton.length === 0) { + throw new Error("Number skeleton cannot be empty"); + } + var stringTokens = skeleton.split(regex_generated_1.WHITE_SPACE_REGEX).filter(function(x) { + return x.length > 0; + }); + var tokens = []; + for (var _i = 0, stringTokens_1 = stringTokens; _i < stringTokens_1.length; _i++) { + var stringToken = stringTokens_1[_i]; + var stemAndOptions = stringToken.split("/"); + if (stemAndOptions.length === 0) { + throw new Error("Invalid number skeleton"); + } + var stem = stemAndOptions[0], options = stemAndOptions.slice(1); + for (var _a3 = 0, options_1 = options; _a3 < options_1.length; _a3++) { + var option = options_1[_a3]; + if (option.length === 0) { + throw new Error("Invalid number skeleton"); + } + } + tokens.push({ stem, options }); + } + return tokens; + } + __name(parseNumberSkeletonFromString, "parseNumberSkeletonFromString"); + exports2.parseNumberSkeletonFromString = parseNumberSkeletonFromString; + function icuUnitToEcma(unit) { + return unit.replace(/^(.*?)-/, ""); + } + __name(icuUnitToEcma, "icuUnitToEcma"); + var FRACTION_PRECISION_REGEX = /^\.(?:(0+)(\*)?|(#+)|(0+)(#+))$/g; + var SIGNIFICANT_PRECISION_REGEX = /^(@+)?(\+|#+)?[rs]?$/g; + var INTEGER_WIDTH_REGEX = /(\*)(0+)|(#+)(0+)|(0+)/g; + var CONCISE_INTEGER_WIDTH_REGEX = /^(0+)$/; + function parseSignificantPrecision(str) { + var result = {}; + if (str[str.length - 1] === "r") { + result.roundingPriority = "morePrecision"; + } else if (str[str.length - 1] === "s") { + result.roundingPriority = "lessPrecision"; + } + str.replace(SIGNIFICANT_PRECISION_REGEX, function(_, g1, g2) { + if (typeof g2 !== "string") { + result.minimumSignificantDigits = g1.length; + result.maximumSignificantDigits = g1.length; + } else if (g2 === "+") { + result.minimumSignificantDigits = g1.length; + } else if (g1[0] === "#") { + result.maximumSignificantDigits = g1.length; + } else { + result.minimumSignificantDigits = g1.length; + result.maximumSignificantDigits = g1.length + (typeof g2 === "string" ? g2.length : 0); + } + return ""; + }); + return result; + } + __name(parseSignificantPrecision, "parseSignificantPrecision"); + function parseSign(str) { + switch (str) { + case "sign-auto": + return { + signDisplay: "auto" + }; + case "sign-accounting": + case "()": + return { + currencySign: "accounting" + }; + case "sign-always": + case "+!": + return { + signDisplay: "always" + }; + case "sign-accounting-always": + case "()!": + return { + signDisplay: "always", + currencySign: "accounting" + }; + case "sign-except-zero": + case "+?": + return { + signDisplay: "exceptZero" + }; + case "sign-accounting-except-zero": + case "()?": + return { + signDisplay: "exceptZero", + currencySign: "accounting" + }; + case "sign-never": + case "+_": + return { + signDisplay: "never" + }; + } + } + __name(parseSign, "parseSign"); + function parseConciseScientificAndEngineeringStem(stem) { + var result; + if (stem[0] === "E" && stem[1] === "E") { + result = { + notation: "engineering" + }; + stem = stem.slice(2); + } else if (stem[0] === "E") { + result = { + notation: "scientific" + }; + stem = stem.slice(1); + } + if (result) { + var signDisplay = stem.slice(0, 2); + if (signDisplay === "+!") { + result.signDisplay = "always"; + stem = stem.slice(2); + } else if (signDisplay === "+?") { + result.signDisplay = "exceptZero"; + stem = stem.slice(2); + } + if (!CONCISE_INTEGER_WIDTH_REGEX.test(stem)) { + throw new Error("Malformed concise eng/scientific notation"); + } + result.minimumIntegerDigits = stem.length; + } + return result; + } + __name(parseConciseScientificAndEngineeringStem, "parseConciseScientificAndEngineeringStem"); + function parseNotationOptions(opt) { + var result = {}; + var signOpts = parseSign(opt); + if (signOpts) { + return signOpts; + } + return result; + } + __name(parseNotationOptions, "parseNotationOptions"); + function parseNumberSkeleton(tokens) { + var result = {}; + for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) { + var token = tokens_1[_i]; + switch (token.stem) { + case "percent": + case "%": + result.style = "percent"; + continue; + case "%x100": + result.style = "percent"; + result.scale = 100; + continue; + case "currency": + result.style = "currency"; + result.currency = token.options[0]; + continue; + case "group-off": + case ",_": + result.useGrouping = false; + continue; + case "precision-integer": + case ".": + result.maximumFractionDigits = 0; + continue; + case "measure-unit": + case "unit": + result.style = "unit"; + result.unit = icuUnitToEcma(token.options[0]); + continue; + case "compact-short": + case "K": + result.notation = "compact"; + result.compactDisplay = "short"; + continue; + case "compact-long": + case "KK": + result.notation = "compact"; + result.compactDisplay = "long"; + continue; + case "scientific": + result = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, result), { notation: "scientific" }), token.options.reduce(function(all, opt2) { + return tslib_1.__assign(tslib_1.__assign({}, all), parseNotationOptions(opt2)); + }, {})); + continue; + case "engineering": + result = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, result), { notation: "engineering" }), token.options.reduce(function(all, opt2) { + return tslib_1.__assign(tslib_1.__assign({}, all), parseNotationOptions(opt2)); + }, {})); + continue; + case "notation-simple": + result.notation = "standard"; + continue; + // https://github.com/unicode-org/icu/blob/master/icu4c/source/i18n/unicode/unumberformatter.h + case "unit-width-narrow": + result.currencyDisplay = "narrowSymbol"; + result.unitDisplay = "narrow"; + continue; + case "unit-width-short": + result.currencyDisplay = "code"; + result.unitDisplay = "short"; + continue; + case "unit-width-full-name": + result.currencyDisplay = "name"; + result.unitDisplay = "long"; + continue; + case "unit-width-iso-code": + result.currencyDisplay = "symbol"; + continue; + case "scale": + result.scale = parseFloat(token.options[0]); + continue; + // https://unicode-org.github.io/icu/userguide/format_parse/numbers/skeletons.html#integer-width + case "integer-width": + if (token.options.length > 1) { + throw new RangeError("integer-width stems only accept a single optional option"); + } + token.options[0].replace(INTEGER_WIDTH_REGEX, function(_, g1, g2, g3, g4, g5) { + if (g1) { + result.minimumIntegerDigits = g2.length; + } else if (g3 && g4) { + throw new Error("We currently do not support maximum integer digits"); + } else if (g5) { + throw new Error("We currently do not support exact integer digits"); + } + return ""; + }); + continue; + } + if (CONCISE_INTEGER_WIDTH_REGEX.test(token.stem)) { + result.minimumIntegerDigits = token.stem.length; + continue; + } + if (FRACTION_PRECISION_REGEX.test(token.stem)) { + if (token.options.length > 1) { + throw new RangeError("Fraction-precision stems only accept a single optional option"); + } + token.stem.replace(FRACTION_PRECISION_REGEX, function(_, g1, g2, g3, g4, g5) { + if (g2 === "*") { + result.minimumFractionDigits = g1.length; + } else if (g3 && g3[0] === "#") { + result.maximumFractionDigits = g3.length; + } else if (g4 && g5) { + result.minimumFractionDigits = g4.length; + result.maximumFractionDigits = g4.length + g5.length; + } else { + result.minimumFractionDigits = g1.length; + result.maximumFractionDigits = g1.length; + } + return ""; + }); + var opt = token.options[0]; + if (opt === "w") { + result = tslib_1.__assign(tslib_1.__assign({}, result), { trailingZeroDisplay: "stripIfInteger" }); + } else if (opt) { + result = tslib_1.__assign(tslib_1.__assign({}, result), parseSignificantPrecision(opt)); + } + continue; + } + if (SIGNIFICANT_PRECISION_REGEX.test(token.stem)) { + result = tslib_1.__assign(tslib_1.__assign({}, result), parseSignificantPrecision(token.stem)); + continue; + } + var signOpts = parseSign(token.stem); + if (signOpts) { + result = tslib_1.__assign(tslib_1.__assign({}, result), signOpts); + } + var conciseScientificAndEngineeringOpts = parseConciseScientificAndEngineeringStem(token.stem); + if (conciseScientificAndEngineeringOpts) { + result = tslib_1.__assign(tslib_1.__assign({}, result), conciseScientificAndEngineeringOpts); + } + } + return result; + } + __name(parseNumberSkeleton, "parseNumberSkeleton"); + exports2.parseNumberSkeleton = parseNumberSkeleton; + } +}); + +// node_modules/@formatjs/icu-skeleton-parser/index.js +var require_icu_skeleton_parser = __commonJS({ + "node_modules/@formatjs/icu-skeleton-parser/index.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + var tslib_1 = (init_tslib_es63(), __toCommonJS(tslib_es6_exports3)); + tslib_1.__exportStar(require_date_time(), exports2); + tslib_1.__exportStar(require_number(), exports2); + } +}); + +// node_modules/@formatjs/icu-messageformat-parser/time-data.generated.js +var require_time_data_generated = __commonJS({ + "node_modules/@formatjs/icu-messageformat-parser/time-data.generated.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.timeData = void 0; + exports2.timeData = { + "001": [ + "H", + "h" + ], + "AC": [ + "H", + "h", + "hb", + "hB" + ], + "AD": [ + "H", + "hB" + ], + "AE": [ + "h", + "hB", + "hb", + "H" + ], + "AF": [ + "H", + "hb", + "hB", + "h" + ], + "AG": [ + "h", + "hb", + "H", + "hB" + ], + "AI": [ + "H", + "h", + "hb", + "hB" + ], + "AL": [ + "h", + "H", + "hB" + ], + "AM": [ + "H", + "hB" + ], + "AO": [ + "H", + "hB" + ], + "AR": [ + "H", + "h", + "hB", + "hb" + ], + "AS": [ + "h", + "H" + ], + "AT": [ + "H", + "hB" + ], + "AU": [ + "h", + "hb", + "H", + "hB" + ], + "AW": [ + "H", + "hB" + ], + "AX": [ + "H" + ], + "AZ": [ + "H", + "hB", + "h" + ], + "BA": [ + "H", + "hB", + "h" + ], + "BB": [ + "h", + "hb", + "H", + "hB" + ], + "BD": [ + "h", + "hB", + "H" + ], + "BE": [ + "H", + "hB" + ], + "BF": [ + "H", + "hB" + ], + "BG": [ + "H", + "hB", + "h" + ], + "BH": [ + "h", + "hB", + "hb", + "H" + ], + "BJ": [ + "H", + "hB" + ], + "BL": [ + "H", + "hB" + ], + "BM": [ + "h", + "hb", + "H", + "hB" + ], + "BN": [ + "hb", + "hB", + "h", + "H" + ], + "BO": [ + "H", + "hB", + "h", + "hb" + ], + "BQ": [ + "H" + ], + "BR": [ + "H", + "hB" + ], + "BS": [ + "h", + "hb", + "H", + "hB" + ], + "BT": [ + "h", + "H" + ], + "BW": [ + "H", + "h", + "hb", + "hB" + ], + "BZ": [ + "H", + "h", + "hb", + "hB" + ], + "CA": [ + "h", + "hb", + "H", + "hB" + ], + "CC": [ + "H", + "h", + "hb", + "hB" + ], + "CD": [ + "hB", + "H" + ], + "CF": [ + "H", + "h", + "hB" + ], + "CG": [ + "H", + "hB" + ], + "CH": [ + "H", + "hB", + "h" + ], + "CI": [ + "H", + "hB" + ], + "CK": [ + "H", + "h", + "hb", + "hB" + ], + "CL": [ + "H", + "h", + "hB", + "hb" + ], + "CM": [ + "H", + "h", + "hB" + ], + "CN": [ + "H", + "hB", + "hb", + "h" + ], + "CO": [ + "h", + "H", + "hB", + "hb" + ], + "CP": [ + "H" + ], + "CR": [ + "H", + "h", + "hB", + "hb" + ], + "CU": [ + "H", + "h", + "hB", + "hb" + ], + "CV": [ + "H", + "hB" + ], + "CX": [ + "H", + "h", + "hb", + "hB" + ], + "CY": [ + "h", + "H", + "hb", + "hB" + ], + "CZ": [ + "H" + ], + "DE": [ + "H", + "hB" + ], + "DG": [ + "H", + "h", + "hb", + "hB" + ], + "DJ": [ + "h", + "H" + ], + "DK": [ + "H" + ], + "DM": [ + "h", + "hb", + "H", + "hB" + ], + "DO": [ + "h", + "H", + "hB", + "hb" + ], + "DZ": [ + "h", + "hB", + "hb", + "H" + ], + "EA": [ + "H", + "h", + "hB", + "hb" + ], + "EC": [ + "H", + "hB", + "h", + "hb" + ], + "EE": [ + "H", + "hB" + ], + "EG": [ + "h", + "hB", + "hb", + "H" + ], + "EH": [ + "h", + "hB", + "hb", + "H" + ], + "ER": [ + "h", + "H" + ], + "ES": [ + "H", + "hB", + "h", + "hb" + ], + "ET": [ + "hB", + "hb", + "h", + "H" + ], + "FI": [ + "H" + ], + "FJ": [ + "h", + "hb", + "H", + "hB" + ], + "FK": [ + "H", + "h", + "hb", + "hB" + ], + "FM": [ + "h", + "hb", + "H", + "hB" + ], + "FR": [ + "H", + "hB" + ], + "GA": [ + "H", + "hB" + ], + "GB": [ + "H", + "h", + "hb", + "hB" + ], + "GD": [ + "h", + "hb", + "H", + "hB" + ], + "GE": [ + "H", + "hB", + "h" + ], + "GF": [ + "H", + "hB" + ], + "GG": [ + "H", + "h", + "hb", + "hB" + ], + "GH": [ + "h", + "H" + ], + "GI": [ + "H", + "h", + "hb", + "hB" + ], + "GM": [ + "h", + "hb", + "H", + "hB" + ], + "GN": [ + "H", + "hB" + ], + "GP": [ + "H", + "hB" + ], + "GQ": [ + "H", + "hB", + "h", + "hb" + ], + "GR": [ + "h", + "H", + "hb", + "hB" + ], + "GT": [ + "H", + "h", + "hB", + "hb" + ], + "GU": [ + "h", + "hb", + "H", + "hB" + ], + "GW": [ + "H", + "hB" + ], + "GY": [ + "h", + "hb", + "H", + "hB" + ], + "HK": [ + "h", + "hB", + "hb", + "H" + ], + "HN": [ + "H", + "h", + "hB", + "hb" + ], + "HR": [ + "H", + "hB" + ], + "IC": [ + "H", + "h", + "hB", + "hb" + ], + "ID": [ + "H" + ], + "IE": [ + "H", + "h", + "hb", + "hB" + ], + "IL": [ + "H", + "hB" + ], + "IM": [ + "H", + "h", + "hb", + "hB" + ], + "IN": [ + "h", + "H" + ], + "IO": [ + "H", + "h", + "hb", + "hB" + ], + "IQ": [ + "h", + "hB", + "hb", + "H" + ], + "IR": [ + "hB", + "H" + ], + "IS": [ + "H" + ], + "IT": [ + "H", + "hB" + ], + "JE": [ + "H", + "h", + "hb", + "hB" + ], + "JM": [ + "h", + "hb", + "H", + "hB" + ], + "JO": [ + "h", + "hB", + "hb", + "H" + ], + "JP": [ + "H", + "h", + "K" + ], + "KE": [ + "hB", + "hb", + "H", + "h" + ], + "KG": [ + "H", + "h", + "hB", + "hb" + ], + "KH": [ + "hB", + "h", + "H", + "hb" + ], + "KI": [ + "h", + "hb", + "H", + "hB" + ], + "KM": [ + "H", + "h", + "hB", + "hb" + ], + "KN": [ + "h", + "hb", + "H", + "hB" + ], + "KP": [ + "h", + "H", + "hB", + "hb" + ], + "KR": [ + "h", + "H", + "hB", + "hb" + ], + "KW": [ + "h", + "hB", + "hb", + "H" + ], + "KY": [ + "h", + "hb", + "H", + "hB" + ], + "KZ": [ + "H", + "hB" + ], + "LA": [ + "H", + "hb", + "hB", + "h" + ], + "LB": [ + "h", + "hB", + "hb", + "H" + ], + "LC": [ + "h", + "hb", + "H", + "hB" + ], + "LI": [ + "H", + "hB", + "h" + ], + "LK": [ + "H", + "h", + "hB", + "hb" + ], + "LR": [ + "h", + "hb", + "H", + "hB" + ], + "LS": [ + "h", + "H" + ], + "LT": [ + "H", + "h", + "hb", + "hB" + ], + "LU": [ + "H", + "h", + "hB" + ], + "LV": [ + "H", + "hB", + "hb", + "h" + ], + "LY": [ + "h", + "hB", + "hb", + "H" + ], + "MA": [ + "H", + "h", + "hB", + "hb" + ], + "MC": [ + "H", + "hB" + ], + "MD": [ + "H", + "hB" + ], + "ME": [ + "H", + "hB", + "h" + ], + "MF": [ + "H", + "hB" + ], + "MH": [ + "h", + "hb", + "H", + "hB" + ], + "MK": [ + "H", + "h", + "hb", + "hB" + ], + "ML": [ + "H" + ], + "MM": [ + "hB", + "hb", + "H", + "h" + ], + "MN": [ + "H", + "h", + "hb", + "hB" + ], + "MO": [ + "h", + "hB", + "hb", + "H" + ], + "MP": [ + "h", + "hb", + "H", + "hB" + ], + "MQ": [ + "H", + "hB" + ], + "MR": [ + "h", + "hB", + "hb", + "H" + ], + "MS": [ + "H", + "h", + "hb", + "hB" + ], + "MW": [ + "h", + "hb", + "H", + "hB" + ], + "MX": [ + "H", + "h", + "hB", + "hb" + ], + "MY": [ + "hb", + "hB", + "h", + "H" + ], + "MZ": [ + "H", + "hB" + ], + "NA": [ + "h", + "H", + "hB", + "hb" + ], + "NC": [ + "H", + "hB" + ], + "NE": [ + "H" + ], + "NF": [ + "H", + "h", + "hb", + "hB" + ], + "NG": [ + "H", + "h", + "hb", + "hB" + ], + "NI": [ + "H", + "h", + "hB", + "hb" + ], + "NL": [ + "H", + "hB" + ], + "NP": [ + "H", + "h", + "hB" + ], + "NR": [ + "H", + "h", + "hb", + "hB" + ], + "NU": [ + "H", + "h", + "hb", + "hB" + ], + "NZ": [ + "h", + "hb", + "H", + "hB" + ], + "OM": [ + "h", + "hB", + "hb", + "H" + ], + "PA": [ + "h", + "H", + "hB", + "hb" + ], + "PE": [ + "H", + "hB", + "h", + "hb" + ], + "PF": [ + "H", + "h", + "hB" + ], + "PG": [ + "h", + "H" + ], + "PH": [ + "h", + "hB", + "hb", + "H" + ], + "PK": [ + "h", + "hB", + "H" + ], + "PM": [ + "H", + "hB" + ], + "PN": [ + "H", + "h", + "hb", + "hB" + ], + "PR": [ + "h", + "H", + "hB", + "hb" + ], + "PS": [ + "h", + "hB", + "hb", + "H" + ], + "PT": [ + "H", + "hB" + ], + "PW": [ + "h", + "H" + ], + "PY": [ + "H", + "h", + "hB", + "hb" + ], + "QA": [ + "h", + "hB", + "hb", + "H" + ], + "RE": [ + "H", + "hB" + ], + "RO": [ + "H", + "hB" + ], + "RS": [ + "H", + "hB", + "h" + ], + "RU": [ + "H" + ], + "SA": [ + "h", + "hB", + "hb", + "H" + ], + "SB": [ + "h", + "hb", + "H", + "hB" + ], + "SC": [ + "H", + "h", + "hB" + ], + "SD": [ + "h", + "hB", + "hb", + "H" + ], + "SE": [ + "H" + ], + "SG": [ + "h", + "hb", + "H", + "hB" + ], + "SH": [ + "H", + "h", + "hb", + "hB" + ], + "SI": [ + "H", + "hB" + ], + "SJ": [ + "H" + ], + "SK": [ + "H" + ], + "SL": [ + "h", + "hb", + "H", + "hB" + ], + "SM": [ + "H", + "h", + "hB" + ], + "SN": [ + "H", + "h", + "hB" + ], + "SO": [ + "h", + "H" + ], + "SR": [ + "H", + "hB" + ], + "SS": [ + "h", + "hb", + "H", + "hB" + ], + "ST": [ + "H", + "hB" + ], + "SV": [ + "H", + "h", + "hB", + "hb" + ], + "SX": [ + "H", + "h", + "hb", + "hB" + ], + "SY": [ + "h", + "hB", + "hb", + "H" + ], + "SZ": [ + "h", + "hb", + "H", + "hB" + ], + "TA": [ + "H", + "h", + "hb", + "hB" + ], + "TC": [ + "h", + "hb", + "H", + "hB" + ], + "TD": [ + "h", + "H", + "hB" + ], + "TF": [ + "H", + "h", + "hB" + ], + "TG": [ + "H", + "hB" + ], + "TL": [ + "H", + "hB", + "hb", + "h" + ], + "TN": [ + "h", + "hB", + "hb", + "H" + ], + "TO": [ + "h", + "H" + ], + "TR": [ + "H", + "hB" + ], + "TT": [ + "h", + "hb", + "H", + "hB" + ], + "TW": [ + "hB", + "hb", + "h", + "H" + ], + "TZ": [ + "hB", + "hb", + "H", + "h" + ], + "UA": [ + "H", + "hB", + "h" + ], + "UG": [ + "hB", + "hb", + "H", + "h" + ], + "UM": [ + "h", + "hb", + "H", + "hB" + ], + "US": [ + "h", + "hb", + "H", + "hB" + ], + "UY": [ + "H", + "h", + "hB", + "hb" + ], + "UZ": [ + "H", + "hB", + "h" + ], + "VA": [ + "H", + "h", + "hB" + ], + "VC": [ + "h", + "hb", + "H", + "hB" + ], + "VE": [ + "h", + "H", + "hB", + "hb" + ], + "VG": [ + "h", + "hb", + "H", + "hB" + ], + "VI": [ + "h", + "hb", + "H", + "hB" + ], + "VU": [ + "h", + "H" + ], + "WF": [ + "H", + "hB" + ], + "WS": [ + "h", + "H" + ], + "XK": [ + "H", + "hB", + "h" + ], + "YE": [ + "h", + "hB", + "hb", + "H" + ], + "YT": [ + "H", + "hB" + ], + "ZA": [ + "H", + "h", + "hb", + "hB" + ], + "ZM": [ + "h", + "hb", + "H", + "hB" + ], + "af-ZA": [ + "H", + "h", + "hB", + "hb" + ], + "ar-001": [ + "h", + "hB", + "hb", + "H" + ], + "ca-ES": [ + "H", + "h", + "hB" + ], + "en-001": [ + "h", + "hb", + "H", + "hB" + ], + "es-BO": [ + "H", + "h", + "hB", + "hb" + ], + "es-BR": [ + "H", + "h", + "hB", + "hb" + ], + "es-EC": [ + "H", + "h", + "hB", + "hb" + ], + "es-ES": [ + "H", + "h", + "hB", + "hb" + ], + "es-GQ": [ + "H", + "h", + "hB", + "hb" + ], + "es-PE": [ + "H", + "h", + "hB", + "hb" + ], + "fr-CA": [ + "H", + "h", + "hB" + ], + "gl-ES": [ + "H", + "h", + "hB" + ], + "gu-IN": [ + "hB", + "hb", + "h", + "H" + ], + "hi-IN": [ + "hB", + "h", + "H" + ], + "it-CH": [ + "H", + "h", + "hB" + ], + "it-IT": [ + "H", + "h", + "hB" + ], + "kn-IN": [ + "hB", + "h", + "H" + ], + "ml-IN": [ + "hB", + "h", + "H" + ], + "mr-IN": [ + "hB", + "hb", + "h", + "H" + ], + "pa-IN": [ + "hB", + "hb", + "h", + "H" + ], + "ta-IN": [ + "hB", + "h", + "hb", + "H" + ], + "te-IN": [ + "hB", + "h", + "H" + ], + "zu-ZA": [ + "H", + "hB", + "hb", + "h" + ] + }; + } +}); + +// node_modules/@formatjs/icu-messageformat-parser/date-time-pattern-generator.js +var require_date_time_pattern_generator = __commonJS({ + "node_modules/@formatjs/icu-messageformat-parser/date-time-pattern-generator.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.getBestPattern = void 0; + var time_data_generated_1 = require_time_data_generated(); + function getBestPattern(skeleton, locale) { + var skeletonCopy = ""; + for (var patternPos = 0; patternPos < skeleton.length; patternPos++) { + var patternChar = skeleton.charAt(patternPos); + if (patternChar === "j") { + var extraLength = 0; + while (patternPos + 1 < skeleton.length && skeleton.charAt(patternPos + 1) === patternChar) { + extraLength++; + patternPos++; + } + var hourLen = 1 + (extraLength & 1); + var dayPeriodLen = extraLength < 2 ? 1 : 3 + (extraLength >> 1); + var dayPeriodChar = "a"; + var hourChar = getDefaultHourSymbolFromLocale(locale); + if (hourChar == "H" || hourChar == "k") { + dayPeriodLen = 0; + } + while (dayPeriodLen-- > 0) { + skeletonCopy += dayPeriodChar; + } + while (hourLen-- > 0) { + skeletonCopy = hourChar + skeletonCopy; + } + } else if (patternChar === "J") { + skeletonCopy += "H"; + } else { + skeletonCopy += patternChar; + } + } + return skeletonCopy; + } + __name(getBestPattern, "getBestPattern"); + exports2.getBestPattern = getBestPattern; + function getDefaultHourSymbolFromLocale(locale) { + var hourCycle = locale.hourCycle; + if (hourCycle === void 0 && // @ts-ignore hourCycle(s) is not identified yet + locale.hourCycles && // @ts-ignore + locale.hourCycles.length) { + hourCycle = locale.hourCycles[0]; + } + if (hourCycle) { + switch (hourCycle) { + case "h24": + return "k"; + case "h23": + return "H"; + case "h12": + return "h"; + case "h11": + return "K"; + default: + throw new Error("Invalid hourCycle"); + } + } + var languageTag = locale.language; + var regionTag; + if (languageTag !== "root") { + regionTag = locale.maximize().region; + } + var hourCycles = time_data_generated_1.timeData[regionTag || ""] || time_data_generated_1.timeData[languageTag || ""] || time_data_generated_1.timeData["".concat(languageTag, "-001")] || time_data_generated_1.timeData["001"]; + return hourCycles[0]; + } + __name(getDefaultHourSymbolFromLocale, "getDefaultHourSymbolFromLocale"); + } +}); + +// node_modules/@formatjs/icu-messageformat-parser/parser.js +var require_parser = __commonJS({ + "node_modules/@formatjs/icu-messageformat-parser/parser.js"(exports2) { + "use strict"; + init_process_global(); + var _a3; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Parser = void 0; + var tslib_1 = (init_tslib_es62(), __toCommonJS(tslib_es6_exports2)); + var error_1 = require_error(); + var types_1 = require_types(); + var regex_generated_1 = require_regex_generated(); + var icu_skeleton_parser_1 = require_icu_skeleton_parser(); + var date_time_pattern_generator_1 = require_date_time_pattern_generator(); + var SPACE_SEPARATOR_START_REGEX = new RegExp("^".concat(regex_generated_1.SPACE_SEPARATOR_REGEX.source, "*")); + var SPACE_SEPARATOR_END_REGEX = new RegExp("".concat(regex_generated_1.SPACE_SEPARATOR_REGEX.source, "*$")); + function createLocation(start, end) { + return { start, end }; + } + __name(createLocation, "createLocation"); + var hasNativeStartsWith = !!String.prototype.startsWith && "_a".startsWith("a", 1); + var hasNativeFromCodePoint = !!String.fromCodePoint; + var hasNativeFromEntries = !!Object.fromEntries; + var hasNativeCodePointAt = !!String.prototype.codePointAt; + var hasTrimStart = !!String.prototype.trimStart; + var hasTrimEnd = !!String.prototype.trimEnd; + var hasNativeIsSafeInteger = !!Number.isSafeInteger; + var isSafeInteger = hasNativeIsSafeInteger ? Number.isSafeInteger : function(n) { + return typeof n === "number" && isFinite(n) && Math.floor(n) === n && Math.abs(n) <= 9007199254740991; + }; + var REGEX_SUPPORTS_U_AND_Y = true; + try { + re = RE("([^\\p{White_Space}\\p{Pattern_Syntax}]*)", "yu"); + REGEX_SUPPORTS_U_AND_Y = ((_a3 = re.exec("a")) === null || _a3 === void 0 ? void 0 : _a3[0]) === "a"; + } catch (_) { + REGEX_SUPPORTS_U_AND_Y = false; + } + var re; + var startsWith = hasNativeStartsWith ? ( + // Native + /* @__PURE__ */ __name(function startsWith2(s, search, position) { + return s.startsWith(search, position); + }, "startsWith") + ) : ( + // For IE11 + /* @__PURE__ */ __name(function startsWith2(s, search, position) { + return s.slice(position, position + search.length) === search; + }, "startsWith") + ); + var fromCodePoint = hasNativeFromCodePoint ? String.fromCodePoint : ( + // IE11 + /* @__PURE__ */ __name(function fromCodePoint2() { + var codePoints = []; + for (var _i = 0; _i < arguments.length; _i++) { + codePoints[_i] = arguments[_i]; + } + var elements = ""; + var length = codePoints.length; + var i = 0; + var code; + while (length > i) { + code = codePoints[i++]; + if (code > 1114111) + throw RangeError(code + " is not a valid code point"); + elements += code < 65536 ? String.fromCharCode(code) : String.fromCharCode(((code -= 65536) >> 10) + 55296, code % 1024 + 56320); + } + return elements; + }, "fromCodePoint") + ); + var fromEntries = ( + // native + hasNativeFromEntries ? Object.fromEntries : ( + // Ponyfill + /* @__PURE__ */ __name(function fromEntries2(entries) { + var obj = {}; + for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { + var _a4 = entries_1[_i], k = _a4[0], v = _a4[1]; + obj[k] = v; + } + return obj; + }, "fromEntries") + ) + ); + var codePointAt = hasNativeCodePointAt ? ( + // Native + /* @__PURE__ */ __name(function codePointAt2(s, index) { + return s.codePointAt(index); + }, "codePointAt") + ) : ( + // IE 11 + /* @__PURE__ */ __name(function codePointAt2(s, index) { + var size = s.length; + if (index < 0 || index >= size) { + return void 0; + } + var first = s.charCodeAt(index); + var second; + return first < 55296 || first > 56319 || index + 1 === size || (second = s.charCodeAt(index + 1)) < 56320 || second > 57343 ? first : (first - 55296 << 10) + (second - 56320) + 65536; + }, "codePointAt") + ); + var trimStart = hasTrimStart ? ( + // Native + /* @__PURE__ */ __name(function trimStart2(s) { + return s.trimStart(); + }, "trimStart") + ) : ( + // Ponyfill + /* @__PURE__ */ __name(function trimStart2(s) { + return s.replace(SPACE_SEPARATOR_START_REGEX, ""); + }, "trimStart") + ); + var trimEnd = hasTrimEnd ? ( + // Native + /* @__PURE__ */ __name(function trimEnd2(s) { + return s.trimEnd(); + }, "trimEnd") + ) : ( + // Ponyfill + /* @__PURE__ */ __name(function trimEnd2(s) { + return s.replace(SPACE_SEPARATOR_END_REGEX, ""); + }, "trimEnd") + ); + function RE(s, flag) { + return new RegExp(s, flag); + } + __name(RE, "RE"); + var matchIdentifierAtIndex; + if (REGEX_SUPPORTS_U_AND_Y) { + IDENTIFIER_PREFIX_RE_1 = RE("([^\\p{White_Space}\\p{Pattern_Syntax}]*)", "yu"); + matchIdentifierAtIndex = /* @__PURE__ */ __name(function matchIdentifierAtIndex2(s, index) { + var _a4; + IDENTIFIER_PREFIX_RE_1.lastIndex = index; + var match = IDENTIFIER_PREFIX_RE_1.exec(s); + return (_a4 = match[1]) !== null && _a4 !== void 0 ? _a4 : ""; + }, "matchIdentifierAtIndex"); + } else { + matchIdentifierAtIndex = /* @__PURE__ */ __name(function matchIdentifierAtIndex2(s, index) { + var match = []; + while (true) { + var c = codePointAt(s, index); + if (c === void 0 || _isWhiteSpace(c) || _isPatternSyntax(c)) { + break; + } + match.push(c); + index += c >= 65536 ? 2 : 1; + } + return fromCodePoint.apply(void 0, match); + }, "matchIdentifierAtIndex"); + } + var IDENTIFIER_PREFIX_RE_1; + var Parser = ( + /** @class */ + (function() { + function Parser2(message, options) { + if (options === void 0) { + options = {}; + } + this.message = message; + this.position = { offset: 0, line: 1, column: 1 }; + this.ignoreTag = !!options.ignoreTag; + this.locale = options.locale; + this.requiresOtherClause = !!options.requiresOtherClause; + this.shouldParseSkeletons = !!options.shouldParseSkeletons; + } + __name(Parser2, "Parser"); + Parser2.prototype.parse = function() { + if (this.offset() !== 0) { + throw Error("parser can only be used once"); + } + return this.parseMessage(0, "", false); + }; + Parser2.prototype.parseMessage = function(nestingLevel, parentArgType, expectingCloseTag) { + var elements = []; + while (!this.isEOF()) { + var char = this.char(); + if (char === 123) { + var result = this.parseArgument(nestingLevel, expectingCloseTag); + if (result.err) { + return result; + } + elements.push(result.val); + } else if (char === 125 && nestingLevel > 0) { + break; + } else if (char === 35 && (parentArgType === "plural" || parentArgType === "selectordinal")) { + var position = this.clonePosition(); + this.bump(); + elements.push({ + type: types_1.TYPE.pound, + location: createLocation(position, this.clonePosition()) + }); + } else if (char === 60 && !this.ignoreTag && this.peek() === 47) { + if (expectingCloseTag) { + break; + } else { + return this.error(error_1.ErrorKind.UNMATCHED_CLOSING_TAG, createLocation(this.clonePosition(), this.clonePosition())); + } + } else if (char === 60 && !this.ignoreTag && _isAlpha(this.peek() || 0)) { + var result = this.parseTag(nestingLevel, parentArgType); + if (result.err) { + return result; + } + elements.push(result.val); + } else { + var result = this.parseLiteral(nestingLevel, parentArgType); + if (result.err) { + return result; + } + elements.push(result.val); + } + } + return { val: elements, err: null }; + }; + Parser2.prototype.parseTag = function(nestingLevel, parentArgType) { + var startPosition = this.clonePosition(); + this.bump(); + var tagName = this.parseTagName(); + this.bumpSpace(); + if (this.bumpIf("/>")) { + return { + val: { + type: types_1.TYPE.literal, + value: "<".concat(tagName, "/>"), + location: createLocation(startPosition, this.clonePosition()) + }, + err: null + }; + } else if (this.bumpIf(">")) { + var childrenResult = this.parseMessage(nestingLevel + 1, parentArgType, true); + if (childrenResult.err) { + return childrenResult; + } + var children = childrenResult.val; + var endTagStartPosition = this.clonePosition(); + if (this.bumpIf("")) { + return this.error(error_1.ErrorKind.INVALID_TAG, createLocation(endTagStartPosition, this.clonePosition())); + } + return { + val: { + type: types_1.TYPE.tag, + value: tagName, + children, + location: createLocation(startPosition, this.clonePosition()) + }, + err: null + }; + } else { + return this.error(error_1.ErrorKind.UNCLOSED_TAG, createLocation(startPosition, this.clonePosition())); + } + } else { + return this.error(error_1.ErrorKind.INVALID_TAG, createLocation(startPosition, this.clonePosition())); + } + }; + Parser2.prototype.parseTagName = function() { + var startOffset = this.offset(); + this.bump(); + while (!this.isEOF() && _isPotentialElementNameChar(this.char())) { + this.bump(); + } + return this.message.slice(startOffset, this.offset()); + }; + Parser2.prototype.parseLiteral = function(nestingLevel, parentArgType) { + var start = this.clonePosition(); + var value = ""; + while (true) { + var parseQuoteResult = this.tryParseQuote(parentArgType); + if (parseQuoteResult) { + value += parseQuoteResult; + continue; + } + var parseUnquotedResult = this.tryParseUnquoted(nestingLevel, parentArgType); + if (parseUnquotedResult) { + value += parseUnquotedResult; + continue; + } + var parseLeftAngleResult = this.tryParseLeftAngleBracket(); + if (parseLeftAngleResult) { + value += parseLeftAngleResult; + continue; + } + break; + } + var location = createLocation(start, this.clonePosition()); + return { + val: { type: types_1.TYPE.literal, value, location }, + err: null + }; + }; + Parser2.prototype.tryParseLeftAngleBracket = function() { + if (!this.isEOF() && this.char() === 60 && (this.ignoreTag || // If at the opening tag or closing tag position, bail. + !_isAlphaOrSlash(this.peek() || 0))) { + this.bump(); + return "<"; + } + return null; + }; + Parser2.prototype.tryParseQuote = function(parentArgType) { + if (this.isEOF() || this.char() !== 39) { + return null; + } + switch (this.peek()) { + case 39: + this.bump(); + this.bump(); + return "'"; + // '{', '<', '>', '}' + case 123: + case 60: + case 62: + case 125: + break; + case 35: + if (parentArgType === "plural" || parentArgType === "selectordinal") { + break; + } + return null; + default: + return null; + } + this.bump(); + var codePoints = [this.char()]; + this.bump(); + while (!this.isEOF()) { + var ch = this.char(); + if (ch === 39) { + if (this.peek() === 39) { + codePoints.push(39); + this.bump(); + } else { + this.bump(); + break; + } + } else { + codePoints.push(ch); + } + this.bump(); + } + return fromCodePoint.apply(void 0, codePoints); + }; + Parser2.prototype.tryParseUnquoted = function(nestingLevel, parentArgType) { + if (this.isEOF()) { + return null; + } + var ch = this.char(); + if (ch === 60 || ch === 123 || ch === 35 && (parentArgType === "plural" || parentArgType === "selectordinal") || ch === 125 && nestingLevel > 0) { + return null; + } else { + this.bump(); + return fromCodePoint(ch); + } + }; + Parser2.prototype.parseArgument = function(nestingLevel, expectingCloseTag) { + var openingBracePosition = this.clonePosition(); + this.bump(); + this.bumpSpace(); + if (this.isEOF()) { + return this.error(error_1.ErrorKind.EXPECT_ARGUMENT_CLOSING_BRACE, createLocation(openingBracePosition, this.clonePosition())); + } + if (this.char() === 125) { + this.bump(); + return this.error(error_1.ErrorKind.EMPTY_ARGUMENT, createLocation(openingBracePosition, this.clonePosition())); + } + var value = this.parseIdentifierIfPossible().value; + if (!value) { + return this.error(error_1.ErrorKind.MALFORMED_ARGUMENT, createLocation(openingBracePosition, this.clonePosition())); + } + this.bumpSpace(); + if (this.isEOF()) { + return this.error(error_1.ErrorKind.EXPECT_ARGUMENT_CLOSING_BRACE, createLocation(openingBracePosition, this.clonePosition())); + } + switch (this.char()) { + // Simple argument: `{name}` + case 125: { + this.bump(); + return { + val: { + type: types_1.TYPE.argument, + // value does not include the opening and closing braces. + value, + location: createLocation(openingBracePosition, this.clonePosition()) + }, + err: null + }; + } + // Argument with options: `{name, format, ...}` + case 44: { + this.bump(); + this.bumpSpace(); + if (this.isEOF()) { + return this.error(error_1.ErrorKind.EXPECT_ARGUMENT_CLOSING_BRACE, createLocation(openingBracePosition, this.clonePosition())); + } + return this.parseArgumentOptions(nestingLevel, expectingCloseTag, value, openingBracePosition); + } + default: + return this.error(error_1.ErrorKind.MALFORMED_ARGUMENT, createLocation(openingBracePosition, this.clonePosition())); + } + }; + Parser2.prototype.parseIdentifierIfPossible = function() { + var startingPosition = this.clonePosition(); + var startOffset = this.offset(); + var value = matchIdentifierAtIndex(this.message, startOffset); + var endOffset = startOffset + value.length; + this.bumpTo(endOffset); + var endPosition = this.clonePosition(); + var location = createLocation(startingPosition, endPosition); + return { value, location }; + }; + Parser2.prototype.parseArgumentOptions = function(nestingLevel, expectingCloseTag, value, openingBracePosition) { + var _a4; + var typeStartPosition = this.clonePosition(); + var argType = this.parseIdentifierIfPossible().value; + var typeEndPosition = this.clonePosition(); + switch (argType) { + case "": + return this.error(error_1.ErrorKind.EXPECT_ARGUMENT_TYPE, createLocation(typeStartPosition, typeEndPosition)); + case "number": + case "date": + case "time": { + this.bumpSpace(); + var styleAndLocation = null; + if (this.bumpIf(",")) { + this.bumpSpace(); + var styleStartPosition = this.clonePosition(); + var result = this.parseSimpleArgStyleIfPossible(); + if (result.err) { + return result; + } + var style = trimEnd(result.val); + if (style.length === 0) { + return this.error(error_1.ErrorKind.EXPECT_ARGUMENT_STYLE, createLocation(this.clonePosition(), this.clonePosition())); + } + var styleLocation = createLocation(styleStartPosition, this.clonePosition()); + styleAndLocation = { style, styleLocation }; + } + var argCloseResult = this.tryParseArgumentClose(openingBracePosition); + if (argCloseResult.err) { + return argCloseResult; + } + var location_1 = createLocation(openingBracePosition, this.clonePosition()); + if (styleAndLocation && startsWith(styleAndLocation === null || styleAndLocation === void 0 ? void 0 : styleAndLocation.style, "::", 0)) { + var skeleton = trimStart(styleAndLocation.style.slice(2)); + if (argType === "number") { + var result = this.parseNumberSkeletonFromString(skeleton, styleAndLocation.styleLocation); + if (result.err) { + return result; + } + return { + val: { type: types_1.TYPE.number, value, location: location_1, style: result.val }, + err: null + }; + } else { + if (skeleton.length === 0) { + return this.error(error_1.ErrorKind.EXPECT_DATE_TIME_SKELETON, location_1); + } + var dateTimePattern = skeleton; + if (this.locale) { + dateTimePattern = (0, date_time_pattern_generator_1.getBestPattern)(skeleton, this.locale); + } + var style = { + type: types_1.SKELETON_TYPE.dateTime, + pattern: dateTimePattern, + location: styleAndLocation.styleLocation, + parsedOptions: this.shouldParseSkeletons ? (0, icu_skeleton_parser_1.parseDateTimeSkeleton)(dateTimePattern) : {} + }; + var type = argType === "date" ? types_1.TYPE.date : types_1.TYPE.time; + return { + val: { type, value, location: location_1, style }, + err: null + }; + } + } + return { + val: { + type: argType === "number" ? types_1.TYPE.number : argType === "date" ? types_1.TYPE.date : types_1.TYPE.time, + value, + location: location_1, + style: (_a4 = styleAndLocation === null || styleAndLocation === void 0 ? void 0 : styleAndLocation.style) !== null && _a4 !== void 0 ? _a4 : null + }, + err: null + }; + } + case "plural": + case "selectordinal": + case "select": { + var typeEndPosition_1 = this.clonePosition(); + this.bumpSpace(); + if (!this.bumpIf(",")) { + return this.error(error_1.ErrorKind.EXPECT_SELECT_ARGUMENT_OPTIONS, createLocation(typeEndPosition_1, tslib_1.__assign({}, typeEndPosition_1))); + } + this.bumpSpace(); + var identifierAndLocation = this.parseIdentifierIfPossible(); + var pluralOffset = 0; + if (argType !== "select" && identifierAndLocation.value === "offset") { + if (!this.bumpIf(":")) { + return this.error(error_1.ErrorKind.EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE, createLocation(this.clonePosition(), this.clonePosition())); + } + this.bumpSpace(); + var result = this.tryParseDecimalInteger(error_1.ErrorKind.EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE, error_1.ErrorKind.INVALID_PLURAL_ARGUMENT_OFFSET_VALUE); + if (result.err) { + return result; + } + this.bumpSpace(); + identifierAndLocation = this.parseIdentifierIfPossible(); + pluralOffset = result.val; + } + var optionsResult = this.tryParsePluralOrSelectOptions(nestingLevel, argType, expectingCloseTag, identifierAndLocation); + if (optionsResult.err) { + return optionsResult; + } + var argCloseResult = this.tryParseArgumentClose(openingBracePosition); + if (argCloseResult.err) { + return argCloseResult; + } + var location_2 = createLocation(openingBracePosition, this.clonePosition()); + if (argType === "select") { + return { + val: { + type: types_1.TYPE.select, + value, + options: fromEntries(optionsResult.val), + location: location_2 + }, + err: null + }; + } else { + return { + val: { + type: types_1.TYPE.plural, + value, + options: fromEntries(optionsResult.val), + offset: pluralOffset, + pluralType: argType === "plural" ? "cardinal" : "ordinal", + location: location_2 + }, + err: null + }; + } + } + default: + return this.error(error_1.ErrorKind.INVALID_ARGUMENT_TYPE, createLocation(typeStartPosition, typeEndPosition)); + } + }; + Parser2.prototype.tryParseArgumentClose = function(openingBracePosition) { + if (this.isEOF() || this.char() !== 125) { + return this.error(error_1.ErrorKind.EXPECT_ARGUMENT_CLOSING_BRACE, createLocation(openingBracePosition, this.clonePosition())); + } + this.bump(); + return { val: true, err: null }; + }; + Parser2.prototype.parseSimpleArgStyleIfPossible = function() { + var nestedBraces = 0; + var startPosition = this.clonePosition(); + while (!this.isEOF()) { + var ch = this.char(); + switch (ch) { + case 39: { + this.bump(); + var apostrophePosition = this.clonePosition(); + if (!this.bumpUntil("'")) { + return this.error(error_1.ErrorKind.UNCLOSED_QUOTE_IN_ARGUMENT_STYLE, createLocation(apostrophePosition, this.clonePosition())); + } + this.bump(); + break; + } + case 123: { + nestedBraces += 1; + this.bump(); + break; + } + case 125: { + if (nestedBraces > 0) { + nestedBraces -= 1; + } else { + return { + val: this.message.slice(startPosition.offset, this.offset()), + err: null + }; + } + break; + } + default: + this.bump(); + break; + } + } + return { + val: this.message.slice(startPosition.offset, this.offset()), + err: null + }; + }; + Parser2.prototype.parseNumberSkeletonFromString = function(skeleton, location) { + var tokens = []; + try { + tokens = (0, icu_skeleton_parser_1.parseNumberSkeletonFromString)(skeleton); + } catch (e) { + return this.error(error_1.ErrorKind.INVALID_NUMBER_SKELETON, location); + } + return { + val: { + type: types_1.SKELETON_TYPE.number, + tokens, + location, + parsedOptions: this.shouldParseSkeletons ? (0, icu_skeleton_parser_1.parseNumberSkeleton)(tokens) : {} + }, + err: null + }; + }; + Parser2.prototype.tryParsePluralOrSelectOptions = function(nestingLevel, parentArgType, expectCloseTag, parsedFirstIdentifier) { + var _a4; + var hasOtherClause = false; + var options = []; + var parsedSelectors = /* @__PURE__ */ new Set(); + var selector = parsedFirstIdentifier.value, selectorLocation = parsedFirstIdentifier.location; + while (true) { + if (selector.length === 0) { + var startPosition = this.clonePosition(); + if (parentArgType !== "select" && this.bumpIf("=")) { + var result = this.tryParseDecimalInteger(error_1.ErrorKind.EXPECT_PLURAL_ARGUMENT_SELECTOR, error_1.ErrorKind.INVALID_PLURAL_ARGUMENT_SELECTOR); + if (result.err) { + return result; + } + selectorLocation = createLocation(startPosition, this.clonePosition()); + selector = this.message.slice(startPosition.offset, this.offset()); + } else { + break; + } + } + if (parsedSelectors.has(selector)) { + return this.error(parentArgType === "select" ? error_1.ErrorKind.DUPLICATE_SELECT_ARGUMENT_SELECTOR : error_1.ErrorKind.DUPLICATE_PLURAL_ARGUMENT_SELECTOR, selectorLocation); + } + if (selector === "other") { + hasOtherClause = true; + } + this.bumpSpace(); + var openingBracePosition = this.clonePosition(); + if (!this.bumpIf("{")) { + return this.error(parentArgType === "select" ? error_1.ErrorKind.EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT : error_1.ErrorKind.EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT, createLocation(this.clonePosition(), this.clonePosition())); + } + var fragmentResult = this.parseMessage(nestingLevel + 1, parentArgType, expectCloseTag); + if (fragmentResult.err) { + return fragmentResult; + } + var argCloseResult = this.tryParseArgumentClose(openingBracePosition); + if (argCloseResult.err) { + return argCloseResult; + } + options.push([ + selector, + { + value: fragmentResult.val, + location: createLocation(openingBracePosition, this.clonePosition()) + } + ]); + parsedSelectors.add(selector); + this.bumpSpace(); + _a4 = this.parseIdentifierIfPossible(), selector = _a4.value, selectorLocation = _a4.location; + } + if (options.length === 0) { + return this.error(parentArgType === "select" ? error_1.ErrorKind.EXPECT_SELECT_ARGUMENT_SELECTOR : error_1.ErrorKind.EXPECT_PLURAL_ARGUMENT_SELECTOR, createLocation(this.clonePosition(), this.clonePosition())); + } + if (this.requiresOtherClause && !hasOtherClause) { + return this.error(error_1.ErrorKind.MISSING_OTHER_CLAUSE, createLocation(this.clonePosition(), this.clonePosition())); + } + return { val: options, err: null }; + }; + Parser2.prototype.tryParseDecimalInteger = function(expectNumberError, invalidNumberError) { + var sign = 1; + var startingPosition = this.clonePosition(); + if (this.bumpIf("+")) { + } else if (this.bumpIf("-")) { + sign = -1; + } + var hasDigits = false; + var decimal = 0; + while (!this.isEOF()) { + var ch = this.char(); + if (ch >= 48 && ch <= 57) { + hasDigits = true; + decimal = decimal * 10 + (ch - 48); + this.bump(); + } else { + break; + } + } + var location = createLocation(startingPosition, this.clonePosition()); + if (!hasDigits) { + return this.error(expectNumberError, location); + } + decimal *= sign; + if (!isSafeInteger(decimal)) { + return this.error(invalidNumberError, location); + } + return { val: decimal, err: null }; + }; + Parser2.prototype.offset = function() { + return this.position.offset; + }; + Parser2.prototype.isEOF = function() { + return this.offset() === this.message.length; + }; + Parser2.prototype.clonePosition = function() { + return { + offset: this.position.offset, + line: this.position.line, + column: this.position.column + }; + }; + Parser2.prototype.char = function() { + var offset = this.position.offset; + if (offset >= this.message.length) { + throw Error("out of bound"); + } + var code = codePointAt(this.message, offset); + if (code === void 0) { + throw Error("Offset ".concat(offset, " is at invalid UTF-16 code unit boundary")); + } + return code; + }; + Parser2.prototype.error = function(kind, location) { + return { + val: null, + err: { + kind, + message: this.message, + location + } + }; + }; + Parser2.prototype.bump = function() { + if (this.isEOF()) { + return; + } + var code = this.char(); + if (code === 10) { + this.position.line += 1; + this.position.column = 1; + this.position.offset += 1; + } else { + this.position.column += 1; + this.position.offset += code < 65536 ? 1 : 2; + } + }; + Parser2.prototype.bumpIf = function(prefix) { + if (startsWith(this.message, prefix, this.offset())) { + for (var i = 0; i < prefix.length; i++) { + this.bump(); + } + return true; + } + return false; + }; + Parser2.prototype.bumpUntil = function(pattern) { + var currentOffset = this.offset(); + var index = this.message.indexOf(pattern, currentOffset); + if (index >= 0) { + this.bumpTo(index); + return true; + } else { + this.bumpTo(this.message.length); + return false; + } + }; + Parser2.prototype.bumpTo = function(targetOffset) { + if (this.offset() > targetOffset) { + throw Error("targetOffset ".concat(targetOffset, " must be greater than or equal to the current offset ").concat(this.offset())); + } + targetOffset = Math.min(targetOffset, this.message.length); + while (true) { + var offset = this.offset(); + if (offset === targetOffset) { + break; + } + if (offset > targetOffset) { + throw Error("targetOffset ".concat(targetOffset, " is at invalid UTF-16 code unit boundary")); + } + this.bump(); + if (this.isEOF()) { + break; + } + } + }; + Parser2.prototype.bumpSpace = function() { + while (!this.isEOF() && _isWhiteSpace(this.char())) { + this.bump(); + } + }; + Parser2.prototype.peek = function() { + if (this.isEOF()) { + return null; + } + var code = this.char(); + var offset = this.offset(); + var nextCode = this.message.charCodeAt(offset + (code >= 65536 ? 2 : 1)); + return nextCode !== null && nextCode !== void 0 ? nextCode : null; + }; + return Parser2; + })() + ); + exports2.Parser = Parser; + function _isAlpha(codepoint) { + return codepoint >= 97 && codepoint <= 122 || codepoint >= 65 && codepoint <= 90; + } + __name(_isAlpha, "_isAlpha"); + function _isAlphaOrSlash(codepoint) { + return _isAlpha(codepoint) || codepoint === 47; + } + __name(_isAlphaOrSlash, "_isAlphaOrSlash"); + function _isPotentialElementNameChar(c) { + return c === 45 || c === 46 || c >= 48 && c <= 57 || c === 95 || c >= 97 && c <= 122 || c >= 65 && c <= 90 || c == 183 || c >= 192 && c <= 214 || c >= 216 && c <= 246 || c >= 248 && c <= 893 || c >= 895 && c <= 8191 || c >= 8204 && c <= 8205 || c >= 8255 && c <= 8256 || c >= 8304 && c <= 8591 || c >= 11264 && c <= 12271 || c >= 12289 && c <= 55295 || c >= 63744 && c <= 64975 || c >= 65008 && c <= 65533 || c >= 65536 && c <= 983039; + } + __name(_isPotentialElementNameChar, "_isPotentialElementNameChar"); + function _isWhiteSpace(c) { + return c >= 9 && c <= 13 || c === 32 || c === 133 || c >= 8206 && c <= 8207 || c === 8232 || c === 8233; + } + __name(_isWhiteSpace, "_isWhiteSpace"); + function _isPatternSyntax(c) { + return c >= 33 && c <= 35 || c === 36 || c >= 37 && c <= 39 || c === 40 || c === 41 || c === 42 || c === 43 || c === 44 || c === 45 || c >= 46 && c <= 47 || c >= 58 && c <= 59 || c >= 60 && c <= 62 || c >= 63 && c <= 64 || c === 91 || c === 92 || c === 93 || c === 94 || c === 96 || c === 123 || c === 124 || c === 125 || c === 126 || c === 161 || c >= 162 && c <= 165 || c === 166 || c === 167 || c === 169 || c === 171 || c === 172 || c === 174 || c === 176 || c === 177 || c === 182 || c === 187 || c === 191 || c === 215 || c === 247 || c >= 8208 && c <= 8213 || c >= 8214 && c <= 8215 || c === 8216 || c === 8217 || c === 8218 || c >= 8219 && c <= 8220 || c === 8221 || c === 8222 || c === 8223 || c >= 8224 && c <= 8231 || c >= 8240 && c <= 8248 || c === 8249 || c === 8250 || c >= 8251 && c <= 8254 || c >= 8257 && c <= 8259 || c === 8260 || c === 8261 || c === 8262 || c >= 8263 && c <= 8273 || c === 8274 || c === 8275 || c >= 8277 && c <= 8286 || c >= 8592 && c <= 8596 || c >= 8597 && + c <= 8601 || c >= 8602 && c <= 8603 || c >= 8604 && c <= 8607 || c === 8608 || c >= 8609 && c <= 8610 || c === 8611 || c >= 8612 && c <= 8613 || c === 8614 || c >= 8615 && c <= 8621 || c === 8622 || c >= 8623 && c <= 8653 || c >= 8654 && c <= 8655 || c >= 8656 && c <= 8657 || c === 8658 || c === 8659 || c === 8660 || c >= 8661 && c <= 8691 || c >= 8692 && c <= 8959 || c >= 8960 && c <= 8967 || c === 8968 || c === 8969 || c === 8970 || c === 8971 || c >= 8972 && c <= 8991 || c >= 8992 && c <= 8993 || c >= 8994 && c <= 9e3 || c === 9001 || c === 9002 || c >= 9003 && c <= 9083 || c === 9084 || c >= 9085 && c <= 9114 || c >= 9115 && c <= 9139 || c >= 9140 && c <= 9179 || c >= 9180 && c <= 9185 || c >= 9186 && c <= 9254 || c >= 9255 && c <= 9279 || c >= 9280 && c <= 9290 || c >= 9291 && c <= 9311 || c >= 9472 && c <= 9654 || c === 9655 || c >= 9656 && c <= 9664 || c === 9665 || c >= 9666 && c <= 9719 || c >= 9720 && c <= 9727 || c >= 9728 && c <= 9838 || c === 9839 || c >= 9840 && c <= + 10087 || c === 10088 || c === 10089 || c === 10090 || c === 10091 || c === 10092 || c === 10093 || c === 10094 || c === 10095 || c === 10096 || c === 10097 || c === 10098 || c === 10099 || c === 10100 || c === 10101 || c >= 10132 && c <= 10175 || c >= 10176 && c <= 10180 || c === 10181 || c === 10182 || c >= 10183 && c <= 10213 || c === 10214 || c === 10215 || c === 10216 || c === 10217 || c === 10218 || c === 10219 || c === 10220 || c === 10221 || c === 10222 || c === 10223 || c >= 10224 && c <= 10239 || c >= 10240 && c <= 10495 || c >= 10496 && c <= 10626 || c === 10627 || c === 10628 || c === 10629 || c === 10630 || c === 10631 || c === 10632 || c === 10633 || c === 10634 || c === 10635 || c === 10636 || c === 10637 || c === 10638 || c === 10639 || c === 10640 || c === 10641 || c === 10642 || c === 10643 || c === 10644 || c === 10645 || c === 10646 || c === 10647 || c === 10648 || c >= 10649 && c <= 10711 || c === 10712 || c === 10713 || c === 10714 || c === 10715 || c >= 10716 && + c <= 10747 || c === 10748 || c === 10749 || c >= 10750 && c <= 11007 || c >= 11008 && c <= 11055 || c >= 11056 && c <= 11076 || c >= 11077 && c <= 11078 || c >= 11079 && c <= 11084 || c >= 11085 && c <= 11123 || c >= 11124 && c <= 11125 || c >= 11126 && c <= 11157 || c === 11158 || c >= 11159 && c <= 11263 || c >= 11776 && c <= 11777 || c === 11778 || c === 11779 || c === 11780 || c === 11781 || c >= 11782 && c <= 11784 || c === 11785 || c === 11786 || c === 11787 || c === 11788 || c === 11789 || c >= 11790 && c <= 11798 || c === 11799 || c >= 11800 && c <= 11801 || c === 11802 || c === 11803 || c === 11804 || c === 11805 || c >= 11806 && c <= 11807 || c === 11808 || c === 11809 || c === 11810 || c === 11811 || c === 11812 || c === 11813 || c === 11814 || c === 11815 || c === 11816 || c === 11817 || c >= 11818 && c <= 11822 || c === 11823 || c >= 11824 && c <= 11833 || c >= 11834 && c <= 11835 || c >= 11836 && c <= 11839 || c === 11840 || c === 11841 || c === 11842 || c >= 11843 && + c <= 11855 || c >= 11856 && c <= 11857 || c === 11858 || c >= 11859 && c <= 11903 || c >= 12289 && c <= 12291 || c === 12296 || c === 12297 || c === 12298 || c === 12299 || c === 12300 || c === 12301 || c === 12302 || c === 12303 || c === 12304 || c === 12305 || c >= 12306 && c <= 12307 || c === 12308 || c === 12309 || c === 12310 || c === 12311 || c === 12312 || c === 12313 || c === 12314 || c === 12315 || c === 12316 || c === 12317 || c >= 12318 && c <= 12319 || c === 12320 || c === 12336 || c === 64830 || c === 64831 || c >= 65093 && c <= 65094; + } + __name(_isPatternSyntax, "_isPatternSyntax"); + } +}); + +// node_modules/@formatjs/icu-messageformat-parser/index.js +var require_icu_messageformat_parser = __commonJS({ + "node_modules/@formatjs/icu-messageformat-parser/index.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2._Parser = exports2.parse = void 0; + var tslib_1 = (init_tslib_es62(), __toCommonJS(tslib_es6_exports2)); + var error_1 = require_error(); + var parser_1 = require_parser(); + var types_1 = require_types(); + function pruneLocation(els) { + els.forEach(function(el) { + delete el.location; + if ((0, types_1.isSelectElement)(el) || (0, types_1.isPluralElement)(el)) { + for (var k in el.options) { + delete el.options[k].location; + pruneLocation(el.options[k].value); + } + } else if ((0, types_1.isNumberElement)(el) && (0, types_1.isNumberSkeleton)(el.style)) { + delete el.style.location; + } else if (((0, types_1.isDateElement)(el) || (0, types_1.isTimeElement)(el)) && (0, types_1.isDateTimeSkeleton)(el.style)) { + delete el.style.location; + } else if ((0, types_1.isTagElement)(el)) { + pruneLocation(el.children); + } + }); + } + __name(pruneLocation, "pruneLocation"); + function parse(message, opts) { + if (opts === void 0) { + opts = {}; + } + opts = tslib_1.__assign({ shouldParseSkeletons: true, requiresOtherClause: true }, opts); + var result = new parser_1.Parser(message, opts).parse(); + if (result.err) { + var error = SyntaxError(error_1.ErrorKind[result.err.kind]); + error.location = result.err.location; + error.originalMessage = result.err.message; + throw error; + } + if (!(opts === null || opts === void 0 ? void 0 : opts.captureLocation)) { + pruneLocation(result.val); + } + return result.val; + } + __name(parse, "parse"); + exports2.parse = parse; + tslib_1.__exportStar(require_types(), exports2); + exports2._Parser = parser_1.Parser; + } +}); + +// node_modules/@formatjs/fast-memoize/index.js +var require_fast_memoize = __commonJS({ + "node_modules/@formatjs/fast-memoize/index.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.strategies = exports2.memoize = void 0; + function memoize(fn, options) { + var cache = options && options.cache ? options.cache : cacheDefault; + var serializer = options && options.serializer ? options.serializer : serializerDefault; + var strategy = options && options.strategy ? options.strategy : strategyDefault; + return strategy(fn, { + cache, + serializer + }); + } + __name(memoize, "memoize"); + exports2.memoize = memoize; + function isPrimitive(value) { + return value == null || typeof value === "number" || typeof value === "boolean"; + } + __name(isPrimitive, "isPrimitive"); + function monadic(fn, cache, serializer, arg) { + var cacheKey = isPrimitive(arg) ? arg : serializer(arg); + var computedValue = cache.get(cacheKey); + if (typeof computedValue === "undefined") { + computedValue = fn.call(this, arg); + cache.set(cacheKey, computedValue); + } + return computedValue; + } + __name(monadic, "monadic"); + function variadic(fn, cache, serializer) { + var args = Array.prototype.slice.call(arguments, 3); + var cacheKey = serializer(args); + var computedValue = cache.get(cacheKey); + if (typeof computedValue === "undefined") { + computedValue = fn.apply(this, args); + cache.set(cacheKey, computedValue); + } + return computedValue; + } + __name(variadic, "variadic"); + function assemble(fn, context, strategy, cache, serialize) { + return strategy.bind(context, fn, cache, serialize); + } + __name(assemble, "assemble"); + function strategyDefault(fn, options) { + var strategy = fn.length === 1 ? monadic : variadic; + return assemble(fn, this, strategy, options.cache.create(), options.serializer); + } + __name(strategyDefault, "strategyDefault"); + function strategyVariadic(fn, options) { + return assemble(fn, this, variadic, options.cache.create(), options.serializer); + } + __name(strategyVariadic, "strategyVariadic"); + function strategyMonadic(fn, options) { + return assemble(fn, this, monadic, options.cache.create(), options.serializer); + } + __name(strategyMonadic, "strategyMonadic"); + var serializerDefault = /* @__PURE__ */ __name(function() { + return JSON.stringify(arguments); + }, "serializerDefault"); + function ObjectWithoutPrototypeCache() { + this.cache = /* @__PURE__ */ Object.create(null); + } + __name(ObjectWithoutPrototypeCache, "ObjectWithoutPrototypeCache"); + ObjectWithoutPrototypeCache.prototype.get = function(key) { + return this.cache[key]; + }; + ObjectWithoutPrototypeCache.prototype.set = function(key, value) { + this.cache[key] = value; + }; + var cacheDefault = { + create: /* @__PURE__ */ __name(function create() { + return new ObjectWithoutPrototypeCache(); + }, "create") + }; + exports2.strategies = { + variadic: strategyVariadic, + monadic: strategyMonadic + }; + } +}); + +// node_modules/intl-messageformat/src/error.js +var require_error2 = __commonJS({ + "node_modules/intl-messageformat/src/error.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MissingValueError = exports2.InvalidValueTypeError = exports2.InvalidValueError = exports2.FormatError = exports2.ErrorCode = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var ErrorCode; + (function(ErrorCode2) { + ErrorCode2["MISSING_VALUE"] = "MISSING_VALUE"; + ErrorCode2["INVALID_VALUE"] = "INVALID_VALUE"; + ErrorCode2["MISSING_INTL_API"] = "MISSING_INTL_API"; + })(ErrorCode = exports2.ErrorCode || (exports2.ErrorCode = {})); + var FormatError = ( + /** @class */ + (function(_super) { + tslib_1.__extends(FormatError2, _super); + function FormatError2(msg, code, originalMessage) { + var _this = _super.call(this, msg) || this; + _this.code = code; + _this.originalMessage = originalMessage; + return _this; + } + __name(FormatError2, "FormatError"); + FormatError2.prototype.toString = function() { + return "[formatjs Error: ".concat(this.code, "] ").concat(this.message); + }; + return FormatError2; + })(Error) + ); + exports2.FormatError = FormatError; + var InvalidValueError = ( + /** @class */ + (function(_super) { + tslib_1.__extends(InvalidValueError2, _super); + function InvalidValueError2(variableId, value, options, originalMessage) { + return _super.call(this, 'Invalid values for "'.concat(variableId, '": "').concat(value, '". Options are "').concat(Object.keys(options).join('", "'), '"'), ErrorCode.INVALID_VALUE, originalMessage) || this; + } + __name(InvalidValueError2, "InvalidValueError"); + return InvalidValueError2; + })(FormatError) + ); + exports2.InvalidValueError = InvalidValueError; + var InvalidValueTypeError = ( + /** @class */ + (function(_super) { + tslib_1.__extends(InvalidValueTypeError2, _super); + function InvalidValueTypeError2(value, type, originalMessage) { + return _super.call(this, 'Value for "'.concat(value, '" must be of type ').concat(type), ErrorCode.INVALID_VALUE, originalMessage) || this; + } + __name(InvalidValueTypeError2, "InvalidValueTypeError"); + return InvalidValueTypeError2; + })(FormatError) + ); + exports2.InvalidValueTypeError = InvalidValueTypeError; + var MissingValueError = ( + /** @class */ + (function(_super) { + tslib_1.__extends(MissingValueError2, _super); + function MissingValueError2(variableId, originalMessage) { + return _super.call(this, 'The intl string context variable "'.concat(variableId, '" was not provided to the string "').concat(originalMessage, '"'), ErrorCode.MISSING_VALUE, originalMessage) || this; + } + __name(MissingValueError2, "MissingValueError"); + return MissingValueError2; + })(FormatError) + ); + exports2.MissingValueError = MissingValueError; + } +}); + +// node_modules/intl-messageformat/src/formatters.js +var require_formatters = __commonJS({ + "node_modules/intl-messageformat/src/formatters.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.formatToParts = exports2.isFormatXMLElementFn = exports2.PART_TYPE = void 0; + var icu_messageformat_parser_1 = require_icu_messageformat_parser(); + var error_1 = require_error2(); + var PART_TYPE; + (function(PART_TYPE2) { + PART_TYPE2[PART_TYPE2["literal"] = 0] = "literal"; + PART_TYPE2[PART_TYPE2["object"] = 1] = "object"; + })(PART_TYPE = exports2.PART_TYPE || (exports2.PART_TYPE = {})); + function mergeLiteral(parts) { + if (parts.length < 2) { + return parts; + } + return parts.reduce(function(all, part) { + var lastPart = all[all.length - 1]; + if (!lastPart || lastPart.type !== PART_TYPE.literal || part.type !== PART_TYPE.literal) { + all.push(part); + } else { + lastPart.value += part.value; + } + return all; + }, []); + } + __name(mergeLiteral, "mergeLiteral"); + function isFormatXMLElementFn(el) { + return typeof el === "function"; + } + __name(isFormatXMLElementFn, "isFormatXMLElementFn"); + exports2.isFormatXMLElementFn = isFormatXMLElementFn; + function formatToParts(els, locales2, formatters, formats2, values, currentPluralValue, originalMessage) { + if (els.length === 1 && (0, icu_messageformat_parser_1.isLiteralElement)(els[0])) { + return [ + { + type: PART_TYPE.literal, + value: els[0].value + } + ]; + } + var result = []; + for (var _i = 0, els_1 = els; _i < els_1.length; _i++) { + var el = els_1[_i]; + if ((0, icu_messageformat_parser_1.isLiteralElement)(el)) { + result.push({ + type: PART_TYPE.literal, + value: el.value + }); + continue; + } + if ((0, icu_messageformat_parser_1.isPoundElement)(el)) { + if (typeof currentPluralValue === "number") { + result.push({ + type: PART_TYPE.literal, + value: formatters.getNumberFormat(locales2).format(currentPluralValue) + }); + } + continue; + } + var varName = el.value; + if (!(values && varName in values)) { + throw new error_1.MissingValueError(varName, originalMessage); + } + var value = values[varName]; + if ((0, icu_messageformat_parser_1.isArgumentElement)(el)) { + if (!value || typeof value === "string" || typeof value === "number") { + value = typeof value === "string" || typeof value === "number" ? String(value) : ""; + } + result.push({ + type: typeof value === "string" ? PART_TYPE.literal : PART_TYPE.object, + value + }); + continue; + } + if ((0, icu_messageformat_parser_1.isDateElement)(el)) { + var style = typeof el.style === "string" ? formats2.date[el.style] : (0, icu_messageformat_parser_1.isDateTimeSkeleton)(el.style) ? el.style.parsedOptions : void 0; + result.push({ + type: PART_TYPE.literal, + value: formatters.getDateTimeFormat(locales2, style).format(value) + }); + continue; + } + if ((0, icu_messageformat_parser_1.isTimeElement)(el)) { + var style = typeof el.style === "string" ? formats2.time[el.style] : (0, icu_messageformat_parser_1.isDateTimeSkeleton)(el.style) ? el.style.parsedOptions : formats2.time.medium; + result.push({ + type: PART_TYPE.literal, + value: formatters.getDateTimeFormat(locales2, style).format(value) + }); + continue; + } + if ((0, icu_messageformat_parser_1.isNumberElement)(el)) { + var style = typeof el.style === "string" ? formats2.number[el.style] : (0, icu_messageformat_parser_1.isNumberSkeleton)(el.style) ? el.style.parsedOptions : void 0; + if (style && style.scale) { + value = value * (style.scale || 1); + } + result.push({ + type: PART_TYPE.literal, + value: formatters.getNumberFormat(locales2, style).format(value) + }); + continue; + } + if ((0, icu_messageformat_parser_1.isTagElement)(el)) { + var children = el.children, value_1 = el.value; + var formatFn = values[value_1]; + if (!isFormatXMLElementFn(formatFn)) { + throw new error_1.InvalidValueTypeError(value_1, "function", originalMessage); + } + var parts = formatToParts(children, locales2, formatters, formats2, values, currentPluralValue); + var chunks = formatFn(parts.map(function(p) { + return p.value; + })); + if (!Array.isArray(chunks)) { + chunks = [chunks]; + } + result.push.apply(result, chunks.map(function(c) { + return { + type: typeof c === "string" ? PART_TYPE.literal : PART_TYPE.object, + value: c + }; + })); + } + if ((0, icu_messageformat_parser_1.isSelectElement)(el)) { + var opt = el.options[value] || el.options.other; + if (!opt) { + throw new error_1.InvalidValueError(el.value, value, Object.keys(el.options), originalMessage); + } + result.push.apply(result, formatToParts(opt.value, locales2, formatters, formats2, values)); + continue; + } + if ((0, icu_messageformat_parser_1.isPluralElement)(el)) { + var opt = el.options["=".concat(value)]; + if (!opt) { + if (!Intl.PluralRules) { + throw new error_1.FormatError('Intl.PluralRules is not available in this environment.\nTry polyfilling it using "@formatjs/intl-pluralrules"\n', error_1.ErrorCode.MISSING_INTL_API, originalMessage); + } + var rule = formatters.getPluralRules(locales2, { type: el.pluralType }).select(value - (el.offset || 0)); + opt = el.options[rule] || el.options.other; + } + if (!opt) { + throw new error_1.InvalidValueError(el.value, value, Object.keys(el.options), originalMessage); + } + result.push.apply(result, formatToParts(opt.value, locales2, formatters, formats2, values, value - (el.offset || 0))); + continue; + } + } + return mergeLiteral(result); + } + __name(formatToParts, "formatToParts"); + exports2.formatToParts = formatToParts; + } +}); + +// node_modules/intl-messageformat/src/core.js +var require_core = __commonJS({ + "node_modules/intl-messageformat/src/core.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.IntlMessageFormat = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var icu_messageformat_parser_1 = require_icu_messageformat_parser(); + var fast_memoize_1 = require_fast_memoize(); + var formatters_1 = require_formatters(); + function mergeConfig(c1, c2) { + if (!c2) { + return c1; + } + return tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, c1 || {}), c2 || {}), Object.keys(c1).reduce(function(all, k) { + all[k] = tslib_1.__assign(tslib_1.__assign({}, c1[k]), c2[k] || {}); + return all; + }, {})); + } + __name(mergeConfig, "mergeConfig"); + function mergeConfigs(defaultConfig2, configs) { + if (!configs) { + return defaultConfig2; + } + return Object.keys(defaultConfig2).reduce(function(all, k) { + all[k] = mergeConfig(defaultConfig2[k], configs[k]); + return all; + }, tslib_1.__assign({}, defaultConfig2)); + } + __name(mergeConfigs, "mergeConfigs"); + function createFastMemoizeCache(store) { + return { + create: /* @__PURE__ */ __name(function() { + return { + get: /* @__PURE__ */ __name(function(key) { + return store[key]; + }, "get"), + set: /* @__PURE__ */ __name(function(key, value) { + store[key] = value; + }, "set") + }; + }, "create") + }; + } + __name(createFastMemoizeCache, "createFastMemoizeCache"); + function createDefaultFormatters(cache) { + if (cache === void 0) { + cache = { + number: {}, + dateTime: {}, + pluralRules: {} + }; + } + return { + getNumberFormat: (0, fast_memoize_1.memoize)(function() { + var _a3; + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return new ((_a3 = Intl.NumberFormat).bind.apply(_a3, tslib_1.__spreadArray([void 0], args, false)))(); + }, { + cache: createFastMemoizeCache(cache.number), + strategy: fast_memoize_1.strategies.variadic + }), + getDateTimeFormat: (0, fast_memoize_1.memoize)(function() { + var _a3; + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return new ((_a3 = Intl.DateTimeFormat).bind.apply(_a3, tslib_1.__spreadArray([void 0], args, false)))(); + }, { + cache: createFastMemoizeCache(cache.dateTime), + strategy: fast_memoize_1.strategies.variadic + }), + getPluralRules: (0, fast_memoize_1.memoize)(function() { + var _a3; + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return new ((_a3 = Intl.PluralRules).bind.apply(_a3, tslib_1.__spreadArray([void 0], args, false)))(); + }, { + cache: createFastMemoizeCache(cache.pluralRules), + strategy: fast_memoize_1.strategies.variadic + }) + }; + } + __name(createDefaultFormatters, "createDefaultFormatters"); + var IntlMessageFormat2 = exports2.IntlMessageFormat = /** @class */ + (function() { + function IntlMessageFormat3(message, locales2, overrideFormats, opts) { + if (locales2 === void 0) { + locales2 = IntlMessageFormat3.defaultLocale; + } + var _this = this; + this.formatterCache = { + number: {}, + dateTime: {}, + pluralRules: {} + }; + this.format = function(values) { + var parts = _this.formatToParts(values); + if (parts.length === 1) { + return parts[0].value; + } + var result = parts.reduce(function(all, part) { + if (!all.length || part.type !== formatters_1.PART_TYPE.literal || typeof all[all.length - 1] !== "string") { + all.push(part.value); + } else { + all[all.length - 1] += part.value; + } + return all; + }, []); + if (result.length <= 1) { + return result[0] || ""; + } + return result; + }; + this.formatToParts = function(values) { + return (0, formatters_1.formatToParts)(_this.ast, _this.locales, _this.formatters, _this.formats, values, void 0, _this.message); + }; + this.resolvedOptions = function() { + var _a4; + return { + locale: ((_a4 = _this.resolvedLocale) === null || _a4 === void 0 ? void 0 : _a4.toString()) || Intl.NumberFormat.supportedLocalesOf(_this.locales)[0] + }; + }; + this.getAst = function() { + return _this.ast; + }; + this.locales = locales2; + this.resolvedLocale = IntlMessageFormat3.resolveLocale(locales2); + if (typeof message === "string") { + this.message = message; + if (!IntlMessageFormat3.__parse) { + throw new TypeError("IntlMessageFormat.__parse must be set to process `message` of type `string`"); + } + var _a3 = opts || {}, formatters = _a3.formatters, parseOpts = tslib_1.__rest(_a3, ["formatters"]); + this.ast = IntlMessageFormat3.__parse(message, tslib_1.__assign(tslib_1.__assign({}, parseOpts), { locale: this.resolvedLocale })); + } else { + this.ast = message; + } + if (!Array.isArray(this.ast)) { + throw new TypeError("A message must be provided as a String or AST."); + } + this.formats = mergeConfigs(IntlMessageFormat3.formats, overrideFormats); + this.formatters = opts && opts.formatters || createDefaultFormatters(this.formatterCache); + } + __name(IntlMessageFormat3, "IntlMessageFormat"); + Object.defineProperty(IntlMessageFormat3, "defaultLocale", { + get: /* @__PURE__ */ __name(function() { + if (!IntlMessageFormat3.memoizedDefaultLocale) { + IntlMessageFormat3.memoizedDefaultLocale = new Intl.NumberFormat().resolvedOptions().locale; + } + return IntlMessageFormat3.memoizedDefaultLocale; + }, "get"), + enumerable: false, + configurable: true + }); + IntlMessageFormat3.memoizedDefaultLocale = null; + IntlMessageFormat3.resolveLocale = function(locales2) { + if (typeof Intl.Locale === "undefined") { + return; + } + var supportedLocales = Intl.NumberFormat.supportedLocalesOf(locales2); + if (supportedLocales.length > 0) { + return new Intl.Locale(supportedLocales[0]); + } + return new Intl.Locale(typeof locales2 === "string" ? locales2 : locales2[0]); + }; + IntlMessageFormat3.__parse = icu_messageformat_parser_1.parse; + IntlMessageFormat3.formats = { + number: { + integer: { + maximumFractionDigits: 0 + }, + currency: { + style: "currency" + }, + percent: { + style: "percent" + } + }, + date: { + short: { + month: "numeric", + day: "numeric", + year: "2-digit" + }, + medium: { + month: "short", + day: "numeric", + year: "numeric" + }, + long: { + month: "long", + day: "numeric", + year: "numeric" + }, + full: { + weekday: "long", + month: "long", + day: "numeric", + year: "numeric" + } + }, + time: { + short: { + hour: "numeric", + minute: "numeric" + }, + medium: { + hour: "numeric", + minute: "numeric", + second: "numeric" + }, + long: { + hour: "numeric", + minute: "numeric", + second: "numeric", + timeZoneName: "short" + }, + full: { + hour: "numeric", + minute: "numeric", + second: "numeric", + timeZoneName: "short" + } + } + }; + return IntlMessageFormat3; + })(); + } +}); + +// node_modules/intl-messageformat/index.js +var require_intl_messageformat = __commonJS({ + "node_modules/intl-messageformat/index.js"(exports2) { + "use strict"; + init_process_global(); + Object.defineProperty(exports2, "__esModule", { value: true }); + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var core_1 = require_core(); + tslib_1.__exportStar(require_formatters(), exports2); + tslib_1.__exportStar(require_core(), exports2); + tslib_1.__exportStar(require_error2(), exports2); + exports2.default = core_1.IntlMessageFormat; + } +}); + +// replace-modules:module +var createRequire; +var init_module = __esm({ + "replace-modules:module"() { + init_process_global(); + createRequire = /* @__PURE__ */ __name(() => ({ + resolve() { + throw new Error("createRequire.resolve is not supported"); + } + }), "createRequire"); + } +}); + +// replace-modules:url +var URL2, fileURLToPath, url_default; +var init_url = __esm({ + "replace-modules:url"() { + init_process_global(); + URL2 = globalThis.URL; + fileURLToPath = /* @__PURE__ */ __name((url) => url, "fileURLToPath"); + url_default = { URL: URL2, fileURLToPath }; + } +}); + +// shared/esm-utils.js +function getModulePath(importMeta) { + return url_default.fileURLToPath(importMeta.url); +} +var init_esm_utils = __esm({ + "shared/esm-utils.js"() { + "use strict"; + init_process_global(); + init_module(); + init_url(); + /** + * @license + * Copyright 2021 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + __name(getModulePath, "getModulePath"); + } +}); + +// shared/type-verifiers.js +function isObjectOfUnknownValues(val) { + return typeof val === "object" && val !== null && !Array.isArray(val); +} +function isObjectOrArrayOfUnknownValues(val) { + return typeof val === "object" && val !== null; +} +var init_type_verifiers = __esm({ + "shared/type-verifiers.js"() { + "use strict"; + init_process_global(); + /** + * @license + * Copyright 2020 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + __name(isObjectOfUnknownValues, "isObjectOfUnknownValues"); + __name(isObjectOrArrayOfUnknownValues, "isObjectOrArrayOfUnknownValues"); + } +}); + +// replace-modules:/Users/alexrudenko/src/lighthouse/shared/localization/locales.js +var locales; +var init_locales = __esm({ + "replace-modules:/Users/alexrudenko/src/lighthouse/shared/localization/locales.js"() { + init_process_global(); + locales = {}; + } +}); + +// shared/localization/format.js +function collectAllCustomElementsFromICU(icuElements, customElements = /* @__PURE__ */ new Map()) { + for (const el of icuElements) { + if (el.type === TYPE.literal || el.type === TYPE.pound) continue; + customElements.set(el.value, el); + if (el.type === TYPE.plural) { + for (const option of Object.values(el.options)) { + collectAllCustomElementsFromICU(option.value, customElements); + } + } + } + return customElements; +} +function _preformatValues(messageFormatter, values = {}, lhlMessage) { + const customElements = collectAllCustomElementsFromICU(messageFormatter.getAst()); + const formattedValues = {}; + for (const [id, element] of customElements) { + if (!(id in values)) { + throw new Error(`ICU Message "${lhlMessage}" contains a value reference ("${id}") that wasn't provided`); + } + const value = values[id]; + if (element.type !== TYPE.number) { + formattedValues[id] = value; + continue; + } + if (typeof value !== "number") { + throw new Error(`ICU Message "${lhlMessage}" contains a numeric reference ("${id}") but provided value was not a number`); + } + if (element.style === "milliseconds") { + formattedValues[id] = Math.round(value / 10) * 10; + } else if (element.style === "seconds" && id === "timeInMs") { + formattedValues[id] = Math.round(value / 100) / 10; + } else if (element.style === "bytes") { + formattedValues[id] = value / 1024; + } else { + formattedValues[id] = value; + } + } + for (const valueId of Object.keys(values)) { + if (valueId in formattedValues) continue; + if (valueId === "errorCode") { + formattedValues.errorCode = values.errorCode; + continue; + } + throw new Error(`Provided value "${valueId}" does not match any placeholder in ICU message "${lhlMessage}"`); + } + return formattedValues; +} +function escapeIcuMessage(message) { + return message.replace(/'/g, `''`).replace(/\\{/g, `'{`).replace(/\\}/g, `'}`); +} +function formatMessage(message, values, locale) { + message = escapeIcuMessage(message); + const localeForMessageFormat = locale === "en-XA" || locale === "en-XL" ? "de-DE" : locale; + const IntlMessageFormatCtor = import_intl_messageformat.default.IntlMessageFormat || import_intl_messageformat.default; + const formatter = new IntlMessageFormatCtor(message, localeForMessageFormat, formats, { + ignoreTag: true + }); + const valuesForMessageFormat = _preformatValues(formatter, values, message); + const formattedResult = formatter.format(valuesForMessageFormat); + if (typeof formattedResult !== "string") { + throw new Error("unexpected formatted result"); + } + return formattedResult; +} +function _localizeIcuMessage(icuMessage, locale) { + const localeMessages = _getLocaleMessages(locale); + const localeMessage = localeMessages[icuMessage.i18nId]; + if (!localeMessage) { + return icuMessage.formattedDefault; + } + return formatMessage(localeMessage.message, icuMessage.values, locale); +} +function getRendererFormattedStrings(locale) { + const localeMessages = _getLocaleMessages(locale); + const icuMessageIds = Object.keys(localeMessages).filter((f) => f.startsWith("report/renderer/report-utils.js")); + const strings = {}; + for (const icuMessageId of icuMessageIds) { + const { filename, key } = getIcuMessageIdParts(icuMessageId); + if (!filename.endsWith("report-utils.js")) { + throw new Error(`Unexpected message: ${icuMessageId}`); + } + strings[key] = localeMessages[icuMessageId].message; + } + return strings; +} +function isIcuMessage(icuMessageOrNot) { + if (!isObjectOfUnknownValues(icuMessageOrNot)) { + return false; + } + const { i18nId, values, formattedDefault } = icuMessageOrNot; + if (typeof i18nId !== "string") { + return false; + } + if (typeof formattedDefault !== "string") { + return false; + } + if (values !== void 0) { + if (!isObjectOfUnknownValues(values)) { + return false; + } + for (const value of Object.values(values)) { + if (typeof value !== "string" && typeof value !== "number") { + return false; + } + } + } + return MESSAGE_I18N_ID_REGEX.test(i18nId); +} +function getFormatted(icuMessageOrRawString, locale) { + if (isIcuMessage(icuMessageOrRawString)) { + return _localizeIcuMessage(icuMessageOrRawString, locale); + } + if (typeof icuMessageOrRawString === "string") { + return icuMessageOrRawString; + } + throw new Error("Attempted to format invalid icuMessage type"); +} +function _formatPathAsString(pathInLHR) { + let pathAsString = ""; + for (const property of pathInLHR) { + if (/^[a-z]+$/i.test(property)) { + if (pathAsString.length) pathAsString += "."; + pathAsString += property; + } else { + if (/]|"|'|\s/.test(property)) throw new Error(`Cannot handle "${property}" in i18n`); + pathAsString += `[${property}]`; + } + } + return pathAsString; +} +function replaceIcuMessages(inputObject, locale) { + function replaceInObject(subObject, icuMessagePaths2, pathInLHR = []) { + if (!isObjectOrArrayOfUnknownValues(subObject)) return; + for (const [property, possibleIcuMessage] of Object.entries(subObject)) { + const currentPathInLHR = pathInLHR.concat([property]); + if (isIcuMessage(possibleIcuMessage)) { + const formattedString = getFormatted(possibleIcuMessage, locale); + const messageInstancesInLHR = icuMessagePaths2[possibleIcuMessage.i18nId] || []; + const currentPathAsString = _formatPathAsString(currentPathInLHR); + messageInstancesInLHR.push( + possibleIcuMessage.values ? { values: possibleIcuMessage.values, path: currentPathAsString } : currentPathAsString + ); + subObject[property] = formattedString; + icuMessagePaths2[possibleIcuMessage.i18nId] = messageInstancesInLHR; + } else { + replaceInObject(possibleIcuMessage, icuMessagePaths2, currentPathInLHR); + } + } + } + __name(replaceInObject, "replaceInObject"); + const icuMessagePaths = {}; + replaceInObject(inputObject, icuMessagePaths); + return icuMessagePaths; +} +function _getLocaleMessages(locale) { + const localeMessages = LOCALE_MESSAGES[locale]; + if (!localeMessages) { + if (locale === DEFAULT_LOCALE) { + return {}; + } + throw new Error(`Unsupported locale '${locale}'`); + } + return localeMessages; +} +function getAvailableLocales() { + const localesWithMessages = /* @__PURE__ */ new Set([...Object.keys(LOCALE_MESSAGES), DEFAULT_LOCALE]); + return ( + /** @type {Array} */ + [...localesWithMessages].sort() + ); +} +function getIcuMessageIdParts(i18nMessageId) { + if (!MESSAGE_I18N_ID_REGEX.test(i18nMessageId)) { + throw Error(`"${i18nMessageId}" does not appear to be a valid ICU message id`); + } + const [filename, key] = i18nMessageId.split(" | "); + return { filename, key }; +} +var import_intl_messageformat, TYPE, LOCALE_MESSAGES, DEFAULT_LOCALE, CANONICAL_LOCALES, MESSAGE_I18N_ID_REGEX, formats; +var init_format = __esm({ + "shared/localization/format.js"() { + "use strict"; + init_process_global(); + import_intl_messageformat = __toESM(require_intl_messageformat(), 1); + init_esm_utils(); + init_type_verifiers(); + init_locales(); + /** + * @license + * Copyright 2021 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + TYPE = /** @type {const} */ + { + literal: 0, + argument: 1, + number: 2, + date: 3, + time: 4, + select: 5, + plural: 6, + pound: 7, + tag: 8 + }; + LOCALE_MESSAGES = locales; + DEFAULT_LOCALE = "en-US"; + CANONICAL_LOCALES = ["ar-XB.json", "ar.json", "bg.json", "ca.json", "cs.json", "da.json", "de.json", "el.json", "en-GB.json", "en-US.json", "en-XA.json", "en-XL.json", "es-419.json", "es.json", "fi.json", "fil.json", "fr.json", "he.json", "hi.json", "hr.json", "hu.json", "id.json", "it.json", "ja.json", "ko.json", "lt.json", "lv.json", "nl.json", "no.json", "pl.json", "pt-PT.json", "pt.json", "ro.json", "ru.json", "sk.json", "sl.json", "sr-Latn.json", "sr.json", "sv.json", "ta.json", "te.json", "th.json", "tr.json", "uk.json", "vi.json", "zh-HK.json", "zh-TW.json", "zh.json"].filter((basename) => basename.endsWith(".json") && !basename.endsWith(".ctc.json")).map((locale) => locale.replace(".json", "")).sort(); + MESSAGE_I18N_ID_REGEX = / | [^\s]+$/; + formats = { + number: { + bytes: { + maximumFractionDigits: 0 + }, + milliseconds: { + maximumFractionDigits: 0 + }, + seconds: { + // Force the seconds to the tenths place for limited output and ease of scanning + minimumFractionDigits: 1, + maximumFractionDigits: 1 + }, + extendedPercent: { + // Force allow up to two digits after decimal place in percentages. (Intl.NumberFormat options) + maximumFractionDigits: 2, + style: "percent" + } + } + }; + __name(collectAllCustomElementsFromICU, "collectAllCustomElementsFromICU"); + __name(_preformatValues, "_preformatValues"); + __name(escapeIcuMessage, "escapeIcuMessage"); + __name(formatMessage, "formatMessage"); + __name(_localizeIcuMessage, "_localizeIcuMessage"); + __name(getRendererFormattedStrings, "getRendererFormattedStrings"); + __name(isIcuMessage, "isIcuMessage"); + __name(getFormatted, "getFormatted"); + __name(_formatPathAsString, "_formatPathAsString"); + __name(replaceIcuMessages, "replaceIcuMessages"); + __name(_getLocaleMessages, "_getLocaleMessages"); + __name(getAvailableLocales, "getAvailableLocales"); + __name(getIcuMessageIdParts, "getIcuMessageIdParts"); + } +}); + +// node_modules/lighthouse-stack-packs/packs/amp.js +var require_amp = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/amp.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can improve image loading by using WebP in the context of AMP. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "modern-image-formats": "Consider displaying all [`amp-img`](https://amp.dev/documentation/components/amp-img/?format=websites) components in WebP formats while specifying an appropriate fallback for other browsers. [Learn more](https://amp.dev/documentation/components/amp-img/#example:-specifying-a-fallback-image).", + /** Additional description of a Lighthouse audit that tells the user how images are automatically lazy loaded for the AMP framewok. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "offscreen-images": "Ensure that you are using [`amp-img`](https://amp.dev/documentation/components/amp-img/?format=websites) for images to automatically lazy-load. [Learn more](https://amp.dev/documentation/guides-and-tutorials/develop/media_iframes_3p/?format=websites#images).", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by reducing the amount of render blocking resources present on their page in the context of the AMP framework. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "render-blocking-resources": "Use tools such as [AMP Optimizer](https://github.com/ampproject/amp-toolbox/tree/master/packages/optimizer) to [server-side render AMP layouts](https://amp.dev/documentation/guides-and-tutorials/optimize-and-measure/server-side-rendering/).", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by ensuring all the CSS written is supported by the AMP framework. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-css": "Refer to the [AMP documentation](https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/style_pages/) to ensure all styles are supported.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by using a runtime-managed animated image in the context of the AMP framework. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "efficient-animated-content": "For animated content, use [`amp-anim`](https://amp.dev/documentation/components/amp-anim/) to minimize CPU usage when the content is offscreen.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by using responsive images in the context of the AMP framework. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-responsive-images": "The [`amp-img`](https://amp.dev/documentation/components/amp-img/?format=websites) component supports the [`srcset`](https://web.dev/use-srcset-to-automatically-choose-the-right-image/) attribute to specify which image assets to use based on the screen size. [Learn more](https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/art_direction/)." + }; + module2.exports = { + id: "amp", + title: "AMP", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/angular.js +var require_angular = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/angular.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can improve site loading performance by reducing the total bytes delivered by their page in the context of the Angular framework. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "total-byte-weight": "Apply [route-level code splitting](https://web.dev/route-level-code-splitting-in-angular/) to minimize the size of your JavaScript bundles. Also, consider precaching assets with the [Angular service worker](https://web.dev/precaching-with-the-angular-service-worker/).", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS and JS files in the context of the Angular framework. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-warning": "If you are using Angular CLI, ensure that builds are generated in production mode. [Learn more](https://angular.io/guide/deployment#enable-runtime-production-mode).", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the Angular framework. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-javascript": "If you are using Angular CLI, include source maps in your production build to inspect your bundles. [Learn more](https://angular.io/guide/deployment#inspect-the-bundles).", + /** Additional description of a Lighthouse audit that tells the user how they can use responsive images in the context of the Angular framework. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-responsive-images": "Consider using the `BreakpointObserver` utility in the Component Dev Kit (CDK) to manage image breakpoints. [Learn more](https://material.angular.io/cdk/layout/overview).", + /** Additional description of a Lighthouse audit that tells the user how they can use preload to improve performance in the context of the Angular framework. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-rel-preload": "Preload routes ahead of time to speed up navigation. [Learn more](https://web.dev/route-preloading-in-angular/).", + /** Additional description of a Lighthouse audit that tells the user and *how* they should reduce the size of the web page's DOM in the context of the Angular framework. 'Learn More' becomes link text to additional documentation. */ + "dom-size": "Consider virtual scrolling with the Component Dev Kit (CDK) if very large lists are being rendered. [Learn more](https://web.dev/virtualize-lists-with-angular-cdk/)." + }; + module2.exports = { + id: "angular", + title: "Angular", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/drupal.js +var require_drupal = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/drupal.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused CSS, in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-css-rules": "Consider removing unused CSS rules and only attach the needed `Drupal` libraries to the relevant page or component in a page. See the [`Drupal` documentation](https://www.drupal.org/docs/develop/theming-drupal/adding-assets-css-js-to-a-drupal-theme-via-librariesyml#define) for details. To identify attached libraries that are adding extraneous CSS, try running [code coverage](https://developer.chrome.com/docs/devtools/coverage) in Chrome DevTools. You can identify the theme/module responsible from the URL of the stylesheet when CSS aggregation is disabled in your `Drupal` site. Look out for themes/modules that have many stylesheets in the list which have a lot of red in code coverage. A theme/module should only attach a stylesheet library if it is actually used on the page.", + /** Additional description of a Lighthouse audit that tells the user how they can improve image loading by using webp in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "modern-image-formats": "Consider configuring [WebP image formats with a Convert image style](https://www.drupal.org/docs/core-modules-and-themes/core-modules/image-module/working-with-images#styles) on your site.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by lazy loading images that are initially offscreen in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "offscreen-images": "Consider configuring lazy load images in `Drupal`. The field formatters for images support `lazy` or `eager`.", + /** Additional description of a Lighthouse audit that tells the user how they can improve site loading performance by reducing the total bytes delivered by their page in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "total-byte-weight": "Consider using [Responsive Image Styles](https://www.drupal.org/documentation/modules/responsive_image) to reduce the size of images loaded on your page. If you are using `Views` to show multiple content items on a page, consider implementing pagination to limit the number of content items shown on a given page.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by reducing the amount of render blocking resources present on their page, in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "render-blocking-resources": "Consider using [a module](https://www.drupal.org/project/critical_css) to inline critical CSS and JavaScript, and use the defer attribute for non-critical CSS or JavaScript.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS files in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-css": 'Ensure you have enabled "Aggregate CSS files" in the "Administration » Configuration » Development" page.', + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their Javascript files in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-javascript": 'Ensure you have enabled "Aggregate JavaScript files" in the "Administration » Configuration » Development" page.', + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by encoding animated images as video, in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "efficient-animated-content": "Consider uploading your `GIF` to a service which will make it available to embed as an HTML5 video.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-javascript": "Consider removing unused JavaScript assets and only attach the needed `Drupal` libraries to the relevant page or component in a page. See the [Drupal documentation](https://www.drupal.org/docs/develop/theming-drupal/adding-assets-css-js-to-a-drupal-theme-via-librariesyml#define) for details. To identify attached libraries that are adding extraneous JavaScript, try running [code coverage](https://developer.chrome.com/docs/devtools/coverage) in Chrome DevTools. You can identify the theme/module responsible from the URL of the script when JavaScript aggregation is disabled in your `Drupal` site. Look out for themes/modules that have many scripts in the list which have a lot of red in code coverage. A theme/module should only attach a script library if it is actually used on the page.", + /** Additional description of a Lighthouse audit that tells the user how they can improve their site by enabling long caching in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-long-cache-ttl": 'Set the "Browser and proxy cache maximum age" in the "Administration » Configuration » Development" page. Read about [`Drupal` cache and optimizing for performance](https://www.drupal.org/docs/8/api/cache-api/cache-api).', + /** Additional description of a Lighthouse audit that tells the user how they can improve site performance by optimizing images, in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-optimized-images": "Consider using [a module](https://www.drupal.org/project/project_module?f%5B0%5D=&f%5B1%5D=&f%5B2%5D=im_vid_3%3A123&f%5B3%5D=&f%5B4%5D=sm_field_project_type%3Afull&f%5B5%5D=&f%5B6%5D=&text=image&solrsort=iss_project_release_usage+desc&op=Search) that automatically optimizes and reduces the size of images uploaded through the site while retaining quality. Also, ensure you are using the native [Responsive Image Styles](https://www.drupal.org/documentation/modules/responsive_image) provided from `Drupal` for all images rendered on the site.", + /** Additional description of a Lighthouse audit for a third-party framework called `Drupal`. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-text-compression": "Text-based resources should be served with compression (gzip, deflate or brotli) to minimize total network bytes. Consider using a CDN that natively supports this, or configure the web server to perform this operation. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/text-compression).", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by using responsive images in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-responsive-images": "Ensure that you are using the native [Responsive Image Styles](https://www.drupal.org/documentation/modules/responsive_image) provided from `Drupal`. Use the Responsive Image Styles when rendering image fields through view modes, views, or images uploaded through the WYSIWYG editor.", + /** Additional description of a Lighthouse audit for a third-party framework called `Drupal`. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "prioritize-lcp-image": "If the LCP element is dynamically added to the page, you should optimize the image in order to improve LCP. [Learn more](https://www.smashingmagazine.com/2023/08/methods-improving-drupal-largest-contentful-paint-core-web-vital/).", + /** Additional description of a Lighthouse audit that tells the user how they can improve the time to first byte speed metric, in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "server-response-time": "Offload traffic with one or more `Drupal` caching modules such as `Internal Page Cache`, `Internal Dynamic Page Cache`, and `BigPipe`. Couple these with a CDN to further improve response time. Your hosting servers should make use of PHP OPcache. Consider using memory-caching such as Redis or Memcached to reduce database query times. Lastly use performant themes, modules, and faster servers to lower server response time.", + /** Additional description of a Lighthouse audit for a third-party framework called `Drupal`. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "redirects": "Redirects introduce additional delays before the page can be loaded. If the [Redirect](https://www.drupal.org/project/redirect) module is installed, review if unnecessary redirects can be removed. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/redirects).", + /** Additional description of a Lighthouse audit that tells the user how they can add preconnect or dns-prefetch resource hints, in the context of the `Drupal` CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-rel-preconnect": "`Preconnect` or `dns-prefetch` resource hints can be added by installing and configuring [a module](https://www.drupal.org/project/project_module?f%5B0%5D=&f%5B1%5D=&f%5B2%5D=&f%5B3%5D=&f%5B4%5D=sm_field_project_type%3Afull&f%5B5%5D=&f%5B6%5D=&text=Preconnect&solrsort=score+desc&op=Search) that provides facilities for user agent resource hints." + }; + module2.exports = { + id: "drupal", + title: "Drupal", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/ezoic.js +var require_ezoic = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/ezoic.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Remove Unused CSS is a setting name. */ + "unused-css-rules": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Remove Unused CSS` to help with this issue. It will identify the CSS classes that are actually used on each page of your site, and remove any others to keep the file size small.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Next-Gen Formats is a setting name.*/ + "modern-image-formats": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Next-Gen Formats` to convert images to WebP.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Lazy Load Images is a setting name.*/ + "offscreen-images": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Lazy Load Images` to defer loading off-screen images until they are needed.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Script Delay is a setting name.*/ + "render-blocking-resources": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Script Delay` to defer non-critical JS.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Minify CSS is a setting name.*/ + "unminified-css": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Minify CSS` to automatically minify your CSS to reduce network payload sizes.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Minify Javascript is a setting name.*/ + "unminified-javascript": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Minify Javascript` to automatically minify your JS to reduce network payload sizes.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Efficient Static Cache Policy is a setting name.*/ + "uses-long-cache-ttl": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Efficient Static Cache Policy` to set recommended values in the caching header for static assests.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Next-Gen Formats is a setting name.*/ + "uses-optimized-images": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Next-Gen Formats` to convert images to WebP.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Resize Images is a setting name.*/ + "uses-responsive-images": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Resize Images` to resize images to a device appropriate size, reducing network payload sizes.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Cloud Caching is Ezoic's CDN.*/ + "server-response-time": "Use [Ezoic Cloud Caching](https://pubdash.ezoic.com/leap/caching) to cache your content across our world wide network, improving time to first byte.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Pre-Connect Origins is a setting name.*/ + "uses-rel-preconnect": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Pre-Connect Origins` to automatically add `preconnect` resource hints to establish early connections to important third-party origins.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Preload Fonts and Preload Background Images are setting names.*/ + "uses-rel-preload": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Preload Fonts` and `Preload Background Images` to add `preload` links to prioritize fetching resources that are currently requested later in page load.", + /** Additional description of a Lighthouse audit for a third-party framework called `Ezoic`. This is displayed after a user expands the section to see more. No character length limits. Ezoic Leap is Ezoic's site speed improvement toolset. Optimize Fonts is a setting name.*/ + "font-display": "Use [Ezoic Leap](https://pubdash.ezoic.com/leap) and enable `Optimize Fonts` to automatically leverage the `font-display` CSS feature to ensure text is user-visible while webfonts are loading." + }; + module2.exports = { + id: "ezoic", + title: "Ezoic", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/gatsby.js +var require_gatsby = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/gatsby.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can remove unused CSS rules by configuring the Gatsby plugin `gatsby-plugin-purgecss` which sets up PurgeCSS */ + "unused-css-rules": "Use the `PurgeCSS` `Gatsby` plugin to remove unused rules from stylesheets. [Learn more](https://purgecss.com/plugins/gatsby.html).", + /** Additional description of a Lighthouse audit that tells the user to use the gatsby-plugin-image component to automatically optimize image format */ + "modern-image-formats": "Use the `gatsby-plugin-image` component instead of `` to automatically optimize image format. [Learn more](https://www.gatsbyjs.com/docs/how-to/images-and-media/using-gatsby-plugin-image).", + /** Additional description of a Lighthouse audit that tells the user to defer loading images which are not shown on screen using the gatsby-plugin-image component */ + "offscreen-images": "Use the `gatsby-plugin-image` component instead of `` to automatically lazy-load images. [Learn more](https://www.gatsbyjs.com/docs/how-to/images-and-media/using-gatsby-plugin-image).", + /** Additional description of a Lighthouse audit that tells the user to use gatsby-script to defer loading of non-critical third-party libraries */ + "render-blocking-resources": "Use the `Gatsby Script API` to defer loading of non-critical third-party scripts. [Learn more](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-script/).", + /** Additional description of a Lighthouse audit that tells the user to use Webpack Bundle Analyzer to discover JavaScript code that is not used */ + "unused-javascript": "Use `Webpack Bundle Analyzer` to detect unused JavaScript code. [Learn more](https://www.gatsbyjs.com/plugins/gatsby-plugin-webpack-bundle-analyser-v2/)", + /** Additional description of a Lighthouse audit that tells the user to enable caching for assets (e.g. images) and artifacts that don't change between deployments */ + "uses-long-cache-ttl": "Configure caching for immutable assets. [Learn more](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/caching/).", + /** Additional description of a Lighthouse audit that tells the user to use the gatsby-plugin-image component to adjust image quality */ + "uses-optimized-images": "Use the `gatsby-plugin-image` component instead of `` to adjust image quality. [Learn more](https://www.gatsbyjs.com/docs/how-to/images-and-media/using-gatsby-plugin-image).", + /** Additional description of a Lighthouse audit that tells the user to serve responsive images using the gatsby-plugin-image component with appropriate `sizes` set */ + "uses-responsive-images": "Use the `gatsby-plugin-image` component to set appropriate `sizes`. [Learn more](https://www.gatsbyjs.com/docs/how-to/images-and-media/using-gatsby-plugin-image).", + /** Additional description of a Lighthouse audit that tells the user to use the gatsby-plugin-image component to automatically preload LCP images. "prop" is short for "property" */ + "prioritize-lcp-image": "Use the `gatsby-plugin-image` component and set the `loading` prop to `eager`. [Learn more](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-plugin-image#shared-props)." + }; + module2.exports = { + id: "gatsby", + title: "Gatsby", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/joomla.js +var require_joomla = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/joomla.js"(exports2, module2) { + "use strict"; + init_process_global(); + /** + * @license Copyright 2020 The Lighthouse Authors. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the 'License'); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused CSS, in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-css-rules": "Consider reducing, or switching, the number of [Joomla extensions](https://extensions.joomla.org/) loading unused CSS in your page. To identify extensions that are adding extraneous CSS, try running [code coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the stylesheet. Look out for plugins that have many stylesheets in the list which have a lot of red in code coverage. A plugin should only enqueue a stylesheet if it is actually used on the page.", + /** Additional description of a Lighthouse audit that tells the user how they can improve image loading by using webp in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "modern-image-formats": "Consider using a [plugin](https://extensions.joomla.org/instant-search/?jed_live%5Bquery%5D=webp) or service that will automatically convert your uploaded images to the optimal formats.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by lazy loading images that are initially offscreen in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "offscreen-images": "Install a [lazy-load Joomla plugin](https://extensions.joomla.org/instant-search/?jed_live%5Bquery%5D=lazy%20loading) that provides the ability to defer any offscreen images, or switch to a template that provides that functionality. Starting with Joomla 4.0, all new images will [automatically](https://github.com/joomla/joomla-cms/pull/30748) get the `loading` attribute from the core.", + /** Additional description of a Lighthouse audit that tells the user how they can improve site loading performance by reducing the total bytes delivered by their page in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "total-byte-weight": "Consider showing excerpts in your article categories (e.g. via the read more link), reducing the number of articles shown on a given page, breaking your long posts into multiple pages, or using a plugin to lazy-load comments.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by reducing the amount of render blocking resources present on their page, in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "render-blocking-resources": "There are a number of Joomla plugins that can help you [inline critical assets](https://extensions.joomla.org/instant-search/?jed_live%5Bquery%5D=performance) or [defer less important resources](https://extensions.joomla.org/instant-search/?jed_live%5Bquery%5D=performance). Beware that optimizations provided by these plugins may break features of your templates or plugins, so you will need to test these thoroughly.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS files in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-css": "A number of [Joomla extensions](https://extensions.joomla.org/instant-search/?jed_live%5Bquery%5D=performance) can speed up your site by concatenating, minifying, and compressing your css styles. There are also templates that provide this functionality.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their Javascript files in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-javascript": "A number of [Joomla extensions](https://extensions.joomla.org/instant-search/?jed_live%5Bquery%5D=performance) can speed up your site by concatenating, minifying, and compressing your scripts. There are also templates that provide this functionality.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by encoding animated images as video, in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "efficient-animated-content": "Consider uploading your GIF to a service which will make it available to embed as an HTML5 video.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-javascript": "Consider reducing, or switching, the number of [Joomla extensions](https://extensions.joomla.org/) loading unused JavaScript in your page. To identify plugins that are adding extraneous JS, try running [code coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) in Chrome DevTools. You can identify the extension responsible from the URL of the script. Look out for extensions that have many scripts in the list which have a lot of red in code coverage. An extension should only enqueue a script if it is actually used on the page.", + /** Additional description of a Lighthouse audit that tells the user how they can improve their site by enabling long caching in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-long-cache-ttl": "Read about [Browser Caching in Joomla](https://docs.joomla.org/Cache).", + /** Additional description of a Lighthouse audit that tells the user how they can improve site performance by optimizing images, in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-optimized-images": "Consider using an [image optimization plugin](https://extensions.joomla.org/instant-search/?jed_live%5Bquery%5D=performance) that compresses your images while retaining quality.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance via enabling text compression in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-text-compression": "You can enable text compression by enabling Gzip Page Compression in Joomla (System > Global configuration > Server).", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by using responsive images in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-responsive-images": "Consider using a [responsive images plugin](https://extensions.joomla.org/instant-search/?jed_live%5Bquery%5D=responsive%20images) to use responsive images in your content.", + /** Additional description of a Lighthouse audit that tells the user how they can improve the server-response-time speed metric, in the context of the Joomla CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "server-response-time": "Templates, extensions, and server specifications all contribute to server response time. Consider finding a more optimized template, carefully selecting an optimization extension, and/or upgrading your server." + }; + module2.exports = { + id: "joomla", + title: "Joomla", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/magento.js +var require_magento = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/magento.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can improve image loading by using webp in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "modern-image-formats": "Consider searching the [Magento Marketplace](https://marketplace.magento.com/catalogsearch/result/?q=webp) for a variety of third-party extensions to leverage newer image formats.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by lazy loading images that are initially offscreen in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "offscreen-images": "Consider modifying your product and catalog templates to make use of the web platform's [lazy loading](https://web.dev/native-lazy-loading) feature.", + /** Additional description of a Lighthouse audit that tells the user how they can improve site loading performance by disabling JS bundling in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "disable-bundling": "Disable Magento's built-in [JavaScript bundling and minification](https://devdocs.magento.com/guides/v2.3/frontend-dev-guide/themes/js-bundling.html), and consider using [baler](https://github.com/magento/baler/) instead.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS files in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-css": `Enable the "Minify CSS Files" option in your store's Developer settings. [Learn more](https://devdocs.magento.com/guides/v2.3/performance-best-practices/configuration.html?itm_source=devdocs&itm_medium=search_page&itm_campaign=federated_search&itm_term=minify%20css%20files).`, + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their Javascript files in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-javascript": "Use [Terser](https://www.npmjs.com/package/terser) to minify all JavaScript assets from static content deployment, and disable the built-in minification feature.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-javascript": "Disable Magento's built-in [JavaScript bundling](https://devdocs.magento.com/guides/v2.3/frontend-dev-guide/themes/js-bundling.html).", + /** Additional description of a Lighthouse audit that tells the user how they can improve site performance by optimizing images, in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-optimized-images": "Consider searching the [Magento Marketplace](https://marketplace.magento.com/catalogsearch/result/?q=optimize%20image) for a variety of third party extensions to optimize images.", + /** Additional description of a Lighthouse audit that tells the user how they can improve the time to first byte speed metric, in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "server-response-time": "Use Magento's [Varnish integration](https://devdocs.magento.com/guides/v2.3/config-guide/varnish/config-varnish.html).", + /** Additional description of a Lighthouse audit that tells the user how they can add preconnect or dns-prefetch resource hints, in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-rel-preconnect": "Preconnect or dns-prefetch resource hints can be added by [modifying a themes's layout](https://devdocs.magento.com/guides/v2.3/frontend-dev-guide/layouts/xml-manage.html).", + /** Additional description of a Lighthouse audit that tells the user how they can add preload tags, in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-rel-preload": "`` tags can be added by [modifying a themes's layout](https://devdocs.magento.com/guides/v2.3/frontend-dev-guide/layouts/xml-manage.html).", + /** Additional description of a Lighthouse audit that tells the user how they can minimize critical request chains, in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "critical-request-chains": "If you are not bundling your JavaScript assets, consider using [baler](https://github.com/magento/baler).", + /** Additional description of a Lighthouse audit that tells the user how they can specify font-display, in the context of the Magento platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "font-display": "Specify `@font-display` when [defining custom fonts](https://devdocs.magento.com/guides/v2.3/frontend-dev-guide/css-topics/using-fonts.html)." + }; + module2.exports = { + id: "magento", + title: "Magento", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/next.js +var require_next = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/next.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can remove unusused CSS rules by configuring a plugin named PurgeCSS. */ + "unused-css-rules": "Consider setting up `PurgeCSS` in `Next.js` configuration to remove unused rules from stylesheets. [Learn more](https://purgecss.com/guides/next.html).", + /** Additional description of a Lighthouse audit that tells the user to use the next/image component to automatically optimize image format. */ + "modern-image-formats": "Use the `next/image` component instead of `` to automatically optimize image format. [Learn more](https://nextjs.org/docs/app/getting-started/images).", + /** Additional description of a Lighthouse audit that tells the user to defer loading images which are not shown on screen using the next/image component. */ + "offscreen-images": "Use the `next/image` component instead of `` to automatically lazy-load images. [Learn more](https://nextjs.org/docs/app/getting-started/images).", + /** Additional description of a Lighthouse audit that tells the user to use next/script to defer loading of non-critical third-party libraries. */ + "render-blocking-resources": "Use the `next/script` component to defer loading of non-critical third-party scripts. [Learn more](https://nextjs.org/docs/app/guides/scripts).", + /** Additional description of a Lighthouse audit that tells the user to use Webpack Bundle Analyzer to discover JavaScript code that is not used. */ + "unused-javascript": "Use `Webpack Bundle Analyzer` to detect unused JavaScript code. [Learn more](https://github.com/vercel/next.js/tree/canary/packages/next-bundle-analyzer)", + /** Additional description of a Lighthouse audit that tells the user to enable caching for assets (e.g. images) and server-side rendered (SSR) pages that don't change between deployments. */ + "uses-long-cache-ttl": "Configure caching for immutable assets and `Server-side Rendered` (SSR) pages. [Learn more](https://nextjs.org/docs/13/pages/building-your-application/deploying/production-checklist#caching).", + /** Additional description of a Lighthouse audit that tells the user to use the next/image component to adjust image quality. */ + "uses-optimized-images": "Use the `next/image` component instead of `` to adjust image quality. [Learn more](https://nextjs.org/docs/app/getting-started/images).", + /** Additional description of a Lighthouse audit that tells the user to enable compression (gzip, brotli) on their servers. */ + "uses-text-compression": "Enable compression on your Next.js server. [Learn more](https://nextjs.org/docs/api-reference/next.config.js/compression).", + /** Additional description of a Lighthouse audit that tells the user to serve responsive images using the next/image component with appropriate `sizes` set. */ + "uses-responsive-images": "Use the `next/image` component to set the appropriate `sizes`. [Learn more](https://nextjs.org/docs/api-reference/next/image#sizes).", + /** Additional description of a Lighthouse audit that tells the user to analyze the performance of their applications using Next.js Analytics. */ + "user-timings": "Consider using `Next.js Analytics` to measure your app's real-world performance. [Learn more](https://nextjs.org/docs/pages/guides/analytics).", + /** Additional description of a Lighthouse audit that tells the user to use the next/image component to automatically preload LCP images. */ + "prioritize-lcp-image": 'Use the `next/image` component and set "priority" to true to preload LCP image. [Learn more](https://nextjs.org/docs/api-reference/next/image#priority).', + /** Additional description of a Lighthouse audit that tells the user to use the next/image component to make sure `width` and `height` of image elements are always specified. */ + "unsized-images": "Use the `next/image` component to make sure images are always sized appropriately. [Learn more](https://nextjs.org/docs/api-reference/next/image#width)." + }; + module2.exports = { + id: "next.js", + title: "Next.js", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/nitropack.js +var require_nitropack = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/nitropack.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Reduce Unused CSS` is the name of a feature and becomes link text to additional documentation.*/ + "unused-css-rules": "Enable [`Reduce Unused CSS`](https://support.nitropack.io/hc/en-us/articles/360020418457-Reduce-Unused-CSS) to remove CSS rules that are not applicable to this page.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Image Optimization` is the name of a feature and becomes link text to additional documentation. `WebP` is the name of a standardized image format for the web.*/ + "modern-image-formats": "Use [`Image Optimization`](https://support.nitropack.io/hc/en-us/articles/16547237162513) to automatically convert your images to WebP.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Automatic Image Lazy Loading` is the name of a feature and becomes link text to additional documentation.*/ + "offscreen-images": "Defer offscreen images by enabling [`Automatic Image Lazy Loading`](https://support.nitropack.io/hc/en-us/articles/12457493524369-NitroPack-Lazy-Loading-Feature-for-Images).", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Remove render-blocking resources` is the name of a feature and becomes link text to additional documentation.*/ + "render-blocking-resources": "Enable [`Remove render-blocking resources`](https://support.nitropack.io/hc/en-us/articles/13820893500049-How-to-Deal-with-Render-Blocking-Resources-in-NitroPack) in NitroPack for faster initial load times.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Minify resources` is the name of a feature and becomes link text to additional documentation.*/ + "unminified-css": "Enable [`Minify resources`](https://support.nitropack.io/hc/en-us/articles/360061059394-Minify-Resources) in your Caching settings to reduce the size of your CSS, HTML, and JavaScript files for faster load times.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Minify resources` is the name of a feature and becomes link text to additional documentation.*/ + "unminified-javascript": "Enable [`Minify resources`](https://support.nitropack.io/hc/en-us/articles/360061059394-Minify-Resources) in your Caching settings to reduce the size of your JS, HTML, and CSS files for faster load times.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Delayed Scripts` is the name of a feature and becomes link text to additional documentation.*/ + "unused-javascript": "Configure [`Delayed Scripts`](https://support.nitropack.io/hc/en-us/articles/1500002600942-Delayed-Scripts) in NitroPack to delay loading of scripts until they are needed.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Improve Server Response Time` is the name of a feature and becomes link text to additional documentation.*/ + "uses-long-cache-ttl": "Go to the [`Improve Server Response Time`](https://support.nitropack.io/hc/en-us/articles/1500002321821-Improve-Server-Response-Time) feature in the `Caching` menu and adjust your page cache expiration time to improve loading times and user experience.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Image Optimization` is the name of a feature and becomes link text to additional documentation.*/ + "uses-optimized-images": "Automatically compress, optimize, and convert your images into WebP by enabling the [`Image Optimization`](https://support.nitropack.io/hc/en-us/articles/14177271695121-How-to-serve-images-in-next-gen-formats-using-NitroPack) setting.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Adaptive Image Sizing` is the name of a feature and becomes link text to additional documentation.*/ + "uses-responsive-images": "Enable [`Adaptive Image Sizing`](https://support.nitropack.io/hc/en-us/articles/10123833029905-How-to-Enable-Adaptive-Image-Sizing-For-Your-Site) to preemptively optimize your images and make them match the dimensions of the containers they’re displayed in across all devices.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `HTML Lazy Load` is the name of a feature.*/ + "dom-size": "Contact your account manager to enable [`HTML Lazy Load`](https://support.nitropack.io/hc/en-us/articles/17144942904337). Configuring it will prioritize and optimize your page rendering performance.", + /** Additional description of a Lighthouse audit for a third-party framework called `NitroPack`. This is displayed after a user expands the section to see more. No character length limits. `Override Font Rendering Behavior` is the name of a feature and becomes link text to additional documentation.*/ + "font-display": "Use the [`Override Font Rendering Behavior`](https://support.nitropack.io/hc/en-us/articles/16547358865041) option in NitroPack to set a desired value for the CSS font-display rule." + }; + module2.exports = { + id: "nitropack", + title: "NitroPack", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/nuxt.js +var require_nuxt = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/nuxt.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user to use the nuxt/image component to serve modern formats like WebP. */ + "modern-image-formats": 'Use the `nuxt/image` component and set `format="webp"`. [Learn more](https://image.nuxt.com/usage/nuxt-img#format).', + /** Additional description of a Lighthouse audit that tells the user to use the nuxt/image component to defer loading images which are not shown on screen. */ + "offscreen-images": 'Use the `nuxt/image` component and set `loading="lazy"` for offscreen images. [Learn more](https://image.nuxt.com/usage/nuxt-img#loading).', + /** Additional description of a Lighthouse audit that tells the user to use the nuxt/image component to automatically compress their images. */ + "uses-optimized-images": "Use the `nuxt/image` component and set the appropriate `quality`. [Learn more](https://image.nuxt.com/usage/nuxt-img#quality).", + /** Additional description of a Lighthouse audit that tells the user to use the nuxt/image component to serve appropriately sized images to different devices. */ + "uses-responsive-images": "Use the `nuxt/image` component and set the appropriate `sizes`. [Learn more](https://image.nuxt.com/usage/nuxt-img#sizes).", + /** Additional description of a Lighthouse audit that tells the user to use the nuxt/image component to prioritize the loading of the image that is part of the Largest Contentful Paint (LCP). */ + "prioritize-lcp-image": "Use the `nuxt/image` component and specify `preload` for LCP image. [Learn more](https://image.nuxt.com/usage/nuxt-img#preload).", + /** Additional description of a Lighthouse audit that tells the user to use the nuxt/image component to provide explicit `width` and `height` for images to prevent layout shift. */ + "unsized-images": "Use the `nuxt/image` component and specify explicit `width` and `height`. [Learn more](https://image.nuxt.com/usage/nuxt-img#width-height)." + }; + module2.exports = { + id: "nuxt", + title: "Nuxt", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/octobercms.js +var require_octobercms = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/octobercms.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused CSS, in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-css-rules": "Consider reviewing the [plugins](https://octobercms.com/plugins) loading unused CSS on the website. To identify plugins that add unnecessary CSS, run [code coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) in Chrome DevTools. Identify the theme/plugin responsible from the stylesheet URL. Look for plugins with many stylesheets with lots of red in code coverage. A plugin should only add a stylesheet if it is actually used on the web page.", + /** Additional description of a Lighthouse audit that tells the user how they can improve image loading by using webp in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "modern-image-formats": "Consider using a [plugin](https://octobercms.com/plugins?search=image) or service that will automatically convert the uploaded images to the optimal formats. [WebP lossless images](https://developers.google.com/speed/webp) are 26% smaller in size compared to PNGs and 25-34% smaller than comparable JPEG images at the equivalent SSIM quality index. Another next-gen image format to consider is [AVIF](https://jakearchibald.com/2020/avif-has-landed/).", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by lazy loading images that are initially offscreen in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "offscreen-images": "Consider installing an [image lazy loading plugin](https://octobercms.com/plugins?search=lazy) that provides the ability to defer any offscreen images, or switch to a theme that provides that functionality. Also consider using [the AMP plugin](https://octobercms.com/plugins?search=Accelerated+Mobile+Pages).", + /** Additional description of a Lighthouse audit that tells the user how they can improve site loading performance by reducing the total bytes delivered by their page in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "total-byte-weight": "Consider showing excerpts in the post lists (e.g. using a `show more` button), reducing the number of posts shown on a given web page, breaking long posts into multiple web pages, or using a plugin to lazy-load comments.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by reducing the amount of render blocking resources present on their page, in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "render-blocking-resources": "There are many plugins that help [inline critical assets](https://octobercms.com/plugins?search=css). These plugins may break other plugins, so you should test thoroughly.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS files in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-css": "There are many [plugins](https://octobercms.com/plugins?search=css) that can speed up a website by concatenating, minifying and compressing the styles. Using a build process to do this minification up-front can speed up development.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their Javascript files in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-javascript": "There are many [plugins](https://octobercms.com/plugins?search=javascript) that can speed up a website by concatenating, minifying and compressing the scripts. Using a build process to do this minification up-front can speed up development.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by encoding animated images as video, in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "efficient-animated-content": "[Replace animated GIFs with video](https://web.dev/replace-gifs-with-videos/) for faster web page loads and consider using modern file formats such as [WebM](https://web.dev/replace-gifs-with-videos/#create-webm-videos) or [AV1](https://developers.google.com/web/updates/2018/09/chrome-70-media-updates#av1-decoder) to improve compression efficiency by greater than 30% over the current state-of-the-art video codec, VP9.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-javascript": "Consider reviewing the [plugins](https://octobercms.com/plugins?search=javascript) that load unused JavaScript in the web page. To identify plugins that add unnecessary JavaScript, run [code coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) in Chrome DevTools. Identify the theme/plugin responsible from the URL of the script. Look for plugins with many scripts with lots of red in code coverage. A plugin should only add a script if it is actually used on the web page.", + /** Additional description of a Lighthouse audit that tells the user how they can improve their site by enabling long caching in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-long-cache-ttl": "Read about [preventing unnecessary network requests with the HTTP Cache](https://web.dev/http-cache/#caching-checklist). There are many [plugins](https://octobercms.com/plugins?search=Caching) that can be used to speed up caching.", + /** Additional description of a Lighthouse audit that tells the user how they can improve site performance by optimizing images, in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-optimized-images": "Consider using an [image optimization plugin](https://octobercms.com/plugins?search=image) to compresses images while retaining the quality.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance via enabling text compression in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-text-compression": "Enable text compression in the web server configuration.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by using responsive images in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-responsive-images": "Upload images directly in the media manager to ensure the required image sizes are available. Consider using the [resize filter](https://octobercms.com/docs/markup/filter-resize) or an [image resizing plugin](https://octobercms.com/plugins?search=image) to ensure the optimal image sizes are used.", + /** Additional description of a Lighthouse audit that tells the user how they can improve the time to first byte speed metric, in the context of the October CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "server-response-time": "Themes, plugins and server specifications all contribute to the server response time. Consider finding a more optimized theme, carefully selecting an optimization plugin and/or upgrade the server. October CMS also allows developers to use [`Queues`](https://octobercms.com/docs/services/queues) to defer the processing of a time consuming task, such as sending an e-mail. This drastically speeds up web requests." + }; + module2.exports = { + id: "octobercms", + title: "October CMS", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/react.js +var require_react = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/react.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS files in the context of the React library. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-css": "If your build system minifies CSS files automatically, ensure that you are deploying the production build of your application. You can check this with the React Developer Tools extension. [Learn more](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build).", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their Javascript files in the context of the React library. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-javascript": "If your build system minifies JS files automatically, ensure that you are deploying the production build of your application. You can check this with the React Developer Tools extension. [Learn more](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build).", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the React library. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-javascript": "If you are not server-side rendering, [split your JavaScript bundles](https://web.dev/code-splitting-suspense/) with `React.lazy()`. Otherwise, code-split using a third-party library such as [loadable-components](https://loadable-components.com/).", + /** Additional description of a Lighthouse audit that tells the user how they can improve the time to first byte speed metric, in the context of the React library. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "server-response-time": "If you are server-side rendering any React components, consider using `renderToPipeableStream()` or `renderToStaticNodeStream()` to allow the client to receive and hydrate different parts of the markup instead of all at once. [Learn more](https://reactjs.org/docs/react-dom-server.html#renderToPipeableStream).", + /** Additional description of a Lighthouse audit that tells the user how they can minimize redirects, in the context of the React library. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "redirects": "If you are using React Router, minimize usage of the `` component for [route navigations](https://reacttraining.com/react-router/web/api/Redirect).", + /** Additional description of a Lighthouse audit that tells the user how they can use the Profiler to help measure performance. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "user-timings": "Use the React DevTools Profiler, which makes use of the Profiler API, to measure the rendering performance of your components. [Learn more.](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html)", + /** Additional description of a Lighthouse audit that tells the user *why* and *how* they should reduce the size of the web page"s DOM, in the context of the React library, as well as how to maximize component performance when many DOM nodes are present. 'Learn More' becomes link text to additional documentation. */ + "dom-size": 'Consider using a "windowing" library like `react-window` to minimize the number of DOM nodes created if you are rendering many repeated elements on the page. [Learn more](https://web.dev/virtualize-long-lists-react-window/). Also, minimize unnecessary re-renders using [`shouldComponentUpdate`](https://reactjs.org/docs/optimizing-performance.html#shouldcomponentupdate-in-action), [`PureComponent`](https://reactjs.org/docs/react-api.html#reactpurecomponent), or [`React.memo`](https://reactjs.org/docs/react-api.html#reactmemo) and [skip effects](https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects) only until certain dependencies have changed if you are using the `Effect` hook to improve runtime performance.' + }; + module2.exports = { + id: "react", + title: "React", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/wix.js +var require_wix = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/wix.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user to optimize image formats, in the context of the Wix CMS platform. */ + "modern-image-formats": "Upload images using `Wix Media Manager` to ensure they are automatically served as WebP. Find [more ways to optimize](https://support.wix.com/en/article/site-performance-optimizing-your-media) your site's media.", + /** Additional description of a Lighthouse audit that tells the user to defer loading of non-critical third-party libraries, in the context of the Wix CMS platform. */ + "render-blocking-resources": "When [adding third-party code](https://support.wix.com/en/article/site-performance-using-third-party-code-on-your-site) in the `Custom Code` tab of your site's dashboard, make sure it's deferred or loaded at the end of the code body. Where possible, use Wix’s [integrations](https://support.wix.com/en/article/about-marketing-integrations) to embed marketing tools on your site. ", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by avoiding animated images and using videos where possible, in the context of the Wix CMS platform. */ + "efficient-animated-content": "Place videos inside `VideoBoxes`, customize them using `Video Masks` or add `Transparent Videos`. [Learn more](https://support.wix.com/en/article/wix-video-about-wix-video).", + /** Additional description of a Lighthouse audit that tells the user to be aware of JavaScript code that is not used, particularly from third-parties, in the context of the Wix CMS platform. */ + "unused-javascript": "Review any third-party code you've added to your site in the `Custom Code` tab of your site's dashboard and only keep the services that are necessary to your site. [Find out more](https://support.wix.com/en/article/site-performance-removing-unused-javascript).", + /** Additional description of a Lighthouse audit that tells the user how they can improve the server response time, in the context of the Wix CMS platform. */ + "server-response-time": "Wix utilizes CDNs and caching to serve responses as fast as possible for most visitors. Consider [manually enabling caching](https://support.wix.com/en/article/site-performance-caching-pages-to-optimize-loading-speed) for your site, especially if using `Velo`." + }; + module2.exports = { + id: "wix", + title: "Wix", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/wordpress.js +var require_wordpress = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/wordpress.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused CSS, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-css-rules": "Consider reducing, or switching, the number of [WordPress plugins](https://wordpress.org/plugins/) loading unused CSS in your page. To identify plugins that are adding extraneous CSS, try running [code coverage](https://developer.chrome.com/docs/devtools/coverage/) in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the stylesheet. Look out for plugins that have many stylesheets in the list which have a lot of red in code coverage. A plugin should only enqueue a stylesheet if it is actually used on the page.", + /** Additional description of a Lighthouse audit that tells the user how they can improve image loading by using webp in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. */ + "modern-image-formats": "Consider using the [Performance Lab](https://wordpress.org/plugins/performance-lab/) plugin to automatically convert your uploaded JPEG images into WebP, wherever supported.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by lazy loading images that are initially offscreen in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "offscreen-images": "Install a [lazy-load WordPress plugin](https://wordpress.org/plugins/search/lazy+load/) that provides the ability to defer any offscreen images, or switch to a theme that provides that functionality. Also consider using [the AMP plugin](https://wordpress.org/plugins/amp/).", + /** Additional description of a Lighthouse audit that tells the user how they can improve site loading performance by reducing the total bytes delivered by their page in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "total-byte-weight": "Consider showing excerpts in your post lists (e.g. via the more tag), reducing the number of posts shown on a given page, breaking your long posts into multiple pages, or using a plugin to lazy-load comments.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by reducing the amount of render blocking resources present on their page, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "render-blocking-resources": "There are a number of WordPress plugins that can help you [inline critical assets](https://wordpress.org/plugins/search/critical+css/) or [defer less important resources](https://wordpress.org/plugins/search/defer+css+javascript/). Beware that optimizations provided by these plugins may break features of your theme or plugins, so you will likely need to make code changes.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their CSS files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-css": "A number of [WordPress plugins](https://wordpress.org/plugins/search/minify+css/) can speed up your site by concatenating, minifying, and compressing your styles. You may also want to use a build process to do this minification up-front if possible.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by minifying their Javascript files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unminified-javascript": "A number of [WordPress plugins](https://wordpress.org/plugins/search/minify+javascript/) can speed up your site by concatenating, minifying, and compressing your scripts. You may also want to use a build process to do this minification up front if possible.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by encoding animated images as video, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "efficient-animated-content": "Consider uploading your GIF to a service which will make it available to embed as an HTML5 video.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by removing unused Javascript files in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "unused-javascript": "Consider reducing, or switching, the number of [WordPress plugins](https://wordpress.org/plugins/) loading unused JavaScript in your page. To identify plugins that are adding extraneous JS, try running [code coverage](https://developer.chrome.com/docs/devtools/coverage/) in Chrome DevTools. You can identify the theme/plugin responsible from the URL of the script. Look out for plugins that have many scripts in the list which have a lot of red in code coverage. A plugin should only enqueue a script if it is actually used on the page.", + /** Additional description of a Lighthouse audit that tells the user how they can improve their site by enabling long caching in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-long-cache-ttl": "Read about [Browser Caching in WordPress](https://wordpress.org/support/article/optimization/#browser-caching).", + /** Additional description of a Lighthouse audit that tells the user how they can improve site performance by optimizing images, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-optimized-images": "Consider using an [image optimization WordPress plugin](https://wordpress.org/plugins/search/optimize+images/) that compresses your images while retaining quality.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance via enabling text compression in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-text-compression": "You can enable text compression in your web server configuration.", + /** Additional description of a Lighthouse audit that tells the user how they can improve performance by using responsive images in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "uses-responsive-images": "Upload images directly through the [media library](https://wordpress.org/support/article/media-library-screen/) to ensure that the required image sizes are available, and then insert them from the media library or use the image widget to ensure the optimal image sizes are used (including those for the responsive breakpoints). Avoid using `Full Size` images unless the dimensions are adequate for their usage. [Learn More](https://wordpress.org/support/article/inserting-images-into-posts-and-pages/).", + /** Additional description of a Lighthouse audit that tells the user how they can improve the time to first byte speed metric, in the context of the Wordpress CMS platform. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + "server-response-time": "Choose a lightweight theme (ideally a block theme) and implement full-page caching or a static site solution. Disable unnecessary plugins to minimize server overhead. Consider upgrading your hosting to managed or dedicated service." + }; + module2.exports = { + id: "wordpress", + title: "WordPress", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/packs/wp-rocket.js +var require_wp_rocket = __commonJS({ + "node_modules/lighthouse-stack-packs/packs/wp-rocket.js"(exports2, module2) { + init_process_global(); + var icon = `data:image/svg+xml,`; + var UIStrings125 = { + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. Remove Unused CSS is a name of the feature */ + "unused-css-rules": `Enable [Remove Unused CSS](https://docs.wp-rocket.me/article/1529-remove-unused-css) in 'WP Rocket' to fix this issue. It reduces page size by removing all CSS and stylesheets that are not used while keeping only the used CSS for each page.`, + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. `Imagify` is an image optimization add-on */ + "modern-image-formats": `Enable 'Imagify' from the Image Optimization tab in 'WP Rocket' to convert your images to WebP.`, + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. Delay JavaScript, LazyLoad for iframes and videos and Replace YouTube iframe with preview image are names of the features */ + "unused-javascript": `Enable [Delay JavaScript execution](https://docs.wp-rocket.me/article/1349-delay-javascript-execution) in 'WP Rocket' to fix this problem. It will improve the loading of your page by delaying the execution of scripts until user interaction. If your site has iframes, you can use WP Rocket's [LazyLoad for iframes and videos](https://docs.wp-rocket.me/article/1674-lazyload-for-iframes-and-videos) and [Replace YouTube iframe with preview image](https://docs.wp-rocket.me/article/1488-replace-youtube-iframe-with-preview-image) as well.`, + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. Remove Unused CSS, Load JavaScript deferred are names of the features */ + "render-blocking-resources": `Enable [Remove Unused CSS](https://docs.wp-rocket.me/article/1529-remove-unused-css) and [Load JavaScript deferred](https://docs.wp-rocket.me/article/1265-load-javascript-deferred) in 'WP Rocket' to address this recommendation. These features will respectively optimize the CSS and JavaScript files so that they don't block the rendering of your page.`, + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. Minify CSS Files is a name of the feature */ + "unminified-css": `Enable [Minify CSS files](https://docs.wp-rocket.me/article/1350-css-minify-combine) in 'WP Rocket' to fix this issue. Any spaces and comments in your site's CSS files will be removed to make the file size smaller and faster to download.`, + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. Minify JavaScript Files is a name of the feature */ + "unminified-javascript": `Enable [Minify JavaScript files](https://docs.wp-rocket.me/article/1351-javascript-minify-combine) in 'WP Rocket' to fix this issue. Empty spaces and comments will be removed from JavaScript files to make their size smaller and faster to download.`, + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. `Imagify` is an image optimization add-on */ + "uses-optimized-images": `Enable 'Imagify' from the Image Optimization tab in 'WP Rocket' and run Bulk Optimization to compress your images.`, + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. Prefetch DNS Requests, Enable CDN are names of the features */ + "uses-rel-preconnect": `Use [Prefetch DNS Requests](https://docs.wp-rocket.me/article/1302-prefetch-dns-requests) in 'WP Rocket' to add "dns-prefetch" and speed up the connection with external domains. Also, 'WP Rocket' automatically adds "preconnect" to [Google Fonts domain](https://docs.wp-rocket.me/article/1312-optimize-google-fonts) and any CNAME(S) added via the [Enable CDN](https://docs.wp-rocket.me/article/42-using-wp-rocket-with-a-cdn) feature.`, + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. Remove Unused CSS is a name of the feature*/ + "uses-rel-preload": `To fix this issue for fonts, enable [Remove Unused CSS](https://docs.wp-rocket.me/article/1529-remove-unused-css) in 'WP Rocket'. Your site's critical fonts will be preloaded with priority.`, + /** Additional description of a Lighthouse audit for a third-party framework called 'WP Rocket'. This is displayed after a user expands the section to see more. No character length limits. LazyLoad for images is a name of the feature*/ + "offscreen-images": `Enable [LazyLoad](https://docs.wp-rocket.me/article/1141-lazyload-for-images) in WP Rocket to fix this recommendation. This feature delays the loading of the images until the visitor scrolls down the page and actually needs to see them.` + }; + module2.exports = { + id: "wp-rocket", + title: "WP Rocket", + icon, + UIStrings: UIStrings125 + }; + } +}); + +// node_modules/lighthouse-stack-packs/index.js +var require_lighthouse_stack_packs = __commonJS({ + "node_modules/lighthouse-stack-packs/index.js"(exports2, module2) { + init_process_global(); + var stackPacks2 = [ + require_amp(), + require_angular(), + require_drupal(), + require_ezoic(), + require_gatsby(), + require_joomla(), + require_magento(), + require_next(), + require_nitropack(), + require_nuxt(), + require_octobercms(), + require_react(), + require_wix(), + require_wordpress(), + require_wp_rocket() + ]; + module2.exports = stackPacks2; + } +}); + +// node_modules/lookup-closest-locale/index.js +var require_lookup_closest_locale = __commonJS({ + "node_modules/lookup-closest-locale/index.js"(exports2, module2) { + init_process_global(); + module2.exports = /* @__PURE__ */ __name(function lookupClosestLocale2(locale, available) { + if (typeof locale === "string" && available[locale]) return locale; + var locales2 = [].concat(locale || []); + for (var l = 0, ll = locales2.length; l < ll; ++l) { + var current = locales2[l].split("-"); + while (current.length) { + var candidate = current.join("-"); + if (available[candidate]) return candidate; + current.pop(); + } + } + }, "lookupClosestLocale"); + } +}); + +// shared/root.js +import path from "path"; +var LH_ROOT, pkg, lighthouseVersion; +var init_root2 = __esm({ + "shared/root.js"() { + "use strict"; + init_process_global(); + init_esm_utils(); + /** + * @license + * Copyright 2021 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + LH_ROOT = path.dirname(""); + pkg = JSON.parse(`{ + "name": "lighthouse", + "type": "module", + "version": "13.0.3", + "description": "Automated auditing, performance metrics, and best practices for the web.", + "main": "./core/index.js", + "bin": { + "lighthouse": "./cli/index.js", + "chrome-debug": "./core/scripts/manual-chrome-launcher.js", + "smokehouse": "./cli/test/smokehouse/frontends/smokehouse-bin.js" + }, + "engines": { + "node": ">=22.19" + }, + "scripts": { + "prepack": "yarn build-report --standalone --flow --esm && yarn build-types", + "postpack": "yarn clean-types", + "build-all": "yarn build-report && yarn build-cdt-strings && yarn build-devtools && concurrently 'yarn build-extension' 'yarn build-lr' 'yarn build-viewer' 'yarn build-treemap' 'yarn build-smokehouse-bundle' 'yarn build-legacy-javascript' 'yarn build-devtools-mcp' && yarn build-pack", + "build-cdt-lib": "node ./build/build-cdt-lib.js", + "build-cdt-strings": "node ./build/build-cdt-strings.js", + "build-extension": "yarn build-extension-chrome && yarn build-extension-firefox", + "build-extension-chrome": "node ./build/build-extension.js chrome", + "build-extension-firefox": "node ./build/build-extension.js firefox", + "build-devtools": "yarn reset-link && node ./build/build-bundle.js clients/devtools/devtools-entry.js dist/lighthouse-dt-bundle.js && node ./build/build-dt-report-resources.js", + "build-legacy-javascript": "node ./build/build-legacy-javascript.js", + "build-devtools-mcp": "node ./build/build-bundle-mcp.js clients/devtools-mcp/devtools-mcp-entry.js dist/lighthouse-devtools-mcp-bundle.js", + "build-smokehouse-bundle": "node ./build/build-smokehouse-bundle.js", + "build-lr": "yarn reset-link && node --max-old-space-size=4096 ./build/build-lightrider-bundles.js", + "build-pack": "bash build/build-pack.sh", + "build-report": "node build/build-report-components.js && node build/build-report.js", + "build-sample-reports": "yarn build-report && node build/build-sample-reports.js", + "build-treemap": "node ./build/build-treemap.js", + "build-viewer": "node ./build/build-viewer.js", + "build-types": "yarn type-check && rsync -a .tmp/tsbuildinfo/ ./ --include='*.d.ts' --include='*.d.cts' --exclude='*.map' --exclude='*.tsbuildinfo'", + "reset-link": "(yarn unlink || true) && yarn link && yarn link lighthouse", + "c8": "bash core/scripts/c8.sh", + "clean": "rm -r dist proto/scripts/*.json proto/scripts/*_pb2.* proto/scripts/*_pb.* proto/scripts/__pycache__ proto/scripts/*.pyc *.report.html *.report.dom.html *.report.json *.devtoolslog.json *.trace.json shared/localization/locales/*.ctc.json || true", + "clean-types": "git clean -xfq '*.d.ts' '*.d.cts' -e 'node_modules/' -e 'dist/' -e '.tmp/' -e '**/types/'", + "lint": "[ \\"$CI\\" = true ] && eslint --quiet -f codeframe . || eslint .", + "smoke": "node -r source-map-support/register cli/test/smokehouse/frontends/smokehouse-bin.js", + "debug": "node --inspect-brk ./cli/index.js", + "start": "yarn build-report --standalone && node ./cli/index.js", + "mocha": "node core/test/scripts/run-mocha-tests.js", + "test": "yarn diff:sample-json && yarn lint --quiet && yarn unit && yarn type-check", + "test-bundle": "yarn smoke --runner bundle", + "test-clients": "yarn mocha --testMatch clients/**/*-test.js && yarn mocha --testMatch clients/**/*-test-pptr.js", + "test-viewer": "yarn unit-viewer && yarn mocha --testMatch viewer/**/*-test-pptr.js --timeout 35000", + "test-treemap": "yarn unit-treemap && yarn mocha --testMatch treemap/**/*-test-pptr.js --timeout 35000", + "test-lantern": "bash core/scripts/test-lantern.sh", + "test-legacy-javascript": "bash core/scripts/test-legacy-javascript.sh", + "test-docs": "yarn --cwd docs/recipes/ test", + "test-proto": "yarn compile-proto && yarn build-proto-roundtrip", + "unit-core": "yarn mocha core", + "unit-cli": "yarn mocha --testMatch cli/**/*-test.js", + "unit-lantern-trace": "INTERNAL_LANTERN_USE_TRACE=1 yarn mocha core/test/computed/metrics core/test/audits", + "unit-report": "yarn mocha --testMatch report/**/*-test.js", + "unit-treemap": "yarn mocha --testMatch treemap/**/*-test.js", + "unit-viewer": "yarn mocha --testMatch viewer/**/*-test.js", + "unit-flow": "bash flow-report/test/run-flow-report-tests.sh", + "unit": "yarn unit-flow && yarn mocha && yarn unit-lantern-trace", + "unit:ci": "NODE_OPTIONS=--max-old-space-size=8192 npm run unit", + "unit-lantern-trace:ci": "NODE_OPTIONS=--max-old-space-size=8192 npm run unit-lantern-trace", + "core-unit": "yarn unit-core", + "cli-unit": "yarn unit-cli", + "viewer-unit": "yarn unit-viewer", + "watch": "yarn unit-core --watch", + "unit:cicoverage": "yarn c8 --all yarn unit:ci && yarn c8 --all yarn unit-lantern-trace:ci", + "coverage": "yarn unit:cicoverage && c8 report --reporter html", + "coverage:smoke": "yarn c8 yarn smoke -j=1 && c8 report --reporter html", + "devtools": "bash core/scripts/roll-to-devtools.sh", + "chrome": "node core/scripts/manual-chrome-launcher.js", + "fast": "node ./cli/index.js --preset=desktop --throttlingMethod=provided", + "deploy-treemap": "yarn build-treemap --deploy", + "deploy-viewer": "yarn build-viewer --deploy", + "vercel-build": "yarn build-sample-reports && yarn build-viewer && yarn build-treemap", + "dogfood-lhci": "./core/scripts/dogfood-lhci.sh", + "timing-trace": "node core/scripts/generate-timing-trace.js", + "changelog": "conventional-changelog --config ./build/changelog-generator/index.cjs --infile changelog.md --same-file", + "type-check": "tsc --build ./tsconfig-all.json", + "i18n:checks": "./core/scripts/i18n/assert-strings-collected.sh", + "i18n:collect-strings": "node core/scripts/i18n/collect-strings.js", + "update:lantern-baseline": "node core/scripts/lantern/update-baseline-lantern-values.js", + "update:sample-artifacts": "node core/scripts/update-report-fixtures.js", + "update:sample-json": "yarn i18n:collect-strings && node ./cli -A=./core/test/results/artifacts --config-path=./core/test/results/sample-config.js --output=json --output-path=./core/test/results/sample_v2.json && node core/scripts/cleanup-LHR-for-diff.js ./core/test/results/sample_v2.json --only-remove-timing && node ./core/scripts/update-flow-fixtures.js", + "update:flow-sample-json": "yarn i18n:collect-strings && node ./core/scripts/update-flow-fixtures.js", + "test-devtools": "bash core/test/devtools-tests/test-locally.sh", + "open-devtools": "bash core/scripts/open-devtools.sh", + "run-devtools": "node core/scripts/pptr-run-devtools.js", + "diff:sample-json": "yarn i18n:checks && bash core/scripts/assert-golden-lhr-unchanged.sh", + "diff:flow-sample-json": "yarn i18n:collect-strings && bash core/scripts/assert-baseline-flow-result-unchanged.sh", + "computeBenchmarkIndex": "./core/scripts/benchmark.js", + "save-latest-run": "./core/scripts/save-latest-run.sh", + "compile-proto": "protoc --python_out=./ ./proto/lighthouse-result.proto && mv ./proto/*_pb2.py ./proto/scripts || (echo \\"❌ Install protobuf = 3.20.x to compile the proto file.\\" && false)", + "build-proto-roundtrip": "mkdir -p .tmp && python3 proto/scripts/json_roundtrip_via_proto.py", + "static-server": "node cli/test/fixtures/static-server.js", + "serve-dist": "cd dist && python3 -m http.server 7878", + "serve-gh-pages": "cd dist/gh-pages && python3 -m http.server 7333", + "serve-treemap": "yarn serve-gh-pages", + "serve-viewer": "yarn serve-gh-pages", + "flow-report": "yarn build-report --flow && node ./core/scripts/build-test-flow-report.js", + "generate-insight-audits": "node core/scripts/generate-insight-audits.js" + }, + "devDependencies": { + "@build-tracker/cli": "^1.0.0-beta.15", + "@esbuild-kit/esm-loader": "^2.6.5", + "@esbuild-plugins/node-modules-polyfill": "^0.1.4", + "@eslint/compat": "^1.3.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "^9.28.0", + "@formatjs/icu-messageformat-parser": "^2.6.2", + "@jest/fake-timers": "^29.7.0", + "@testing-library/preact": "^3.1.1", + "@testing-library/preact-hooks": "^1.1.0", + "@types/archiver": "^2.1.2", + "@types/chrome": "^0.0.154", + "@types/configstore": "^6.0.2", + "@types/cpy": "^5.1.0", + "@types/debug": "^4.1.7", + "@types/eslint": "^9.6.1", + "@types/estree": "^0.0.50", + "@types/gh-pages": "^2.0.0", + "@types/google.analytics": "0.0.39", + "@types/gtag.js": "0.0.20", + "@types/jpeg-js": "^0.3.7", + "@types/jsdom": "^16.2.13", + "@types/lodash-es": "^4.17.12", + "@types/mocha": "^9.0.0", + "@types/node": "*", + "@types/pako": "^1.0.1", + "@types/resize-observer-browser": "^0.1.1", + "@types/resolve": "^1.20.2", + "@types/semver": "^5.5.0", + "@types/ws": "^7.0.0", + "@types/yargs": "^17.0.8", + "@types/yargs-parser": "^20.2.1", + "@typescript-eslint/eslint-plugin": "^8.34.0", + "@typescript-eslint/parser": "^8.34.0", + "acorn": "^8.5.0", + "angular": "^1.7.4", + "archiver": "^7.0.1", + "builtin-modules": "^3.3.0", + "c8": "^7.11.3", + "chalk": "^2.4.1", + "chrome-devtools-frontend": "1.0.1526630", + "colors": "^1.4.0", + "concurrently": "^9.2.1", + "conventional-changelog-cli": "^2.1.1", + "core-js-compat": "^3.44.0", + "cpy": "^8.1.2", + "csv-validator": "^0.0.3", + "esbuild": "0.25.9", + "eslint": "^9.28.0", + "eslint-config-google": "^0.14.0", + "eslint-formatter-codeframe": "^7.32.1", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-local-rules": "1.1.0", + "expect": "^28.1.0", + "firebase": "^9.0.2", + "gh-pages": "^2.0.1", + "glob": "^7.1.3", + "globals": "^15.14.0", + "idb-keyval": "2.2.0", + "jest-mock": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jsdom": "^12.2.0", + "lighthouse-plugin-soft-navigation": "^1.1.0", + "magic-string": "^0.25.7", + "mime-types": "^2.1.30", + "mocha": "^10.0.0", + "pako": "^2.1.0", + "preact": "^10.7.2", + "pretty-json-stringify": "^0.0.2", + "puppeteer": "^24.23.0", + "resolve": "^1.22.10", + "rollup-plugin-polyfill-node": "^0.12.0", + "source-map-support": "^0.5.21", + "terser": "^5.18.2", + "testdouble": "^3.20.2", + "typed-query-selector": "^2.12.0", + "typescript": "5.8.2", + "wait-for-expect": "^3.0.2", + "webtreemap-cdt": "^3.2.1" + }, + "dependencies": { + "@paulirish/trace_engine": "0.0.61", + "@sentry/node": "^9.28.1", + "axe-core": "^4.11.0", + "chrome-launcher": "^1.2.1", + "configstore": "^7.0.0", + "csp_evaluator": "1.1.5", + "devtools-protocol": "0.0.1527314", + "enquirer": "^2.3.6", + "http-link-header": "^1.1.1", + "intl-messageformat": "^10.5.3", + "jpeg-js": "^0.4.4", + "js-library-detector": "^6.7.0", + "lighthouse-logger": "^2.0.2", + "lighthouse-stack-packs": "1.12.3", + "lodash-es": "^4.17.21", + "lookup-closest-locale": "6.2.0", + "open": "^8.4.0", + "puppeteer-core": "^24.23.0", + "robots-parser": "^3.0.1", + "speedline-core": "^1.4.3", + "third-party-web": "^0.27.0", + "tldts-icann": "^7.0.17", + "ws": "^7.0.0", + "yargs": "^17.3.1", + "yargs-parser": "^21.0.0" + }, + "resolutions": { + "puppeteer/**/devtools-protocol": "0.0.1527314", + "puppeteer-core/**/devtools-protocol": "0.0.1527314" + }, + "repository": "GoogleChrome/lighthouse", + "keywords": [ + "google", + "chrome", + "devtools" + ], + "author": "Google LLC", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/GoogleChrome/lighthouse/issues" + }, + "homepage": "https://github.com/GoogleChrome/lighthouse#readme", + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" +} +`); + lighthouseVersion = pkg.version; + } +}); + +// core/lib/i18n/i18n.js +import path2 from "path"; +function lookupLocale(locales2, possibleLocales) { + if (typeof Intl !== "object") { + throw new Error("Lighthouse must be run in Node with `Intl` support. See https://nodejs.org/api/intl.html for help"); + } + const canonicalLocales = Intl.getCanonicalLocales(locales2); + const availableLocales = Intl.NumberFormat.supportedLocalesOf(canonicalLocales); + const localesWithMessages = possibleLocales || getAvailableLocales(); + const localesWithmessagesObj = ( + /** @type {Record} */ + Object.fromEntries(localesWithMessages.map((l) => [l, {}])) + ); + const closestLocale = (0, import_lookup_closest_locale.default)(availableLocales, localesWithmessagesObj); + if (!closestLocale) { + if (Intl.NumberFormat.supportedLocalesOf("es").length === 0) { + lighthouse_logger_default.warn("i18n", "Requested locale not available in this version of node. The `full-icu` npm module can provide additional locales. For help, see https://github.com/GoogleChrome/lighthouse/blob/main/readme.md#how-do-i-get-localized-lighthouse-results-via-the-cli"); + } + lighthouse_logger_default.warn("i18n", `locale(s) '${locales2}' not available. Falling back to default '${DEFAULT_LOCALE}'`); + } + return closestLocale || DEFAULT_LOCALE; +} +function createIcuMessageFn(filename, fileStrings = {}) { + if (filename.startsWith("file://")) filename = url_default.fileURLToPath(filename); + if (path2.isAbsolute(filename)) filename = path2.relative(LH_ROOT, filename); + const mergedStrings = { ...UIStrings, ...fileStrings }; + const getIcuMessageFn = /* @__PURE__ */ __name((message, values) => { + const keyname = Object.keys(mergedStrings).find((key) => mergedStrings[key] === message); + if (!keyname) throw new Error(`Could not locate: ${message}`); + const filenameToLookup = keyname in fileStrings ? filename : path2.relative(LH_ROOT, getModulePath({ url: "core/lib/i18n/i18n.js" })); + const unixStyleFilename = filenameToLookup.replace(/\\/g, "/"); + const i18nId = `${unixStyleFilename} | ${keyname}`; + return { + i18nId, + values, + formattedDefault: formatMessage(message, values, DEFAULT_LOCALE) + }; + }, "getIcuMessageFn"); + return getIcuMessageFn; +} +function isStringOrIcuMessage(value) { + return typeof value === "string" || isIcuMessage(value); +} +var import_lookup_closest_locale, UIStrings; +var init_i18n = __esm({ + "core/lib/i18n/i18n.js"() { + "use strict"; + init_process_global(); + init_url(); + import_lookup_closest_locale = __toESM(require_lookup_closest_locale(), 1); + init_lighthouse_logger(); + init_format(); + init_root2(); + init_format(); + init_esm_utils(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + UIStrings = { + /** Used to show the duration in milliseconds that something lasted. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 63 ms) */ + ms: "{timeInMs, number, milliseconds} ms", + /** Used to show the duration in seconds that something lasted. The {timeInMs} placeholder will be replaced with the time duration, shown in seconds (e.g. 5.2 s) */ + seconds: "{timeInMs, number, seconds} s", + /** Label shown per-audit to show how many bytes smaller the page could be if the user implemented the suggestions. The `{wastedBytes}` placeholder will be replaced with the number of bytes, shown in kibibytes (e.g. 148 KiB) */ + displayValueByteSavings: "Est savings of {wastedBytes, number, bytes} KiB", + /** Label shown per-audit to show how many milliseconds faster the page load could be if the user implemented the suggestions. The `{wastedMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 140 ms) */ + displayValueMsSavings: "Est savings of {wastedMs, number, milliseconds} ms", + /** Label shown per-audit to show how many HTML elements did not pass the audit. The `{# elements found}` placeholder will be replaced with the number of failing HTML elements. */ + displayValueElementsFound: `{nodeCount, plural, =1 {1 element found} other {# elements found}}`, + /** Label for a column in a data table; entries will be the URL of a web resource */ + columnURL: "URL", + /** Label for a column in a data table; entries will be the size or quantity of some resource, e.g. the width and height dimensions of an image or the number of images in a web page. */ + columnSize: "Size", + /** Label for a column in a data table; entries will be the file size of a web resource in kilobytes. */ + columnResourceSize: "Resource Size", + /** Label for a column in a data table; entries will be the download size of a web resource in kilobytes. */ + columnTransferSize: "Transfer Size", + /** Label for a column in a data table; entries will be the time to live value of the cache header on a web resource. */ + columnCacheTTL: "Cache TTL", + /** Label for a column in a data table; entries will be the number of kilobytes the user could reduce their page by if they implemented the suggestions. */ + columnWastedBytes: "Est Savings", + /** Label for a column in a data table; entries will be the number of milliseconds the user could reduce page load by if they implemented the suggestions. */ + columnWastedMs: "Est Savings", + /** Label for a table column that displays how much time each row spent blocking other work on the main thread, entries will be the number of milliseconds spent. */ + columnBlockingTime: "Main-Thread Blocking Time", + /** Label for a column in a data table; entries will be the number of milliseconds spent during a particular activity. */ + columnTimeSpent: "Time Spent", + /** Label for a column in a data table; entries will be the location of a specific line of code in a file, in the format "line: 102". */ + columnLocation: "Location", + /** Label for a column in a data table; entries will be types of resources loaded over the network, e.g. "Scripts", "Third-Party", "Stylesheet". */ + columnResourceType: "Resource Type", + /** Label for a column in a data table; entries will be the number of network requests done by a webpage. */ + columnRequests: "Requests", + /** Label for a column in a data table; entries will be the names of arbitrary objects, e.g. the name of a Javascript library, or the name of a user defined timing event. */ + columnName: "Name", + /** Label for a column in a data table; entries will be the locations of JavaScript or CSS code, e.g. the name of a Javascript package or module. */ + columnSource: "Source", + /** Label for a column in a data table; entries will be a representation of a DOM element. */ + columnElement: "Element", + /** Label for a column in a data table; entries will be the number of milliseconds since the page started loading. */ + columnStartTime: "Start Time", + /** Label for a column in a data table; entries will be the total number of milliseconds from the start time until the end time. */ + columnDuration: "Duration", + /** Label for a column in a data table; entries will be a representation of a DOM element that did not meet certain suggestions. */ + columnFailingElem: "Failing Elements", + /** Label for a column in a data table; entries will be a description of the table item. */ + columnDescription: "Description", + /** Label for a row in a data table; the row represents the total number of something. */ + total: "Total", + /** Label for a row in a data table; entries will be the total number and byte size of all resources loaded by a web page. */ + totalResourceType: "Total", + /** Label for a row in a data table; entries will be the total number and byte size of all 'Document' resources loaded by a web page. */ + documentResourceType: "Document", + /** Label for a row in a data table; entries will be the total number and byte size of all 'Script' resources loaded by a web page. 'Script' refers to JavaScript or other files that are executable by a browser. */ + scriptResourceType: "Script", + /** Label for a row in a data table; entries will be the total number and byte size of all 'Stylesheet' resources loaded by a web page. 'Stylesheet' refers to CSS stylesheets. */ + stylesheetResourceType: "Stylesheet", + /** Label for a row in a data table; entries will be the total number and byte size of all 'Image' resources loaded by a web page. */ + imageResourceType: "Image", + /** Label for a row in a data table; entries will be the total number and byte size of all 'Media' resources loaded by a web page. 'Media' refers to audio and video files. */ + mediaResourceType: "Media", + /** Label for a row in a data table; entries will be the total number and byte size of all 'Font' resources loaded by a web page. */ + fontResourceType: "Font", + /** Label for a row in a data table; entries will be the total number and byte size of all resources loaded by a web page that don't fit into the categories of Document, Script, Stylesheet, Image, Media, & Font.*/ + otherResourceType: "Other", + /** Label for a row in a data table; entries will be the total number and byte size of all third-party resources loaded by a web page. 'Third-party resources are items loaded from URLs that aren't controlled by the owner of the web page. */ + thirdPartyResourceType: "Third-party", + /** Label used to identify a value in a table where many individual values are aggregated to a single value, for brevity. "Other resources" could also be read as "the rest of the resources". Resource refers to network resources requested by the browser. */ + otherResourcesLabel: "Other resources", + /** The name of the metric that marks the time at which the first text or image is painted by the browser. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */ + firstContentfulPaintMetric: "First Contentful Paint", + /** The name of the metric that marks the time at which the page is fully loaded and is able to quickly respond to user input (clicks, taps, and keypresses feel responsive). Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */ + interactiveMetric: "Time to Interactive", + /** The name of the metric that marks the time at which a majority of the content has been painted by the browser. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */ + firstMeaningfulPaintMetric: "First Meaningful Paint", + /** The name of a metric that calculates the total duration of blocking time for a web page. Blocking times are time periods when the page would be blocked (prevented) from responding to user input (clicks, taps, and keypresses will feel slow to respond). Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */ + totalBlockingTimeMetric: "Total Blocking Time", + /** The name of the metric "Maximum Potential First Input Delay" that marks the maximum estimated time between the page receiving input (a user clicking, tapping, or typing) and the page responding. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */ + maxPotentialFIDMetric: "Max Potential First Input Delay", + /** The name of the metric that summarizes how quickly the page looked visually complete. The name of this metric is largely abstract and can be loosely translated. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */ + speedIndexMetric: "Speed Index", + /** The name of the metric that marks the time at which the largest text or image is painted by the browser. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */ + largestContentfulPaintMetric: "Largest Contentful Paint", + /** The name of the metric "Cumulative Layout Shift" that indicates how much the page changes its layout while it loads. If big segments of the page shift their location during load, the Cumulative Layout Shift will be higher. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */ + cumulativeLayoutShiftMetric: "Cumulative Layout Shift", + /** The name of the "Interaction to Next Paint" metric that measures the time between a user interaction and when the browser displays a response on screen. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */ + interactionToNextPaint: "Interaction to Next Paint", + /** Table item value for the severity of a small, or low impact vulnerability. Part of a ranking scale in the form: low, medium, high. */ + itemSeverityLow: "Low", + /** Table item value for the severity of a vulnerability. Part of a ranking scale in the form: low, medium, high. */ + itemSeverityMedium: "Medium", + /** Table item value for the severity of a high impact, or dangerous vulnerability. Part of a ranking scale in the form: low, medium, high. */ + itemSeverityHigh: "High" + }; + __name(lookupLocale, "lookupLocale"); + __name(createIcuMessageFn, "createIcuMessageFn"); + __name(isStringOrIcuMessage, "isStringOrIcuMessage"); + } +}); + +// core/lib/stack-packs.js +function getStackPacks(pageStacks) { + if (!pageStacks) return []; + const packs = []; + for (const pageStack of pageStacks) { + const stackPackToIncl = stackPacksToInclude.find((stackPackToIncl2) => stackPackToIncl2.requiredStacks.includes(`${pageStack.detector}:${pageStack.id}`)); + if (!stackPackToIncl) { + continue; + } + const matchedPack = import_lighthouse_stack_packs.default.find((pack) => pack.id === stackPackToIncl.packId); + if (!matchedPack) { + lighthouse_logger_default.warn( + "StackPacks", + `'${stackPackToIncl.packId}' stack pack was matched but is not found in stack-packs lib` + ); + continue; + } + const str_105 = createIcuMessageFn( + `node_modules/lighthouse-stack-packs/packs/${matchedPack.id}.js`, + matchedPack.UIStrings + ); + const descriptions = {}; + const UIStrings125 = matchedPack.UIStrings; + for (const key in UIStrings125) { + if (UIStrings125[key]) { + descriptions[key] = str_105(UIStrings125[key]); + } + } + packs.push({ + id: matchedPack.id, + title: matchedPack.title, + iconDataURL: matchedPack.icon, + descriptions + }); + } + return packs.sort((a, b) => { + const aVal = stackPacksToInclude.findIndex((p) => p.packId === a.id); + const bVal = stackPacksToInclude.findIndex((p) => p.packId === b.id); + return aVal - bVal; + }); +} +var import_lighthouse_stack_packs, stackPacksToInclude; +var init_stack_packs = __esm({ + "core/lib/stack-packs.js"() { + "use strict"; + init_process_global(); + init_lighthouse_logger(); + import_lighthouse_stack_packs = __toESM(require_lighthouse_stack_packs(), 1); + init_i18n(); + /** + * @license + * Copyright 2019 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + stackPacksToInclude = [ + { + packId: "gatsby", + requiredStacks: ["js:gatsby"] + }, + { + packId: "wordpress", + requiredStacks: ["js:wordpress"] + }, + { + packId: "wix", + requiredStacks: ["js:wix"] + }, + { + packId: "wp-rocket", + requiredStacks: ["js:wp-rocket"] + }, + { + packId: "ezoic", + requiredStacks: ["js:ezoic"] + }, + { + packId: "drupal", + requiredStacks: ["js:drupal"] + }, + { + packId: "nitropack", + requiredStacks: ["js:nitropack"] + }, + { + packId: "amp", + requiredStacks: ["js:amp"] + }, + { + packId: "magento", + requiredStacks: ["js:magento"] + }, + { + packId: "octobercms", + requiredStacks: ["js:octobercms"] + }, + { + packId: "joomla", + requiredStacks: ["js:joomla"] + }, + { + packId: "next.js", + requiredStacks: ["js:next"] + }, + { + packId: "nuxt", + requiredStacks: ["js:nuxt"] + }, + { + packId: "angular", + requiredStacks: ["js:angular"] + }, + { + packId: "react", + requiredStacks: ["js:react"] + } + ]; + __name(getStackPacks, "getStackPacks"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/core/LanternError.js +var LanternError; +var init_LanternError = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/core/LanternError.js"() { + init_process_global(); + LanternError = class extends Error { + static { + __name(this, "LanternError"); + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/core/NetworkAnalyzer.js +var UrlUtils, INITIAL_CWD, DEFAULT_SERVER_RESPONSE_PERCENTAGE, SERVER_RESPONSE_PERCENTAGE_OF_TTFB, NetworkAnalyzer; +var init_NetworkAnalyzer = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/core/NetworkAnalyzer.js"() { + init_process_global(); + init_LanternError(); + UrlUtils = class { + static { + __name(this, "UrlUtils"); + } + /** + * There is fancy URL rewriting logic for the chrome://settings page that we need to work around. + * Why? Special handling was added by Chrome team to allow a pushState transition between chrome:// pages. + * As a result, the network URL (chrome://chrome/settings/) doesn't match the final document URL (chrome://settings/). + */ + static rewriteChromeInternalUrl(url) { + if (!url?.startsWith("chrome://")) { + return url; + } + if (url.endsWith("/")) { + url = url.replace(/\/$/, ""); + } + return url.replace(/^chrome:\/\/chrome\//, "chrome://"); + } + /** + * Determine if url1 equals url2, ignoring URL fragments. + */ + static equalWithExcludedFragments(url1, url2) { + [url1, url2] = [url1, url2].map(this.rewriteChromeInternalUrl); + try { + const urla = new URL(url1); + urla.hash = ""; + const urlb = new URL(url2); + urlb.hash = ""; + return urla.href === urlb.href; + } catch { + return false; + } + } + }; + INITIAL_CWD = 14 * 1024; + DEFAULT_SERVER_RESPONSE_PERCENTAGE = 0.4; + SERVER_RESPONSE_PERCENTAGE_OF_TTFB = { + Document: 0.9, + XHR: 0.9, + Fetch: 0.9 + }; + NetworkAnalyzer = class _NetworkAnalyzer { + static { + __name(this, "NetworkAnalyzer"); + } + static get summary() { + return "__SUMMARY__"; + } + static groupByOrigin(records) { + const grouped = /* @__PURE__ */ new Map(); + records.forEach((item) => { + const key = item.parsedURL.securityOrigin; + const group = grouped.get(key) || []; + group.push(item); + grouped.set(key, group); + }); + return grouped; + } + static getSummary(values) { + values.sort((a, b) => a - b); + let median; + if (values.length === 0) { + median = values[0]; + } else if (values.length % 2 === 0) { + const a = values[Math.floor((values.length - 1) / 2)]; + const b = values[Math.floor((values.length - 1) / 2) + 1]; + median = (a + b) / 2; + } else { + median = values[Math.floor((values.length - 1) / 2)]; + } + return { + min: values[0], + max: values[values.length - 1], + avg: values.reduce((a, b) => a + b, 0) / values.length, + median + }; + } + static summarize(values) { + const summaryByKey = /* @__PURE__ */ new Map(); + const allEstimates = []; + for (const [key, estimates] of values) { + summaryByKey.set(key, _NetworkAnalyzer.getSummary(estimates)); + allEstimates.push(...estimates); + } + summaryByKey.set(_NetworkAnalyzer.summary, _NetworkAnalyzer.getSummary(allEstimates)); + return summaryByKey; + } + static estimateValueByOrigin(requests, iteratee) { + const connectionWasReused = _NetworkAnalyzer.estimateIfConnectionWasReused(requests); + const groupedByOrigin = _NetworkAnalyzer.groupByOrigin(requests); + const estimates = /* @__PURE__ */ new Map(); + for (const [origin, originRequests] of groupedByOrigin.entries()) { + let originEstimates = []; + for (const request of originRequests) { + const timing = request.timing; + if (!timing) { + continue; + } + const value = iteratee({ + request, + timing, + connectionReused: connectionWasReused.get(request.requestId) + }); + if (typeof value !== "undefined") { + originEstimates = originEstimates.concat(value); + } + } + if (!originEstimates.length) { + continue; + } + estimates.set(origin, originEstimates); + } + return estimates; + } + /** + * Estimates the observed RTT to each origin based on how long the connection setup. + * For h1 and h2, this could includes two estimates - one for the TCP handshake, another for + * SSL negotiation. + * For h3, we get only one estimate since QUIC establishes a secure connection in a + * single handshake. + * This is the most accurate and preferred method of measurement when the data is available. + */ + static estimateRTTViaConnectionTiming(info) { + const { timing, connectionReused, request } = info; + if (connectionReused) { + return; + } + const { connectStart, sslStart, sslEnd, connectEnd } = timing; + if (connectEnd >= 0 && connectStart >= 0 && request.protocol.startsWith("h3")) { + return connectEnd - connectStart; + } + if (sslStart >= 0 && sslEnd >= 0 && sslStart !== connectStart) { + return [connectEnd - sslStart, sslStart - connectStart]; + } + if (connectStart >= 0 && connectEnd >= 0) { + return connectEnd - connectStart; + } + return; + } + /** + * Estimates the observed RTT to each origin based on how long a download took on a fresh connection. + * NOTE: this will tend to overestimate the actual RTT quite significantly as the download can be + * slow for other reasons as well such as bandwidth constraints. + */ + static estimateRTTViaDownloadTiming(info) { + const { timing, connectionReused, request } = info; + if (connectionReused) { + return; + } + if (request.transferSize <= INITIAL_CWD) { + return; + } + if (!Number.isFinite(timing.receiveHeadersEnd) || timing.receiveHeadersEnd < 0) { + return; + } + const totalTime = request.networkEndTime - request.networkRequestTime; + const downloadTimeAfterFirstByte = totalTime - timing.receiveHeadersEnd; + const numberOfRoundTrips = Math.log2(request.transferSize / INITIAL_CWD); + if (numberOfRoundTrips > 5) { + return; + } + return downloadTimeAfterFirstByte / numberOfRoundTrips; + } + /** + * Estimates the observed RTT to each origin based on how long it took until Chrome could + * start sending the actual request when a new connection was required. + * NOTE: this will tend to overestimate the actual RTT as the request can be delayed for other + * reasons as well such as more SSL handshakes if TLS False Start is not enabled. + */ + static estimateRTTViaSendStartTiming(info) { + const { timing, connectionReused, request } = info; + if (connectionReused) { + return; + } + if (!Number.isFinite(timing.sendStart) || timing.sendStart < 0) { + return; + } + let roundTrips = 1; + if (!request.protocol.startsWith("h3")) { + roundTrips += 1; + } + if (request.parsedURL.scheme === "https") { + roundTrips += 1; + } + return timing.sendStart / roundTrips; + } + /** + * Estimates the observed RTT to each origin based on how long it took until Chrome received the + * headers of the response (~TTFB). + * NOTE: this is the most inaccurate way to estimate the RTT, but in some environments it's all + * we have access to :( + */ + static estimateRTTViaHeadersEndTiming(info) { + const { timing, connectionReused, request } = info; + if (!Number.isFinite(timing.receiveHeadersEnd) || timing.receiveHeadersEnd < 0) { + return; + } + if (!request.resourceType) { + return; + } + const serverResponseTimePercentage = SERVER_RESPONSE_PERCENTAGE_OF_TTFB[request.resourceType] || DEFAULT_SERVER_RESPONSE_PERCENTAGE; + const estimatedServerResponseTime = timing.receiveHeadersEnd * serverResponseTimePercentage; + let roundTrips = 1; + if (!connectionReused) { + roundTrips += 1; + if (!request.protocol.startsWith("h3")) { + roundTrips += 1; + } + if (request.parsedURL.scheme === "https") { + roundTrips += 1; + } + } + return Math.max((timing.receiveHeadersEnd - estimatedServerResponseTime) / roundTrips, 3); + } + /** + * Given the RTT to each origin, estimates the observed server response times. + */ + static estimateResponseTimeByOrigin(records, rttByOrigin) { + return _NetworkAnalyzer.estimateValueByOrigin(records, ({ request, timing }) => { + if (request.serverResponseTime !== void 0) { + return request.serverResponseTime; + } + if (!Number.isFinite(timing.receiveHeadersEnd) || timing.receiveHeadersEnd < 0) { + return; + } + if (!Number.isFinite(timing.sendEnd) || timing.sendEnd < 0) { + return; + } + const ttfb = timing.receiveHeadersEnd - timing.sendEnd; + const origin = request.parsedURL.securityOrigin; + const rtt = rttByOrigin.get(origin) || rttByOrigin.get(_NetworkAnalyzer.summary) || 0; + return Math.max(ttfb - rtt, 0); + }); + } + static canTrustConnectionInformation(requests) { + const connectionIdWasStarted = /* @__PURE__ */ new Map(); + for (const request of requests) { + const started = connectionIdWasStarted.get(request.connectionId) || !request.connectionReused; + connectionIdWasStarted.set(request.connectionId, started); + } + if (connectionIdWasStarted.size <= 1) { + return false; + } + return Array.from(connectionIdWasStarted.values()).every((started) => started); + } + /** + * Returns a map of requestId -> connectionReused, estimating the information if the information + * available in the records themselves appears untrustworthy. + */ + static estimateIfConnectionWasReused(records, options) { + const { forceCoarseEstimates = false } = options || {}; + if (!forceCoarseEstimates && _NetworkAnalyzer.canTrustConnectionInformation(records)) { + return new Map(records.map((request) => [request.requestId, Boolean(request.connectionReused)])); + } + const connectionWasReused = /* @__PURE__ */ new Map(); + const groupedByOrigin = _NetworkAnalyzer.groupByOrigin(records); + for (const originRecords of groupedByOrigin.values()) { + const earliestReusePossible = originRecords.map((request) => request.networkEndTime).reduce((a, b) => Math.min(a, b), Infinity); + for (const request of originRecords) { + connectionWasReused.set(request.requestId, request.networkRequestTime >= earliestReusePossible || request.protocol === "h2"); + } + const firstRecord = originRecords.reduce((a, b) => { + return a.networkRequestTime > b.networkRequestTime ? b : a; + }); + connectionWasReused.set(firstRecord.requestId, false); + } + return connectionWasReused; + } + /** + * Estimates the RTT to each origin by examining observed network timing information. + * Attempts to use the most accurate information first and falls back to coarser estimates when it + * is unavailable. + */ + static estimateRTTByOrigin(records, options) { + const { + forceCoarseEstimates = false, + // coarse estimates include lots of extra time and noise + // multiply by some factor to deflate the estimates a bit. + coarseEstimateMultiplier = 0.3, + useDownloadEstimates = true, + useSendStartEstimates = true, + useHeadersEndEstimates = true + } = options || {}; + const connectionWasReused = _NetworkAnalyzer.estimateIfConnectionWasReused(records); + const groupedByOrigin = _NetworkAnalyzer.groupByOrigin(records); + const estimatesByOrigin = /* @__PURE__ */ new Map(); + for (const [origin, originRequests] of groupedByOrigin.entries()) { + let collectEstimates = function(estimator, multiplier = 1) { + for (const request of originRequests) { + const timing = request.timing; + if (!timing || !request.transferSize) { + continue; + } + const estimates = estimator({ + request, + timing, + connectionReused: connectionWasReused.get(request.requestId) + }); + if (estimates === void 0) { + continue; + } + if (!Array.isArray(estimates)) { + originEstimates.push(estimates * multiplier); + } else { + originEstimates.push(...estimates.map((e) => e * multiplier)); + } + } + }; + __name(collectEstimates, "collectEstimates"); + const originEstimates = []; + if (!forceCoarseEstimates) { + collectEstimates(this.estimateRTTViaConnectionTiming); + } + if (!originEstimates.length) { + if (useDownloadEstimates) { + collectEstimates(this.estimateRTTViaDownloadTiming, coarseEstimateMultiplier); + } + if (useSendStartEstimates) { + collectEstimates(this.estimateRTTViaSendStartTiming, coarseEstimateMultiplier); + } + if (useHeadersEndEstimates) { + collectEstimates(this.estimateRTTViaHeadersEndTiming, coarseEstimateMultiplier); + } + } + if (originEstimates.length) { + estimatesByOrigin.set(origin, originEstimates); + } + } + if (!estimatesByOrigin.size) { + throw new LanternError("No timing information available"); + } + return _NetworkAnalyzer.summarize(estimatesByOrigin); + } + /** + * Estimates the server response time of each origin. RTT times can be passed in or will be + * estimated automatically if not provided. + */ + static estimateServerResponseTimeByOrigin(records, options) { + let rttByOrigin = options?.rttByOrigin; + if (!rttByOrigin) { + rttByOrigin = /* @__PURE__ */ new Map(); + const rttSummaryByOrigin = _NetworkAnalyzer.estimateRTTByOrigin(records, options); + for (const [origin, summary] of rttSummaryByOrigin.entries()) { + rttByOrigin.set(origin, summary.min); + } + } + const estimatesByOrigin = _NetworkAnalyzer.estimateResponseTimeByOrigin(records, rttByOrigin); + return _NetworkAnalyzer.summarize(estimatesByOrigin); + } + /** + * Computes the average throughput for the given requests in bits/second. + * Excludes data URI, failed or otherwise incomplete, and cached requests. + * Returns null if there were no analyzable network requests. + */ + static estimateThroughput(records) { + let totalBytes = 0; + const timeBoundaries = records.reduce((boundaries, request) => { + const scheme = request.parsedURL?.scheme; + if (scheme === "data" || request.failed || !request.finished || request.statusCode > 300 || !request.transferSize) { + return boundaries; + } + totalBytes += request.transferSize; + boundaries.push({ time: request.responseHeadersEndTime / 1e3, isStart: true }); + boundaries.push({ time: request.networkEndTime / 1e3, isStart: false }); + return boundaries; + }, []).sort((a, b) => a.time - b.time); + if (!timeBoundaries.length) { + return null; + } + let inflight = 0; + let currentStart = 0; + let totalDuration = 0; + timeBoundaries.forEach((boundary) => { + if (boundary.isStart) { + if (inflight === 0) { + currentStart = boundary.time; + } + inflight++; + } else { + inflight--; + if (inflight === 0) { + totalDuration += boundary.time - currentStart; + } + } + }); + return totalBytes * 8 / totalDuration; + } + static computeRTTAndServerResponseTime(records) { + const rttByOrigin = /* @__PURE__ */ new Map(); + for (const [origin, summary] of _NetworkAnalyzer.estimateRTTByOrigin(records).entries()) { + rttByOrigin.set(origin, summary.min); + } + const minimumRtt = Math.min(...Array.from(rttByOrigin.values())); + const responseTimeSummaries = _NetworkAnalyzer.estimateServerResponseTimeByOrigin(records, { + rttByOrigin + }); + const additionalRttByOrigin = /* @__PURE__ */ new Map(); + const serverResponseTimeByOrigin = /* @__PURE__ */ new Map(); + for (const [origin, summary] of responseTimeSummaries.entries()) { + const rttForOrigin = rttByOrigin.get(origin) || minimumRtt; + additionalRttByOrigin.set(origin, rttForOrigin - minimumRtt); + serverResponseTimeByOrigin.set(origin, summary.median); + } + return { + rtt: minimumRtt, + additionalRttByOrigin, + serverResponseTimeByOrigin + }; + } + static analyze(records) { + const throughput = _NetworkAnalyzer.estimateThroughput(records); + if (throughput === null) { + return null; + } + return { + throughput, + ..._NetworkAnalyzer.computeRTTAndServerResponseTime(records) + }; + } + static findResourceForUrl(records, resourceUrl) { + return records.find((request) => resourceUrl.startsWith(request.url) && UrlUtils.equalWithExcludedFragments(request.url, resourceUrl)); + } + static findLastDocumentForUrl(records, resourceUrl) { + const matchingRequests = records.filter((request) => request.resourceType === "Document" && !request.failed && // Note: `request.url` should never have a fragment, else this optimization gives wrong results. + resourceUrl.startsWith(request.url) && UrlUtils.equalWithExcludedFragments(request.url, resourceUrl)); + return matchingRequests[matchingRequests.length - 1]; + } + /** + * Resolves redirect chain given a main document. + * See: {@link NetworkAnalyzer.findLastDocumentForUrl} for how to retrieve main document. + */ + static resolveRedirects(request) { + while (request.redirectDestination) { + request = request.redirectDestination; + } + return request; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/core/core.js +var core_exports = {}; +__export(core_exports, { + LanternError: () => LanternError, + NetworkAnalyzer: () => NetworkAnalyzer +}); +var init_core = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/core/core.js"() { + init_process_global(); + init_LanternError(); + init_NetworkAnalyzer(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/graph/BaseNode.js +var BaseNode; +var init_BaseNode = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/BaseNode.js"() { + init_process_global(); + init_core(); + BaseNode = class _BaseNode { + static { + __name(this, "BaseNode"); + } + static types = { + NETWORK: "network", + CPU: "cpu" + }; + _id; + _isMainDocument; + dependents; + dependencies; + constructor(id) { + this._id = id; + this._isMainDocument = false; + this.dependents = []; + this.dependencies = []; + } + get id() { + return this._id; + } + get type() { + throw new LanternError("Unimplemented"); + } + /** + * In microseconds + */ + get startTime() { + throw new LanternError("Unimplemented"); + } + /** + * In microseconds + */ + get endTime() { + throw new LanternError("Unimplemented"); + } + setIsMainDocument(value) { + this._isMainDocument = value; + } + isMainDocument() { + return this._isMainDocument; + } + getDependents() { + return this.dependents.slice(); + } + getNumberOfDependents() { + return this.dependents.length; + } + getDependencies() { + return this.dependencies.slice(); + } + getNumberOfDependencies() { + return this.dependencies.length; + } + getRootNode() { + let rootNode = this; + while (rootNode.dependencies.length) { + rootNode = rootNode.dependencies[0]; + } + return rootNode; + } + addDependent(node) { + node.addDependency(this); + } + addDependency(node) { + if (node === this) { + throw new LanternError("Cannot add dependency on itself"); + } + if (this.dependencies.includes(node)) { + return; + } + node.dependents.push(this); + this.dependencies.push(node); + } + removeDependent(node) { + node.removeDependency(this); + } + removeDependency(node) { + if (!this.dependencies.includes(node)) { + return; + } + const thisIndex = node.dependents.indexOf(this); + node.dependents.splice(thisIndex, 1); + this.dependencies.splice(this.dependencies.indexOf(node), 1); + } + // Unused in devtools, but used in LH. + removeAllDependencies() { + for (const node of this.dependencies.slice()) { + this.removeDependency(node); + } + } + /** + * Computes whether the given node is anywhere in the dependency graph of this node. + * While this method can prevent cycles, it walks the graph and should be used sparingly. + * Nodes are always considered dependent on themselves for the purposes of cycle detection. + */ + isDependentOn(node) { + let isDependentOnNode = false; + this.traverse((currentNode) => { + if (isDependentOnNode) { + return; + } + isDependentOnNode = currentNode === node; + }, (currentNode) => { + if (isDependentOnNode) { + return []; + } + return currentNode.getDependencies(); + }); + return isDependentOnNode; + } + /** + * Clones the node's information without adding any dependencies/dependents. + */ + cloneWithoutRelationships() { + const node = new _BaseNode(this.id); + node.setIsMainDocument(this._isMainDocument); + return node; + } + /** + * Clones the entire graph connected to this node filtered by the optional predicate. If a node is + * included by the predicate, all nodes along the paths between the node and the root will be included. If the + * node this was called on is not included in the resulting filtered graph, the method will throw. + * + * This does not clone NetworkNode's `record` or `rawRecord` fields. It may be reasonable to clone the former, + * to assist in graph construction, but the latter should never be cloned as one constraint of Lantern is that + * the underlying data records are accessible for plain object reference equality checks. + */ + cloneWithRelationships(predicate) { + const rootNode = this.getRootNode(); + const idsToIncludedClones = /* @__PURE__ */ new Map(); + rootNode.traverse((node) => { + if (idsToIncludedClones.has(node.id)) { + return; + } + if (predicate === void 0) { + idsToIncludedClones.set(node.id, node.cloneWithoutRelationships()); + return; + } + if (predicate(node)) { + node.traverse( + (node2) => idsToIncludedClones.set(node2.id, node2.cloneWithoutRelationships()), + // Dependencies already cloned have already cloned ancestors, so no need to visit again. + (node2) => node2.dependencies.filter((parent) => !idsToIncludedClones.has(parent.id)) + ); + } + }); + rootNode.traverse((originalNode) => { + const clonedNode = idsToIncludedClones.get(originalNode.id); + if (!clonedNode) { + return; + } + for (const dependency of originalNode.dependencies) { + const clonedDependency = idsToIncludedClones.get(dependency.id); + if (!clonedDependency) { + throw new LanternError("Dependency somehow not cloned"); + } + clonedNode.addDependency(clonedDependency); + } + }); + const clonedThisNode = idsToIncludedClones.get(this.id); + if (!clonedThisNode) { + throw new LanternError("Cloned graph missing node"); + } + return clonedThisNode; + } + /** + * Traverses all connected nodes in BFS order, calling `callback` exactly once + * on each. `traversalPath` is the shortest (though not necessarily unique) + * path from `node` to the root of the iteration. + * + * The `getNextNodes` function takes a visited node and returns which nodes to + * visit next. It defaults to returning the node's dependents. + */ + traverse(callback, getNextNodes) { + for (const { node, traversalPath } of this.traverseGenerator(getNextNodes)) { + callback(node, traversalPath); + } + } + /** + * @see BaseNode.traverse + */ + // clang-format off + *traverseGenerator(getNextNodes) { + if (!getNextNodes) { + getNextNodes = /* @__PURE__ */ __name((node) => node.getDependents(), "getNextNodes"); + } + const queue = [[this]]; + const visited = /* @__PURE__ */ new Set([this.id]); + while (queue.length) { + const traversalPath = queue.shift(); + const node = traversalPath[0]; + yield { node, traversalPath }; + for (const nextNode of getNextNodes(node)) { + if (visited.has(nextNode.id)) { + continue; + } + visited.add(nextNode.id); + queue.push([nextNode, ...traversalPath]); + } + } + } + /** + * If the given node has a cycle, returns a path representing that cycle. + * Else returns null. + * + * Does a DFS on in its dependent graph. + */ + static findCycle(node, direction = "both") { + if (direction === "both") { + return _BaseNode.findCycle(node, "dependents") || _BaseNode.findCycle(node, "dependencies"); + } + const visited = /* @__PURE__ */ new Set(); + const currentPath = []; + const toVisit = [node]; + const depthAdded = /* @__PURE__ */ new Map([[node, 0]]); + while (toVisit.length) { + const currentNode = toVisit.pop(); + if (currentPath.includes(currentNode)) { + return currentPath; + } + if (visited.has(currentNode)) { + continue; + } + while (currentPath.length > depthAdded.get(currentNode)) { + currentPath.pop(); + } + visited.add(currentNode); + currentPath.push(currentNode); + const nodesToExplore = direction === "dependents" ? currentNode.dependents : currentNode.dependencies; + for (const nextNode of nodesToExplore) { + if (toVisit.includes(nextNode)) { + continue; + } + toVisit.push(nextNode); + depthAdded.set(nextNode, currentPath.length); + } + } + return null; + } + canDependOn(node) { + return node.startTime <= this.startTime; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/graph/CPUNode.js +var CPUNode; +var init_CPUNode = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/CPUNode.js"() { + init_process_global(); + init_BaseNode(); + CPUNode = class _CPUNode extends BaseNode { + static { + __name(this, "CPUNode"); + } + _event; + _childEvents; + correctedEndTs; + constructor(parentEvent, childEvents = [], correctedEndTs) { + const nodeId = `${parentEvent.tid}.${parentEvent.ts}`; + super(nodeId); + this._event = parentEvent; + this._childEvents = childEvents; + this.correctedEndTs = correctedEndTs; + } + get type() { + return BaseNode.types.CPU; + } + get startTime() { + return this._event.ts; + } + get endTime() { + if (this.correctedEndTs) { + return this.correctedEndTs; + } + return this._event.ts + this._event.dur; + } + get duration() { + return this.endTime - this.startTime; + } + get event() { + return this._event; + } + get childEvents() { + return this._childEvents; + } + /** + * Returns true if this node contains a Layout task. + */ + didPerformLayout() { + return this._childEvents.some((evt) => evt.name === "Layout"); + } + /** + * Returns the script URLs that had their EvaluateScript events occur in this task. + */ + getEvaluateScriptURLs() { + const urls = /* @__PURE__ */ new Set(); + for (const event of this._childEvents) { + if (event.name !== "EvaluateScript") { + continue; + } + if (!event.args.data?.url) { + continue; + } + urls.add(event.args.data.url); + } + return urls; + } + cloneWithoutRelationships() { + return new _CPUNode(this._event, this._childEvents, this.correctedEndTs); + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/graph/NetworkNode.js +function isNonNetworkProtocol(protocol) { + const urlScheme = protocol.includes(":") ? protocol.slice(0, protocol.indexOf(":")) : protocol; + return NON_NETWORK_SCHEMES.includes(urlScheme); +} +var NON_NETWORK_SCHEMES, NetworkNode; +var init_NetworkNode = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/NetworkNode.js"() { + init_process_global(); + init_BaseNode(); + NON_NETWORK_SCHEMES = [ + "blob", + // @see https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL + "data", + // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs + "intent", + // @see https://developer.chrome.com/docs/multidevice/android/intents/ + "file", + // @see https://en.wikipedia.org/wiki/File_URI_scheme + "filesystem", + // @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystem + "chrome-extension" + ]; + __name(isNonNetworkProtocol, "isNonNetworkProtocol"); + NetworkNode = class _NetworkNode extends BaseNode { + static { + __name(this, "NetworkNode"); + } + _request; + constructor(networkRequest) { + super(networkRequest.requestId); + this._request = networkRequest; + } + get type() { + return BaseNode.types.NETWORK; + } + get startTime() { + return this._request.rendererStartTime * 1e3; + } + get endTime() { + return this._request.networkEndTime * 1e3; + } + get rawRequest() { + return this._request.rawRequest; + } + get request() { + return this._request; + } + get initiatorType() { + return this._request.initiator.type; + } + get fromDiskCache() { + return Boolean(this._request.fromDiskCache); + } + get isNonNetworkProtocol() { + return isNonNetworkProtocol(this.request.protocol) || // But `protocol` can fail to be populated if the request fails, so fallback to scheme. + isNonNetworkProtocol(this.request.parsedURL.scheme); + } + /** + * Returns whether this network request can be downloaded without a TCP connection. + * During simulation we treat data coming in over a network connection separately from on-device data. + */ + get isConnectionless() { + return this.fromDiskCache || this.isNonNetworkProtocol; + } + hasRenderBlockingPriority() { + const priority = this._request.priority; + const isScript = this._request.resourceType === "Script"; + const isDocument = this._request.resourceType === "Document"; + const isBlockingScript = priority === "High" && isScript; + const isBlockingHtmlImport = priority === "High" && isDocument; + return priority === "VeryHigh" || isBlockingScript || isBlockingHtmlImport; + } + cloneWithoutRelationships() { + const node = new _NetworkNode(this._request); + node.setIsMainDocument(this._isMainDocument); + return node; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/graph/PageDependencyGraph.js +var SCHEDULABLE_TASK_TITLE_LH, SCHEDULABLE_TASK_TITLE_ALT1, SCHEDULABLE_TASK_TITLE_ALT2, SCHEDULABLE_TASK_TITLE_ALT3, SIGNIFICANT_DUR_THRESHOLD_MS, IGNORED_MIME_TYPES_REGEX, PageDependencyGraph; +var init_PageDependencyGraph = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/PageDependencyGraph.js"() { + init_process_global(); + init_core(); + init_CPUNode(); + init_NetworkNode(); + SCHEDULABLE_TASK_TITLE_LH = "RunTask"; + SCHEDULABLE_TASK_TITLE_ALT1 = "ThreadControllerImpl::RunTask"; + SCHEDULABLE_TASK_TITLE_ALT2 = "ThreadControllerImpl::DoWork"; + SCHEDULABLE_TASK_TITLE_ALT3 = "TaskQueueManager::ProcessTaskFromWorkQueue"; + SIGNIFICANT_DUR_THRESHOLD_MS = 10; + IGNORED_MIME_TYPES_REGEX = /^video/; + PageDependencyGraph = class _PageDependencyGraph { + static { + __name(this, "PageDependencyGraph"); + } + static getNetworkInitiators(request) { + if (!request.initiator) { + return []; + } + if (request.initiator.url) { + return [request.initiator.url]; + } + if (request.initiator.type === "script") { + const scriptURLs = /* @__PURE__ */ new Set(); + let stack = request.initiator.stack; + while (stack) { + const callFrames = stack.callFrames || []; + for (const frame of callFrames) { + if (frame.url) { + scriptURLs.add(frame.url); + } + } + stack = stack.parent; + } + return Array.from(scriptURLs); + } + return []; + } + static getNetworkNodeOutput(networkRequests) { + const nodes = []; + const idToNodeMap = /* @__PURE__ */ new Map(); + const urlToNodeMap = /* @__PURE__ */ new Map(); + const frameIdToNodeMap = /* @__PURE__ */ new Map(); + networkRequests.forEach((request) => { + if (IGNORED_MIME_TYPES_REGEX.test(request.mimeType)) { + return; + } + if (request.fromWorker) { + return; + } + while (idToNodeMap.has(request.requestId)) { + request.requestId += ":duplicate"; + } + const node = new NetworkNode(request); + nodes.push(node); + const urlList = urlToNodeMap.get(request.url) || []; + urlList.push(node); + idToNodeMap.set(request.requestId, node); + urlToNodeMap.set(request.url, urlList); + if (request.frameId && request.resourceType === "Document" && request.documentURL === request.url) { + const value = frameIdToNodeMap.has(request.frameId) ? null : node; + frameIdToNodeMap.set(request.frameId, value); + } + }); + return { nodes, idToNodeMap, urlToNodeMap, frameIdToNodeMap }; + } + static isScheduleableTask(evt) { + return evt.name === SCHEDULABLE_TASK_TITLE_LH || evt.name === SCHEDULABLE_TASK_TITLE_ALT1 || evt.name === SCHEDULABLE_TASK_TITLE_ALT2 || evt.name === SCHEDULABLE_TASK_TITLE_ALT3; + } + /** + * There should *always* be at least one top level event, having 0 typically means something is + * drastically wrong with the trace and we should just give up early and loudly. + */ + static assertHasToplevelEvents(events) { + const hasToplevelTask = events.some(this.isScheduleableTask); + if (!hasToplevelTask) { + throw new LanternError("Could not find any top level events"); + } + } + static getCPUNodes(mainThreadEvents) { + const nodes = []; + let i = 0; + _PageDependencyGraph.assertHasToplevelEvents(mainThreadEvents); + while (i < mainThreadEvents.length) { + const evt = mainThreadEvents[i]; + i++; + if (!_PageDependencyGraph.isScheduleableTask(evt) || !evt.dur) { + continue; + } + let correctedEndTs = void 0; + const children = []; + for (const endTime = evt.ts + evt.dur; i < mainThreadEvents.length && mainThreadEvents[i].ts < endTime; i++) { + const event = mainThreadEvents[i]; + if (_PageDependencyGraph.isScheduleableTask(event) && event.dur) { + correctedEndTs = event.ts - 1; + break; + } + children.push(event); + } + nodes.push(new CPUNode(evt, children, correctedEndTs)); + } + return nodes; + } + static linkNetworkNodes(rootNode, networkNodeOutput) { + networkNodeOutput.nodes.forEach((node) => { + const directInitiatorRequest = node.request.initiatorRequest || rootNode.request; + const directInitiatorNode = networkNodeOutput.idToNodeMap.get(directInitiatorRequest.requestId) || rootNode; + const canDependOnInitiator = !directInitiatorNode.isDependentOn(node) && node.canDependOn(directInitiatorNode); + const initiators = _PageDependencyGraph.getNetworkInitiators(node.request); + if (initiators.length) { + initiators.forEach((initiator) => { + const parentCandidates = networkNodeOutput.urlToNodeMap.get(initiator) || []; + if (parentCandidates.length === 1 && parentCandidates[0].startTime <= node.startTime && !parentCandidates[0].isDependentOn(node)) { + node.addDependency(parentCandidates[0]); + } else if (canDependOnInitiator) { + directInitiatorNode.addDependent(node); + } + }); + } else if (canDependOnInitiator) { + directInitiatorNode.addDependent(node); + } + if (node !== rootNode && node.getDependencies().length === 0 && node.canDependOn(rootNode)) { + node.addDependency(rootNode); + } + if (!node.request.redirects) { + return; + } + const redirects = [...node.request.redirects, node.request]; + for (let i = 1; i < redirects.length; i++) { + const redirectNode = networkNodeOutput.idToNodeMap.get(redirects[i - 1].requestId); + const actualNode = networkNodeOutput.idToNodeMap.get(redirects[i].requestId); + if (actualNode && redirectNode) { + actualNode.addDependency(redirectNode); + } + } + }); + } + static linkCPUNodes(rootNode, networkNodeOutput, cpuNodes) { + const linkableResourceTypes = /* @__PURE__ */ new Set([ + "XHR", + "Fetch", + "Script" + ]); + function addDependentNetworkRequest(cpuNode, reqId) { + const networkNode = networkNodeOutput.idToNodeMap.get(reqId); + if (!networkNode || // Ignore all network nodes that started before this CPU task started + // A network request that started earlier could not possibly have been started by this task + networkNode.startTime <= cpuNode.startTime) { + return; + } + const { request } = networkNode; + const resourceType = request.resourceType || request.redirectDestination?.resourceType; + if (!linkableResourceTypes.has(resourceType)) { + return; + } + cpuNode.addDependent(networkNode); + } + __name(addDependentNetworkRequest, "addDependentNetworkRequest"); + function addDependencyOnFrame(cpuNode, frameId) { + if (!frameId) { + return; + } + const networkNode = networkNodeOutput.frameIdToNodeMap.get(frameId); + if (!networkNode) { + return; + } + if (networkNode.startTime >= cpuNode.startTime) { + return; + } + cpuNode.addDependency(networkNode); + } + __name(addDependencyOnFrame, "addDependencyOnFrame"); + function addDependencyOnUrl(cpuNode, url) { + if (!url) { + return; + } + const minimumAllowableTimeSinceNetworkNodeEnd = -100 * 1e3; + const candidates = networkNodeOutput.urlToNodeMap.get(url) || []; + let minCandidate = null; + let minDistance = Infinity; + for (const candidate of candidates) { + if (cpuNode.startTime <= candidate.startTime) { + return; + } + const distance = cpuNode.startTime - candidate.endTime; + if (distance >= minimumAllowableTimeSinceNetworkNodeEnd && distance < minDistance) { + minCandidate = candidate; + minDistance = distance; + } + } + if (!minCandidate) { + return; + } + cpuNode.addDependency(minCandidate); + } + __name(addDependencyOnUrl, "addDependencyOnUrl"); + const timers = /* @__PURE__ */ new Map(); + for (const node of cpuNodes) { + for (const evt of node.childEvents) { + if (!evt.args.data) { + continue; + } + const argsUrl = evt.args.data.url; + const stackTraceUrls = (evt.args.data.stackTrace || []).map((l) => l.url).filter(Boolean); + switch (evt.name) { + case "TimerInstall": + timers.set(evt.args.data.timerId, node); + stackTraceUrls.forEach((url) => addDependencyOnUrl(node, url)); + break; + case "TimerFire": { + const installer = timers.get(evt.args.data.timerId); + if (!installer || installer.endTime > node.startTime) { + break; + } + installer.addDependent(node); + break; + } + case "InvalidateLayout": + case "ScheduleStyleRecalculation": + addDependencyOnFrame(node, evt.args.data.frame); + stackTraceUrls.forEach((url) => addDependencyOnUrl(node, url)); + break; + case "EvaluateScript": + addDependencyOnFrame(node, evt.args.data.frame); + addDependencyOnUrl(node, argsUrl); + stackTraceUrls.forEach((url) => addDependencyOnUrl(node, url)); + break; + case "XHRReadyStateChange": + if (evt.args.data.readyState !== 4) { + break; + } + addDependencyOnUrl(node, argsUrl); + stackTraceUrls.forEach((url) => addDependencyOnUrl(node, url)); + break; + case "FunctionCall": + case "v8.compile": + addDependencyOnFrame(node, evt.args.data.frame); + addDependencyOnUrl(node, argsUrl); + break; + case "ParseAuthorStyleSheet": + addDependencyOnFrame(node, evt.args.data.frame); + addDependencyOnUrl(node, evt.args.data.styleSheetUrl); + break; + case "ResourceSendRequest": + addDependencyOnFrame(node, evt.args.data.frame); + addDependentNetworkRequest(node, evt.args.data.requestId); + stackTraceUrls.forEach((url) => addDependencyOnUrl(node, url)); + break; + } + } + if (node.getNumberOfDependencies() === 0 && node.canDependOn(rootNode)) { + node.addDependency(rootNode); + } + } + const minimumEvtDur = SIGNIFICANT_DUR_THRESHOLD_MS * 1e3; + let foundFirstLayout = false; + let foundFirstPaint = false; + let foundFirstParse = false; + for (const node of cpuNodes) { + let isFirst = false; + if (!foundFirstLayout && node.childEvents.some((evt) => evt.name === "Layout")) { + isFirst = foundFirstLayout = true; + } + if (!foundFirstPaint && node.childEvents.some((evt) => evt.name === "Paint")) { + isFirst = foundFirstPaint = true; + } + if (!foundFirstParse && node.childEvents.some((evt) => evt.name === "ParseHTML")) { + isFirst = foundFirstParse = true; + } + if (isFirst || node.duration >= minimumEvtDur) { + continue; + } + if (node.getNumberOfDependencies() === 1 || node.getNumberOfDependents() <= 1) { + _PageDependencyGraph.pruneNode(node); + } + } + } + /** + * Removes the given node from the graph, but retains all paths between its dependencies and + * dependents. + */ + static pruneNode(node) { + const dependencies = node.getDependencies(); + const dependents = node.getDependents(); + for (const dependency of dependencies) { + node.removeDependency(dependency); + for (const dependent of dependents) { + dependency.addDependent(dependent); + } + } + for (const dependent of dependents) { + node.removeDependent(dependent); + } + } + /** + * TODO: remove when CDT backend in Lighthouse is gone. Until then, this is a useful debugging tool + * to find delta between using CDP or the trace to create the network requests. + * + * When a test fails using the trace backend, I enabled this debug method and copied the network + * requests when CDP was used, then when trace is used, and diff'd them. This method helped + * remove non-logical differences from the comparison (order of properties, slight rounding + * discrepancies, removing object cycles, etc). + * + * When using for a unit test, make sure to do `.only` so you are getting what you expect. + */ + static debugNormalizeRequests(lanternRequests) { + for (const request of lanternRequests) { + request.rendererStartTime = Math.round(request.rendererStartTime * 1e3) / 1e3; + request.networkRequestTime = Math.round(request.networkRequestTime * 1e3) / 1e3; + request.responseHeadersEndTime = Math.round(request.responseHeadersEndTime * 1e3) / 1e3; + request.networkEndTime = Math.round(request.networkEndTime * 1e3) / 1e3; + } + for (const r of lanternRequests) { + delete r.rawRequest; + if (r.initiatorRequest) { + r.initiatorRequest = { id: r.initiatorRequest.requestId }; + } + if (r.redirectDestination) { + r.redirectDestination = { id: r.redirectDestination.requestId }; + } + if (r.redirectSource) { + r.redirectSource = { id: r.redirectSource.requestId }; + } + if (r.redirects) { + r.redirects = r.redirects.map((r2) => r2.requestId); + } + } + const requests = lanternRequests.map((r) => ({ + requestId: r.requestId, + connectionId: r.connectionId, + connectionReused: r.connectionReused, + url: r.url, + protocol: r.protocol, + parsedURL: r.parsedURL, + documentURL: r.documentURL, + rendererStartTime: r.rendererStartTime, + networkRequestTime: r.networkRequestTime, + responseHeadersEndTime: r.responseHeadersEndTime, + networkEndTime: r.networkEndTime, + transferSize: r.transferSize, + resourceSize: r.resourceSize, + fromDiskCache: r.fromDiskCache, + fromMemoryCache: r.fromMemoryCache, + finished: r.finished, + statusCode: r.statusCode, + redirectSource: r.redirectSource, + redirectDestination: r.redirectDestination, + redirects: r.redirects, + failed: r.failed, + initiator: r.initiator, + timing: r.timing ? { + requestTime: r.timing.requestTime, + proxyStart: r.timing.proxyStart, + proxyEnd: r.timing.proxyEnd, + dnsStart: r.timing.dnsStart, + dnsEnd: r.timing.dnsEnd, + connectStart: r.timing.connectStart, + connectEnd: r.timing.connectEnd, + sslStart: r.timing.sslStart, + sslEnd: r.timing.sslEnd, + workerStart: r.timing.workerStart, + workerReady: r.timing.workerReady, + workerFetchStart: r.timing.workerFetchStart, + workerRespondWithSettled: r.timing.workerRespondWithSettled, + sendStart: r.timing.sendStart, + sendEnd: r.timing.sendEnd, + pushStart: r.timing.pushStart, + pushEnd: r.timing.pushEnd, + receiveHeadersStart: r.timing.receiveHeadersStart, + receiveHeadersEnd: r.timing.receiveHeadersEnd + } : r.timing, + resourceType: r.resourceType, + mimeType: r.mimeType, + priority: r.priority, + initiatorRequest: r.initiatorRequest, + frameId: r.frameId, + fromWorker: r.fromWorker, + isLinkPreload: r.isLinkPreload, + serverResponseTime: r.serverResponseTime + })).filter((r) => !r.fromWorker); + const debug2 = requests; + console.log(debug2); + } + static createGraph(mainThreadEvents, networkRequests, url) { + const networkNodeOutput = _PageDependencyGraph.getNetworkNodeOutput(networkRequests); + const cpuNodes = _PageDependencyGraph.getCPUNodes(mainThreadEvents); + const { requestedUrl, mainDocumentUrl } = url; + if (!requestedUrl) { + throw new LanternError("requestedUrl is required to get the root request"); + } + if (!mainDocumentUrl) { + throw new LanternError("mainDocumentUrl is required to get the main resource"); + } + const rootRequest = NetworkAnalyzer.findResourceForUrl(networkRequests, requestedUrl); + if (!rootRequest) { + throw new LanternError("rootRequest not found"); + } + const rootNode = networkNodeOutput.idToNodeMap.get(rootRequest.requestId); + if (!rootNode) { + throw new LanternError("rootNode not found"); + } + const mainDocumentRequest = NetworkAnalyzer.findLastDocumentForUrl(networkRequests, mainDocumentUrl); + if (!mainDocumentRequest) { + throw new LanternError("mainDocumentRequest not found"); + } + const mainDocumentNode = networkNodeOutput.idToNodeMap.get(mainDocumentRequest.requestId); + if (!mainDocumentNode) { + throw new LanternError("mainDocumentNode not found"); + } + _PageDependencyGraph.linkNetworkNodes(rootNode, networkNodeOutput); + _PageDependencyGraph.linkCPUNodes(rootNode, networkNodeOutput, cpuNodes); + mainDocumentNode.setIsMainDocument(true); + if (NetworkNode.findCycle(rootNode)) { + throw new LanternError("Invalid dependency graph created, cycle detected"); + } + return rootNode; + } + // Unused, but useful for debugging. + static printGraph(rootNode, widthInCharacters = 80) { + function padRight(str, target, padChar = " ") { + return str + padChar.repeat(Math.max(target - str.length, 0)); + } + __name(padRight, "padRight"); + const nodes = []; + rootNode.traverse((node) => nodes.push(node)); + nodes.sort((a, b) => a.startTime - b.startTime); + const nodeToLabel = /* @__PURE__ */ new Map(); + rootNode.traverse((node) => { + const ascii = 65 + nodeToLabel.size; + let label; + if (ascii > 90) { + label = `Z${ascii - 90}`; + } else { + label = String.fromCharCode(ascii); + } + nodeToLabel.set(node, label); + }); + const min = nodes[0].startTime; + const max = nodes.reduce((max2, node) => Math.max(max2, node.endTime), 0); + const totalTime = max - min; + const timePerCharacter = totalTime / widthInCharacters; + nodes.forEach((node) => { + const offset = Math.round((node.startTime - min) / timePerCharacter); + const length = Math.ceil((node.endTime - node.startTime) / timePerCharacter); + const bar = padRight("", offset) + padRight("", length, "="); + const displayName = node.request ? node.request.url : node.type; + console.log(padRight(bar, widthInCharacters), `| ${displayName.slice(0, 50)}`); + }); + console.log(); + nodes.forEach((node) => { + const displayName = node.request ? node.request.url : node.type; + console.log(nodeToLabel.get(node), displayName.slice(0, widthInCharacters - 5)); + for (const child of node.dependents) { + const displayName2 = child.request ? child.request.url : child.type; + console.log(" ->", nodeToLabel.get(child), displayName2.slice(0, widthInCharacters - 10)); + } + console.log(); + }); + const cyclePath = NetworkNode.findCycle(rootNode); + console.log("Cycle?", cyclePath ? "yes" : "no"); + if (cyclePath) { + const path7 = [...cyclePath]; + path7.push(path7[0]); + console.log(path7.map((node) => nodeToLabel.get(node)).join(" -> ")); + } + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/graph/graph.js +var graph_exports = {}; +__export(graph_exports, { + BaseNode: () => BaseNode, + CPUNode: () => CPUNode, + NetworkNode: () => NetworkNode, + PageDependencyGraph: () => PageDependencyGraph +}); +var init_graph = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/graph.js"() { + init_process_global(); + init_BaseNode(); + init_CPUNode(); + init_NetworkNode(); + init_PageDependencyGraph(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Metric.js +var Metric; +var init_Metric = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Metric.js"() { + init_process_global(); + init_core(); + init_graph(); + Metric = class { + static { + __name(this, "Metric"); + } + static getScriptUrls(dependencyGraph, treatNodeAsRenderBlocking) { + const scriptUrls = /* @__PURE__ */ new Set(); + dependencyGraph.traverse((node) => { + if (node.type !== BaseNode.types.NETWORK) { + return; + } + if (node.request.resourceType !== "Script") { + return; + } + if (treatNodeAsRenderBlocking?.(node)) { + scriptUrls.add(node.request.url); + } + }); + return scriptUrls; + } + static get coefficients() { + throw new LanternError("coefficients unimplemented!"); + } + /** + * Returns the coefficients, scaled by the throttling settings if needed by the metric. + * Some lantern metrics (speed-index) use components in their estimate that are not + * from the simulator. In this case, we need to adjust the coefficients as the target throttling + * settings change. + */ + static getScaledCoefficients(_rttMs) { + return this.coefficients; + } + static getOptimisticGraph(_dependencyGraph, _processedNavigation) { + throw new LanternError("Optimistic graph unimplemented!"); + } + static getPessimisticGraph(_dependencyGraph, _processedNavigation) { + throw new LanternError("Pessmistic graph unimplemented!"); + } + static getEstimateFromSimulation(simulationResult, _extras) { + return simulationResult; + } + static compute(data31, extras) { + const { simulator, graph: graph2, processedNavigation } = data31; + const metricName = this.name.replace("Lantern", ""); + const optimisticGraph = this.getOptimisticGraph(graph2, processedNavigation); + const pessimisticGraph = this.getPessimisticGraph(graph2, processedNavigation); + let simulateOptions = { label: `optimistic${metricName}` }; + const optimisticSimulation = simulator.simulate(optimisticGraph, simulateOptions); + simulateOptions = { label: `pessimistic${metricName}` }; + const pessimisticSimulation = simulator.simulate(pessimisticGraph, simulateOptions); + const optimisticEstimate = this.getEstimateFromSimulation(optimisticSimulation, { ...extras, optimistic: true }); + const pessimisticEstimate = this.getEstimateFromSimulation(pessimisticSimulation, { ...extras, optimistic: false }); + const coefficients = this.getScaledCoefficients(simulator.rtt); + const interceptMultiplier = coefficients.intercept > 0 ? Math.min(1, optimisticEstimate.timeInMs / 1e3) : 1; + const timing = coefficients.intercept * interceptMultiplier + coefficients.optimistic * optimisticEstimate.timeInMs + coefficients.pessimistic * pessimisticEstimate.timeInMs; + return { + timing, + optimisticEstimate, + pessimisticEstimate, + optimisticGraph, + pessimisticGraph + }; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/FirstContentfulPaint.js +var FirstContentfulPaint; +var init_FirstContentfulPaint = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/FirstContentfulPaint.js"() { + init_process_global(); + init_graph(); + init_Metric(); + FirstContentfulPaint = class extends Metric { + static { + __name(this, "FirstContentfulPaint"); + } + static get coefficients() { + return { + intercept: 0, + optimistic: 0.5, + pessimistic: 0.5 + }; + } + /** + * Computes the set of URLs that *appeared* to be render-blocking based on our filter, + * *but definitely were not* render-blocking based on the timing of their EvaluateScript task. + * It also computes the set of corresponding CPU node ids that were needed for the paint at the + * given timestamp. + */ + static getRenderBlockingNodeData(graph2, { cutoffTimestamp, treatNodeAsRenderBlocking, additionalCpuNodesToTreatAsRenderBlocking }) { + const scriptUrlToNodeMap = /* @__PURE__ */ new Map(); + const cpuNodes = []; + graph2.traverse((node) => { + if (node.type === BaseNode.types.CPU) { + if (node.startTime <= cutoffTimestamp) { + cpuNodes.push(node); + } + const scriptUrls = node.getEvaluateScriptURLs(); + for (const url of scriptUrls) { + const existing = scriptUrlToNodeMap.get(url) || node; + scriptUrlToNodeMap.set(url, node.startTime < existing.startTime ? node : existing); + } + } + }); + cpuNodes.sort((a, b) => a.startTime - b.startTime); + const possiblyRenderBlockingScriptUrls = Metric.getScriptUrls(graph2, (node) => { + return node.endTime <= cutoffTimestamp && treatNodeAsRenderBlocking(node); + }); + const definitelyNotRenderBlockingScriptUrls = /* @__PURE__ */ new Set(); + const renderBlockingCpuNodeIds = /* @__PURE__ */ new Set(); + for (const url of possiblyRenderBlockingScriptUrls) { + const cpuNodeForUrl = scriptUrlToNodeMap.get(url); + if (!cpuNodeForUrl) { + continue; + } + if (cpuNodes.includes(cpuNodeForUrl)) { + renderBlockingCpuNodeIds.add(cpuNodeForUrl.id); + continue; + } + definitelyNotRenderBlockingScriptUrls.add(url); + } + const firstLayout = cpuNodes.find((node) => node.didPerformLayout()); + if (firstLayout) { + renderBlockingCpuNodeIds.add(firstLayout.id); + } + const firstPaint = cpuNodes.find((node) => node.childEvents.some((e) => e.name === "Paint")); + if (firstPaint) { + renderBlockingCpuNodeIds.add(firstPaint.id); + } + const firstParse = cpuNodes.find((node) => node.childEvents.some((e) => e.name === "ParseHTML")); + if (firstParse) { + renderBlockingCpuNodeIds.add(firstParse.id); + } + if (additionalCpuNodesToTreatAsRenderBlocking) { + cpuNodes.filter(additionalCpuNodesToTreatAsRenderBlocking).forEach((node) => renderBlockingCpuNodeIds.add(node.id)); + } + return { + definitelyNotRenderBlockingScriptUrls, + renderBlockingCpuNodeIds + }; + } + /** + * Computes the graph required for the first paint of interest. + */ + static getFirstPaintBasedGraph(dependencyGraph, { cutoffTimestamp, treatNodeAsRenderBlocking, additionalCpuNodesToTreatAsRenderBlocking }) { + const rbData = this.getRenderBlockingNodeData(dependencyGraph, { + cutoffTimestamp, + treatNodeAsRenderBlocking, + additionalCpuNodesToTreatAsRenderBlocking + }); + const { definitelyNotRenderBlockingScriptUrls, renderBlockingCpuNodeIds } = rbData; + return dependencyGraph.cloneWithRelationships((node) => { + if (node.type === BaseNode.types.NETWORK) { + const endedAfterPaint = node.endTime > cutoffTimestamp || node.startTime > cutoffTimestamp; + if (endedAfterPaint && !node.isMainDocument()) { + return false; + } + const url = node.request.url; + if (definitelyNotRenderBlockingScriptUrls.has(url)) { + return false; + } + return treatNodeAsRenderBlocking(node); + } + return renderBlockingCpuNodeIds.has(node.id); + }); + } + static getOptimisticGraph(dependencyGraph, processedNavigation) { + return this.getFirstPaintBasedGraph(dependencyGraph, { + cutoffTimestamp: processedNavigation.timestamps.firstContentfulPaint, + // In the optimistic graph we exclude resources that appeared to be render blocking but were + // initiated by a script. While they typically have a very high importance and tend to have a + // significant impact on the page's content, these resources don't technically block rendering. + treatNodeAsRenderBlocking: /* @__PURE__ */ __name((node) => node.hasRenderBlockingPriority() && node.initiatorType !== "script", "treatNodeAsRenderBlocking") + }); + } + static getPessimisticGraph(dependencyGraph, processedNavigation) { + return this.getFirstPaintBasedGraph(dependencyGraph, { + cutoffTimestamp: processedNavigation.timestamps.firstContentfulPaint, + treatNodeAsRenderBlocking: /* @__PURE__ */ __name((node) => node.hasRenderBlockingPriority(), "treatNodeAsRenderBlocking") + }); + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Interactive.js +var CRITICAL_LONG_TASK_THRESHOLD, Interactive; +var init_Interactive = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Interactive.js"() { + init_process_global(); + init_core(); + init_graph(); + init_Metric(); + CRITICAL_LONG_TASK_THRESHOLD = 20; + Interactive = class _Interactive extends Metric { + static { + __name(this, "Interactive"); + } + static get coefficients() { + return { + intercept: 0, + optimistic: 0.45, + pessimistic: 0.55 + }; + } + static getOptimisticGraph(dependencyGraph) { + const minimumCpuTaskDuration = CRITICAL_LONG_TASK_THRESHOLD * 1e3; + return dependencyGraph.cloneWithRelationships((node) => { + if (node.type === BaseNode.types.CPU) { + return node.duration > minimumCpuTaskDuration; + } + const isImage = node.request.resourceType === "Image"; + const isScript = node.request.resourceType === "Script"; + return !isImage && (isScript || node.request.priority === "High" || node.request.priority === "VeryHigh"); + }); + } + static getPessimisticGraph(dependencyGraph) { + return dependencyGraph; + } + static getEstimateFromSimulation(simulationResult, extras) { + if (!extras.lcpResult) { + throw new LanternError("missing lcpResult"); + } + const lastTaskAt = _Interactive.getLastLongTaskEndTime(simulationResult.nodeTimings); + const minimumTime = extras.optimistic ? extras.lcpResult.optimisticEstimate.timeInMs : extras.lcpResult.pessimisticEstimate.timeInMs; + return { + timeInMs: Math.max(minimumTime, lastTaskAt), + nodeTimings: simulationResult.nodeTimings + }; + } + static compute(data31, extras) { + const lcpResult = extras?.lcpResult; + if (!lcpResult) { + throw new LanternError("LCP is required to calculate the Interactive metric"); + } + const metricResult = super.compute(data31, extras); + metricResult.timing = Math.max(metricResult.timing, lcpResult.timing); + return metricResult; + } + static getLastLongTaskEndTime(nodeTimings, duration = 50) { + return Array.from(nodeTimings.entries()).filter(([node, timing]) => { + if (node.type !== BaseNode.types.CPU) { + return false; + } + return timing.duration > duration; + }).map(([_, timing]) => timing.endTime).reduce((max, x) => Math.max(max || 0, x || 0), 0); + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/LargestContentfulPaint.js +var LargestContentfulPaint; +var init_LargestContentfulPaint = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/LargestContentfulPaint.js"() { + init_process_global(); + init_core(); + init_FirstContentfulPaint(); + init_Metric(); + LargestContentfulPaint = class _LargestContentfulPaint extends Metric { + static { + __name(this, "LargestContentfulPaint"); + } + static get coefficients() { + return { + intercept: 0, + optimistic: 0.5, + pessimistic: 0.5 + }; + } + /** + * Low priority image nodes are usually offscreen and very unlikely to be the + * resource that is required for LCP. Our LCP graphs include everything except for these images. + */ + static isNotLowPriorityImageNode(node) { + if (node.type !== "network") { + return true; + } + const isImage = node.request.resourceType === "Image"; + const isLowPriority = node.request.priority === "Low" || node.request.priority === "VeryLow"; + return !isImage || !isLowPriority; + } + static getOptimisticGraph(dependencyGraph, processedNavigation) { + const lcp = processedNavigation.timestamps.largestContentfulPaint; + if (!lcp) { + throw new LanternError("NO_LCP"); + } + return FirstContentfulPaint.getFirstPaintBasedGraph(dependencyGraph, { + cutoffTimestamp: lcp, + treatNodeAsRenderBlocking: _LargestContentfulPaint.isNotLowPriorityImageNode + }); + } + static getPessimisticGraph(dependencyGraph, processedNavigation) { + const lcp = processedNavigation.timestamps.largestContentfulPaint; + if (!lcp) { + throw new LanternError("NO_LCP"); + } + return FirstContentfulPaint.getFirstPaintBasedGraph(dependencyGraph, { + cutoffTimestamp: lcp, + treatNodeAsRenderBlocking: /* @__PURE__ */ __name((_) => true, "treatNodeAsRenderBlocking"), + // For pessimistic LCP we'll include *all* layout nodes + additionalCpuNodesToTreatAsRenderBlocking: /* @__PURE__ */ __name((node) => node.didPerformLayout(), "additionalCpuNodesToTreatAsRenderBlocking") + }); + } + static getEstimateFromSimulation(simulationResult) { + const nodeTimesNotOffscreenImages = Array.from(simulationResult.nodeTimings.entries()).filter((entry) => _LargestContentfulPaint.isNotLowPriorityImageNode(entry[0])).map((entry) => entry[1].endTime); + return { + timeInMs: Math.max(...nodeTimesNotOffscreenImages), + nodeTimings: simulationResult.nodeTimings + }; + } + static compute(data31, extras) { + const fcpResult = extras?.fcpResult; + if (!fcpResult) { + throw new LanternError("FCP is required to calculate the LCP metric"); + } + const metricResult = super.compute(data31, extras); + metricResult.timing = Math.max(metricResult.timing, fcpResult.timing); + return metricResult; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/MaxPotentialFID.js +var MaxPotentialFID; +var init_MaxPotentialFID = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/MaxPotentialFID.js"() { + init_process_global(); + init_core(); + init_graph(); + init_Metric(); + MaxPotentialFID = class _MaxPotentialFID extends Metric { + static { + __name(this, "MaxPotentialFID"); + } + static get coefficients() { + return { + intercept: 0, + optimistic: 0.5, + pessimistic: 0.5 + }; + } + static getOptimisticGraph(dependencyGraph) { + return dependencyGraph; + } + static getPessimisticGraph(dependencyGraph) { + return dependencyGraph; + } + static getEstimateFromSimulation(simulation, extras) { + if (!extras.fcpResult) { + throw new LanternError("missing fcpResult"); + } + const fcpTimeInMs = extras.optimistic ? extras.fcpResult.pessimisticEstimate.timeInMs : extras.fcpResult.optimisticEstimate.timeInMs; + const timings = _MaxPotentialFID.getTimingsAfterFCP(simulation.nodeTimings, fcpTimeInMs); + return { + timeInMs: Math.max(...timings.map((timing) => timing.duration), 16), + nodeTimings: simulation.nodeTimings + }; + } + static compute(data31, extras) { + const fcpResult = extras?.fcpResult; + if (!fcpResult) { + throw new LanternError("FCP is required to calculate the Max Potential FID metric"); + } + return super.compute(data31, extras); + } + static getTimingsAfterFCP(nodeTimings, fcpTimeInMs) { + return Array.from(nodeTimings.entries()).filter(([node, timing]) => node.type === BaseNode.types.CPU && timing.endTime > fcpTimeInMs).map(([_, timing]) => timing); + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/SpeedIndex.js +var mobileSlow4GRtt, SpeedIndex; +var init_SpeedIndex = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/SpeedIndex.js"() { + init_process_global(); + init_core(); + init_graph(); + init_Metric(); + mobileSlow4GRtt = 150; + SpeedIndex = class _SpeedIndex extends Metric { + static { + __name(this, "SpeedIndex"); + } + static get coefficients() { + return { + // Note that the optimistic estimate is based on the real observed speed index rather than a + // real lantern graph (and the final estimate will be Math.max(FCP, Speed Index)). + intercept: 0, + optimistic: 1.4, + pessimistic: 0.4 + }; + } + static getScaledCoefficients(rttMs) { + const defaultCoefficients = this.coefficients; + const defaultRttExcess = mobileSlow4GRtt - 30; + const multiplier = Math.max((rttMs - 30) / defaultRttExcess, 0); + return { + intercept: defaultCoefficients.intercept * multiplier, + optimistic: 0.5 + (defaultCoefficients.optimistic - 0.5) * multiplier, + pessimistic: 0.5 + (defaultCoefficients.pessimistic - 0.5) * multiplier + }; + } + static getOptimisticGraph(dependencyGraph) { + return dependencyGraph; + } + static getPessimisticGraph(dependencyGraph) { + return dependencyGraph; + } + static getEstimateFromSimulation(simulationResult, extras) { + if (!extras.fcpResult) { + throw new LanternError("missing fcpResult"); + } + if (extras.observedSpeedIndex === void 0) { + throw new LanternError("missing observedSpeedIndex"); + } + const fcpTimeInMs = extras.fcpResult.pessimisticEstimate.timeInMs; + const estimate = extras.optimistic ? extras.observedSpeedIndex : _SpeedIndex.computeLayoutBasedSpeedIndex(simulationResult.nodeTimings, fcpTimeInMs); + return { + timeInMs: estimate, + nodeTimings: simulationResult.nodeTimings + }; + } + static compute(data31, extras) { + const fcpResult = extras?.fcpResult; + if (!fcpResult) { + throw new LanternError("FCP is required to calculate the SpeedIndex metric"); + } + const metricResult = super.compute(data31, extras); + metricResult.timing = Math.max(metricResult.timing, fcpResult.timing); + return metricResult; + } + /** + * Approximate speed index using layout events from the simulated node timings. + * The layout-based speed index is the weighted average of the endTime of CPU nodes that contained + * a 'Layout' task. log(duration) is used as the weight to stand for "significance" to the page. + * + * If no layout events can be found or the endTime of a CPU task is too early, FCP is used instead. + * + * This approach was determined after evaluating the accuracy/complexity tradeoff of many + * different methods. Read more in the evaluation doc. + * + * @see https://docs.google.com/document/d/1qJWXwxoyVLVadezIp_Tgdk867G3tDNkkVRvUJSH3K1E/edit# + */ + static computeLayoutBasedSpeedIndex(nodeTimings, fcpTimeInMs) { + const layoutWeights = []; + for (const [node, timing] of nodeTimings.entries()) { + if (node.type !== BaseNode.types.CPU) { + continue; + } + if (node.childEvents.some((x) => x.name === "Layout")) { + const timingWeight = Math.max(Math.log2(timing.endTime - timing.startTime), 0); + layoutWeights.push({ time: timing.endTime, weight: timingWeight }); + } + } + const totalWeightedTime = layoutWeights.map((evt) => evt.weight * Math.max(evt.time, fcpTimeInMs)).reduce((a, b) => a + b, 0); + const totalWeight = layoutWeights.map((evt) => evt.weight).reduce((a, b) => a + b, 0); + if (!totalWeight) { + return fcpTimeInMs; + } + return totalWeightedTime / totalWeight; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/TBTUtils.js +var TBTUtils_exports = {}; +__export(TBTUtils_exports, { + BLOCKING_TIME_THRESHOLD: () => BLOCKING_TIME_THRESHOLD, + calculateSumOfBlockingTime: () => calculateSumOfBlockingTime, + calculateTbtImpactForEvent: () => calculateTbtImpactForEvent +}); +function calculateTbtImpactForEvent(event, startTimeMs, endTimeMs, topLevelEvent) { + let threshold = BLOCKING_TIME_THRESHOLD; + if (topLevelEvent) { + threshold *= event.duration / topLevelEvent.duration; + } + if (event.duration < threshold) { + return 0; + } + if (event.end < startTimeMs) { + return 0; + } + if (event.start > endTimeMs) { + return 0; + } + const clippedStart = Math.max(event.start, startTimeMs); + const clippedEnd = Math.min(event.end, endTimeMs); + const clippedDuration = clippedEnd - clippedStart; + if (clippedDuration < threshold) { + return 0; + } + return clippedDuration - threshold; +} +function calculateSumOfBlockingTime(topLevelEvents, startTimeMs, endTimeMs) { + if (endTimeMs <= startTimeMs) { + return 0; + } + let sumBlockingTime = 0; + for (const event of topLevelEvents) { + sumBlockingTime += calculateTbtImpactForEvent(event, startTimeMs, endTimeMs); + } + return sumBlockingTime; +} +var BLOCKING_TIME_THRESHOLD; +var init_TBTUtils = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/TBTUtils.js"() { + init_process_global(); + BLOCKING_TIME_THRESHOLD = 50; + __name(calculateTbtImpactForEvent, "calculateTbtImpactForEvent"); + __name(calculateSumOfBlockingTime, "calculateSumOfBlockingTime"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/TotalBlockingTime.js +var TotalBlockingTime; +var init_TotalBlockingTime = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/TotalBlockingTime.js"() { + init_process_global(); + init_core(); + init_graph(); + init_Metric(); + init_TBTUtils(); + TotalBlockingTime = class _TotalBlockingTime extends Metric { + static { + __name(this, "TotalBlockingTime"); + } + static get coefficients() { + return { + intercept: 0, + optimistic: 0.5, + pessimistic: 0.5 + }; + } + static getOptimisticGraph(dependencyGraph) { + return dependencyGraph; + } + static getPessimisticGraph(dependencyGraph) { + return dependencyGraph; + } + static getEstimateFromSimulation(simulation, extras) { + if (!extras.fcpResult) { + throw new LanternError("missing fcpResult"); + } + if (!extras.interactiveResult) { + throw new LanternError("missing interactiveResult"); + } + const fcpTimeInMs = extras.optimistic ? extras.fcpResult.pessimisticEstimate.timeInMs : extras.fcpResult.optimisticEstimate.timeInMs; + const interactiveTimeMs = extras.optimistic ? extras.interactiveResult.optimisticEstimate.timeInMs : extras.interactiveResult.pessimisticEstimate.timeInMs; + const minDurationMs = BLOCKING_TIME_THRESHOLD; + const events = _TotalBlockingTime.getTopLevelEvents(simulation.nodeTimings, minDurationMs); + return { + timeInMs: calculateSumOfBlockingTime(events, fcpTimeInMs, interactiveTimeMs), + nodeTimings: simulation.nodeTimings + }; + } + static compute(data31, extras) { + const fcpResult = extras?.fcpResult; + if (!fcpResult) { + throw new LanternError("FCP is required to calculate the TBT metric"); + } + const interactiveResult = extras?.fcpResult; + if (!interactiveResult) { + throw new LanternError("Interactive is required to calculate the TBT metric"); + } + return super.compute(data31, extras); + } + static getTopLevelEvents(nodeTimings, minDurationMs) { + const events = []; + for (const [node, timing] of nodeTimings.entries()) { + if (node.type !== BaseNode.types.CPU) { + continue; + } + if (timing.duration < minDurationMs) { + continue; + } + events.push({ + start: timing.startTime, + end: timing.endTime, + duration: timing.duration + }); + } + return events; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/metrics.js +var metrics_exports = {}; +__export(metrics_exports, { + FirstContentfulPaint: () => FirstContentfulPaint, + Interactive: () => Interactive, + LargestContentfulPaint: () => LargestContentfulPaint, + MaxPotentialFID: () => MaxPotentialFID, + Metric: () => Metric, + SpeedIndex: () => SpeedIndex, + TBTUtils: () => TBTUtils_exports, + TotalBlockingTime: () => TotalBlockingTime +}); +var init_metrics = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/metrics.js"() { + init_process_global(); + init_FirstContentfulPaint(); + init_Interactive(); + init_LargestContentfulPaint(); + init_MaxPotentialFID(); + init_Metric(); + init_SpeedIndex(); + init_TotalBlockingTime(); + init_TBTUtils(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/TCPConnection.js +var INITIAL_CONGESTION_WINDOW, TCP_SEGMENT_SIZE, TCPConnection; +var init_TCPConnection = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/TCPConnection.js"() { + init_process_global(); + INITIAL_CONGESTION_WINDOW = 10; + TCP_SEGMENT_SIZE = 1460; + TCPConnection = class _TCPConnection { + static { + __name(this, "TCPConnection"); + } + warmed; + ssl; + h2; + rtt; + throughput; + serverLatency; + _congestionWindow; + h2OverflowBytesDownloaded; + constructor(rtt, throughput, serverLatency = 0, ssl = true, h2 = false) { + this.warmed = false; + this.ssl = ssl; + this.h2 = h2; + this.rtt = rtt; + this.throughput = throughput; + this.serverLatency = serverLatency; + this._congestionWindow = INITIAL_CONGESTION_WINDOW; + this.h2OverflowBytesDownloaded = 0; + } + static maximumSaturatedConnections(rtt, availableThroughput) { + const roundTripsPerSecond = 1e3 / rtt; + const bytesPerRoundTrip = TCP_SEGMENT_SIZE; + const bytesPerSecond = roundTripsPerSecond * bytesPerRoundTrip; + const minimumThroughputRequiredPerRequest = bytesPerSecond * 8; + return Math.floor(availableThroughput / minimumThroughputRequiredPerRequest); + } + computeMaximumCongestionWindowInSegments() { + const bytesPerSecond = this.throughput / 8; + const secondsPerRoundTrip = this.rtt / 1e3; + const bytesPerRoundTrip = bytesPerSecond * secondsPerRoundTrip; + return Math.floor(bytesPerRoundTrip / TCP_SEGMENT_SIZE); + } + setThroughput(throughput) { + this.throughput = throughput; + } + setCongestionWindow(congestion) { + this._congestionWindow = congestion; + } + setWarmed(warmed) { + this.warmed = warmed; + } + isH2() { + return this.h2; + } + get congestionWindow() { + return this._congestionWindow; + } + /** + * Sets the number of excess bytes that are available to this connection on future downloads, only + * applies to H2 connections. + */ + setH2OverflowBytesDownloaded(bytes) { + if (!this.h2) { + return; + } + this.h2OverflowBytesDownloaded = bytes; + } + clone() { + return Object.assign(new _TCPConnection(this.rtt, this.throughput), this); + } + /** + * Simulates a network download of a particular number of bytes over an optional maximum amount of time + * and returns information about the ending state. + * + * See https://hpbn.co/building-blocks-of-tcp/#three-way-handshake and + * https://hpbn.co/transport-layer-security-tls/#tls-handshake for details. + */ + simulateDownloadUntil(bytesToDownload, options) { + const { timeAlreadyElapsed = 0, maximumTimeToElapse = Infinity, dnsResolutionTime = 0 } = options || {}; + if (this.warmed && this.h2) { + bytesToDownload -= this.h2OverflowBytesDownloaded; + } + const twoWayLatency = this.rtt; + const oneWayLatency = twoWayLatency / 2; + const maximumCongestionWindow = this.computeMaximumCongestionWindowInSegments(); + let handshakeAndRequest = oneWayLatency; + if (!this.warmed) { + handshakeAndRequest = // DNS lookup + dnsResolutionTime + // SYN + oneWayLatency + // SYN ACK + oneWayLatency + // ACK + initial request + oneWayLatency + // ClientHello/ServerHello assuming TLS False Start is enabled (https://istlsfastyet.com/#server-performance). + (this.ssl ? twoWayLatency : 0); + } + let roundTrips = Math.ceil(handshakeAndRequest / twoWayLatency); + let timeToFirstByte = handshakeAndRequest + this.serverLatency + oneWayLatency; + if (this.warmed && this.h2) { + timeToFirstByte = 0; + } + const timeElapsedForTTFB = Math.max(timeToFirstByte - timeAlreadyElapsed, 0); + const maximumDownloadTimeToElapse = maximumTimeToElapse - timeElapsedForTTFB; + let congestionWindow = Math.min(this._congestionWindow, maximumCongestionWindow); + let totalBytesDownloaded = 0; + if (timeElapsedForTTFB > 0) { + totalBytesDownloaded = congestionWindow * TCP_SEGMENT_SIZE; + } else { + roundTrips = 0; + } + let downloadTimeElapsed = 0; + let bytesRemaining = bytesToDownload - totalBytesDownloaded; + while (bytesRemaining > 0 && downloadTimeElapsed <= maximumDownloadTimeToElapse) { + roundTrips++; + downloadTimeElapsed += twoWayLatency; + congestionWindow = Math.max(Math.min(maximumCongestionWindow, congestionWindow * 2), 1); + const bytesDownloadedInWindow = congestionWindow * TCP_SEGMENT_SIZE; + totalBytesDownloaded += bytesDownloadedInWindow; + bytesRemaining -= bytesDownloadedInWindow; + } + const timeElapsed = timeElapsedForTTFB + downloadTimeElapsed; + const extraBytesDownloaded = this.h2 ? Math.max(totalBytesDownloaded - bytesToDownload, 0) : 0; + const bytesDownloaded = Math.max(Math.min(totalBytesDownloaded, bytesToDownload), 0); + let connectionTiming; + if (!this.warmed) { + connectionTiming = { + dnsResolutionTime, + connectionTime: handshakeAndRequest - dnsResolutionTime, + sslTime: this.ssl ? twoWayLatency : void 0, + timeToFirstByte + }; + } else if (this.h2) { + connectionTiming = { + timeToFirstByte + }; + } else { + connectionTiming = { + connectionTime: handshakeAndRequest, + timeToFirstByte + }; + } + return { + roundTrips, + timeElapsed, + bytesDownloaded, + extraBytesDownloaded, + congestionWindow, + connectionTiming + }; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/ConnectionPool.js +var DEFAULT_SERVER_RESPONSE_TIME, TLS_SCHEMES, CONNECTIONS_PER_ORIGIN, ConnectionPool; +var init_ConnectionPool = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/ConnectionPool.js"() { + init_process_global(); + init_core(); + init_TCPConnection(); + DEFAULT_SERVER_RESPONSE_TIME = 30; + TLS_SCHEMES = ["https", "wss"]; + CONNECTIONS_PER_ORIGIN = 6; + ConnectionPool = class { + static { + __name(this, "ConnectionPool"); + } + options; + records; + connectionsByOrigin; + connectionsByRequest; + _connectionsInUse; + connectionReusedByRequestId; + constructor(records, options) { + this.options = options; + this.records = records; + this.connectionsByOrigin = /* @__PURE__ */ new Map(); + this.connectionsByRequest = /* @__PURE__ */ new Map(); + this._connectionsInUse = /* @__PURE__ */ new Set(); + this.connectionReusedByRequestId = NetworkAnalyzer.estimateIfConnectionWasReused(records, { + forceCoarseEstimates: true + }); + this.initializeConnections(); + } + connectionsInUse() { + return Array.from(this._connectionsInUse); + } + initializeConnections() { + const connectionReused = this.connectionReusedByRequestId; + const additionalRttByOrigin = this.options.additionalRttByOrigin; + const serverResponseTimeByOrigin = this.options.serverResponseTimeByOrigin; + const recordsByOrigin = NetworkAnalyzer.groupByOrigin(this.records); + for (const [origin, requests] of recordsByOrigin.entries()) { + const connections = []; + const additionalRtt = additionalRttByOrigin.get(origin) || 0; + const responseTime = serverResponseTimeByOrigin.get(origin) || DEFAULT_SERVER_RESPONSE_TIME; + for (const request of requests) { + if (connectionReused.get(request.requestId)) { + continue; + } + const isTLS = TLS_SCHEMES.includes(request.parsedURL.scheme); + const isH2 = request.protocol === "h2"; + const connection = new TCPConnection(this.options.rtt + additionalRtt, this.options.throughput, responseTime, isTLS, isH2); + connections.push(connection); + } + if (!connections.length) { + throw new LanternError(`Could not find a connection for origin: ${origin}`); + } + const minConnections = connections[0].isH2() ? 1 : CONNECTIONS_PER_ORIGIN; + while (connections.length < minConnections) { + connections.push(connections[0].clone()); + } + this.connectionsByOrigin.set(origin, connections); + } + } + findAvailableConnectionWithLargestCongestionWindow(connections) { + let maxConnection = null; + for (let i = 0; i < connections.length; i++) { + const connection = connections[i]; + if (this._connectionsInUse.has(connection)) { + continue; + } + const currentMax = maxConnection?.congestionWindow || -Infinity; + if (connection.congestionWindow > currentMax) { + maxConnection = connection; + } + } + return maxConnection; + } + /** + * This method finds an available connection to the origin specified by the network request or null + * if no connection was available. If returned, connection will not be available for other network + * records until release is called. + */ + acquire(request) { + if (this.connectionsByRequest.has(request)) { + throw new LanternError("Record already has a connection"); + } + const origin = request.parsedURL.securityOrigin; + const connections = this.connectionsByOrigin.get(origin) || []; + const connectionToUse = this.findAvailableConnectionWithLargestCongestionWindow(connections); + if (!connectionToUse) { + return null; + } + this._connectionsInUse.add(connectionToUse); + this.connectionsByRequest.set(request, connectionToUse); + return connectionToUse; + } + /** + * Return the connection currently being used to fetch a request. If no connection + * currently being used for this request, an error will be thrown. + */ + acquireActiveConnectionFromRequest(request) { + const activeConnection = this.connectionsByRequest.get(request); + if (!activeConnection) { + throw new LanternError("Could not find an active connection for request"); + } + return activeConnection; + } + release(request) { + const connection = this.connectionsByRequest.get(request); + this.connectionsByRequest.delete(request); + if (connection) { + this._connectionsInUse.delete(connection); + } + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Constants.js +var DEVTOOLS_RTT_ADJUSTMENT_FACTOR, DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR, throttling, Constants; +var init_Constants = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Constants.js"() { + init_process_global(); + DEVTOOLS_RTT_ADJUSTMENT_FACTOR = 3.75; + DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR = 0.9; + throttling = { + DEVTOOLS_RTT_ADJUSTMENT_FACTOR, + DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR, + // These values align with WebPageTest's definition of "Fast 3G" + // But offer similar characteristics to roughly the 75th percentile of 4G connections. + mobileSlow4G: { + rttMs: 150, + throughputKbps: 1.6 * 1024, + requestLatencyMs: 150 * DEVTOOLS_RTT_ADJUSTMENT_FACTOR, + downloadThroughputKbps: 1.6 * 1024 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR, + uploadThroughputKbps: 750 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR, + cpuSlowdownMultiplier: 4 + }, + // These values partially align with WebPageTest's definition of "Regular 3G". + // These values are meant to roughly align with Chrome UX report's 3G definition which are based + // on HTTP RTT of 300-1400ms and downlink throughput of <700kbps. + mobileRegular3G: { + rttMs: 300, + throughputKbps: 700, + requestLatencyMs: 300 * DEVTOOLS_RTT_ADJUSTMENT_FACTOR, + downloadThroughputKbps: 700 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR, + uploadThroughputKbps: 700 * DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR, + cpuSlowdownMultiplier: 4 + }, + // Using a "broadband" connection type + // Corresponds to "Dense 4G 25th percentile" in https://docs.google.com/document/d/1Ft1Bnq9-t4jK5egLSOc28IL4TvR-Tt0se_1faTA4KTY/edit#heading=h.bb7nfy2x9e5v + desktopDense4G: { + rttMs: 40, + throughputKbps: 10 * 1024, + cpuSlowdownMultiplier: 1, + requestLatencyMs: 0, + // 0 means unset + downloadThroughputKbps: 0, + uploadThroughputKbps: 0 + } + }; + Constants = { throttling }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/DNSCache.js +var DNS_RESOLUTION_RTT_MULTIPLIER, DNSCache; +var init_DNSCache = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/DNSCache.js"() { + init_process_global(); + DNS_RESOLUTION_RTT_MULTIPLIER = 2; + DNSCache = class _DNSCache { + static { + __name(this, "DNSCache"); + } + static rttMultiplier = DNS_RESOLUTION_RTT_MULTIPLIER; + rtt; + resolvedDomainNames; + constructor({ rtt }) { + this.rtt = rtt; + this.resolvedDomainNames = /* @__PURE__ */ new Map(); + } + getTimeUntilResolution(request, options) { + const { requestedAt = 0, shouldUpdateCache = false } = options || {}; + const domain = request.parsedURL.host; + const cacheEntry = this.resolvedDomainNames.get(domain); + let timeUntilResolved = this.rtt * _DNSCache.rttMultiplier; + if (cacheEntry) { + const timeUntilCachedIsResolved = Math.max(cacheEntry.resolvedAt - requestedAt, 0); + timeUntilResolved = Math.min(timeUntilCachedIsResolved, timeUntilResolved); + } + const resolvedAt = requestedAt + timeUntilResolved; + if (shouldUpdateCache) { + this.updateCacheResolvedAtIfNeeded(request, resolvedAt); + } + return timeUntilResolved; + } + updateCacheResolvedAtIfNeeded(request, resolvedAt) { + const domain = request.parsedURL.host; + const cacheEntry = this.resolvedDomainNames.get(domain) || { resolvedAt }; + cacheEntry.resolvedAt = Math.min(cacheEntry.resolvedAt, resolvedAt); + this.resolvedDomainNames.set(domain, cacheEntry); + } + /** + * Forcefully sets the DNS resolution time for a request. + * Useful for testing and alternate execution simulations. + */ + setResolvedAt(domain, resolvedAt) { + this.resolvedDomainNames.set(domain, { resolvedAt }); + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/SimulationTimingMap.js +var SimulatorTimingMap; +var init_SimulationTimingMap = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/SimulationTimingMap.js"() { + init_process_global(); + init_core(); + init_graph(); + SimulatorTimingMap = class { + static { + __name(this, "SimulatorTimingMap"); + } + nodeTimings; + constructor() { + this.nodeTimings = /* @__PURE__ */ new Map(); + } + getNodes() { + return Array.from(this.nodeTimings.keys()); + } + setReadyToStart(node, values) { + this.nodeTimings.set(node, values); + } + setInProgress(node, values) { + const nodeTiming = { + ...this.getQueued(node), + startTime: values.startTime, + timeElapsed: 0 + }; + this.nodeTimings.set(node, node.type === BaseNode.types.NETWORK ? { ...nodeTiming, timeElapsedOvershoot: 0, bytesDownloaded: 0 } : nodeTiming); + } + setCompleted(node, values) { + const nodeTiming = { + ...this.getInProgress(node), + endTime: values.endTime, + connectionTiming: values.connectionTiming + }; + this.nodeTimings.set(node, nodeTiming); + } + setCpu(node, values) { + const nodeTiming = { + ...this.getCpuStarted(node), + timeElapsed: values.timeElapsed + }; + this.nodeTimings.set(node, nodeTiming); + } + setCpuEstimated(node, values) { + const nodeTiming = { + ...this.getCpuStarted(node), + estimatedTimeElapsed: values.estimatedTimeElapsed + }; + this.nodeTimings.set(node, nodeTiming); + } + setNetwork(node, values) { + const nodeTiming = { + ...this.getNetworkStarted(node), + timeElapsed: values.timeElapsed, + timeElapsedOvershoot: values.timeElapsedOvershoot, + bytesDownloaded: values.bytesDownloaded + }; + this.nodeTimings.set(node, nodeTiming); + } + setNetworkEstimated(node, values) { + const nodeTiming = { + ...this.getNetworkStarted(node), + estimatedTimeElapsed: values.estimatedTimeElapsed + }; + this.nodeTimings.set(node, nodeTiming); + } + getQueued(node) { + const timing = this.nodeTimings.get(node); + if (!timing) { + throw new LanternError(`Node ${node.id} not yet queued`); + } + return timing; + } + getCpuStarted(node) { + const timing = this.nodeTimings.get(node); + if (!timing) { + throw new LanternError(`Node ${node.id} not yet queued`); + } + if (!("startTime" in timing)) { + throw new LanternError(`Node ${node.id} not yet started`); + } + if ("bytesDownloaded" in timing) { + throw new LanternError(`Node ${node.id} timing not valid`); + } + return timing; + } + getNetworkStarted(node) { + const timing = this.nodeTimings.get(node); + if (!timing) { + throw new LanternError(`Node ${node.id} not yet queued`); + } + if (!("startTime" in timing)) { + throw new LanternError(`Node ${node.id} not yet started`); + } + if (!("bytesDownloaded" in timing)) { + throw new LanternError(`Node ${node.id} timing not valid`); + } + return timing; + } + getInProgress(node) { + const timing = this.nodeTimings.get(node); + if (!timing) { + throw new LanternError(`Node ${node.id} not yet queued`); + } + if (!("startTime" in timing)) { + throw new LanternError(`Node ${node.id} not yet started`); + } + if (!("estimatedTimeElapsed" in timing)) { + throw new LanternError(`Node ${node.id} not yet in progress`); + } + return timing; + } + getCompleted(node) { + const timing = this.nodeTimings.get(node); + if (!timing) { + throw new LanternError(`Node ${node.id} not yet queued`); + } + if (!("startTime" in timing)) { + throw new LanternError(`Node ${node.id} not yet started`); + } + if (!("estimatedTimeElapsed" in timing)) { + throw new LanternError(`Node ${node.id} not yet in progress`); + } + if (!("endTime" in timing)) { + throw new LanternError(`Node ${node.id} not yet completed`); + } + return timing; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Simulator.js +var defaultThrottling, DEFAULT_MAXIMUM_CONCURRENT_REQUESTS, DEFAULT_LAYOUT_TASK_MULTIPLIER, DEFAULT_MAXIMUM_CPU_TASK_DURATION, NodeState, PriorityStartTimePenalty, ALL_SIMULATION_NODE_TIMINGS, Simulator; +var init_Simulator = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Simulator.js"() { + init_process_global(); + init_core(); + init_graph(); + init_ConnectionPool(); + init_Constants(); + init_DNSCache(); + init_SimulationTimingMap(); + init_TCPConnection(); + defaultThrottling = Constants.throttling.mobileSlow4G; + DEFAULT_MAXIMUM_CONCURRENT_REQUESTS = 10; + DEFAULT_LAYOUT_TASK_MULTIPLIER = 0.5; + DEFAULT_MAXIMUM_CPU_TASK_DURATION = 1e4; + NodeState = { + NotReadyToStart: 0, + ReadyToStart: 1, + InProgress: 2, + Complete: 3 + }; + PriorityStartTimePenalty = { + VeryHigh: 0, + High: 0.25, + Medium: 0.5, + Low: 1, + VeryLow: 2 + }; + ALL_SIMULATION_NODE_TIMINGS = /* @__PURE__ */ new Map(); + Simulator = class _Simulator { + static { + __name(this, "Simulator"); + } + static createSimulator(settings) { + const { throttlingMethod, throttling: throttling3, precomputedLanternData, networkAnalysis } = settings; + const options = { + additionalRttByOrigin: networkAnalysis.additionalRttByOrigin, + serverResponseTimeByOrigin: networkAnalysis.serverResponseTimeByOrigin, + observedThroughput: networkAnalysis.throughput + }; + if (precomputedLanternData) { + options.additionalRttByOrigin = new Map(Object.entries(precomputedLanternData.additionalRttByOrigin)); + options.serverResponseTimeByOrigin = new Map(Object.entries(precomputedLanternData.serverResponseTimeByOrigin)); + } + switch (throttlingMethod) { + case "provided": + options.rtt = networkAnalysis.rtt; + options.throughput = networkAnalysis.throughput; + options.cpuSlowdownMultiplier = 1; + options.layoutTaskMultiplier = 1; + break; + case "devtools": + if (throttling3) { + options.rtt = throttling3.requestLatencyMs / Constants.throttling.DEVTOOLS_RTT_ADJUSTMENT_FACTOR; + options.throughput = throttling3.downloadThroughputKbps * 1024 / Constants.throttling.DEVTOOLS_THROUGHPUT_ADJUSTMENT_FACTOR; + } + options.cpuSlowdownMultiplier = 1; + options.layoutTaskMultiplier = 1; + break; + case "simulate": + if (throttling3) { + options.rtt = throttling3.rttMs; + options.throughput = throttling3.throughputKbps * 1024; + options.cpuSlowdownMultiplier = throttling3.cpuSlowdownMultiplier; + } + break; + default: + break; + } + return new _Simulator(options); + } + options; + _rtt; + throughput; + maximumConcurrentRequests; + cpuSlowdownMultiplier; + layoutTaskMultiplier; + cachedNodeListByStartPosition; + nodeTimings; + numberInProgressByType; + nodes; + dns; + connectionPool; + constructor(options) { + this.options = Object.assign({ + rtt: defaultThrottling.rttMs, + throughput: defaultThrottling.throughputKbps * 1024, + maximumConcurrentRequests: DEFAULT_MAXIMUM_CONCURRENT_REQUESTS, + cpuSlowdownMultiplier: defaultThrottling.cpuSlowdownMultiplier, + layoutTaskMultiplier: DEFAULT_LAYOUT_TASK_MULTIPLIER, + additionalRttByOrigin: /* @__PURE__ */ new Map(), + serverResponseTimeByOrigin: /* @__PURE__ */ new Map() + }, options); + this._rtt = this.options.rtt; + this.throughput = this.options.throughput; + this.maximumConcurrentRequests = Math.max(Math.min(TCPConnection.maximumSaturatedConnections(this._rtt, this.throughput), this.options.maximumConcurrentRequests), 1); + this.cpuSlowdownMultiplier = this.options.cpuSlowdownMultiplier; + this.layoutTaskMultiplier = this.cpuSlowdownMultiplier * this.options.layoutTaskMultiplier; + this.cachedNodeListByStartPosition = []; + this.nodeTimings = new SimulatorTimingMap(); + this.numberInProgressByType = /* @__PURE__ */ new Map(); + this.nodes = {}; + this.dns = new DNSCache({ rtt: this._rtt }); + this.connectionPool = null; + if (!Number.isFinite(this._rtt)) { + throw new LanternError(`Invalid rtt ${this._rtt}`); + } + if (!Number.isFinite(this.throughput)) { + throw new LanternError(`Invalid throughput ${this.throughput}`); + } + } + get rtt() { + return this._rtt; + } + initializeConnectionPool(graph2) { + const records = []; + graph2.getRootNode().traverse((node) => { + if (node.type === BaseNode.types.NETWORK) { + records.push(node.request); + } + }); + this.connectionPool = new ConnectionPool(records, this.options); + } + /** + * Initializes the various state data structures such _nodeTimings and the _node Sets by state. + */ + initializeAuxiliaryData() { + this.nodeTimings = new SimulatorTimingMap(); + this.numberInProgressByType = /* @__PURE__ */ new Map(); + this.nodes = {}; + this.cachedNodeListByStartPosition = []; + for (const state of Object.values(NodeState)) { + this.nodes[state] = /* @__PURE__ */ new Set(); + } + } + numberInProgress(type) { + return this.numberInProgressByType.get(type) || 0; + } + markNodeAsReadyToStart(node, queuedTime) { + const nodeStartPosition = _Simulator.computeNodeStartPosition(node); + const firstNodeIndexWithGreaterStartPosition = this.cachedNodeListByStartPosition.findIndex((candidate) => _Simulator.computeNodeStartPosition(candidate) > nodeStartPosition); + const insertionIndex = firstNodeIndexWithGreaterStartPosition === -1 ? this.cachedNodeListByStartPosition.length : firstNodeIndexWithGreaterStartPosition; + this.cachedNodeListByStartPosition.splice(insertionIndex, 0, node); + this.nodes[NodeState.ReadyToStart].add(node); + this.nodes[NodeState.NotReadyToStart].delete(node); + this.nodeTimings.setReadyToStart(node, { queuedTime }); + } + markNodeAsInProgress(node, startTime) { + const indexOfNodeToStart = this.cachedNodeListByStartPosition.indexOf(node); + this.cachedNodeListByStartPosition.splice(indexOfNodeToStart, 1); + this.nodes[NodeState.InProgress].add(node); + this.nodes[NodeState.ReadyToStart].delete(node); + this.numberInProgressByType.set(node.type, this.numberInProgress(node.type) + 1); + this.nodeTimings.setInProgress(node, { startTime }); + } + markNodeAsComplete(node, endTime, connectionTiming) { + this.nodes[NodeState.Complete].add(node); + this.nodes[NodeState.InProgress].delete(node); + this.numberInProgressByType.set(node.type, this.numberInProgress(node.type) - 1); + this.nodeTimings.setCompleted(node, { endTime, connectionTiming }); + for (const dependent of node.getDependents()) { + const dependencies = dependent.getDependencies(); + if (dependencies.some((dep) => !this.nodes[NodeState.Complete].has(dep))) { + continue; + } + this.markNodeAsReadyToStart(dependent, endTime); + } + } + acquireConnection(request) { + return this.connectionPool.acquire(request); + } + getNodesSortedByStartPosition() { + return Array.from(this.cachedNodeListByStartPosition); + } + startNodeIfPossible(node, totalElapsedTime) { + if (node.type === BaseNode.types.CPU) { + if (this.numberInProgress(node.type) === 0) { + this.markNodeAsInProgress(node, totalElapsedTime); + } + return; + } + if (node.type !== BaseNode.types.NETWORK) { + throw new LanternError("Unsupported"); + } + if (!node.isConnectionless) { + const numberOfActiveRequests = this.numberInProgress(node.type); + if (numberOfActiveRequests >= this.maximumConcurrentRequests) { + return; + } + const connection = this.acquireConnection(node.request); + if (!connection) { + return; + } + } + this.markNodeAsInProgress(node, totalElapsedTime); + } + /** + * Updates each connection in use with the available throughput based on the number of network requests + * currently in flight. + */ + updateNetworkCapacity() { + const inFlight = this.numberInProgress(BaseNode.types.NETWORK); + if (inFlight === 0) { + return; + } + for (const connection of this.connectionPool.connectionsInUse()) { + connection.setThroughput(this.throughput / inFlight); + } + } + /** + * Estimates the number of milliseconds remaining given current conditions before the node is complete. + */ + estimateTimeRemaining(node) { + if (node.type === BaseNode.types.CPU) { + return this.estimateCPUTimeRemaining(node); + } + if (node.type === BaseNode.types.NETWORK) { + return this.estimateNetworkTimeRemaining(node); + } + throw new LanternError("Unsupported"); + } + estimateCPUTimeRemaining(cpuNode) { + const timingData = this.nodeTimings.getCpuStarted(cpuNode); + const multiplier = cpuNode.didPerformLayout() ? this.layoutTaskMultiplier : this.cpuSlowdownMultiplier; + const totalDuration = Math.min(Math.round(cpuNode.duration / 1e3 * multiplier), DEFAULT_MAXIMUM_CPU_TASK_DURATION); + const estimatedTimeElapsed = totalDuration - timingData.timeElapsed; + this.nodeTimings.setCpuEstimated(cpuNode, { estimatedTimeElapsed }); + return estimatedTimeElapsed; + } + estimateNetworkTimeRemaining(networkNode) { + const request = networkNode.request; + const timingData = this.nodeTimings.getNetworkStarted(networkNode); + let timeElapsed = 0; + if (networkNode.fromDiskCache) { + const sizeInMb = (request.resourceSize || 0) / 1024 / 1024; + timeElapsed = 8 + 20 * sizeInMb - timingData.timeElapsed; + } else if (networkNode.isNonNetworkProtocol) { + const sizeInMb = (request.resourceSize || 0) / 1024 / 1024; + timeElapsed = 2 + 10 * sizeInMb - timingData.timeElapsed; + } else { + const connection = this.connectionPool.acquireActiveConnectionFromRequest(request); + const dnsResolutionTime = this.dns.getTimeUntilResolution(request, { + requestedAt: timingData.startTime, + shouldUpdateCache: true + }); + const timeAlreadyElapsed = timingData.timeElapsed; + const calculation = connection.simulateDownloadUntil(request.transferSize - timingData.bytesDownloaded, { timeAlreadyElapsed, dnsResolutionTime, maximumTimeToElapse: Infinity }); + timeElapsed = calculation.timeElapsed; + } + const estimatedTimeElapsed = timeElapsed + timingData.timeElapsedOvershoot; + this.nodeTimings.setNetworkEstimated(networkNode, { estimatedTimeElapsed }); + return estimatedTimeElapsed; + } + /** + * Computes and returns the minimum estimated completion time of the nodes currently in progress. + */ + findNextNodeCompletionTime() { + let minimumTime = Infinity; + for (const node of this.nodes[NodeState.InProgress]) { + minimumTime = Math.min(minimumTime, this.estimateTimeRemaining(node)); + } + return minimumTime; + } + /** + * Given a time period, computes the progress toward completion that the node made during that time. + */ + updateProgressMadeInTimePeriod(node, timePeriodLength, totalElapsedTime) { + const timingData = this.nodeTimings.getInProgress(node); + const isFinished = timingData.estimatedTimeElapsed === timePeriodLength; + if (node.type === BaseNode.types.CPU || node.isConnectionless) { + if (isFinished) { + this.markNodeAsComplete(node, totalElapsedTime); + } else { + timingData.timeElapsed += timePeriodLength; + } + return; + } + if (node.type !== BaseNode.types.NETWORK) { + throw new LanternError("Unsupported"); + } + if (!("bytesDownloaded" in timingData)) { + throw new LanternError("Invalid timing data"); + } + const request = node.request; + const connection = this.connectionPool.acquireActiveConnectionFromRequest(request); + const dnsResolutionTime = this.dns.getTimeUntilResolution(request, { + requestedAt: timingData.startTime, + shouldUpdateCache: true + }); + const calculation = connection.simulateDownloadUntil(request.transferSize - timingData.bytesDownloaded, { + dnsResolutionTime, + timeAlreadyElapsed: timingData.timeElapsed, + maximumTimeToElapse: timePeriodLength - timingData.timeElapsedOvershoot + }); + connection.setCongestionWindow(calculation.congestionWindow); + connection.setH2OverflowBytesDownloaded(calculation.extraBytesDownloaded); + if (isFinished) { + connection.setWarmed(true); + this.connectionPool.release(request); + this.markNodeAsComplete(node, totalElapsedTime, calculation.connectionTiming); + } else { + timingData.timeElapsed += calculation.timeElapsed; + timingData.timeElapsedOvershoot += calculation.timeElapsed - timePeriodLength; + timingData.bytesDownloaded += calculation.bytesDownloaded; + } + } + computeFinalNodeTimings() { + const completeNodeTimingEntries = this.nodeTimings.getNodes().map((node) => { + return [node, this.nodeTimings.getCompleted(node)]; + }); + completeNodeTimingEntries.sort((a, b) => a[1].startTime - b[1].startTime); + const nodeTimingEntries = completeNodeTimingEntries.map(([node, timing]) => { + return [ + node, + { + startTime: timing.startTime, + endTime: timing.endTime, + duration: timing.endTime - timing.startTime + } + ]; + }); + return { + nodeTimings: new Map(nodeTimingEntries), + completeNodeTimings: new Map(completeNodeTimingEntries) + }; + } + getOptions() { + return this.options; + } + /** + * Estimates the time taken to process all of the graph's nodes, returns the overall time along with + * each node annotated by start/end times. + * + * Simulator/connection pool are allowed to deviate from what was + * observed in the trace/devtoolsLog and start requests as soon as they are queued (i.e. do not + * wait around for a warm connection to be available if the original request was fetched on a warm + * connection). + */ + simulate(graph2, options) { + if (BaseNode.findCycle(graph2)) { + throw new LanternError("Cannot simulate graph with cycle"); + } + options = Object.assign({ + label: void 0 + }, options); + this.dns = new DNSCache({ rtt: this._rtt }); + this.initializeConnectionPool(graph2); + this.initializeAuxiliaryData(); + const nodesNotReadyToStart = this.nodes[NodeState.NotReadyToStart]; + const nodesReadyToStart = this.nodes[NodeState.ReadyToStart]; + const nodesInProgress = this.nodes[NodeState.InProgress]; + const rootNode = graph2.getRootNode(); + rootNode.traverse((node) => nodesNotReadyToStart.add(node)); + let totalElapsedTime = 0; + let iteration = 0; + this.markNodeAsReadyToStart(rootNode, totalElapsedTime); + while (nodesReadyToStart.size || nodesInProgress.size) { + for (const node of this.getNodesSortedByStartPosition()) { + this.startNodeIfPossible(node, totalElapsedTime); + } + if (!nodesInProgress.size) { + throw new LanternError("Failed to start a node"); + } + this.updateNetworkCapacity(); + const minimumTime = this.findNextNodeCompletionTime(); + totalElapsedTime += minimumTime; + if (!Number.isFinite(minimumTime) || iteration > 1e5) { + throw new LanternError("Simulation failed, depth exceeded"); + } + iteration++; + for (const node of nodesInProgress) { + this.updateProgressMadeInTimePeriod(node, minimumTime, totalElapsedTime); + } + } + const { nodeTimings, completeNodeTimings } = this.computeFinalNodeTimings(); + ALL_SIMULATION_NODE_TIMINGS.set(options.label || "unlabeled", completeNodeTimings); + return { + timeInMs: totalElapsedTime, + nodeTimings + }; + } + computeWastedMsFromWastedBytes(wastedBytes) { + const { throughput, observedThroughput } = this.options; + const bitsPerSecond = throughput === 0 ? observedThroughput : throughput; + if (bitsPerSecond === 0) { + return 0; + } + const wastedBits = wastedBytes * 8; + const wastedMs = wastedBits / bitsPerSecond * 1e3; + return Math.round(wastedMs / 10) * 10; + } + // Used by Lighthouse asset-saver + static get allNodeTimings() { + return ALL_SIMULATION_NODE_TIMINGS; + } + /** + * We attempt to start nodes by their observed start time using the request priority as a tie breaker. + * When simulating, just because a low priority image started 5ms before a high priority image doesn't mean + * it would have happened like that when the network was slower. + */ + static computeNodeStartPosition(node) { + if (node.type === "cpu") { + return node.startTime; + } + return node.startTime + (PriorityStartTimePenalty[node.request.priority] * 1e3 * 1e3 || 0); + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/simulation.js +var simulation_exports = {}; +__export(simulation_exports, { + ConnectionPool: () => ConnectionPool, + Constants: () => Constants, + DNSCache: () => DNSCache, + Simulator: () => Simulator, + SimulatorTimingMap: () => SimulatorTimingMap, + TCPConnection: () => TCPConnection +}); +var init_simulation = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/simulation.js"() { + init_process_global(); + init_ConnectionPool(); + init_Constants(); + init_DNSCache(); + init_SimulationTimingMap(); + init_Simulator(); + init_TCPConnection(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/types/Lantern.js +var NetworkRequestTypes; +var init_Lantern = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/types/Lantern.js"() { + init_process_global(); + NetworkRequestTypes = { + XHR: "XHR", + Fetch: "Fetch", + EventSource: "EventSource", + Script: "Script", + Stylesheet: "Stylesheet", + Image: "Image", + Media: "Media", + Font: "Font", + Document: "Document", + TextTrack: "TextTrack", + WebSocket: "WebSocket", + Other: "Other", + Manifest: "Manifest", + SignedExchange: "SignedExchange", + Ping: "Ping", + Preflight: "Preflight", + CSPViolationReport: "CSPViolationReport", + Prefetch: "Prefetch", + FedCM: "FedCM" + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/types/types.js +var types_exports = {}; +__export(types_exports, { + NetworkRequestTypes: () => NetworkRequestTypes +}); +var init_types = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/types/types.js"() { + init_process_global(); + init_Lantern(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/lantern/lantern.js +var init_lantern = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/lantern/lantern.js"() { + init_process_global(); + init_core(); + init_graph(); + init_metrics(); + init_simulation(); + init_types(); + } +}); + +// node_modules/@paulirish/trace_engine/node_modules/third-party-web/lib/create-entity-finder-api.js +var require_create_entity_finder_api = __commonJS({ + "node_modules/@paulirish/trace_engine/node_modules/third-party-web/lib/create-entity-finder-api.js"(exports2, module2) { + init_process_global(); + var DOMAIN_IN_URL_REGEX = /:\/\/(\S*?)(:\d+)?(\/|$)/; + var DOMAIN_CHARACTERS = /([a-z0-9.-]+\.[a-z0-9]+|localhost)/i; + var IP_REGEX = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; + var ROOT_DOMAIN_REGEX = /[^.]+\.([^.]+|(gov|com|co|ne)\.\w{2})$/i; + function getDomainFromOriginOrURL(originOrURL) { + if (typeof originOrURL !== "string") return null; + if (originOrURL.length > 1e4 || originOrURL.startsWith("data:")) return null; + if (DOMAIN_IN_URL_REGEX.test(originOrURL)) return originOrURL.match(DOMAIN_IN_URL_REGEX)[1]; + if (DOMAIN_CHARACTERS.test(originOrURL)) return originOrURL.match(DOMAIN_CHARACTERS)[0]; + return null; + } + __name(getDomainFromOriginOrURL, "getDomainFromOriginOrURL"); + function getRootDomain(originOrURL) { + const domain = getDomainFromOriginOrURL(originOrURL); + if (!domain) return null; + if (IP_REGEX.test(domain)) return domain; + const match = domain.match(ROOT_DOMAIN_REGEX); + return match && match[0] || domain; + } + __name(getRootDomain, "getRootDomain"); + function sliceSubdomainFromDomain(domain, rootDomain) { + if (domain.length <= rootDomain.length) return domain; + return domain.split(".").slice(1).join("."); + } + __name(sliceSubdomainFromDomain, "sliceSubdomainFromDomain"); + function getEntityInDataset(entityByDomain, entityBySubDomain, entityByRootDomain, originOrURL) { + const domain = getDomainFromOriginOrURL(originOrURL); + const rootDomain = getRootDomain(domain); + if (!domain || !rootDomain) return void 0; + if (entityByDomain.has(domain)) return entityByDomain.get(domain); + for (let subdomain = domain; subdomain.length > rootDomain.length; subdomain = sliceSubdomainFromDomain(subdomain, rootDomain)) { + if (entityBySubDomain.has(subdomain)) return entityBySubDomain.get(subdomain); + } + if (entityByRootDomain.has(rootDomain)) return entityByRootDomain.get(rootDomain); + return void 0; + } + __name(getEntityInDataset, "getEntityInDataset"); + function getProductInDataset(entityByDomain, entityBySubDomain, entityByRootDomain, originOrURL) { + const entity = getEntityInDataset( + entityByDomain, + entityBySubDomain, + entityByRootDomain, + originOrURL + ); + const products = entity && entity.products; + if (!products) return void 0; + if (typeof originOrURL !== "string") return void 0; + for (const product of products) { + for (const pattern of product.urlPatterns) { + if (pattern instanceof RegExp && pattern.test(originOrURL)) return product; + if (typeof pattern === "string" && originOrURL.includes(pattern)) return product; + } + } + return void 0; + } + __name(getProductInDataset, "getProductInDataset"); + function cloneEntities(entities) { + return entities.map((entity_) => { + const entity = { + company: entity_.name, + categories: [entity_.category], + ...entity_ + }; + const products = (entity_.products || []).map((product) => ({ + company: entity.company, + category: entity.category, + categories: [entity.category], + facades: [], + ...product, + urlPatterns: (product.urlPatterns || []).map( + (s) => s.startsWith("REGEXP:") ? new RegExp(s.slice("REGEXP:".length)) : s + ) + })); + entity.products = products; + return entity; + }); + } + __name(cloneEntities, "cloneEntities"); + function createAPIFromDataset(entities_) { + const entities = cloneEntities(entities_); + const entityByDomain = /* @__PURE__ */ new Map(); + const entityByRootDomain = /* @__PURE__ */ new Map(); + const entityBySubDomain = /* @__PURE__ */ new Map(); + for (const entity of entities) { + entity.totalExecutionTime = Number(entity.totalExecutionTime) || 0; + entity.totalOccurrences = Number(entity.totalOccurrences) || 0; + entity.averageExecutionTime = entity.totalExecutionTime / entity.totalOccurrences; + for (const domain of entity.domains) { + if (entityByDomain.has(domain)) { + const duplicate = entityByDomain.get(domain); + throw new Error(`Duplicate domain ${domain} (${entity.name} and ${duplicate.name})`); + } + entityByDomain.set(domain, entity); + const rootDomain = getRootDomain(domain); + if (domain.startsWith("*.")) { + const wildcardDomain = domain.slice(2); + if (wildcardDomain === rootDomain) entityByRootDomain.set(rootDomain, entity); + else entityBySubDomain.set(wildcardDomain, entity); + } + } + } + for (const [rootDomain, entity] of entityByRootDomain.entries()) { + if (!entity) entityByRootDomain.delete(rootDomain); + } + const getEntity = getEntityInDataset.bind( + null, + entityByDomain, + entityBySubDomain, + entityByRootDomain + ); + const getProduct = getProductInDataset.bind( + null, + entityByDomain, + entityBySubDomain, + entityByRootDomain + ); + return { getEntity, getProduct, getRootDomain, entities }; + } + __name(createAPIFromDataset, "createAPIFromDataset"); + module2.exports = { createAPIFromDataset }; + } +}); + +// node_modules/@paulirish/trace_engine/node_modules/third-party-web/dist/entities.json +var require_entities = __commonJS({ + "node_modules/@paulirish/trace_engine/node_modules/third-party-web/dist/entities.json"(exports2, module2) { + module2.exports = [{ name: "Google/Doubleclick Ads", company: "Google", homepage: "https://marketingplatform.google.com/about/enterprise/", category: "ad", domains: ["adservice.google.com", "adservice.google.com.au", "adservice.google.com.sg", "adservice.google.com.br", "adservice.google.com.ua", "adservice.google.co.uk", "adservice.google.co.jp", "adservice.google.co.in", "adservice.google.co.kr", "adservice.google.co.id", "adservice.google.co.nz", "adservice.google.ie", "adservice.google.se", "adservice.google.de", "adservice.google.ca", "adservice.google.be", "adservice.google.es", "adservice.google.ch", "adservice.google.fr", "adservice.google.nl", "*.googleadservices.com", "*.googlesyndication.com", "*.googletagservices.com", "*.2mdn.net", "*.doubleclick.net"], examples: ["pagead2.googlesyndication.com", "tpc.googlesyndication.com", "ade.googlesyndication.com", "googleads.g.doubleclick.net", "googleads4.g.doubleclick.net", "securepubads.g.doubleclick.net", "pubads.g.doubleclic\ +k.net", "static.doubleclick.net", "cm.g.doubleclick.net", "bid.g.doubleclick.net", "s0.2mdn.net", "stats.g.doubleclick.net", "survey.g.doubleclick.net", "fls.doubleclick.net", "ad.doubleclick.net", "www.googleadservices.com", "https://www.googletagservices.com/tag/js/gpt.js"], totalExecutionTime: 3224311743, totalOccurrences: 1232210 }, { name: "Facebook", homepage: "https://www.facebook.com", category: "social", domains: ["*.facebook.com", "*.atlassbx.com", "*.fbsbx.com", "fbcdn-photos-e-a.akamaihd.net", "*.facebook.net", "*.fbcdn.net"], examples: ["www.facebook.com", "connect.facebook.net", "staticxx.facebook.com", "static.xx.fbcdn.net", "m.facebook.com", "an.facebook.com", "platform-lookaside.fbsbx.com"], products: [{ name: "Facebook Messenger Customer Chat", urlPatterns: ["REGEXP:connect\\.facebook\\.net\\/.*\\/sdk\\/xfbml\\.customerchat\\.js"], facades: [{ name: "React Live Chat Loader", repo: "https://github.com/calibreapp/react-live-chat-loader" }] }], totalExecutionTime: 1097107210, + totalOccurrences: 3157799 }, { name: "Instagram", homepage: "https://www.instagram.com", category: "social", domains: ["*.cdninstagram.com", "*.instagram.com"], examples: ["scontent.cdninstagram.com"], totalExecutionTime: 31988464, totalOccurrences: 20376 }, { name: "Google CDN", company: "Google", homepage: "https://developers.google.com/speed/libraries/", category: "cdn", domains: ["ajax.googleapis.com", "commondatastorage.googleapis.com", "www.gstatic.com", "ssl.gstatic.com"], totalExecutionTime: 4805631169, totalOccurrences: 3192326 }, { name: "Google Maps", company: "Google", homepage: "https://www.google.com/maps", category: "utility", domains: ["maps.google.com", "maps-api-ssl.google.com", "maps.googleapis.com", "mts.googleapis.com", "mt.googleapis.com", "mt0.googleapis.com", "mt1.googleapis.com", "mt2.googleapis.com", "mt3.googleapis.com", "khm0.googleapis.com", "khm1.googleapis.com", "khms.googleapis.com", "khms1.googleapis.com", "khms2.googleapis.com", "maps.gstatic.com"], + totalExecutionTime: 904392768, totalOccurrences: 1195850 }, { name: "Other Google APIs/SDKs", company: "Google", homepage: "https://developers.google.com/apis-explorer/#p/", category: "utility", domains: ["accounts.google.com", "apis.google.com", "calendar.google.com", "clients2.google.com", "cse.google.com", "news.google.com", "pay.google.com", "payments.google.com", "play.google.com", "smartlock.google.com", "www.google.com", "www.google.de", "www.google.co.jp", "www.google.com.au", "www.google.co.uk", "www.google.ie", "www.google.com.sg", "www.google.co.in", "www.google.com.br", "www.google.ca", "www.google.co.kr", "www.google.co.nz", "www.google.co.id", "www.google.fr", "www.google.be", "www.google.com.ua", "www.google.nl", "www.google.ru", "www.google.se", "www.googleapis.com", "imasdk.googleapis.com", "storage.googleapis.com", "translate.googleapis.com", "translate.google.com", "translate-pa.googleapis.com", "lh3.googleusercontent.com", "jnn-pa.googleapis.com", "csi.gstatic.c\ +om"], totalExecutionTime: 1158368443, totalOccurrences: 2638940 }, { name: "Firebase", homepage: "https://developers.google.com/apis-explorer/#p/", category: "utility", domains: ["firebasestorage.googleapis.com", "firestore.googleapis.com", "firebaseinstallations.googleapis.com", "firebase.googleapis.com", "firebaseremoteconfig.googleapis.com"], totalExecutionTime: 201194, totalOccurrences: 493 }, { name: "Google Analytics", company: "Google", homepage: "https://marketingplatform.google.com/about/analytics/", category: "analytics", domains: ["*.google-analytics.com", "*.urchin.com", "analytics.google.com"], examples: ["www.google-analytics.com", "ssl.google-analytics.com", "analytics.google.com/g/collect"], totalExecutionTime: 495649535, totalOccurrences: 4231882 }, { name: "Google Optimize", company: "Google", homepage: "https://marketingplatform.google.com/about/optimize/", category: "analytics", domains: ["www.googleoptimize.com"], examples: ["https://www.googleoptimize.com/optimize\ +.js?id="], totalExecutionTime: 9330261, totalOccurrences: 38797 }, { name: "Google AMP", company: "Google", homepage: "https://github.com/google/amp-client-id-library", category: "analytics", domains: ["ampcid.google.com"] }, { name: "Google Tag Manager", company: "Google", homepage: "https://marketingplatform.google.com/about/tag-manager/", category: "tag-manager", domains: ["*.googletagmanager.com"], examples: ["www.googletagmanager.com"], totalExecutionTime: 6770912735, totalOccurrences: 8124119 }, { name: "Google Fonts", company: "Google", homepage: "https://fonts.google.com/", category: "cdn", domains: ["fonts.googleapis.com", "fonts.gstatic.com"], totalExecutionTime: 53081, totalOccurrences: 220864 }, { name: "Adobe TypeKit", company: "Adobe", homepage: "https://fonts.adobe.com/", category: "cdn", domains: ["*.typekit.com", "*.typekit.net"], examples: ["use.typekit.net", "p.typekit.net"], totalExecutionTime: 78981507, totalOccurrences: 119621 }, { name: "YouTube", homepage: "http\ +s://youtube.com", category: "video", domains: ["*.youtube.com", "*.ggpht.com", "*.youtube-nocookie.com", "*.ytimg.com"], examples: ["www.youtube.com", "s.ytimg.com", "yt3.ggpht.com", "img.youtube.com", "fcmatch.youtube.com"], products: [{ name: "YouTube Embedded Player", urlPatterns: ["youtube.com/embed/"], facades: [{ name: "Lite YouTube", repo: "https://github.com/paulirish/lite-youtube-embed" }, { name: "Ngx Lite Video", repo: "https://github.com/karim-mamdouh/ngx-lite-video" }] }], totalExecutionTime: 6277579675, totalOccurrences: 977311 }, { name: "Twitter", homepage: "https://twitter.com", category: "social", domains: ["*.vine.co", "*.twimg.com", "*.twitpic.com", "platform.twitter.com", "syndication.twitter.com"], examples: ["cdn.syndication.twimg.com", "abs.twimg.com", "pbs.twimg.com"], totalExecutionTime: 804233203, totalOccurrences: 319957 }, { name: "AddThis", homepage: "https://www.addthis.com/", category: "social", domains: ["*.addthis.com", "*.addthiscdn.com", "*.addthised\ +ge.com"], examples: ["s7.addthis.com", "r.dlx.addthis.com", "su.addthis.com", "x.dlx.addthis.com"], totalExecutionTime: 23, totalOccurrences: 42 }, { name: "AddToAny", homepage: "https://www.addtoany.com/", category: "social", domains: ["*.addtoany.com"], examples: ["static.addtoany.com"], totalExecutionTime: 10606113, totalOccurrences: 66065 }, { name: "Akamai", homepage: "https://www.akamai.com/", category: "cdn", domains: ["23.62.3.183", "*.akamaitechnologies.com", "*.akamaitechnologies.fr", "*.akamai.net", "*.akamaiedge.net", "*.akamaihd.net", "*.akamaized.net", "*.edgefcs.net", "*.edgekey.net", "edgesuite.net", "*.srip.net"], totalExecutionTime: 4795669, totalOccurrences: 9820 }, { name: "Blogger", homepage: "https://www.blogger.com/", category: "hosting", domains: ["*.blogblog.com", "*.blogger.com", "*.blogspot.com", "images-blogger-opensocial.googleusercontent.com"], examples: ["1.bp.blogspot.com", "www.blogger.com"], totalExecutionTime: 58390438, totalOccurrences: 213326 }, { name: "\ +Gravatar", homepage: "https://en.gravatar.com/", category: "social", domains: ["*.gravatar.com"], examples: ["secure.gravatar.com", "www.gravatar.com"], totalExecutionTime: 9235, totalOccurrences: 43 }, { name: "Yandex Metrica", company: "Yandex", homepage: "https://metrica.yandex.com/about?", category: "analytics", domains: ["mc.yandex.ru", "mc.yandex.com", "d31j93rd8oukbv.cloudfront.net"], totalExecutionTime: 1438544698, totalOccurrences: 602136 }, { name: "Hotjar", homepage: "https://www.hotjar.com/", category: "analytics", domains: ["*.hotjar.com", "*.hotjar.io"], examples: ["script.hotjar.com", "static.hotjar.com", "in.hotjar.com", "vc.hotjar.io", "vars.hotjar.com"], totalExecutionTime: 241418055, totalOccurrences: 333356 }, { name: "Baidu Analytics", homepage: "https://tongji.baidu.com/web/welcome/login", category: "analytics", domains: ["hm.baidu.com", "hmcdn.baidu.com"], examples: ["hm.baidu.com", "hmcdn.baidu.com"], totalExecutionTime: 7739347, totalOccurrences: 32612 }, { name: "\ +Insider", homepage: "", category: "analytics", domains: ["*.useinsider.com"], examples: ["hit.api.useinsider.com"], totalExecutionTime: 2214966, totalOccurrences: 1861 }, { name: "Adobe Experience Cloud", company: "Adobe", homepage: "", category: "analytics", domains: ["*.2o7.net", "du8783wkf05yr.cloudfront.net", "*.hitbox.com", "*.imageg.net", "*.nedstat.com", "*.omtrdc.net"], examples: ["audiag.112.2o7.net", "du8783wkf05yr.cloudfront.net/NS_mbox.js"], totalExecutionTime: 2369, totalOccurrences: 38 }, { name: "Adobe Tag Manager", company: "Adobe", homepage: "https://www.adobe.com/experience-platform/", category: "tag-manager", domains: ["*.adobedtm.com", "*.demdex.net", "*.everesttech.net", "sstats.adobe.com", "hbrt.adobe.com"], examples: ["assets.adobedtm.com", "sync-tm.everesttech.net", "cm.everesttech.net"], totalExecutionTime: 34937564, totalOccurrences: 200160 }, { name: "jQuery CDN", homepage: "https://code.jquery.com/", category: "cdn", domains: ["*.jquery.com"], examples: ["co\ +de.jquery.com"], totalExecutionTime: 302334055, totalOccurrences: 724477 }, { name: "Cloudflare CDN", homepage: "https://cdnjs.com/", category: "cdn", domains: ["cdnjs.cloudflare.com", "amp.cloudflare.com"], totalExecutionTime: 337711119, totalOccurrences: 666628 }, { name: "Cloudflare", homepage: "https://www.cloudflare.com/website-optimization/", category: "utility", domains: ["ajax.cloudflare.com", "*.nel.cloudflare.com", "static.cloudflareinsights.com"], totalExecutionTime: 58723052, totalOccurrences: 467719 }, { name: "WordPress", company: "Automattic", homepage: "https://wp.com/", category: "hosting", domains: ["*.wordpress.com", "s0.wp.com", "s2.wp.com", "*.w.org", "c0.wp.com", "s1.wp.com", "i0.wp.com", "i1.wp.com", "i2.wp.com", "widgets.wp.com"], examples: ["s.w.org"], totalExecutionTime: 220910650, totalOccurrences: 308694 }, { name: "WordPress Site Stats", company: "Automattic", homepage: "https://wp.com/", category: "analytics", domains: ["pixel.wp.com", "stats.wp.com"], totalExecutionTime: 8573549, + totalOccurrences: 128931 }, { name: "Hatena Blog", homepage: "https://hatenablog.com/", category: "hosting", domains: ["*.st-hatena.com", "*.hatena.ne.jp"], examples: ["cdn.blog.st-hatena.com", "cdn.pool.st-hatena.com", "cdn7.www.st-hatena.com", "s.hatena.ne.jp", "b.st-hatena.com"], totalExecutionTime: 106337940, totalOccurrences: 43183 }, { name: "Shopify", homepage: "https://www.shopify.com/", category: "hosting", domains: ["*.shopify.com", "*.shopifyapps.com", "*.shopifycdn.com", "*.shopifysvc.com"], examples: ["cdn.shopify.com", "productreviews.shopifycdn.com", "monorail-edge.shopifysvc.com"], totalExecutionTime: 287428893, totalOccurrences: 338668 }, { name: "Dealer", homepage: "https://www.dealer.com/", category: "hosting", domains: ["*.dealer.com"], examples: ["static.dealer.com"], totalExecutionTime: 871324, totalOccurrences: 2620 }, { name: "PIXNET", homepage: "https://www.pixnet.net/", category: "social", domains: ["*.pixfs.net", "*.pixnet.net"], examples: ["front.pixfs.n\ +et", "falcon-asset.pixfs.net", "pixgame-asset.pixfs.net"], totalExecutionTime: 18541448, totalOccurrences: 13718 }, { name: "Moat", homepage: "https://moat.com/", category: "ad", domains: ["*.moatads.com", "*.moatpixel.com"], examples: ["z.moatads.com", "px.moatads.com", "geo.moatads.com", "sejs.moatads.com", "mb.moatads.com", "v4.moatads.com"] }, { name: "33 Across", homepage: "https://33across.com/", category: "ad", domains: ["*.33across.com"], examples: ["sic.33across.com", "cdn-sic.33across.com"], totalExecutionTime: 10002146, totalOccurrences: 192648 }, { name: "OpenX", homepage: "https://www.openx.com/", category: "ad", domains: ["*.deliverimp.com", "*.openxadexchange.com", "*.servedbyopenx.com", "*.jump-time.net", "*.openx.net", "*.openxcdn.net"], examples: ["uk-ads.openx.net", "us-ads.openx.net", "33across-d.openx.net", "rtb.openx.net", "us-u.openx.net", "eu-u.openx.net", "u.openx.net"], totalExecutionTime: 6274934, totalOccurrences: 76561 }, { name: "Amazon Ads", homepage: "ht\ +tps://ad.amazon.com/", category: "ad", domains: ["*.amazon-adsystem.com"], examples: ["s.amazon-adsystem.com", "c.amazon-adsystem.com", "aax.amazon-adsystem.com", "z-na.amazon-adsystem.com", "fls-na.amazon-adsystem.com", "aax-us-east.amazon-adsystem.com", "ir-na.amazon-adsystem.com"], totalExecutionTime: 98703856, totalOccurrences: 240331 }, { name: "Rubicon Project", homepage: "https://rubiconproject.com/", category: "ad", domains: ["*.rubiconproject.com", "*.chango.com", "*.fimserve.com"], examples: ["pixel.rubiconproject.com", "fastlane.rubiconproject.com", "secure-assets.rubiconproject.com", "eus.rubiconproject.com", "pixel-us-east.rubiconproject.com", "token.rubiconproject.com", "ads.rubiconproject.com"], totalExecutionTime: 287111007, totalOccurrences: 270271 }, { name: "The Trade Desk", homepage: "https://www.thetradedesk.com/", category: "ad", domains: ["*.adsrvr.org", "d1eoo1tco6rr5e.cloudfront.net"], examples: ["js.adsrvr.org", "match.adsrvr.org", "insight.adsrvr.org", "usw-l\ +ax.adsrvr.org", "data.adsrvr.org", "snap.adsrvr.org"], totalExecutionTime: 2197325, totalOccurrences: 25346 }, { name: "Bidswitch", homepage: "https://www.bidswitch.com/", category: "ad", domains: ["*.bidswitch.net"], examples: ["x.bidswitch.net"], totalExecutionTime: 25660, totalOccurrences: 68217 }, { name: "LiveRamp IdentityLink", homepage: "https://liveramp.com/discover-identitylink/", category: "analytics", domains: ["*.circulate.com", "*.rlcdn.com"], examples: ["idsync.rlcdn.com", "id.rlcdn.com", "api.rlcdn.com", "cdn.rlcdn.com"], totalExecutionTime: 141414, totalOccurrences: 1461 }, { name: "Drawbridge", homepage: "https://www.drawbridge.com/", category: "ad", domains: ["*.adsymptotic.com"] }, { name: "AOL / Oath / Verizon Media", homepage: "https://www.oath.com/", category: "ad", domains: ["*.advertising.com", "*.aol.com", "*.aolcdn.com", "*.blogsmithmedia.com", "*.oath.com", "*.aol.net", "*.tacoda.net", "*.aol.co.uk"], examples: ["pixel.advertising.com", "dtm.advertising.com", + "tag.sp.advertising.com", "service.sp.advertising.com", "adtech.advertising.com", "adaptv.advertising.com", "mighty.aol.net", "consent.cmp.oath.com"], totalExecutionTime: 165968, totalOccurrences: 278 }, { name: "Xaxis", homepage: "https://www.xaxis.com/", category: "ad", domains: ["*.247realmedia.com", "*.mookie1.com", "*.gmads.net"], examples: ["t.mookie1.com", "odr.mookie1.com"], totalExecutionTime: 28343, totalOccurrences: 209 }, { name: "Freshdesk", company: "Freshworks", homepage: "https://freshdesk.com/", category: "customer-success", domains: ["d36mpcpuzc4ztk.cloudfront.net"], totalExecutionTime: 64296, totalOccurrences: 225 }, { name: "Help Scout", homepage: "https://www.helpscout.net/", category: "customer-success", domains: ["djtflbt20bdde.cloudfront.net", "*.helpscout.net"], examples: ["beacon-v2.helpscout.net"], products: [{ name: "Help Scout Beacon", urlPatterns: ["beacon-v2.helpscout.net"], facades: [{ name: "React Live Chat Loader", repo: "https://github.com/calibre\ +app/react-live-chat-loader" }] }], totalExecutionTime: 2186050, totalOccurrences: 4906 }, { name: "Alexa", homepage: "https://www.alexa.com/", category: "analytics", domains: ["*.alexametrics.com", "d31qbv1cthcecs.cloudfront.net"], examples: ["certify.alexametrics.com"] }, { name: "OneSignal", homepage: "https://onesignal.com/", category: "utility", domains: ["*.onesignal.com"], examples: ["cdn.onesignal.com", "https://onesignal.com/api/v1/sync/"], totalExecutionTime: 17761218, totalOccurrences: 68282 }, { name: "Lucky Orange", homepage: "https://www.luckyorange.com/", category: "analytics", domains: ["*.luckyorange.com", "d10lpsik1i8c69.cloudfront.net", "*.luckyorange.net"], totalExecutionTime: 12779009, totalOccurrences: 16442 }, { name: "Crazy Egg", homepage: "https://www.crazyegg.com/", category: "analytics", domains: ["*.cetrk.com", "*.crazyegg.com", "dnn506yrbagrg.cloudfront.net"], totalExecutionTime: 27593244, totalOccurrences: 43822 }, { name: "Hello Bar", homepage: "https://ww\ +w.hellobar.com/", category: "marketing", domains: ["*.hellobar.com"], totalExecutionTime: 1533955, totalOccurrences: 4502 }, { name: "Yandex Ads", company: "Yandex", homepage: "https://yandex.com/adv/", category: "ad", domains: ["an.yandex.ru"], totalExecutionTime: 5171537, totalOccurrences: 8488 }, { name: "Salesforce", homepage: "https://www.salesforce.com/products/marketing-cloud/", category: "analytics", domains: ["*.krxd.net"], examples: ["cdn.krxd.net", "beacon.krxd.net", "consumer.krxd.net", "usermatch.krxd.net"] }, { name: "Salesforce Commerce Cloud", homepage: "https://www.salesforce.com/products/commerce-cloud/overview/", category: "hosting", domains: ["*.cquotient.com", "*.demandware.net", "demandware.edgesuite.net"], totalExecutionTime: 2045309, totalOccurrences: 4127 }, { name: "Optimizely", homepage: "https://www.optimizely.com/", category: "analytics", domains: ["*.optimizely.com"], examples: ["cdn.optimizely.com", "cdn-pci.optimizely.com", "logx.optimizely.com", "cdn3.o\ +ptimizely.com"], totalExecutionTime: 12599739, totalOccurrences: 15998 }, { name: "LiveChat", homepage: "https://www.livechat.com/", category: "customer-success", domains: ["*.livechatinc.com", "*.livechat.com", "*.livechat-static.com"], examples: ["cdn.livechatinc.com", "secure.livechatinc.com"], totalExecutionTime: 49171416, totalOccurrences: 39034 }, { name: "VK", homepage: "https://vk.com/", category: "social", domains: ["*.vk.com"], totalExecutionTime: 91334176, totalOccurrences: 22377 }, { name: "Tumblr", homepage: "https://tumblr.com/", category: "social", domains: ["*.tumblr.com"], examples: ["assets.tumblr.com", "static.tumblr.com"], totalExecutionTime: 45570825, totalOccurrences: 18114 }, { name: "Wistia", homepage: "https://wistia.com/", category: "video", domains: ["*.wistia.com", "embedwistia-a.akamaihd.net", "*.wistia.net"], examples: ["fast.wistia.com", "fast.wistia.net", "distillery.wistia.com", "pipedream.wistia.com"], totalExecutionTime: 115722112, totalOccurrences: 27059 }, + { name: "Brightcove", homepage: "https://www.brightcove.com/en/", category: "video", domains: ["*.brightcove.com", "*.brightcove.net", "*.zencdn.net"], examples: ["vjs.zencdn.net", "players.brightcove.net"], totalExecutionTime: 15099708, totalOccurrences: 13745 }, { name: "JSDelivr CDN", homepage: "https://www.jsdelivr.com/", category: "cdn", domains: ["*.jsdelivr.net"], examples: ["cdn.jsdelivr.net"], totalExecutionTime: 260364458, totalOccurrences: 399959 }, { name: "Sumo", homepage: "https://sumo.com/", category: "marketing", domains: ["*.sumo.com", "*.sumome.com", "sumo.b-cdn.net"], examples: ["sumo.b-cdn.net", "load.sumo.com", "load.sumome.com"], totalExecutionTime: 16489977, totalOccurrences: 10901 }, { name: "Vimeo", homepage: "https://vimeo.com/", category: "video", domains: ["*.vimeo.com", "*.vimeocdn.com"], examples: ["f.vimeocdn.com", "player.vimeo.com", "i.vimeocdn.com"], products: [{ name: "Vimeo Embedded Player", urlPatterns: ["player.vimeo.com/video/"], facades: [{ name: "\ +Lite Vimeo", repo: "https://github.com/slightlyoff/lite-vimeo" }, { name: "Lite Vimeo Embed", repo: "https://github.com/luwes/lite-vimeo-embed" }, { name: "Ngx Lite Video", repo: "https://github.com/karim-mamdouh/ngx-lite-video" }] }], totalExecutionTime: 263943622, totalOccurrences: 120397 }, { name: "Disqus", homepage: "https://disqus.com/", category: "social", domains: ["*.disqus.com", "*.disquscdn.com"], examples: ["c.disquscdn.com"], totalExecutionTime: 3697272, totalOccurrences: 1775 }, { name: "Yandex APIs", company: "Yandex", homepage: "https://yandex.ru/", category: "utility", domains: ["api-maps.yandex.ru", "money.yandex.ru"], totalExecutionTime: 40765111, totalOccurrences: 51601 }, { name: "Yandex CDN", company: "Yandex", homepage: "https://yandex.ru/", category: "cdn", domains: ["*.yandex.st", "*.yastatic.net"], examples: ["https://yastatic.net/share2/share.js", "https://yastatic.net/jquery/2.1.4/jquery.min.js"] }, { name: "Integral Ad Science", homepage: "https://integrala\ +ds.com/uk/", category: "ad", domains: ["*.adsafeprotected.com", "*.iasds01.com"], examples: ["pixel.adsafeprotected.com", "static.adsafeprotected.com", "fw.adsafeprotected.com", "cdn.adsafeprotected.com", "dt.adsafeprotected.com"], totalExecutionTime: 88554254, totalOccurrences: 21660 }, { name: "Tealium", homepage: "https://tealium.com/", category: "tag-manager", domains: ["*.aniview.com", "*.delvenetworks.com", "*.limelight.com", "*.tiqcdn.com", "*.llnwd.net", "*.tealiumiq.com"], examples: ["tags.tiqcdn.com", "tealium.hs.llnwd.net", "link.videoplatform.limelight.com", "datacloud.tealiumiq.com"], totalExecutionTime: 20176561, totalOccurrences: 75434 }, { name: "Pubmatic", homepage: "https://pubmatic.com/", category: "ad", domains: ["*.pubmatic.com"], examples: ["image6.pubmatic.com", "ads.pubmatic.com", "image2.pubmatic.com", "simage2.pubmatic.com", "image4.pubmatic.com", "simage4.pubmatic.com", "image5.pubmatic.com", "hbopenbid.pubmatic.com"], totalExecutionTime: 417694368, totalOccurrences: 279418 }, + { name: "Olark", homepage: "https://www.olark.com/", category: "customer-success", domains: ["*.olark.com"], examples: ["static.olark.com"], totalExecutionTime: 9840846, totalOccurrences: 6534 }, { name: "Tawk.to", homepage: "https://www.tawk.to/", category: "customer-success", domains: ["*.tawk.to"], examples: ["embed.tawk.to"], totalExecutionTime: 43074965, totalOccurrences: 111088 }, { name: "OptinMonster", homepage: "https://optinmonster.com/", category: "marketing", domains: ["*.opmnstr.com", "*.optmnstr.com", "*.optmstr.com"], examples: ["a.optmstr.com", "api.opmnstr.com", "a.optmnstr.com"], totalExecutionTime: 1035991, totalOccurrences: 2346 }, { name: "ZenDesk", homepage: "https://zendesk.com/", category: "customer-success", domains: ["*.zdassets.com", "*.zendesk.com", "*.zopim.com"], examples: ["assets.zendesk.com", "static.zdassets.com", "v2.zopim.com"], totalExecutionTime: 106701440, totalOccurrences: 72537 }, { name: "Pusher", homepage: "https://pusher.com/", category: "\ +utility", domains: ["*.pusher.com", "*.pusherapp.com"], examples: ["stats.pusher.com"], totalExecutionTime: 152727, totalOccurrences: 1698 }, { name: "Drift", homepage: "https://www.drift.com/", category: "marketing", domains: ["*.drift.com", "*.driftt.com"], examples: ["js.driftt.com", "api.drift.com"], products: [{ name: "Drift Live Chat", urlPatterns: ["REGEXP:js\\.driftt\\.com\\/include\\/.*\\/.*\\.js"], facades: [{ name: "React Live Chat Loader", repo: "https://github.com/calibreapp/react-live-chat-loader" }] }], totalExecutionTime: 30179596, totalOccurrences: 5515 }, { name: "Sentry", homepage: "https://sentry.io/", category: "utility", domains: ["*.getsentry.com", "*.ravenjs.com", "*.sentry-cdn.com", "*.sentry.io"], examples: ["cdn.ravenjs.com", "browser.sentry-cdn.com"], totalExecutionTime: 47937360, totalOccurrences: 85598 }, { name: "Amazon Web Services", homepage: "https://aws.amazon.com/s3/", category: "other", domains: ["*.amazon.com", "*.amazonaws.com", "*.amazonwebapps.c\ +om", "*.amazonwebservices.com", "*.elasticbeanstalk.com", "*.images-amazon.com", "*.amazon.co.uk"], examples: ["s3.amazonaws.com", "us-east-1.amazonaws.com", "api-cdn.amazon.com", "ecx.images-amazon.com", "ws.amazon.co.uk"], totalExecutionTime: 51892201, totalOccurrences: 119152 }, { name: "Amazon Pay", homepage: "https://pay.amazon.com", category: "utility", domains: ["payments.amazon.com", "*.payments-amazon.com"], totalExecutionTime: 1234650, totalOccurrences: 6833 }, { name: "Media.net", homepage: "https://www.media.net/", category: "ad", domains: ["*.media.net", "*.mnet-ad.net"], examples: ["contextual.media.net", "cdnwest-xch.media.net", "hbx.media.net", "cs.media.net", "hblg.media.net"], totalExecutionTime: 24973689, totalOccurrences: 97679 }, { name: "Yahoo!", homepage: "https://www.yahoo.com/", category: "ad", domains: ["*.bluelithium.com", "*.hostingprod.com", "*.lexity.com", "*.yahoo.com", "*.yahooapis.com", "*.yimg.com", "*.zenfs.com", "*.yahoo.net"], examples: ["ads.yahoo.\ +com", "analytics.yahoo.com", "geo.yahoo.com", "udc.yahoo.com", "ganon.yahoo.com", "ads.yap.yahoo.com"], totalExecutionTime: 2617276, totalOccurrences: 24800 }, { name: "Adroll", homepage: "https://www.adroll.com/", category: "ad", domains: ["*.adroll.com"], examples: ["d.adroll.com", "s.adroll.com"], totalExecutionTime: 11884188, totalOccurrences: 30782 }, { name: "Twitch", homepage: "https://twitch.tv/", category: "video", domains: ["*.twitch.tv"], examples: ["player.twitch.tv"], totalExecutionTime: 18452667, totalOccurrences: 1255 }, { name: "Taboola", homepage: "https://www.taboola.com/", category: "ad", domains: ["*.taboola.com", "*.taboolasyndication.com"], examples: ["cdn.taboola.com", "trc.taboola.com", "vidstat.taboola.com", "images.taboola.com"], totalExecutionTime: 32631891, totalOccurrences: 49191 }, { name: "Sizmek", homepage: "https://www.sizmek.com/", category: "ad", domains: ["*.serving-sys.com", "*.peer39.net"], examples: ["secure-ds.serving-sys.com", "ds.serving-sys.co\ +m", "bs.serving-sys.com"], totalExecutionTime: 6679849, totalOccurrences: 4307 }, { name: "Scorecard Research", homepage: "https://www.scorecardresearch.com/", category: "ad", domains: ["*.scorecardresearch.com"], examples: ["sb.scorecardresearch.com", "sa.scorecardresearch.com", "b.scorecardresearch.com"], totalExecutionTime: 4399371, totalOccurrences: 54577 }, { name: "Criteo", homepage: "https://www.criteo.com/", category: "ad", domains: ["*.criteo.com", "*.emailretargeting.com", "*.criteo.net"], examples: ["static.criteo.net", "bidder.criteo.com", "dis.criteo.com", "gum.criteo.com", "sslwidget.criteo.com", "dis.us.criteo.com"], totalExecutionTime: 25625451, totalOccurrences: 213880 }, { name: "Segment", homepage: "https://segment.com/", category: "analytics", domains: ["*.segment.com", "*.segment.io"], examples: ["cdn.segment.com", "api.segment.io"], totalExecutionTime: 11055141, totalOccurrences: 27036 }, { name: "ShareThis", homepage: "https://www.sharethis.com/", category: "soci\ +al", domains: ["*.sharethis.com"], examples: ["w.sharethis.com", "ws.sharethis.com", "t.sharethis.com"], totalExecutionTime: 30807804, totalOccurrences: 88829 }, { name: "Distil Networks", homepage: "https://www.distilnetworks.com/", category: "utility", domains: ["*.areyouahuman.com"], examples: ["n-cdn.areyouahuman.com"] }, { name: "Connexity", homepage: "https://connexity.com/", category: "analytics", domains: ["*.connexity.net"] }, { name: "Popads", homepage: "https://www.popads.net/", category: "ad", domains: ["*.popads.net"], examples: ["serve.popads.net", "c1.popads.net"], totalExecutionTime: 756593, totalOccurrences: 427 }, { name: "CreateJS CDN", homepage: "https://code.createjs.com/", category: "cdn", domains: ["*.createjs.com"], examples: ["code.createjs.com"], totalExecutionTime: 13654049, totalOccurrences: 3880 }, { name: "Squarespace", homepage: "https://www.squarespace.com/", category: "hosting", domains: ["*.squarespace.com"], examples: ["static.squarespace.com", "stati\ +c1.squarespace.com"], totalExecutionTime: 1106480464, totalOccurrences: 243154 }, { name: "Media Math", homepage: "https://www.mediamath.com/", category: "ad", domains: ["*.mathads.com", "*.mathtag.com"], examples: ["mathid.mathtag.com", "sync.mathtag.com", "pixel.mathtag.com"], totalExecutionTime: 20783, totalOccurrences: 305 }, { name: "Mixpanel", homepage: "https://mixpanel.com/", category: "analytics", domains: ["*.mixpanel.com", "*.mxpnl.com"], examples: ["cdn.mxpnl.com"], totalExecutionTime: 3250547, totalOccurrences: 18817 }, { name: "FontAwesome CDN", homepage: "https://fontawesome.com/", category: "cdn", domains: ["*.fontawesome.com"], examples: ["use.fontawesome.com"], totalExecutionTime: 73007333, totalOccurrences: 291586 }, { name: "Hubspot", homepage: "https://hubspot.com/", category: "marketing", domains: ["*.hs-scripts.com", "*.hubspot.com", "*.leadin.com", "*.hs-analytics.net", "*.hscollectedforms.net", "*.hscta.net", "*.hsforms.net", "*.hsleadflows.net", "*.hsstatic.ne\ +t", "*.hubspot.net", "*.hsforms.com", "*.hs-banner.com", "*.hs-embed-reporting.com", "*.hs-growth-metrics.com", "*.hs-data.com", "*.hsadspixel.net", "*.hubapi.com"], examples: ["forms.hubspot.com", "js.hsforms.net", "js.hs-analytics.net", "js.leadin.com"], totalExecutionTime: 92224372, totalOccurrences: 154415 }, { name: "Mailchimp", homepage: "https://mailchimp.com/", category: "marketing", domains: ["*.chimpstatic.com", "*.list-manage.com", "*.mailchimp.com"], examples: ["downloads.mailchimp.com"], totalExecutionTime: 21592375, totalOccurrences: 45506 }, { name: "MGID", homepage: "https://www.mgid.com/", category: "ad", domains: ["*.mgid.com", "*.dt07.net"], examples: ["servicer.mgid.com"], totalExecutionTime: 22074076, totalOccurrences: 10437 }, { name: "Stripe", homepage: "https://stripe.com", category: "utility", domains: ["*.stripe.com", "*.stripecdn.com", "*.stripe.network"], examples: ["m.stripe.network", "js.stripe.com"], totalExecutionTime: 166354648, totalOccurrences: 136440 }, + { name: "PayPal", homepage: "https://paypal.com", category: "utility", domains: ["*.paypal.com", "*.paypalobjects.com"], examples: ["www.paypalobjects.com"], totalExecutionTime: 64408205, totalOccurrences: 62800 }, { name: "Market GID", homepage: "https://www.marketgid.com/", category: "ad", domains: ["*.marketgid.com"], examples: ["jsc.marketgid.com"] }, { name: "Pinterest", homepage: "https://pinterest.com/", category: "social", domains: ["*.pinimg.com", "*.pinterest.com"], examples: ["assets.pinterest.com", "ct.pinterest.com", "log.pinterest.com"], totalExecutionTime: 17602311, totalOccurrences: 131448 }, { name: "New Relic", homepage: "https://newrelic.com/", category: "utility", domains: ["*.newrelic.com", "*.nr-data.net"], examples: ["js-agent.newrelic.com", "bam.nr-data.net"], totalExecutionTime: 64592740, totalOccurrences: 227672 }, { name: "AppDynamics", homepage: "https://www.appdynamics.com/", category: "utility", domains: ["*.appdynamics.com", "*.eum-appdynamics.com", "\ +d3tjaysgumg9lf.cloudfront.net"], examples: ["cdn.appdynamics.com"], totalExecutionTime: 2509158, totalOccurrences: 2920 }, { name: "Parking Crew", homepage: "https://parkingcrew.net/", category: "other", domains: ["d1lxhc4jvstzrp.cloudfront.net", "*.parkingcrew.net"], totalExecutionTime: 9, totalOccurrences: 1 }, { name: "WordAds", company: "Automattic", homepage: "https://wordads.co/", category: "ad", domains: ["*.pubmine.com"], examples: ["s.pubmine.com"], totalExecutionTime: 74286347, totalOccurrences: 100449 }, { name: "AppNexus", homepage: "https://www.appnexus.com/", category: "ad", domains: ["*.adnxs.com", "*.ctasnet.com", "*.adrdgt.com"], examples: ["acdn.adnxs.com", "secure.adnxs.com", "ib.adnxs.com", "sharethrough.adnxs.com", "cdn.adnxs.com", "vcdn.adnxs.com"], totalExecutionTime: 5948505, totalOccurrences: 234133 }, { name: "Histats", homepage: "https://www.histats.com/", category: "analytics", domains: ["*.histats.com"], examples: ["s10.histats.com"], totalExecutionTime: 5601, + totalOccurrences: 92 }, { name: "DoubleVerify", homepage: "https://www.doubleverify.com/", category: "ad", domains: ["*.doubleverify.com", "*.dvtps.com", "*.iqfp1.com"], examples: ["cdn.doubleverify.com", "cdn3.doubleverify.com", "tps.doubleverify.com", "tps712.doubleverify.com", "tps714.doubleverify.com", "tps706.doubleverify.com", "tps700.doubleverify.com", "tps707.doubleverify.com", "rtb2.doubleverify.com", "rtb0.doubleverify.com", "rtbcdn.doubleverify.com", "tps11020.doubleverify.com", "tm.iqfp1.com"], totalExecutionTime: 46891028, totalOccurrences: 19453 }, { name: "Mediavine", homepage: "https://www.mediavine.com/", category: "ad", domains: ["*.mediavine.com"], examples: ["scripts.mediavine.com", "video.mediavine.com"], totalExecutionTime: 59009373, totalOccurrences: 12963 }, { name: "Wix", homepage: "https://www.wix.com/", category: "hosting", domains: ["*.parastorage.com", "*.wix.com", "*.wixstatic.com", "*.wixapps.net"], examples: ["static.parastorage.com", "static.wixstat\ +ic.com", "www.wix.com", "instagram.codev.wixapps.net"], totalExecutionTime: 2112268981, totalOccurrences: 458273 }, { name: "Webflow", homepage: "https://webflow.com/", category: "hosting", domains: ["*.uploads-ssl.webflow.com", "*.assets-global.website-files.com", "*.assets.website-files.com"], examples: ["uploads-ssl.webflow.com", "assets-global.website-files.com", "assets.website-files.com"] }, { name: "Weebly", homepage: "https://www.weebly.com/", category: "hosting", domains: ["*.editmysite.com"], totalExecutionTime: 413019e3, totalOccurrences: 67864 }, { name: "LinkedIn", homepage: "https://www.linkedin.com/", category: "social", domains: ["*.bizographics.com", "platform.linkedin.com", "*.slideshare.com", "*.slidesharecdn.com", "*.oribi.io"], totalExecutionTime: 5776577, totalOccurrences: 16507 }, { name: "LinkedIn Ads", category: "ad", domains: ["*.licdn.com", "*.ads.linkedin.com", "ads.linkedin.com", "www.linkedin.com"], examples: ["snap.licdn.com"], totalExecutionTime: 22805542, + totalOccurrences: 199088 }, { name: "Vox Media", homepage: "https://www.voxmedia.com/", category: "content", domains: ["*.vox-cdn.com", "*.voxmedia.com"], examples: ["cdn.vox-cdn.com"], totalExecutionTime: 910366, totalOccurrences: 320 }, { name: "Hotmart", homepage: "https://www.hotmart.com/", category: "content", domains: ["*.hotmart.com"], examples: ["launchermodule.hotmart.com"], totalExecutionTime: 15363016, totalOccurrences: 4554 }, { name: "SoundCloud", homepage: "https://www.soundcloud.com/", category: "content", domains: ["*.sndcdn.com", "*.soundcloud.com", "*.stratus.sc"], examples: ["widget.sndcdn.com"], totalExecutionTime: 15888610, totalOccurrences: 5859 }, { name: "Spotify", homepage: "https://www.spotify.com/", category: "content", domains: ["*.scdn.co", "*.spotify.com"], examples: ["open.spotify.com", "open.scdn.co", "i.scdn.co"], totalExecutionTime: 99924, totalOccurrences: 10992 }, { name: "AMP", homepage: "https://amp.dev/", category: "content", domains: ["*.ampp\ +roject.org"], examples: ["cdn.ampproject.org"], totalExecutionTime: 79590738, totalOccurrences: 66265 }, { name: "Beeketing", homepage: "https://beeketing.com/", category: "marketing", domains: ["*.beeketing.com"], examples: ["sdk-cdn.beeketing.com", "sdk.beeketing.com"], totalExecutionTime: 2163106, totalOccurrences: 1971 }, { name: "Albacross", homepage: "https://albacross.com/", category: "marketing", domains: ["*.albacross.com"], examples: ["serve.albacross.com"], totalExecutionTime: 100459, totalOccurrences: 1503 }, { name: "TrafficJunky", homepage: "https://www.trafficjunky.com/", category: "ad", domains: ["*.contentabc.com", "*.trafficjunky.net"], examples: ["ads2.contentabc.com", "hw-cdn.contentabc.com", "media.trafficjunky.net", "ads.trafficjunky.net", "hw-cdn.trafficjunky.net"], totalExecutionTime: 2936, totalOccurrences: 62 }, { name: "Bootstrap CDN", homepage: "https://www.bootstrapcdn.com/", category: "cdn", domains: ["*.bootstrapcdn.com"], examples: ["maxcdn.bootstrapcdn.\ +com", "stackpath.bootstrapcdn.com"], totalExecutionTime: 2075388, totalOccurrences: 38731 }, { name: "Shareaholic", homepage: "https://www.shareaholic.com/", category: "social", domains: ["*.shareaholic.com", "dsms0mj1bbhn4.cloudfront.net"], totalExecutionTime: 122180, totalOccurrences: 1429 }, { name: "Snowplow", homepage: "https://snowplowanalytics.com/", category: "analytics", domains: ["d32hwlnfiv2gyn.cloudfront.net"], totalExecutionTime: 7099041, totalOccurrences: 58566 }, { name: "RD Station", homepage: "https://www.rdstation.com/en/", category: "marketing", domains: ["d335luupugsy2.cloudfront.net"], totalExecutionTime: 7693701, totalOccurrences: 21846 }, { name: "Jivochat", homepage: "https://www.jivochat.com/", category: "customer-success", domains: ["*.jivosite.com"], examples: ["cdn-ca.jivosite.com", "code.jivosite.com"], totalExecutionTime: 36663932, totalOccurrences: 57540 }, { name: "Listrak", homepage: "https://www.listrak.com/", category: "marketing", domains: ["*.listra\ +k.com", "*.listrakbi.com"], examples: ["cdn.listrakbi.com", "s1.listrakbi.com"], totalExecutionTime: 458776, totalOccurrences: 1045 }, { name: "Ontame", homepage: "https://www.ontame.io", category: "analytics", domains: ["*.ontame.io"], examples: ["cdn.ontame.io", "collector.ontame.io"], totalExecutionTime: 23620, totalOccurrences: 101 }, { name: "Ipify", homepage: "https://www.ipify.org", category: "utility", domains: ["*.ipify.org"], examples: ["api.ipify.org", "geo.ipify.org"], totalExecutionTime: 365905, totalOccurrences: 2753 }, { name: "Ensighten", homepage: "https://www.ensighten.com/", category: "tag-manager", domains: ["*.ensighten.com"], examples: ["nexus.ensighten.com"], totalExecutionTime: 1774287, totalOccurrences: 3199 }, { name: "EpiServer", homepage: "https://www.episerver.com", category: "content", domains: ["*.episerver.net"], examples: ["dl.episerver.net"], totalExecutionTime: 9010, totalOccurrences: 80 }, { name: "mPulse", homepage: "https://developer.akamai.com/aka\ +mai-mpulse", category: "analytics", domains: ["*.akstat.io", "*.go-mpulse.net", "*.mpulse.net", "*.mpstat.us"], examples: ["c.go-mpulse.net", "0211c83c.akstat.io"], totalExecutionTime: 3089821, totalOccurrences: 30624 }, { name: "Pingdom RUM", homepage: "https://www.pingdom.com/product/performance-monitoring/", category: "analytics", domains: ["*.pingdom.net"], examples: ["rum-static.pingdom.net", "rum-collector-2.pingdom.net"], totalExecutionTime: 106679, totalOccurrences: 1825 }, { name: "SpeedCurve RUM", company: "SpeedCurve", homepage: "https://www.speedcurve.com/features/performance-monitoring/", category: "analytics", domains: ["*.speedcurve.com"], examples: ["cdn.speedcurve.com", "lux.speedcurve.com"], totalExecutionTime: 323903, totalOccurrences: 5358 }, { name: "Radar", company: "Cedexis", homepage: "https://www.cedexis.com/radar/", category: "analytics", domains: ["*.cedexis-test.com", "*.cedexis.com", "*.cmdolb.com", "cedexis.leasewebcdn.com", "*.cedexis-radar.net", "*.cedex\ +is.net", "cedexis-test01.insnw.net", "cedexisakamaitest.azureedge.net", "cedexispub.cdnetworks.net", "cs600.wac.alphacdn.net", "cs600.wpc.edgecastdns.net", "global2.cmdolb.com", "img-cedexis.mncdn.com", "a-cedexis.msedge.net", "zn3vgszfh.fastestcdn.net"], examples: ["radar.cedexis.com", "rpt.cedexis.com", "2-01-49cd-0002.cdx.cedexis.net", "bench.cedexis-test.com"], totalExecutionTime: 290925, totalOccurrences: 1133 }, { name: "Byside", homepage: "https://byside.com", category: "analytics", domains: ["*.byside.com"], examples: ["byce2.byside.com", "wce2.byside.com"], totalExecutionTime: 45270, totalOccurrences: 87 }, { name: "VWO", homepage: "https://vwo.com", category: "analytics", domains: ["*.vwo.com", "*.visualwebsiteoptimizer.com", "d5phz18u4wuww.cloudfront.net", "*.wingify.com"], examples: ["dev.visualwebsiteoptimizer.com"], totalExecutionTime: 6485310, totalOccurrences: 7903 }, { name: "Bing Ads", homepage: "https://bingads.microsoft.com", category: "ad", domains: ["*.bing.com", "\ +*.microsoft.com", "*.msn.com", "*.s-msft.com", "*.s-msn.com", "*.msads.net", "*.msecnd.net"], examples: ["bat.bing.com", "c.bing.com", "bat.r.msn.com", "ajax.microsoft.com"], totalExecutionTime: 14227177, totalOccurrences: 117720 }, { name: "GoSquared", homepage: "https://www.gosquared.com", category: "analytics", domains: ["*.gosquared.com", "d1l6p2sc9645hc.cloudfront.net"], examples: ["data.gosquared.com", "data2.gosquared.com"], totalExecutionTime: 56152, totalOccurrences: 613 }, { name: "Usabilla", homepage: "https://usabilla.com", category: "analytics", domains: ["*.usabilla.com", "d6tizftlrpuof.cloudfront.net"], examples: ["w.usabilla.com"], totalExecutionTime: 240166, totalOccurrences: 1354 }, { name: "Fastly Insights", homepage: "https://insights.fastlylabs.com", category: "analytics", domains: ["*.fastly-insights.com"], examples: ["www.fastly-insights.com"], totalExecutionTime: 541189, totalOccurrences: 4449 }, { name: "Visual IQ", homepage: "https://www.visualiq.com", category: "\ +analytics", domains: ["*.myvisualiq.net"], examples: ["t.myvisualiq.net"] }, { name: "Snapchat", homepage: "https://www.snapchat.com", category: "analytics", domains: ["*.snapchat.com", "*.sc-static.net"], examples: ["tr.snapchat.com"], totalExecutionTime: 177890, totalOccurrences: 1978 }, { name: "Atlas Solutions", homepage: "https://atlassolutions.com", category: "analytics", domains: ["*.atdmt.com"], examples: ["ad.atdmt.com", "cx.atdmt.com"] }, { name: "Quantcast", homepage: "https://www.quantcast.com", category: "analytics", domains: ["*.brtstats.com", "*.quantcount.com", "*.quantserve.com", "*.semantictec.com", "*.ntv.io"], examples: ["pixel.quantserve.com", "secure.quantserve.com", "cms.quantserve.com", "rules.quantcount.com"], totalExecutionTime: 12419392, totalOccurrences: 77646 }, { name: "Spiceworks", homepage: "https://www.spiceworks.com", category: "analytics", domains: ["*.spiceworks.com"], examples: ["px.spiceworks.com"] }, { name: "Marketo", homepage: "https://www.marke\ +to.com", category: "analytics", domains: ["*.marketo.com", "*.mktoresp.com", "*.marketo.net"], examples: ["munchkin.marketo.net"], totalExecutionTime: 724464, totalOccurrences: 1798 }, { name: "Intercom", homepage: "https://www.intercom.com", category: "customer-success", domains: ["*.intercomcdn.com", "*.intercom.io"], examples: ["js.intercomcdn.com", "api-iam.intercom.io", "widget.intercom.io", "nexus-websocket-a.intercom.io"], products: [{ name: "Intercom Widget", urlPatterns: ["widget.intercom.io", "js.intercomcdn.com/shim.latest.js"], facades: [{ name: "React Live Chat Loader", repo: "https://github.com/calibreapp/react-live-chat-loader" }, { name: "Intercom Facade", repo: "https://github.com/danielbachhuber/intercom-facade/" }] }], totalExecutionTime: 44601345, totalOccurrences: 35197 }, { name: "Unpkg", homepage: "https://unpkg.com", category: "cdn", domains: ["*.unpkg.com", "*.npmcdn.com"], totalExecutionTime: 74666, totalOccurrences: 227 }, { name: "ReadSpeaker", homepage: "ht\ +tps://www.readspeaker.com", category: "other", domains: ["*.readspeaker.com"], examples: ["sf1-eu.readspeaker.com"], totalExecutionTime: 727525, totalOccurrences: 6265 }, { name: "Browsealoud", homepage: "https://www.texthelp.com/en-gb/products/browsealoud/", category: "other", domains: ["*.browsealoud.com", "*.texthelp.com"], examples: ["www.browsealoud.com"], totalExecutionTime: 665425, totalOccurrences: 1951 }, { name: "15gifts", category: "customer-success", domains: ["*.15gifts.com", "*.primefuse.com"], examples: ["www.primefuse.com"] }, { name: "1xRUN", category: "utility", domains: ["*.1xrun.com"] }, { name: "2AdPro Media Solutions", category: "ad", domains: ["*.2adpro.com"] }, { name: "301 Digital Media", category: "content", domains: ["*.301ads.com", "*.301network.com"] }, { name: "360 picnic platform", company: "MediaV", category: "ad", domains: ["*.mediav.com"], totalExecutionTime: 4893, totalOccurrences: 78 }, { name: "365 Media Group", category: "content", domains: ["*.365\ +dm.com"] }, { name: "365 Tech Services", category: "hosting", domains: ["*.365webservices.co.uk"] }, { name: "3D Issue", category: "utility", domains: ["*.3dissue.com", "*.pressjack.com"], totalExecutionTime: 53823, totalOccurrences: 30 }, { name: "47Line Technologies", category: "other", domains: ["*.pejs.net"] }, { name: "4finance", category: "utility", domains: ["*.4finance.com"] }, { name: "5miles", category: "content", domains: ["*.5milesapp.com"] }, { name: "77Tool", company: "77Agency", category: "analytics", domains: ["*.77tracking.com"] }, { name: "9xb", category: "ad", domains: ["*.9xb.com"] }, { name: "@UK", category: "hosting", domains: ["*.uk-plc.net"] }, { name: "A Perfect Pocket", category: "hosting", domains: ["*.aperfectpocketdata.com"] }, { name: "A-FIS PTE", category: "analytics", domains: ["*.websta.me"] }, { name: "AB Tasty", homepage: "https://www.abtasty.com/", category: "analytics", domains: ["*.abtasty.com", "d1447tq2m68ekg.cloudfront.net"], examples: ["try.abt\ +asty.com"], totalExecutionTime: 1720461, totalOccurrences: 3363 }, { name: "ABA RESEARCH", category: "analytics", domains: ["*.abaresearch.uk", "qmodal.azurewebsites.net"] }, { name: "ADMIZED", category: "ad", domains: ["*.admized.com"] }, { name: "ADNOLOGIES", category: "ad", domains: ["*.heias.com"] }, { name: "ADventori", category: "ad", domains: ["*.adventori.com"], totalExecutionTime: 5790, totalOccurrences: 21 }, { name: "AI Media Group", category: "ad", domains: ["*.aimediagroup.com"] }, { name: "AIR.TV", category: "ad", domains: ["*.air.tv"] }, { name: "AKQA", category: "ad", domains: ["*.srtk.net"] }, { name: "AOL ad", company: "AOL", category: "ad", domains: ["*.atwola.com"] }, { name: "AOL On", company: "AOL", category: "content", domains: ["*.5min.com"] }, { name: "AOL Sponsored Listiings", company: "AOL", category: "ad", domains: ["*.adsonar.com"] }, { name: "APSIS Lead", company: "APSIS International AB", category: "ad", domains: ["*.prospecteye.com"] }, { name: "APSIS Pr\ +ofile Cloud", company: "APSIS", category: "analytics", domains: ["*.innomdc.com"] }, { name: "APSIS Forms", company: "APSIS", category: "other", domains: ["*.apsisforms.com"], examples: ["forms.apsisforms.com"] }, { name: "ARENA", company: "Altitude", category: "ad", domains: ["*.altitude-arena.com"], totalExecutionTime: 1, totalOccurrences: 1 }, { name: "ARM", category: "analytics", domains: ["*.tag4arm.com"], totalExecutionTime: 5847, totalOccurrences: 83 }, { name: "ASAPP", category: "other", domains: ["*.asapp.com"], totalExecutionTime: 37052, totalOccurrences: 31 }, { name: "ASP", category: "hosting", domains: ["*.goshowoff.com"] }, { name: "AT Internet", category: "analytics", domains: ["*.ati-host.net"] }, { name: "ATTRAQT", category: "utility", domains: ["*.attraqt.com", "*.locayta.com"] }, { name: "AVANSER", category: "analytics", domains: ["*.avanser.com.au"] }, { name: "AVG", company: "AVG Technologies", category: "utility", domains: ["*.avg.com"], examples: ["omni.avg.com"] }, + { name: "AWeber", category: "ad", domains: ["*.aweber.com"], totalExecutionTime: 40945, totalOccurrences: 280 }, { name: "AXS", category: "content", domains: ["*.axs.com"], totalExecutionTime: 49218, totalOccurrences: 8 }, { name: "Accentuate", company: "Accentuate Digital", category: "utility", homepage: "https://www.accentuate.io/", domains: ["*.accentuate.io"], examples: ["cdn.accentuate.io", "original.accentuate.io"], totalExecutionTime: 1772, totalOccurrences: 17 }, { name: "Accenture", category: "analytics", domains: ["*.tmvtp.com"] }, { name: "Accord Holdings", category: "ad", domains: ["*.agcdn.com"] }, { name: "Accordant Media", category: "ad", domains: ["*.a3cloud.net"], examples: ["segment.a3cloud.net"] }, { name: "Account Kit", category: "other", domains: ["*.accountkit.com"] }, { name: "Accuen Media (Omnicom Media Group)", category: "content", domains: ["*.p-td.com"] }, { name: "Accuweather", category: "content", domains: ["*.accuweather.com"], totalExecutionTime: 291762, + totalOccurrences: 1477 }, { name: "Acquisio", category: "ad", domains: ["*.acq.io"], totalExecutionTime: 1692, totalOccurrences: 32 }, { name: "Act-On Software", category: "marketing", domains: ["*.actonsoftware.com"], totalExecutionTime: 98, totalOccurrences: 2 }, { name: "ActBlue", category: "other", domains: ["*.actblue.com"], totalExecutionTime: 62800, totalOccurrences: 73 }, { name: "Active Agent", category: "ad", domains: ["*.active-agent.com"] }, { name: "ActiveCampaign", category: "ad", domains: ["*.trackcmp.net", "app-us1.com", "*.app-us1.com"], examples: ["trackcmp.net", "prism.app-us1.com", "diffuser-cdn.app-us1.com"], totalExecutionTime: 1605217, totalOccurrences: 19100 }, { name: "AcuityAds", category: "ad", domains: ["*.acuityplatform.com"], totalExecutionTime: 2492, totalOccurrences: 693 }, { name: "Acxiom", category: "ad", domains: ["*.acxiom-online.com", "*.acxiomapac.com", "*.delivery.net"] }, { name: "Ad4Screen", category: "ad", domains: ["*.a4.tl"] }, { name: "A\ +d6Media", category: "ad", domains: ["*.ad6media.fr"], totalExecutionTime: 821770, totalOccurrences: 654 }, { name: "AdCurve", category: "ad", domains: ["*.shop2market.com"] }, { name: "AdEasy", category: "ad", domains: ["*.adeasy.ru"] }, { name: "AdExtent", category: "ad", domains: ["*.adextent.com"] }, { name: "AdForge Edge", company: "AdForge", category: "ad", domains: ["*.adforgeinc.com"] }, { name: "AdGear", company: "Samsung Electronics", category: "ad", domains: ["*.adgear.com", "*.adgrx.com"], totalExecutionTime: 19948, totalOccurrences: 42920 }, { name: "AdInMedia", category: "ad", domains: ["*.fastapi.net"] }, { name: "AdJug", category: "ad", domains: ["*.adjug.com"], examples: ["tracking.adjug.com", "uk.view.adjug.com"] }, { name: "AdMatic", category: "ad", domains: ["*.admatic.com.tr"], totalExecutionTime: 1274496, totalOccurrences: 467 }, { name: "AdMedia", category: "ad", domains: ["*.admedia.com"], examples: ["pixel.admedia.com"], totalExecutionTime: 2027, totalOccurrences: 7 }, + { name: "AdRecover", category: "ad", domains: ["*.adrecover.com"], totalExecutionTime: 5117, totalOccurrences: 46 }, { name: "AdRiver", category: "ad", domains: ["*.adriver.ru"], totalExecutionTime: 1374767, totalOccurrences: 4740 }, { name: "AdSniper", category: "ad", domains: ["*.adsniper.ru", "*.sniperlog.ru"], totalExecutionTime: 2366, totalOccurrences: 22 }, { name: "AdSpeed", category: "ad", domains: ["*.adspeed.net"], totalExecutionTime: 4642, totalOccurrences: 16 }, { name: "AdSpruce", category: "ad", domains: ["*.adspruce.com"] }, { name: "AdSupply", category: "ad", domains: ["*.doublepimp.com"], totalExecutionTime: 1436, totalOccurrences: 13 }, { name: "AdTheorent", category: "ad", domains: ["*.adentifi.com"], totalExecutionTime: 108, totalOccurrences: 1 }, { name: "AdThink AudienceInsights", company: "AdThink Media", category: "analytics", domains: ["*.audienceinsights.net"] }, { name: "AdTrue", company: "FPT AdTrue", category: "ad", domains: ["*.adtrue.com"] }, { name: "\ +AdYapper", category: "ad", domains: ["*.adyapper.com"] }, { name: "Adacado", category: "ad", domains: ["*.adacado.com"], totalExecutionTime: 1777, totalOccurrences: 18 }, { name: "Adap.tv", category: "ad", domains: ["*.adap.tv"] }, { name: "Adapt Services", category: "hosting", domains: ["*.adcmps.com"] }, { name: "Adaptive Web", category: "hosting", domains: ["*.adaptive.co.uk"] }, { name: "Adara Media", category: "ad", domains: ["*.yieldoptimizer.com"], totalExecutionTime: 1324, totalOccurrences: 23 }, { name: "Adblade", category: "ad", domains: ["*.adblade.com"], totalExecutionTime: 704, totalOccurrences: 7 }, { name: "Adbrain", category: "ad", domains: ["*.adbrn.com"] }, { name: "AddEvent", category: "utility", domains: ["*.addevent.com"], examples: ["www.addevent.com"], totalExecutionTime: 73230, totalOccurrences: 203 }, { name: "AddShoppers", category: "social", domains: ["*.addshoppers.com", "d3rr3d0n31t48m.cloudfront.net", "*.shop.pe"], totalExecutionTime: 31574, totalOccurrences: 451 }, + { name: "AddThisEvent", category: "hosting", domains: ["*.addthisevent.com"] }, { name: "Addoox MetaNetwork", company: "Addoox", category: "ad", domains: ["*.metanetwork.net"] }, { name: "Addvantage Media", category: "ad", domains: ["*.addvantagemedia.com", "*.simplytechnology.net"] }, { name: "AD EBis", category: "analytics", homepage: "https://www.ebis.ne.jp/", domains: ["*.ebis.ne.jp"], examples: ["taj1.ebis.ne.jp"], totalExecutionTime: 55086, totalOccurrences: 608 }, { name: "Adecs", category: "customer-success", domains: ["*.adecs.co.uk"], examples: ["www.adecs.co.uk"] }, { name: "Adelphic", category: "ad", domains: ["*.ipredictive.com"], totalExecutionTime: 8196, totalOccurrences: 112 }, { name: "Adestra", category: "ad", domains: ["*.adestra.com", "*.msgfocus.com"] }, { name: "Adform", category: "ad", domains: ["*.adform.net", "*.adformdsp.net"], totalExecutionTime: 1798751, totalOccurrences: 140125 }, { name: "Adkontekst", category: "ad", domains: ["*.adkontekst.pl"] }, { name: "\ +Adlead", category: "ad", domains: ["*.webelapp.com"] }, { name: "Adledge", category: "utility", domains: ["*.adledge.com"] }, { name: "Adloox", category: "ad", domains: ["*.adlooxtracking.com"], totalExecutionTime: 103507, totalOccurrences: 112 }, { name: "Adlux", category: "ad", domains: ["*.adlux.com"] }, { name: "Admedo", category: "ad", domains: ["*.a8723.com", "*.adizio.com", "*.admedo.com"], examples: ["pool.a8723.com"], totalExecutionTime: 9586, totalOccurrences: 695 }, { name: "Admeta", company: "Wideorbit", category: "ad", domains: ["*.atemda.com"] }, { name: "Admetrics", company: "Next Tuesday", category: "analytics", domains: ["*.nt.vc"], examples: ["metrics.nt.vc"] }, { name: "Admiral", category: "ad", domains: ["*.unknowntray.com"] }, { name: "Admitad", category: "ad", domains: ["*.lenmit.com"], totalExecutionTime: 2335, totalOccurrences: 31 }, { name: "Admixer for Publishers", company: "Admixer", category: "ad", domains: ["*.admixer.net"], totalExecutionTime: 1542643, totalOccurrences: 878 }, + { name: "Adnium", category: "ad", domains: ["*.adnium.com"] }, { name: "Adnostic", company: "Dennis Publishing", category: "ad", domains: ["*.adnostic.co.uk"] }, { name: "Adobe Marketing Cloud", company: "Adobe Systems", category: "ad", domains: ["*.adobetag.com"] }, { name: "Adobe Scene7", company: "Adobe Systems", category: "content", domains: ["wwwimages.adobe.com", "*.scene7.com", "*.everestads.net", "*.everestjs.net"], totalExecutionTime: 808424, totalOccurrences: 702 }, { name: "Adobe Systems", category: "content", domains: ["adobe.com", "www.adobe.com"], totalExecutionTime: 38836, totalOccurrences: 179 }, { name: "Adobe Business Catalyst", homepage: "https://www.businesscatalyst.com/", category: "hosting", domains: ["*.businesscatalyst.com"] }, { name: "Adocean", company: "Gemius", category: "ad", domains: ["*.adocean.pl"], totalExecutionTime: 1658274, totalOccurrences: 2151 }, { name: "Adometry", company: "Google", category: "ad", domains: ["*.dmtry.com"] }, { name: "Adomik", + category: "analytics", domains: ["*.adomik.com"] }, { name: "Adotmob", category: "ad", domains: ["*.adotmob.com"] }, { name: "Adrian Quevedo", category: "hosting", domains: ["*.adrianquevedo.com"] }, { name: "Adroit Digital Solutions", category: "ad", domains: ["*.imiclk.com", "*.abmr.net"] }, { name: "AdsNative", category: "ad", domains: ["*.adsnative.com"] }, { name: "AdsWizz", category: "ad", domains: ["*.adswizz.com"], totalExecutionTime: 479514, totalOccurrences: 1901 }, { name: "Adscale", category: "ad", domains: ["*.adscale.de"], totalExecutionTime: 106237, totalOccurrences: 960 }, { name: "Adschoom", company: "JSWeb Production", category: "ad", domains: ["*.adschoom.com"], totalExecutionTime: 491, totalOccurrences: 2 }, { name: "Adscience", category: "ad", domains: ["*.adscience.nl"] }, { name: "Adsiduous", category: "ad", domains: ["*.adsiduous.com"] }, { name: "Adsty", category: "ad", domains: ["*.adx1.com"], totalExecutionTime: 698, totalOccurrences: 5 }, { name: "Adtech\ + (AOL)", category: "ad", domains: ["*.adtechus.com"], totalExecutionTime: 176, totalOccurrences: 2 }, { name: "Adtegrity", category: "ad", domains: ["*.adtpix.com"], totalExecutionTime: 1735, totalOccurrences: 20 }, { name: "Adthink", company: "Adthink Media", category: "ad", domains: ["*.adxcore.com", "*.dcoengine.com"], examples: ["d.adxcore.com"] }, { name: "AdultWebmasterEmpire.Com", category: "ad", domains: ["*.awempire.com"], totalExecutionTime: 65091, totalOccurrences: 38 }, { name: "Adunity", category: "ad", domains: ["*.adunity.com"] }, { name: "Advance Magazine Group", category: "content", domains: ["*.condenastdigital.com", "*.condenet.com", "*.condenast.co.uk"], totalExecutionTime: 2531, totalOccurrences: 8 }, { name: "Adverline Board", company: "Adverline", category: "ad", domains: ["*.adverline.com", "*.adnext.fr"] }, { name: "AdvertServe", category: "ad", domains: ["*.advertserve.com"], totalExecutionTime: 112685, totalOccurrences: 437 }, { name: "Advolution", category: "\ +utility", domains: ["*.advolution.de"] }, { name: "Adwise", category: "ad", domains: ["*.adwise.bg"], totalExecutionTime: 144, totalOccurrences: 2 }, { name: "Adyen", category: "utility", domains: ["*.adyen.com"], totalExecutionTime: 6335144, totalOccurrences: 2363 }, { name: "Adyoulike", category: "ad", domains: ["*.adyoulike.com", "*.omnitagjs.com", "*.adyoulike.net"], totalExecutionTime: 147862, totalOccurrences: 53190 }, { name: "Adzerk", category: "ad", domains: ["*.adzerk.net"], totalExecutionTime: 35184, totalOccurrences: 117 }, { name: "Adzip", company: "Adbox Digital", category: "ad", domains: ["*.adzip.co"] }, { name: "AerServ", category: "ad", domains: ["*.aerserv.com"] }, { name: "Affectv", category: "ad", domains: ["*.affectv.com", "*.affec.tv"], totalExecutionTime: 1187, totalOccurrences: 12 }, { name: "Affiliate Window", company: "Digital Window", category: "ad", domains: ["*.dwin1.com"], totalExecutionTime: 561168, totalOccurrences: 5414 }, { name: "Affiliatly", category: "\ +ad", domains: ["*.affiliatly.com"], examples: ["www.affiliatly.com"], totalExecutionTime: 32020, totalOccurrences: 132 }, { name: "Affino", category: "ad", domains: ["affino.com"] }, { name: "Affirm", category: "utility", domains: ["*.affirm.com"], totalExecutionTime: 3997184, totalOccurrences: 6665 }, { name: "Afterpay", company: "Block", category: "utility", homepage: "https://www.afterpay.com/", domains: ["*.afterpay.com"], examples: ["static-us.afterpay.com"], totalExecutionTime: 1270109, totalOccurrences: 8269 }, { name: "Agenda Media", category: "ad", domains: ["*.agendamedia.co.uk"] }, { name: "Aggregate Knowledge", company: "Neustar", category: "ad", domains: ["*.agkn.com"], totalExecutionTime: 14828, totalOccurrences: 344 }, { name: "AgilOne", category: "marketing", domains: ["*.agilone.com"], totalExecutionTime: 4190, totalOccurrences: 53 }, { name: "Agility", category: "hosting", domains: ["*.agilitycms.com"], totalExecutionTime: 3079, totalOccurrences: 4 }, { name: "Ahalogy", + category: "social", domains: ["*.ahalogy.com"] }, { name: "Aheadworks", category: "utility", domains: ["*.aheadworks.com"] }, { name: "AirPR", category: "analytics", domains: ["*.airpr.com"], totalExecutionTime: 416, totalOccurrences: 5 }, { name: "Aira", category: "ad", domains: ["*.aira.net"], examples: ["www.aira.net"] }, { name: "Airport Parking and Hotels", category: "content", domains: ["*.aph.com"], totalExecutionTime: 277, totalOccurrences: 3 }, { name: "Akanoo", category: "analytics", domains: ["*.akanoo.com"] }, { name: "Alchemy", company: "AndBeyond.Media", category: "ad", domains: ["*.andbeyond.media"], totalExecutionTime: 456340, totalOccurrences: 164 }, { name: "AlephD", company: "AOL", category: "ad", domains: ["*.alephd.com"] }, { name: "AliveChat", company: "AYU Technology Solutions", category: "customer-success", domains: ["*.websitealive.com", "*.websitealive7.com"] }, { name: "All Access", category: "other", domains: ["*.allaccess.com.ph"] }, { name: "Alliance f\ +or Audited Media", category: "ad", domains: ["*.aamsitecertifier.com"] }, { name: "Allyde", category: "marketing", domains: ["*.mautic.com"] }, { name: "AlphaSSL", category: "utility", domains: ["*.alphassl.com"], totalExecutionTime: 1146, totalOccurrences: 10 }, { name: "Altitude", category: "ad", domains: ["*.altitudeplatform.com"] }, { name: "Altocloud", category: "analytics", domains: ["*.altocloud.com"] }, { name: "Amadeus", category: "content", domains: ["*.e-travel.com"] }, { name: "Amazon CloudFront", company: "Amazon", category: "utility", domains: ["cloudfront.net"] }, { name: "Ambassador", category: "ad", domains: ["*.getambassador.com"], totalExecutionTime: 21042, totalOccurrences: 89 }, { name: "Ambient", company: "Ericcson", category: "other", domains: ["*.adnetwork.vn", "*.ambientplatform.vn"] }, { name: "Amelia Communication", category: "hosting", domains: ["*.sara.media"] }, { name: "Amobee", category: "marketing", domains: ["*.amgdgt.com", "*.kontera.com"] }, { name: "\ +Amplience", category: "marketing", domains: ["*.10cms.com", "*.amplience.com", "*.amplience.net", "*.bigcontent.io", "*.adis.ws"], totalExecutionTime: 4093, totalOccurrences: 17 }, { name: "Amplitude Mobile Analytics", company: "Amplitude", category: "analytics", domains: ["*.amplitude.com", "d24n15hnbwhuhn.cloudfront.net"], totalExecutionTime: 8703641, totalOccurrences: 46524 }, { name: "Anametrix", company: "Ensighten", category: "analytics", domains: ["*.anametrix.com"] }, { name: "Ancora Platform", company: "Ancora Media Solutions", category: "ad", domains: ["*.ancoraplatform.com"] }, { name: "Anedot", category: "other", domains: ["*.anedot.com"], totalExecutionTime: 84655, totalOccurrences: 21 }, { name: "AnimateJS", category: "utility", domains: ["*.animatedjs.com"] }, { name: "AnswerDash", category: "customer-success", domains: ["*.answerdash.com"], examples: ["p1.answerdash.com"] }, { name: "Answers", category: "analytics", domains: ["*.answcdn.com", "*.answers.com", "*.dsply.c\ +om"] }, { name: "Apester", category: "analytics", domains: ["*.apester.com", "*.qmerce.com"], totalExecutionTime: 25294, totalOccurrences: 166 }, { name: "Apligraf SmartWeb", company: "Apligraf", category: "utility", domains: ["*.apligraf.com.br"] }, { name: "Appier", category: "ad", domains: ["*.appier.net"], totalExecutionTime: 124524, totalOccurrences: 826 }, { name: "Appsolute", category: "utility", homepage: "https://appsolute.us/", domains: ["dropahint.love"], examples: ["dropahint.love"], totalExecutionTime: 16362, totalOccurrences: 144 }, { name: "Apptus eSales", company: "Apptus", category: "analytics", domains: ["*.apptus.com"] }, { name: "Arbor", company: "LiveRamp", category: "other", domains: ["*.pippio.com"] }, { name: "Ardent Creative", category: "hosting", domains: ["*.ardentcreative.co.uk"] }, { name: "Arnold Clark Automobiles", category: "content", domains: ["*.arnoldclark.com"] }, { name: "Atom Content Marketing", category: "content", domains: ["*.atomvault.net"], examples: [ + "danu.atomvault.net"] }, { name: "Atom Data", category: "other", domains: ["*.atomdata.io"] }, { name: "Attribution", category: "ad", domains: ["*.attributionapp.com"], totalExecutionTime: 44124, totalOccurrences: 124 }, { name: "Audience 360", company: "Datapoint Media", category: "ad", domains: ["*.dpmsrv.com"], totalExecutionTime: 578723, totalOccurrences: 371 }, { name: "Audience Science", category: "ad", domains: ["*.revsci.net"] }, { name: "AudienceSearch", company: "Intimate Merger", category: "ad", domains: ["*.im-apps.net"], totalExecutionTime: 9114981, totalOccurrences: 46726 }, { name: "Auditorius", category: "ad", domains: ["*.audtd.com"] }, { name: "Augur", category: "analytics", domains: ["*.augur.io"] }, { name: "Auto Link Maker", company: "Apple", category: "ad", domains: ["*.apple.com"], examples: ["autolinkmaker.itunes.apple.com"], totalExecutionTime: 657122, totalOccurrences: 2479 }, { name: "Autopilot", category: "ad", domains: ["*.autopilothq.com"], totalExecutionTime: 15490, + totalOccurrences: 74 }, { name: "Avail", company: "RichRelevance", category: "ad", domains: ["*.avail.net"] }, { name: "AvantLink", category: "ad", domains: ["*.avmws.com"], totalExecutionTime: 417, totalOccurrences: 8 }, { name: "Avco Systems", category: "utility", domains: ["*.avcosystems.com"] }, { name: "Avid Media", category: "customer-success", domains: ["*.adspdbl.com", "*.metadsp.co.uk"], totalExecutionTime: 58, totalOccurrences: 1 }, { name: "Avocet Systems", category: "ad", domains: ["*.avocet.io", "ads.avct.cloud"] }, { name: "Avora", category: "analytics", domains: ["*.truedash.com"], examples: ["truetag.truedash.com"] }, { name: "Azure Traffic Manager", company: "Microsoft", category: "other", domains: ["*.gateway.net", "*.trafficmanager.net"], examples: ["analytics.gateway.net"], totalExecutionTime: 51660, totalOccurrences: 148 }, { name: "Azure Web Services", company: "Microsoft", category: "cdn", domains: ["*.azurewebsites.net", "*.azureedge.net", "*.msedge.net", "*\ +.windows.net"], totalExecutionTime: 35665078, totalOccurrences: 51378 }, { name: "BAM", category: "analytics", domains: ["*.bam-x.com"] }, { name: "Baifendian Technology", category: "marketing", domains: ["*.baifendian.com"] }, { name: "Bankrate", category: "utility", domains: ["*.bankrate.com"] }, { name: "BannerFlow", company: "Nordic Factory Solutions", category: "ad", domains: ["*.bannerflow.com"], totalExecutionTime: 50455, totalOccurrences: 42 }, { name: "Barclaycard SmartPay", company: "Barclaycard", category: "utility", domains: ["*.barclaycardsmartpay.com"] }, { name: "Barilliance", category: "analytics", domains: ["*.barilliance.net", "dn3y71tq7jf07.cloudfront.net"], totalExecutionTime: 7250, totalOccurrences: 26 }, { name: "Barnebys", category: "other", domains: ["*.barnebys.com"], totalExecutionTime: 59682, totalOccurrences: 57 }, { name: "Basis", company: "Basis Technologies", category: "ad", homepage: "https://basis.net/", domains: ["*.basis.net"], examples: ["cdn01.basis\ +.net"], totalExecutionTime: 215661, totalOccurrences: 2623 }, { name: "Batch Media", category: "ad", domains: ["*.t4ft.de"] }, { name: "Bauer Consumer Media", category: "content", domains: ["*.bauercdn.com", "*.greatmagazines.co.uk"], examples: ["www.greatmagazines.co.uk"] }, { name: "Baynote", category: "analytics", domains: ["*.baynote.net"] }, { name: "Bazaarvoice", category: "analytics", domains: ["*.bazaarvoice.com", "*.feedmagnet.com"], totalExecutionTime: 1664795, totalOccurrences: 3375 }, { name: "Beachfront Media", category: "ad", domains: ["*.bfmio.com"], totalExecutionTime: 7782, totalOccurrences: 771 }, { name: "BeamPulse", category: "analytics", domains: ["*.beampulse.com"] }, { name: "Beeswax", category: "ad", domains: ["*.bidr.io"], totalExecutionTime: 5298, totalOccurrences: 12735 }, { name: "Beetailer", category: "social", domains: ["*.beetailer.com"], examples: ["www.beetailer.com"] }, { name: "Best Of Media S.A.", category: "content", domains: ["*.servebom.com"], totalExecutionTime: 29, + totalOccurrences: 67 }, { name: "Bet365", category: "ad", domains: ["*.bet365affiliates.com"] }, { name: "Betfair", category: "other", domains: ["*.cdnbf.net"] }, { name: "Betgenius", company: "Genius Sports", category: "content", domains: ["*.connextra.com"], totalExecutionTime: 84739, totalOccurrences: 287 }, { name: "Better Banners", category: "ad", domains: ["*.betterbannerscloud.com"] }, { name: "Better Business Bureau", category: "analytics", domains: ["*.bbb.org"], totalExecutionTime: 10819, totalOccurrences: 78 }, { name: "Between Digital", category: "ad", domains: ["*.betweendigital.com"], totalExecutionTime: 88306, totalOccurrences: 787 }, { name: "BidTheatre", category: "ad", domains: ["*.bidtheatre.com"], totalExecutionTime: 23106, totalOccurrences: 252 }, { name: "Bidtellect", category: "ad", domains: ["*.bttrack.com"], totalExecutionTime: 2834, totalOccurrences: 19 }, { name: "Bigcommerce", category: "marketing", domains: ["*.bigcommerce.com"], totalExecutionTime: 45747978, + totalOccurrences: 19595 }, { name: "BitGravity", company: "Tata Communications", category: "content", domains: ["*.bitgravity.com"] }, { name: "Bitly", category: "utility", domains: ["*.bitly.com", "*.lemde.fr", "*.bit.ly"], totalExecutionTime: 2977, totalOccurrences: 8 }, { name: "Bizible", category: "ad", domains: ["*.bizible.com", "*.bizibly.com"], totalExecutionTime: 435247, totalOccurrences: 1186 }, { name: "Bizrate", category: "analytics", domains: ["*.bizrate.com"], totalExecutionTime: 11197, totalOccurrences: 57 }, { name: "BlastCasta", category: "social", domains: ["*.poweringnews.com"], examples: ["www.poweringnews.com"] }, { name: "Blindado", category: "utility", domains: ["*.siteblindado.com"], totalExecutionTime: 41, totalOccurrences: 1 }, { name: "Blis", category: "ad", domains: ["*.blismedia.com"] }, { name: "Blogg.se", category: "hosting", domains: ["*.cdnme.se", "*.publishme.se"] }, { name: "BloomReach", category: "ad", domains: ["*.brcdn.com", "*.brsrvr.com", "*.b\ +rsvr.com"], totalExecutionTime: 2695, totalOccurrences: 47 }, { name: "Bloomberg", category: "content", domains: ["*.gotraffic.net"] }, { name: "Shop Logic", company: "BloomReach", category: "marketing", domains: ["*.goshoplogic.com"] }, { name: "Blue State Digital", category: "ad", domains: ["*.bsd.net"] }, { name: "Blue Triangle Technologies", category: "analytics", domains: ["*.btttag.com"], totalExecutionTime: 102966, totalOccurrences: 182 }, { name: "BlueCava", category: "ad", domains: ["*.bluecava.com"], totalExecutionTime: 466075, totalOccurrences: 5165 }, { name: "BlueKai", company: "Oracle", category: "ad", domains: ["*.bkrtx.com", "*.bluekai.com"], totalExecutionTime: 4, totalOccurrences: 6 }, { name: "Bluecore", category: "analytics", domains: ["*.bluecore.com"], examples: ["www.bluecore.com"], totalExecutionTime: 83612, totalOccurrences: 225 }, { name: "Bluegg", category: "hosting", domains: ["d1va5oqn59yrvt.cloudfront.net"] }, { name: "Bold Commerce", category: "utility", domains: [ + "*.shappify-cdn.com", "*.shappify.com", "*.boldapps.net"], totalExecutionTime: 5072681, totalOccurrences: 9886 }, { name: "BoldChat", company: "LogMeIn", category: "customer-success", domains: ["*.boldchat.com"] }, { name: "Bombora", category: "ad", domains: ["*.mlno6.com"] }, { name: "Bonnier", category: "content", domains: ["*.bonniercorp.com"] }, { name: "Bookatable", category: "content", domains: ["*.bookatable.com", "*.livebookings.com"] }, { name: "Booking.com", category: "content", domains: ["*.bstatic.com"], totalExecutionTime: 1652677, totalOccurrences: 2448 }, { name: "Boomtrain", category: "ad", domains: ["*.boomtrain.com", "*.boomtrain.net"], totalExecutionTime: 360072, totalOccurrences: 2169 }, { name: "BoostSuite", category: "ad", domains: ["*.poweredbyeden.com"] }, { name: "Boostable", category: "ad", domains: ["*.boostable.com"] }, { name: "Bootstrap Chinese network", category: "cdn", domains: ["*.bootcss.com"], totalExecutionTime: 427117, totalOccurrences: 881 }, { + name: "Booxscale", category: "ad", domains: ["*.booxscale.com"] }, { name: "Borderfree", company: "pitney bowes", category: "utility", domains: ["*.borderfree.com", "*.fiftyone.com"] }, { name: "BowNow", category: "analytics", homepage: "https://bow-now.jp/", domains: ["*.bownow.jp"], examples: ["contents.bownow.jp"], totalExecutionTime: 1298132, totalOccurrences: 2410 }, { name: "Box", category: "hosting", domains: ["*.box.com"], totalExecutionTime: 15191, totalOccurrences: 223 }, { name: "Boxever", category: "analytics", domains: ["*.boxever.com"] }, { name: "Braintree Payments", company: "Paypal", category: "utility", domains: ["*.braintreegateway.com"], totalExecutionTime: 171291, totalOccurrences: 1141 }, { name: "Branch Metrics", category: "ad", domains: ["*.branch.io", "*.app.link"], totalExecutionTime: 441792, totalOccurrences: 8288 }, { name: "Brand Finance", category: "other", domains: ["*.brandirectory.com"] }, { name: "Brand View", category: "analytics", domains: ["*.br\ +andview.com"] }, { name: "Brandscreen", category: "ad", domains: ["*.rtbidder.net"], examples: ["match.rtbidder.net"] }, { name: "BridgeTrack", company: "Sapient", category: "ad", domains: ["*.bridgetrack.com"] }, { name: "BrightRoll", company: "Yahoo!", category: "ad", domains: ["*.btrll.com"] }, { name: "BrightTag / Signal", company: "Signal", homepage: "https://www.signal.co", category: "tag-manager", domains: ["*.btstatic.com", "*.thebrighttag.com"] }, { name: "Brightcove ZenCoder", company: "Brightcove", category: "other", domains: ["*.zencoder.net"] }, { name: "Bronto Software", category: "marketing", domains: ["*.bm23.com", "*.bronto.com", "*.brontops.com"] }, { name: "Browser-Update.org", category: "other", domains: ["*.browser-update.org"] }, { name: "Buffer", category: "social", domains: ["*.bufferapp.com"], totalExecutionTime: 535, totalOccurrences: 7 }, { name: "Bugsnag", category: "utility", domains: ["*.bugsnag.com", "d2wy8f7a9ursnm.cloudfront.net"], examples: ["notify.bu\ +gsnag.com"], totalExecutionTime: 6197502, totalOccurrences: 15069 }, { name: "Burst Media", category: "ad", domains: ["*.burstnet.com", "*.1rx.io"], examples: ["usermatch.burstnet.com"], totalExecutionTime: 1618, totalOccurrences: 52 }, { name: "Burt", category: "analytics", domains: ["*.richmetrics.com", "*.burt.io"] }, { name: "Business Message", category: "ad", domains: ["*.message-business.com"], totalExecutionTime: 7310, totalOccurrences: 21 }, { name: "Business Week", company: "Bloomberg", category: "social", domains: ["*.bwbx.io"], totalExecutionTime: 67737, totalOccurrences: 9 }, { name: "Buto", company: "Big Button", category: "ad", domains: ["*.buto.tv"] }, { name: "Button", category: "ad", domains: ["*.btncdn.com"] }, { name: "BuySellAds", category: "ad", domains: ["*.buysellads.com", "*.buysellads.net"], totalExecutionTime: 179225, totalOccurrences: 170 }, { name: "BuySight (AOL)", category: "ad", domains: ["*.pulsemgr.com"] }, { name: "Buyapowa", category: "ad", domains: [ + "*.co-buying.com"], totalExecutionTime: 3038, totalOccurrences: 37 }, { name: "BuzzFeed", category: "social", domains: ["*.buzzfed.com", "*.buzzfeed.com"], totalExecutionTime: 14608, totalOccurrences: 2 }, { name: "C1X", category: "ad", domains: ["*.c1exchange.com"] }, { name: "C3 Metrics", category: "analytics", domains: ["*.c3tag.com"], totalExecutionTime: 18122, totalOccurrences: 153 }, { name: "CANDDi", company: "Campaign and Digital Intelligence", category: "ad", domains: ["*.canddi.com"], totalExecutionTime: 84756, totalOccurrences: 150 }, { name: "CCM benchmark Group", category: "social", domains: ["*.ccm2.net"] }, { name: "CD Networks", category: "utility", domains: ["*.gccdn.net"] }, { name: "CDN Planet", category: "analytics", domains: ["*.cdnplanet.com"] }, { name: "InAuth", category: "utility", homepage: "https://www.inauth.com/", domains: ["*.cdn-net.com"], examples: ["uk.cdn-net.com"], totalExecutionTime: 306346, totalOccurrences: 298 }, { name: "CJ Affiliate", company: "\ +Conversant", category: "ad", domains: ["*.cj.com", "*.dpbolvw.net"], totalExecutionTime: 7725, totalOccurrences: 17 }, { name: "CJ Affiliate by Conversant", company: "Conversant", category: "ad", domains: ["*.ftjcfx.com"], totalExecutionTime: 8, totalOccurrences: 4 }, { name: "CNBC", category: "content", domains: ["*.cnbc.com"], totalExecutionTime: 11468, totalOccurrences: 12 }, { name: "CNET Content Solutions", company: "CBS Interactive", category: "content", domains: ["*.cnetcontent.com"], examples: ["cdn.cnetcontent.com", "ws.cnetcontent.com"] }, { name: "CPEx", category: "content", domains: ["*.cpex.cz"], totalExecutionTime: 763356, totalOccurrences: 1104 }, { name: "CPXi", category: "ad", domains: ["*.cpxinteractive.com"] }, { name: "CUBED Attribution", company: "CUBED", category: "ad", domains: ["*.withcubed.com"], examples: ["data.withcubed.com"] }, { name: "Cachefly", category: "utility", domains: ["*.cachefly.net"], totalExecutionTime: 128046, totalOccurrences: 258 }, { name: "\ +Calendly", category: "other", domains: ["*.calendly.com"], totalExecutionTime: 8622733, totalOccurrences: 4604 }, { name: "CallRail", category: "analytics", domains: ["*.callrail.com"], totalExecutionTime: 8080185, totalOccurrences: 29537 }, { name: "CallTrackingMetrics", category: "analytics", domains: ["*.tctm.co"], totalExecutionTime: 1981698, totalOccurrences: 7503 }, { name: "Canned Banners", category: "ad", domains: ["*.cannedbanners.com"] }, { name: "Canopy Labs", category: "analytics", domains: ["*.canopylabs.com"] }, { name: "Capita", category: "utility", domains: ["*.crcom.co.uk"], examples: ["emmsrep.crcom.co.uk"] }, { name: "Captify Media", category: "ad", domains: ["*.cpx.to"], totalExecutionTime: 1519, totalOccurrences: 31 }, { name: "Captiify", category: "ad", domains: ["*.captifymedia.com"] }, { name: "Captivate Ai", category: "ad", domains: ["*.captivate.ai"] }, { name: "Captora", category: "marketing", domains: ["*.captora.com"] }, { name: "Carcloud", category: "other", + domains: ["*.carcloud.co.uk"] }, { name: "Cardlytics", category: "ad", domains: ["*.cardlytics.com"] }, { name: "Cardosa Enterprises", category: "analytics", domains: ["*.y-track.com"], totalExecutionTime: 778, totalOccurrences: 17 }, { name: "Caspian Media", category: "ad", domains: ["*.caspianmedia.com"] }, { name: "Cast", category: "utility", domains: ["*.cast.rocks"] }, { name: "Catch", category: "other", domains: ["*.getcatch.com"], examples: ["app.getcatch.com", "assets.getcatch.com", "js.getcatch.com"], totalExecutionTime: 18282, totalOccurrences: 40 }, { name: "Cavisson", category: "analytics", domains: ["*.cavisson.com"] }, { name: "Cedato", category: "ad", domains: ["*.algovid.com", "*.vdoserv.com"] }, { name: "Celebrus Technologies", category: "analytics", domains: ["*.celebrus.com"] }, { name: "Celtra", category: "ad", domains: ["*.celtra.com"], totalExecutionTime: 369517, totalOccurrences: 427 }, { name: "Centro", category: "ad", domains: ["*.brand-server.com"] }, { name: "\ +Ceros", category: "other", domains: ["ceros.com", "view.ceros.com"], totalExecutionTime: 64139, totalOccurrences: 149 }, { name: "Ceros Analytics", company: "Ceros", category: "analytics", domains: ["api.ceros.com"] }, { name: "Certona", category: "analytics", domains: ["*.certona.net"], totalExecutionTime: 376, totalOccurrences: 4 }, { name: "Certum", category: "utility", domains: ["*.ocsp-certum.com", "*.certum.pl"], totalExecutionTime: 8544, totalOccurrences: 3 }, { name: "Cgrdirect", category: "other", domains: ["*.cgrdirect.co.uk"] }, { name: "Channel 5 Media", category: "ad", domains: ["*.five.tv"] }, { name: "Channel.me", category: "customer-success", domains: ["*.channel.me"] }, { name: "ChannelAdvisor", category: "ad", domains: ["*.channeladvisor.com", "*.searchmarketing.com"], totalExecutionTime: 3385, totalOccurrences: 25 }, { name: "ChannelApe", company: "ChannelApe", category: "other", homepage: "https://www.channelape.com/", domains: ["*.channelape.com"], examples: ["call\ +backs.channelape.com"] }, { name: "Chargeads Oscar", company: "Chargeads", category: "ad", domains: ["*.chargeads.com"] }, { name: "Charities Aid Foundation", category: "utility", domains: ["*.cafonline.org"], totalExecutionTime: 4368, totalOccurrences: 7 }, { name: "Chartbeat", category: "analytics", domains: ["*.chartbeat.com", "*.chartbeat.net"], totalExecutionTime: 1270560, totalOccurrences: 6246 }, { name: "Cheapflights Media", company: "Momondo", category: "content", domains: ["*.momondo.net"] }, { name: "CheckM8", category: "ad", domains: ["*.checkm8.com"] }, { name: "CheckRate", company: "FreeStart", category: "utility", domains: ["*.checkrate.co.uk"] }, { name: "Checkfront", category: "other", domains: ["*.checkfront.com", "dcg3jth5savst.cloudfront.net"], totalExecutionTime: 279282, totalOccurrences: 152 }, { name: "CheetahMail", company: "Experian", category: "ad", domains: ["*.chtah.com"] }, { name: "Chitika", category: "ad", domains: ["*.chitika.net"] }, { name: "ChoiceStre\ +am", category: "ad", domains: ["*.choicestream.com"] }, { name: "Cint", category: "social", domains: ["*.cint.com"], totalExecutionTime: 111659, totalOccurrences: 33 }, { name: "Civic", category: "hosting", domains: ["*.civiccomputing.com"], totalExecutionTime: 2815742, totalOccurrences: 7253 }, { name: "ClearRise", category: "customer-success", domains: ["*.clearrise.com"] }, { name: "Clearstream", category: "ad", domains: ["*.clrstm.com"] }, { name: "Clerk.io ApS", category: "analytics", domains: ["*.clerk.io"], totalExecutionTime: 1196778, totalOccurrences: 1915 }, { name: "CleverDATA", category: "ad", domains: ["*.1dmp.io"] }, { name: "CleverTap", category: "analytics", domains: ["d2r1yp2w7bby2u.cloudfront.net"], totalExecutionTime: 163519, totalOccurrences: 1321 }, { name: "Click Density", category: "analytics", domains: ["*.clickdensity.com"] }, { name: "Click4Assistance", category: "customer-success", domains: ["*.click4assistance.co.uk"], totalExecutionTime: 22710, totalOccurrences: 178 }, + { name: "ClickDesk", category: "customer-success", domains: ["*.clickdesk.com", "d1gwclp1pmzk26.cloudfront.net"], totalExecutionTime: 74975, totalOccurrences: 595 }, { name: "ClickDimensions", category: "ad", domains: ["*.clickdimensions.com"], totalExecutionTime: 125295, totalOccurrences: 262 }, { name: "Clickadu (Winner Solutions)", category: "ad", domains: ["*.clickadu.com"], totalExecutionTime: 10740, totalOccurrences: 4 }, { name: "Clickagy Audience Lab", company: "Clickagy", category: "ad", domains: ["*.clickagy.com"], examples: ["aorta.clickagy.com"], totalExecutionTime: 44558, totalOccurrences: 667 }, { name: "Clickio", category: "ad", domains: [] }, { name: "Clicktale", category: "analytics", domains: ["*.cdngc.net", "*.clicktale.net"], examples: ["clicktalecdn.sslcs.cdngc.net"], totalExecutionTime: 288716, totalOccurrences: 256 }, { name: "Clicktripz", category: "content", domains: ["*.clicktripz.com"], examples: ["static.clicktripz.com", "www.clicktripz.com"], totalExecutionTime: 502041, + totalOccurrences: 354 }, { name: "Clik.com Websites", category: "content", domains: ["*.clikpic.com"] }, { name: "Cloud Technologies", category: "ad", domains: ["*.behavioralengine.com", "*.behavioralmailing.com"] }, { name: "Cloud-A", category: "other", domains: ["*.bulkstorage.ca"] }, { name: "Cloud.typography", company: "Hoefler & Co", category: "cdn", domains: ["*.typography.com"], totalExecutionTime: 3308, totalOccurrences: 364 }, { name: "CloudSponge", category: "ad", domains: ["*.cloudsponge.com"] }, { name: "CloudVPS", category: "other", domains: ["*.adoftheyear.com", "*.objectstore.eu"] }, { name: "Cloudinary", category: "content", domains: ["*.cloudinary.com"], totalExecutionTime: 1188126, totalOccurrences: 2129 }, { name: "Cloudqp", company: "Cloudwp", category: "other", domains: ["*.cloudwp.io"] }, { name: "Cludo", category: "utility", domains: ["*.cludo.com"], totalExecutionTime: 25376, totalOccurrences: 249 }, { name: "Cognesia", category: "marketing", domains: ["\ +*.intelli-direct.com"] }, { name: "CogoCast", company: "Cogo Labs", category: "ad", domains: ["*.cogocast.net"] }, { name: "Colbenson", category: "utility", domains: ["*.colbenson.com"] }, { name: "Collective", category: "ad", domains: ["*.collective-media.net"] }, { name: "Com Laude", category: "other", domains: ["*.gdimg.net"] }, { name: "Comm100", category: "customer-success", domains: ["*.comm100.com"], totalExecutionTime: 469389, totalOccurrences: 1045 }, { name: "CommerceHub", category: "marketing", domains: ["*.mercent.com"] }, { name: "Commission Factory", category: "ad", domains: ["*.cfjump.com"], totalExecutionTime: 961, totalOccurrences: 12 }, { name: "Communicator", category: "ad", domains: ["*.communicatorcorp.com", "*.communicatoremail.com"] }, { name: "Comodo", category: "utility", domains: ["*.comodo.com", "*.trust-provider.com", "*.trustlogo.com", "*.usertrust.com", "*.comodo.net"], examples: ["ocsp.trust-provider.com"], totalExecutionTime: 41752, totalOccurrences: 34 }, + { name: "Comodo Certificate Authority", company: "Comodo", category: "utility", domains: ["crt.comodoca.com", "*.comodoca4.com", "ocsp.comodoca.com", "ocsp.usertrust.com", "crt.usertrust.com"], examples: ["ocsp.comodoca4.com"] }, { name: "Compete", company: "Millwood Brown Digital", category: "analytics", domains: ["*.c-col.com", "*.compete.com"] }, { name: "Compuware", category: "analytics", domains: ["*.axf8.net"] }, { name: "Conductrics", category: "analytics", domains: ["*.conductrics.com"], examples: ["cdn-v3.conductrics.com"], totalExecutionTime: 12705, totalOccurrences: 61 }, { name: "Confirmit", category: "analytics", domains: ["*.confirmit.com"], totalExecutionTime: 32100, totalOccurrences: 195 }, { name: "Connatix", category: "ad", domains: ["*.connatix.com"], totalExecutionTime: 6751327, totalOccurrences: 1195 }, { name: "Connect Events", category: "hosting", domains: ["*.connectevents.com.au"] }, { name: "Constant Contact", category: "ad", domains: ["*.ctctcdn.com"], totalExecutionTime: 604932, + totalOccurrences: 17528 }, { name: "Constructor.io", category: "utility", domains: ["*.cnstrc.com"] }, { name: "Contabo", category: "hosting", domains: ["185.2.100.179"] }, { name: "Content Media Corporation", category: "content", domains: ["*.contentmedia.eu"] }, { name: "ContentSquare", category: "analytics", domains: ["d1m6l9dfulcyw7.cloudfront.net", "*.content-square.net", "*.contentsquare.net"], totalExecutionTime: 3626830, totalOccurrences: 2948 }, { name: "ContextWeb", category: "ad", domains: ["*.contextweb.com"], totalExecutionTime: 32437, totalOccurrences: 1909 }, { name: "Continental Exchange Solutions", category: "utility", domains: ["*.hifx.com"] }, { name: "Converge-Digital", category: "ad", domains: ["*.converge-digital.com"], examples: ["ads.converge-digital.com"] }, { name: "Conversant", category: "analytics", domains: ["*.dotomi.com", "*.dtmpub.com", "*.emjcd.com", "mediaplex.com", "*.tqlkg.com", "*.fastclick.net"], examples: ["www.tqlkg.com"], totalExecutionTime: 6531550, + totalOccurrences: 54802 }, { name: "Conversant Ad Server", company: "Conversant", category: "ad", domains: ["adfarm.mediaplex.com", "*.mediaplex.com"] }, { name: "Conversant Tag Manager", company: "Conversant", category: "tag-manager", domains: ["*.mplxtms.com"], totalExecutionTime: 14146, totalOccurrences: 58 }, { name: "Conversio", category: "ad", domains: ["*.conversio.com"] }, { name: "Conversion Labs", category: "ad", domains: ["*.net.pl"], examples: ["conversionlabs.net.pl"], totalExecutionTime: 3243395, totalOccurrences: 1898 }, { name: "Conversion Logic", category: "ad", domains: ["*.conversionlogic.net"] }, { name: "Convert Insights", category: "analytics", domains: ["*.convertexperiments.com"], totalExecutionTime: 2575826, totalOccurrences: 4385 }, { name: "ConvertMedia", category: "ad", domains: ["*.admailtiser.com", "*.basebanner.com", "*.cmbestsrv.com", "*.vidfuture.com", "*.zorosrv.com"], examples: ["www.cmbestsrv.com"] }, { name: "Convertro", category: "ad", domains: [ + "*.convertro.com"] }, { name: "Conviva", category: "content", domains: ["*.conviva.com"], totalExecutionTime: 2955, totalOccurrences: 2 }, { name: "Cookie Reports", category: "utility", domains: ["*.cookiereports.com"], totalExecutionTime: 280810, totalOccurrences: 671 }, { name: "Cookie-Script.com", category: "utility", domains: ["*.cookie-script.com"], totalExecutionTime: 15051619, totalOccurrences: 58095 }, { name: "CookieQ", company: "Baycloud Systems", category: "utility", domains: ["*.cookieq.com"] }, { name: "CoolaData", category: "analytics", domains: ["*.cooladata.com"], totalExecutionTime: 1165, totalOccurrences: 15 }, { name: "CopperEgg", category: "analytics", domains: ["*.copperegg.com", "d2vig74li2resi.cloudfront.net"] }, { name: "Council ad Network", category: "ad", domains: ["*.counciladvertising.net"], totalExecutionTime: 18621, totalOccurrences: 94 }, { name: "Covert Pics", category: "content", domains: ["*.covet.pics"], totalExecutionTime: 4496, totalOccurrences: 55 }, + { name: "Cox Digital Solutions", category: "ad", domains: ["*.afy11.net"] }, { name: "Creafi Online Media", category: "ad", domains: ["*.creafi-online-media.com"] }, { name: "Creators", category: "content", domains: ["*.creators.co"] }, { name: "Crimson Hexagon Analytics", company: "Crimson Hexagon", category: "analytics", domains: ["*.hexagon-analytics.com"] }, { name: "Crimtan", category: "ad", domains: ["*.ctnsnet.com"], totalExecutionTime: 59150, totalOccurrences: 74818 }, { name: "Cross Pixel Media", category: "ad", domains: ["*.crsspxl.com"], totalExecutionTime: 493, totalOccurrences: 8 }, { name: "Crosswise", category: "ad", domains: ["*.univide.com"], examples: ["p.univide.com"] }, { name: "Crowd Control", company: "Lotame", category: "ad", domains: ["*.crwdcntrl.net"], totalExecutionTime: 16298725, totalOccurrences: 101196 }, { name: "Crowd Ignite", category: "ad", domains: ["*.crowdignite.com"] }, { name: "CrowdTwist", category: "ad", domains: ["*.crowdtwist.com"] }, { name: "\ +Crowdskout", category: "ad", domains: ["*.crowdskout.com"] }, { name: "Crowdynews", category: "social", domains: ["*.breakingburner.com"] }, { name: "Curalate", category: "marketing", domains: ["*.curalate.com", "d116tqlcqfmz3v.cloudfront.net"], totalExecutionTime: 628884, totalOccurrences: 683 }, { name: "Customer Acquisition Cloud", company: "[24]7", category: "ad", domains: ["*.campanja.com"] }, { name: "Customer.io", category: "ad", domains: ["*.customer.io"], totalExecutionTime: 210609, totalOccurrences: 1268 }, { name: "Custora", category: "analytics", domains: ["*.custora.com"] }, { name: "Cxense", category: "ad", domains: ["*.cxense.com", "*.cxpublic.com", "*.emediate.dk", "*.emediate.eu"], totalExecutionTime: 2218364, totalOccurrences: 3708 }, { name: "CyberKnight", company: "Namogoo", category: "utility", domains: ["*.namogoo.com"] }, { name: "CyberSource (Visa)", category: "utility", domains: ["*.authorize.net"], totalExecutionTime: 339030, totalOccurrences: 2682 }, { name: "\ +Cybernet Quest", category: "analytics", domains: ["*.cqcounter.com"] }, { name: "D.A. Consortium", category: "ad", domains: ["*.eff1.net"] }, { name: "D4t4 Solutions", category: "analytics", domains: ["*.u5e.com"] }, { name: "DCSL Software", category: "hosting", domains: ["*.dcslsoftware.com"] }, { name: "DMG Media", category: "content", domains: ["*.mol.im", "*.and.co.uk", "*.anm.co.uk", "*.dailymail.co.uk"], totalExecutionTime: 37855, totalOccurrences: 15 }, { name: "DTSCOUT", category: "ad", domains: ["*.dtscout.com"], totalExecutionTime: 645362, totalOccurrences: 8311 }, { name: "Dailykarma", category: "utility", homepage: "https://www.dailykarma.com/", domains: ["*.dailykarma.io"], examples: ["assets.dailykarma.io"], totalExecutionTime: 122378, totalOccurrences: 477 }, { name: "Dailymotion", category: "content", domains: ["*.dailymotion.com", "*.dmxleo.com", "*.dm.gg", "*.pxlad.io", "*.dmcdn.net", "*.sublimevideo.net"], examples: ["ad.pxlad.io", "www.dailymotion.com"], totalExecutionTime: 56076026, + totalOccurrences: 5142 }, { name: "Dash Hudson", company: "Dash Hudson", category: "content", domains: ["*.dashhudson.com"], examples: ["cdn.dashhudson.com"], totalExecutionTime: 154963, totalOccurrences: 91 }, { name: "Datacamp", category: "utility", domains: ["*.cdn77.org"], totalExecutionTime: 3303608, totalOccurrences: 1181 }, { name: "Datalicious", category: "tag-manager", domains: ["*.supert.ag", "*.optimahub.com"] }, { name: "Datalogix", category: "ad", domains: ["*.nexac.com"] }, { name: "Datawrapper", category: "utility", domains: ["*.datawrapper.de", "*.dwcdn.net"], examples: ["www.datawrapper.de"], totalExecutionTime: 951486, totalOccurrences: 249 }, { name: "Dataxu", category: "marketing", domains: ["*.w55c.net"], totalExecutionTime: 10, totalOccurrences: 5 }, { name: "DatoCMS", homepage: "https://www.datocms.com/", category: "content", domains: ["*.datocms-assets.com"], examples: ["www.datocms-assets.com"] }, { name: "Datonics", category: "ad", domains: ["*.pro-market.\ +net"], examples: ["pbid.pro-market.net"], totalExecutionTime: 16955, totalOccurrences: 254 }, { name: "Dealtime", category: "content", domains: ["*.dealtime.com"] }, { name: "Debenhams Geo Location", company: "Debenhams", category: "utility", domains: ["176.74.183.134"] }, { name: "Decibel Insight", category: "analytics", domains: ["*.decibelinsight.net"], totalExecutionTime: 995190, totalOccurrences: 691 }, { name: "Deep Forest Media", company: "Rakuten", category: "ad", domains: ["*.dpclk.com"] }, { name: "DeepIntent", category: "ad", domains: ["*.deepintent.com"], totalExecutionTime: 3875, totalOccurrences: 206 }, { name: "Delicious Media", category: "social", domains: ["*.delicious.com"] }, { name: "Delineo", category: "ad", domains: ["*.delineo.com"], examples: ["www.delineo.com"] }, { name: "Delta Projects AB", category: "ad", domains: ["*.de17a.com"], totalExecutionTime: 90548, totalOccurrences: 382 }, { name: "Demand Media", category: "content", domains: ["*.dmtracker.com"] }, { + name: "DemandBase", category: "marketing", domains: ["*.demandbase.com"], totalExecutionTime: 393206, totalOccurrences: 2552 }, { name: "DemandJump", category: "analytics", domains: ["*.demandjump.com"] }, { name: "Dennis Publishing", category: "content", domains: ["*.alphr.com"] }, { name: "Devatics", category: "analytics", domains: ["*.devatics.com", "*.devatics.io"] }, { name: "Developer Media", category: "ad", domains: ["*.developermedia.com"], totalExecutionTime: 4416, totalOccurrences: 17 }, { name: "DialogTech", category: "ad", domains: ["*.dialogtech.com"] }, { name: "DialogTech SourceTrak", company: "DialogTech", category: "ad", domains: ["d31y97ze264gaa.cloudfront.net"] }, { name: "DigiCert", category: "utility", domains: ["*.digicert.com"], examples: ["ocsp.digicert.com"], totalExecutionTime: 26560, totalOccurrences: 83 }, { name: "Digioh", category: "ad", domains: ["*.lightboxcdn.com"], totalExecutionTime: 1347082, totalOccurrences: 1303 }, { name: "Digital Look", category: "\ +content", domains: ["*.digitallook.com"] }, { name: "Digital Media Exchange", company: "NDN", category: "content", domains: ["*.newsinc.com"] }, { name: "Digital Millennium Copyright Act Services", category: "utility", domains: ["*.dmca.com"], totalExecutionTime: 8820, totalOccurrences: 70 }, { name: "Digital Ocean", category: "other", domains: ["95.85.62.56"] }, { name: "Digital Remedy", category: "ad", domains: ["*.consumedmedia.com"] }, { name: "Digital Window", category: "ad", domains: ["*.awin1.com", "*.zenaps.com"], totalExecutionTime: 195, totalOccurrences: 4 }, { name: "DigitalScirocco", category: "analytics", domains: ["*.digitalscirocco.net"] }, { name: "Digitial Point", category: "utility", domains: ["*.dpstatic.com"] }, { name: "Diligent (Adnetik)", category: "ad", domains: ["*.wtp101.com"] }, { name: "Directed Edge", category: "social", domains: ["*.directededge.com"], examples: ["shopify.directededge.com"], totalExecutionTime: 8371, totalOccurrences: 81 }, { name: "Distri\ +bute Travel", category: "ad", domains: ["*.dtrck.net"] }, { name: "District M", category: "ad", domains: ["*.districtm.io"] }, { name: "DistroScale", category: "ad", domains: ["*.jsrdn.com"], totalExecutionTime: 186009, totalOccurrences: 198 }, { name: "Divido", category: "utility", domains: ["*.divido.com"] }, { name: "Dow Jones", category: "content", domains: ["*.dowjones.com", "*.dowjoneson.com"] }, { name: "Drifty Co", category: "utility", domains: ["*.onicframework.com"] }, { name: "Drip", company: "The Numa Group", category: "ad", domains: ["*.getdrip.com"], totalExecutionTime: 120918, totalOccurrences: 1350 }, { name: "Dropbox", category: "utility", domains: ["*.dropboxusercontent.com"], totalExecutionTime: 142552, totalOccurrences: 145 }, { name: "Dyn Real User Monitoring", company: "Dyn", category: "analytics", domains: ["*.jisusaiche.biz", "*.dynapis.com", "*.jisusaiche.com", "*.dynapis.info"], examples: ["beacon.rum.dynapis.com"] }, { name: "DynAdmic", category: "ad", domains: [ + "*.dyntrk.com"] }, { name: "Dynamic Converter", category: "utility", domains: ["*.dynamicconverter.com"], totalExecutionTime: 58723, totalOccurrences: 96 }, { name: "Dynamic Dummy Image Generator", company: "Open Source", category: "utility", domains: ["*.dummyimage.com"] }, { name: "Dynamic Logic", category: "ad", domains: ["*.dl-rms.com", "*.questionmarket.com"] }, { name: "Dynamic Yield", category: "customer-success", domains: ["*.dynamicyield.com"], totalExecutionTime: 3580074, totalOccurrences: 1843 }, { name: "Dynatrace", category: "analytics", domains: ["*.ruxit.com", "js-cdn.dynatrace.com"], totalExecutionTime: 4106731, totalOccurrences: 3221 }, { name: "ec-concier", homepage: "https://ec-concier.com/", category: "marketing", domains: ["*.ec-concier.com"], examples: ["s.ec-concier.com", "gsync.ec-concier.com"] }, { name: "ECT News Network", category: "content", domains: ["*.ectnews.com"] }, { name: "ELITechGroup", category: "analytics", domains: ["*.elitechnology.com"] }, { + name: "EMAP", category: "content", domains: ["*.emap.com"] }, { name: "EMedia Solutions", category: "ad", domains: ["*.e-shots.eu"], examples: ["www.e-shots.eu"] }, { name: "EQ works", category: "ad", domains: ["*.eqads.com"] }, { name: "ESV Digital", category: "analytics", domains: ["*.esearchvision.com"] }, { name: "Ebiquity", category: "analytics", domains: ["*.ebiquitymedia.com"] }, { name: "Eco Rebates", category: "ad", domains: ["*.ecorebates.com"] }, { name: "Ecwid", category: "hosting", domains: ["*.ecwid.com", "*.shopsettings.com", "d3fi9i0jj23cau.cloudfront.net", "d3j0zfs7paavns.cloudfront.net"], totalExecutionTime: 3757012, totalOccurrences: 4362 }, { name: "Edge Web Fonts", company: "Adobe Systems", category: "cdn", domains: ["*.edgefonts.net"], examples: ["use.edgefonts.net"] }, { name: "Edition Digital", category: "ad", domains: ["*.editiondigital.com"] }, { name: "Edot Web Technologies", category: "hosting", domains: ["*.edot.co.za"] }, { name: "Effective Measure", category: "\ +ad", domains: ["*.effectivemeasure.net"], totalExecutionTime: 17, totalOccurrences: 1 }, { name: "Effiliation sa", category: "ad", domains: ["*.effiliation.com"], totalExecutionTime: 108, totalOccurrences: 3 }, { name: "Ekm Systems", category: "analytics", domains: ["*.ekmsecure.com", "*.ekmpinpoint.co.uk"], examples: ["globalstats.ekmsecure.com"], totalExecutionTime: 67875, totalOccurrences: 789 }, { name: "Elastera", category: "hosting", domains: ["*.elastera.net"] }, { name: "Elastic Ad", category: "ad", domains: ["*.elasticad.net"], totalExecutionTime: 30225, totalOccurrences: 137 }, { name: "Elastic Load Balancing", company: "Amazon Web Services", category: "hosting", domains: ["*.105app.com"], examples: ["rhpury.105app.com", "rhxtd.105app.com"] }, { name: "Elecard StreamEye", company: "Elecard", category: "other", domains: ["*.streameye.net"] }, { name: "Elevate", company: "Elevate Technology Solutions", category: "utility", domains: ["*.elevaate.technology"] }, { name: "Elicit", + category: "utility", domains: ["*.elicitapp.com"] }, { name: "Elogia", category: "ad", domains: ["*.elogia.net"] }, { name: "Email Attitude", company: "1000mercis", category: "ad", domains: ["*.email-attitude.com"] }, { name: "EmailCenter", category: "ad", domains: ["*.emailcenteruk.com"] }, { name: "Embedly", category: "content", domains: ["*.embedly.com", "*.embed.ly"], totalExecutionTime: 5014487, totalOccurrences: 10836 }, { name: "EmpathyBroker Site Search", company: "EmpathyBroker", category: "utility", domains: ["*.empathybroker.com"] }, { name: "Enfusen", category: "analytics", domains: ["*.enfusen.com"] }, { name: "Engadget", company: "Engadget (AOL)", category: "content", domains: ["*.gdgt.com"], examples: ["media.gdgt.com"] }, { name: "Engagio", category: "marketing", domains: ["*.engagio.com"] }, { name: "Ensighten Manage", company: "Ensighten", category: "tag-manager", domains: ["*.levexis.com"] }, { name: "EntityLink", category: "other", domains: ["*.entitytag.co.uk"] }, + { name: "Entrust Datacard", category: "utility", domains: ["*.entrust.com", "*.entrust.net"], examples: ["ocsp.entrust.com", "ocsp.entrust.net"], totalExecutionTime: 14041, totalOccurrences: 3 }, { name: "Equiniti", category: "utility", domains: ["*.equiniti.com"] }, { name: "Errorception", category: "utility", domains: ["*.errorception.com"] }, { name: "Esri ArcGIS", company: "Esri", category: "utility", domains: ["*.arcgis.com", "*.arcgisonline.com"], totalExecutionTime: 21967746, totalOccurrences: 3432 }, { name: "Ethnio", category: "analytics", domains: ["*.ethn.io"] }, { name: "Eulerian Technologies", category: "ad", domains: ["*.eolcdn.com"] }, { name: "Euroland", category: "utility", domains: ["*.euroland.com"], totalExecutionTime: 1, totalOccurrences: 3 }, { name: "European Interactive Digital ad Alli", category: "utility", domains: ["*.edaa.eu"] }, { name: "Eventbrite", category: "hosting", domains: ["*.evbuc.com", "*.eventbrite.co.uk"], totalExecutionTime: 4667, totalOccurrences: 33 }, + { name: "Everflow", category: "analytics", domains: ["*.tp88trk.com"], examples: ["www.tp88trk.com"], totalExecutionTime: 110842, totalOccurrences: 185 }, { name: "Evergage", category: "analytics", domains: ["*.evergage.com", "*.evgnet.com"], examples: ["cdn.evgnet.com"], totalExecutionTime: 1095634, totalOccurrences: 2491 }, { name: "Everquote", category: "content", domains: ["*.evq1.com"] }, { name: "Everyday Health", category: "ad", domains: ["*.agoramedia.com"] }, { name: "Evidon", category: "analytics", domains: ["*.evidon.com"], totalExecutionTime: 1260409, totalOccurrences: 2482 }, { name: "Evolve Media", category: "content", domains: ["*.evolvemediallc.com"] }, { name: "Exactag", category: "ad", domains: ["*.exactag.com"], totalExecutionTime: 662, totalOccurrences: 6 }, { name: "ExoClick", category: "ad", domains: ["*.exoclick.com"], totalExecutionTime: 69348, totalOccurrences: 568 }, { name: "Expedia", category: "content", domains: ["*.travel-assets.com", "*.trvl-media.com", + "*.trvl-px.com", "*.uciservice.com"], examples: ["www.trvl-px.com", "www.uciservice.com"], totalExecutionTime: 15443, totalOccurrences: 15 }, { name: "Expedia Australia", company: "Expedia", category: "content", domains: ["*.expedia.com.au"], examples: ["www.expedia.com.au"] }, { name: "Expedia Canada", company: "Expedia", category: "content", domains: ["*.expedia.ca"], examples: ["www.expedia.ca"] }, { name: "Expedia France", company: "Expedia", category: "content", domains: ["*.expedia.fr"], examples: ["www.expedia.fr"] }, { name: "Expedia Germany", company: "Expedia", category: "content", domains: ["*.expedia.de"], examples: ["www.expedia.de"] }, { name: "Expedia Italy", company: "Expedia", category: "content", domains: ["*.expedia.it"], examples: ["www.expedia.it"] }, { name: "Expedia Japan", company: "Expedia", category: "content", domains: ["*.expedia.co.jp"], examples: ["www.expedia.co.jp"] }, { name: "Expedia USA", company: "Expedia", category: "content", domains: ["*.exped\ +ia.com"], examples: ["www.expedia.com"], totalExecutionTime: 40062, totalOccurrences: 19 }, { name: "Expedia United Kingdom", company: "Expedia", category: "content", domains: ["*.expedia.co.uk"], examples: ["www.expedia.co.uk"] }, { name: "Experian", category: "utility", domains: ["*.audienceiq.com", "*.experian.com", "*.experianmarketingservices.digital"] }, { name: "Experian Cross-Channel Marketing Platform", company: "Experian", category: "marketing", domains: ["*.eccmp.com", "*.ccmp.eu"], totalExecutionTime: 1268, totalOccurrences: 24 }, { name: "Exponea", category: "analytics", domains: ["*.exponea.com"], totalExecutionTime: 154832, totalOccurrences: 1303 }, { name: "Exponential Interactive", category: "ad", domains: ["*.exponential.com"], totalExecutionTime: 5179, totalOccurrences: 120 }, { name: "Extensis WebInk", category: "cdn", domains: ["*.webink.com"] }, { name: "Extole", category: "ad", domains: ["*.extole.com", "*.extole.io"], examples: ["origin.extole.io"], totalExecutionTime: 21067, + totalOccurrences: 44 }, { name: "Ey-Seren", category: "analytics", domains: ["*.webabacus.com"] }, { name: "EyeView", category: "ad", domains: ["*.eyeviewads.com"] }, { name: "Eyeota", category: "ad", domains: ["*.eyeota.net"], totalExecutionTime: 152570, totalOccurrences: 1827 }, { name: "Ezakus Pretargeting", company: "Ezakus", category: "ad", domains: ["*.ezakus.net"] }, { name: "Ezoic", category: "analytics", domains: ["*.ezoic.net"], totalExecutionTime: 93024, totalOccurrences: 173 }, { name: "FLXone", company: "Teradata", category: "ad", domains: ["*.pangolin.blue", "*.flx1.com", "d2hlpp31teaww3.cloudfront.net", "*.flxpxl.com"], totalExecutionTime: 25037, totalOccurrences: 67 }, { name: "Fairfax Media", category: "content", domains: ["ads.fairfax.com.au", "resources.fairfax.com.au"] }, { name: "Fairfax Media Analtics", company: "Fairfax Media", category: "analytics", domains: ["analytics.fairfax.com.au"] }, { name: "Falk Technologies", category: "ad", domains: ["*.angsrvr.com"] }, + { name: "Fanplayr", category: "analytics", domains: ["*.fanplayr.com", "d38nbbai6u794i.cloudfront.net"], totalExecutionTime: 69669, totalOccurrences: 154 }, { name: "Fast Thinking", company: "NE Marketing", category: "marketing", domains: ["*.fast-thinking.co.uk"] }, { name: "Fastest Forward", category: "analytics", domains: ["*.gaug.es"], totalExecutionTime: 13583, totalOccurrences: 261 }, { name: "Fastly", category: "utility", domains: ["*.fastly.net"], totalExecutionTime: 21362072, totalOccurrences: 9582 }, { name: "Feedbackify", company: "InsideMetrics", category: "analytics", domains: ["*.feedbackify.com"], totalExecutionTime: 42808, totalOccurrences: 173 }, { name: "Feefo.com", company: "Feefo", category: "analytics", domains: ["*.feefo.com"], totalExecutionTime: 1362284, totalOccurrences: 2025 }, { name: "Fidelity Media", category: "ad", domains: ["*.fidelity-media.com"], examples: ["x.fidelity-media.com"] }, { name: "Filestack", category: "content", domains: ["*.filepicker.\ +io"], examples: ["api.filepicker.io", "dialog.filepicker.io", "www.filepicker.io"], totalExecutionTime: 27297, totalOccurrences: 200 }, { name: "Finsbury Media", category: "ad", domains: ["*.finsburymedia.com"], totalExecutionTime: 3470, totalOccurrences: 12 }, { name: "Firepush", category: "utility", domains: ["*.firepush.io"] }, { name: "FirstImpression", category: "ad", domains: ["*.firstimpression.io"], totalExecutionTime: 141056, totalOccurrences: 107 }, { name: "Fit Analytics", category: "other", domains: ["*.fitanalytics.com"], examples: ["integrations.fitanalytics.com", "widget.fitanalytics.com", "metrics.fitanalytics.com"] }, { name: "Fits Me", category: "analytics", domains: ["*.fits.me"] }, { name: "Fivetran", category: "analytics", domains: ["*.fivetran.com"], totalExecutionTime: 2922, totalOccurrences: 3 }, { name: "FlexShopper", category: "utility", domains: ["*.flexshopper.com"] }, { name: "Flickr", category: "content", domains: ["*.flickr.com", "*.staticflickr.com"], totalExecutionTime: 262262, + totalOccurrences: 524 }, { name: "Flipboard", category: "social", domains: ["*.flipboard.com"], totalExecutionTime: 50049, totalOccurrences: 41 }, { name: "Flipdesk", category: "customer-success", homepage: "https://flipdesk.jp/", domains: ["*.flipdesk.jp"], examples: ["api.flipdesk.jp"], totalExecutionTime: 322297, totalOccurrences: 411 }, { name: "Flipp", category: "analytics", domains: ["*.wishabi.com", "d2e0sxz09bo7k2.cloudfront.net", "*.wishabi.net"] }, { name: "Flite", category: "ad", domains: ["*.flite.com"] }, { name: "Flixmedia", category: "analytics", domains: ["*.flix360.com", "*.flixcar.com", "*.flixfacts.com", "*.flixsyndication.net", "*.flixfacts.co.uk"], totalExecutionTime: 32827, totalOccurrences: 19 }, { name: "Flockler", category: "ad", domains: ["*.flockler.com"], totalExecutionTime: 504051, totalOccurrences: 1297 }, { name: "Flowplayer", category: "content", domains: ["*.flowplayer.org"], totalExecutionTime: 218859, totalOccurrences: 862 }, { name: "Flowzymes Ky", + category: "cdn", domains: ["*.jquerytools.org"] }, { name: "Fomo", category: "ad", domains: ["*.notifyapp.io"] }, { name: "Fonecall", category: "analytics", domains: ["*.web-call-analytics.com"] }, { name: "Fontdeck", category: "cdn", domains: ["*.fontdeck.com"] }, { name: "Foodity Technologies", category: "ad", domains: ["*.foodity.com"] }, { name: "Force24", category: "ad", domains: ["*.force24.co.uk"], totalExecutionTime: 10225, totalOccurrences: 112 }, { name: "ForeSee", company: "Answers", category: "analytics", domains: ["*.4seeresults.com", "*.answerscloud.com", "*.foresee.com", "*.foreseeresults.com"], totalExecutionTime: 179704, totalOccurrences: 266 }, { name: "Forensiq", category: "utility", domains: ["*.fqtag.com"], totalExecutionTime: 21937, totalOccurrences: 171 }, { name: "Fort Awesome", category: "cdn", domains: ["*.fortawesome.com"], totalExecutionTime: 652365, totalOccurrences: 3635 }, { name: "Forter", category: "utility", domains: ["*.forter.com"], totalExecutionTime: 6578955, + totalOccurrences: 6930 }, { name: "Forward Internet Group", category: "hosting", domains: ["*.f3d.io"] }, { name: "Forward3D", category: "ad", domains: ["*.forward3d.com"] }, { name: "Fospha", category: "analytics", domains: ["*.fospha.com"], examples: ["router.fospha.com"] }, { name: "Foursixty", category: "customer-success", domains: ["*.foursixty.com"] }, { name: "FoxyCart", category: "utility", domains: ["*.foxycart.com"], totalExecutionTime: 361777, totalOccurrences: 669 }, { name: "Fraudlogix", category: "utility", domains: ["*.yabidos.com"], totalExecutionTime: 47637, totalOccurrences: 357 }, { name: "FreakOut", category: "ad", domains: ["*.fout.jp"], totalExecutionTime: 114328, totalOccurrences: 2036 }, { name: "Freespee", category: "customer-success", domains: ["*.freespee.com"], examples: ["analytics.freespee.com"], totalExecutionTime: 67626, totalOccurrences: 484 }, { name: "Freetobook", category: "content", domains: ["*.freetobook.com"], examples: ["www.freetobook.com"], + totalExecutionTime: 297146, totalOccurrences: 649 }, { name: "Fresh 8 Gaming", category: "ad", domains: ["*.fresh8.co"], totalExecutionTime: 319849, totalOccurrences: 76 }, { name: "Fresh Relevance", category: "analytics", domains: ["*.freshrelevance.com", "*.cloudfront.ne", "d1y9qtn9cuc3xw.cloudfront.net", "d81mfvml8p5ml.cloudfront.net", "dkpklk99llpj0.cloudfront.net"], examples: ["d1y9qtn9cuc3xw.cloudfront.ne"], totalExecutionTime: 91181, totalOccurrences: 300 }, { name: "Friendbuy", category: "ad", domains: ["*.friendbuy.com", "djnf6e5yyirys.cloudfront.net"], totalExecutionTime: 17783, totalOccurrences: 150 }, { name: "Frienefit", category: "ad", domains: ["*.frienefit.com"] }, { name: "FuelX", category: "ad", domains: ["*.fuelx.com"] }, { name: "Full Circle Studies", category: "analytics", domains: ["*.securestudies.com"] }, { name: "FullStory", category: "analytics", domains: ["*.fullstory.com"], examples: ["rs.fullstory.com"], totalExecutionTime: 11575233, totalOccurrences: 14687 }, + { name: "Fyber", category: "ad", domains: ["*.fyber.com"] }, { name: "G-Forces Web Management", category: "hosting", domains: ["*.gforcesinternal.co.uk"] }, { name: "G4 Native", company: "Gravity4", category: "ad", domains: ["*.triggit.com"] }, { name: "GET ME IN! (TicketMaster)", category: "content", domains: ["*.getmein.com"] }, { name: "GIPHY", category: "content", domains: ["*.giphy.com"], totalExecutionTime: 4831, totalOccurrences: 6 }, { name: "GainCloud", company: "GainCloud Systems", category: "other", domains: ["*.egaincloud.net"] }, { name: "Gath Adams", category: "content", domains: ["*.iwantthatflight.com.au"] }, { name: "Gecko Tribe", category: "social", domains: ["*.geckotribe.com"] }, { name: "Gemius", category: "ad", domains: ["*.gemius.pl"], totalExecutionTime: 2964756, totalOccurrences: 15596 }, { name: "Genesis Media", category: "ad", domains: ["*.bzgint.com", "*.genesismedia.com", "*.genesismediaus.com"] }, { name: "Genie Ventures", category: "ad", domains: ["*\ +.genieventures.co.uk"] }, { name: "Geniee", category: "ad", domains: ["*.href.asia", "*.genieessp.jp", "*.genieesspv.jp", "*.gssprt.jp"], examples: ["cs.gssprt.jp"], totalExecutionTime: 16956055, totalOccurrences: 16354 }, { name: "Geniuslink", category: "analytics", domains: ["*.geni.us"], totalExecutionTime: 897, totalOccurrences: 3 }, { name: "GeoRiot", category: "other", domains: ["*.georiot.com"] }, { name: "GeoTrust", category: "utility", domains: ["*.geotrust.com"], totalExecutionTime: 3300, totalOccurrences: 2 }, { name: "Geoplugin", category: "utility", domains: ["*.geoplugin.com", "*.geoplugin.net"], totalExecutionTime: 119, totalOccurrences: 3 }, { name: "Georeferencer", company: "Klokan Technologies", category: "utility", domains: ["*.georeferencer.com"] }, { name: "GetIntent RTBSuite", company: "GetIntent", category: "ad", domains: ["*.adhigh.net"], totalExecutionTime: 2768, totalOccurrences: 356 }, { name: "GetResponse", category: "ad", domains: ["*.getresponse.com"], totalExecutionTime: 209076, + totalOccurrences: 1019 }, { name: "GetSiteControl", company: "GetWebCraft", category: "utility", domains: ["*.getsitecontrol.com"], totalExecutionTime: 1739288, totalOccurrences: 3146 }, { name: "GetSocial", category: "social", domains: ["*.getsocial.io"], totalExecutionTime: 1204, totalOccurrences: 11 }, { name: "Getty Images", category: "content", domains: ["*.gettyimages.com", "*.gettyimages.co.uk"], examples: ["www.gettyimages.com"], totalExecutionTime: 17939, totalOccurrences: 65 }, { name: "Gfycat", company: "Gycat", category: "utility", domains: ["*.gfycat.com"] }, { name: "Ghostery Enterprise", company: "Ghostery", category: "marketing", domains: ["*.betrad.com"], totalExecutionTime: 1129, totalOccurrences: 26 }, { name: "Giant Media", category: "ad", domains: ["*.videostat.com"] }, { name: "Gigya", category: "analytics", domains: ["*.gigya.com"], totalExecutionTime: 2692493, totalOccurrences: 1995 }, { name: "GitHub", category: "utility", domains: ["*.github.com", "*.githu\ +busercontent.com", "*.github.io", "*.rawgit.com"], examples: ["raw.githubusercontent.com", "cdn.rawgit.com"], totalExecutionTime: 7126491, totalOccurrences: 14675 }, { name: "Gladly", company: "Gladly", homepage: "https://www.gladly.com/", category: "customer-success", domains: ["*.gladly.com"], examples: ["cdn.gladly.com"], totalExecutionTime: 240417, totalOccurrences: 381 }, { name: "Glassdoor", category: "content", domains: ["*.glassdoor.com"], totalExecutionTime: 68877, totalOccurrences: 19 }, { name: "Gleam", category: "marketing", domains: ["*.gleam.io"], totalExecutionTime: 43249, totalOccurrences: 221 }, { name: "Global Digital Markets", category: "ad", domains: ["*.gdmdigital.com"] }, { name: "Global-e", category: "hosting", domains: ["*.global-e.com"], totalExecutionTime: 706185, totalOccurrences: 1314 }, { name: "GlobalSign", category: "utility", domains: ["*.globalsign.com", "*.globalsign.net"], totalExecutionTime: 11228, totalOccurrences: 48 }, { name: "GlobalWebIndex", category: "\ +analytics", domains: ["*.globalwebindex.net"] }, { name: "Globase International", category: "ad", domains: ["*.globase.com"] }, { name: "GoDataFeed", category: "other", domains: ["*.godatafeed.com"] }, { name: "Google APIs", company: "Google", category: "utility", domains: ["googleapis.com"] }, { name: "Google Ad Block Detection", company: "Google", category: "ad", domains: ["*.0emn.com", "*.0fmm.com"] }, { name: "Google Analytics Experiments", company: "Google", category: "analytics", domains: ["*.gexperiments1.com"] }, { name: "Google DoubleClick Ad Exchange", company: "Google", category: "ad", domains: ["*.admeld.com"] }, { name: "Google IPV6 Metrics", company: "Google", category: "analytics", domains: ["*.ipv6test.net"] }, { name: "Google Plus", company: "Google", category: "social", domains: ["plus.google.com"], totalExecutionTime: 49945, totalOccurrences: 442 }, { name: "Google Trusted Stores", company: "Google", category: "utility", domains: ["*.googlecommerce.com"], totalExecutionTime: 218, + totalOccurrences: 5 }, { name: "Google Video", company: "Google", category: "content", domains: ["*.googlevideo.com"], totalExecutionTime: 4, totalOccurrences: 3 }, { name: "Google reCAPTCHA", company: "Google", category: "utility", domains: ["*.recaptcha.net"], examples: ["api.recaptcha.net"], totalExecutionTime: 8694396, totalOccurrences: 25662 }, { name: "GovMetric", company: "ROL Solutions", category: "analytics", domains: ["*.govmetric.com"], totalExecutionTime: 233, totalOccurrences: 6 }, { name: "Granify", category: "analytics", domains: ["*.granify.com"], totalExecutionTime: 19211, totalOccurrences: 24 }, { name: "Grapeshot", category: "ad", domains: ["*.gscontxt.net", "*.grapeshot.co.uk"], totalExecutionTime: 4945, totalOccurrences: 4 }, { name: "Gravity (AOL)", category: "analytics", domains: ["*.grvcdn.com"] }, { name: "Groovy Gecko", category: "content", domains: ["*.ggwebcast.com", "*.groovygecko.net"] }, { name: "GroupM", category: "ad", domains: ["*.qservz.com"] }, { + name: "Guardian Media", category: "ad", domains: ["*.theguardian.com", "*.guardian.co.uk"], examples: ["oas.theguardian.com"] }, { name: "GumGum", category: "ad", domains: ["*.gumgum.com"], totalExecutionTime: 3440651, totalOccurrences: 167535 }, { name: "Gumtree", category: "content", domains: ["*.gumtree.com"] }, { name: "H264 Codec", company: "Cisco", category: "other", domains: ["*.openh264.org"] }, { name: "HERE", category: "analytics", domains: ["*.medio.com"] }, { name: "HP Optimost", company: "Hewlett-Packard Development Company", category: "marketing", domains: ["*.hp.com", "d2uncb19xzxhzx.cloudfront.net"], examples: ["by.marketinghub.hp.com", "marketinghub.hp.com"], totalExecutionTime: 420577, totalOccurrences: 100 }, { name: "Has Offers", company: "TUNE", category: "ad", domains: ["*.go2cloud.org"], totalExecutionTime: 0, totalOccurrences: 3 }, { name: "Hawk Search", category: "utility", domains: ["*.hawksearch.com"], totalExecutionTime: 15097, totalOccurrences: 132 }, { + name: "Haymarket Media Group", category: "content", domains: ["*.brandrepublic.com", "*.hbpl.co.uk"] }, { name: "Heap", category: "analytics", domains: ["*.heapanalytics.com"], totalExecutionTime: 5187800, totalOccurrences: 12078 }, { name: "Hearst Communications", category: "content", domains: ["*.h-cdn.co", "*.hearstdigital.com", "*.hearstlabs.com", "*.hearst.io", "*.cdnds.net"] }, { name: "Heatmap", category: "analytics", domains: ["*.heatmap.it"], totalExecutionTime: 7337, totalOccurrences: 141 }, { name: "Heroku", category: "other", domains: ["*.herokuapp.com"], totalExecutionTime: 12602535, totalOccurrences: 14119 }, { name: "Hexton", category: "utility", domains: ["*.hextom.com"], totalExecutionTime: 10806589, totalOccurrences: 24738 }, { name: "Hibernia Networks", category: "utility", domains: ["*.hiberniacdn.com"] }, { name: "High Impact Media", category: "ad", domains: ["*.reactx.com"] }, { name: "Highcharts", category: "utility", domains: ["*.highcharts.com"], totalExecutionTime: 746540, + totalOccurrences: 3181 }, { name: "Highwinds", category: "utility", domains: ["*.hwcdn.net"] }, { name: "HitsLink", category: "analytics", domains: ["*.hitslink.com"], totalExecutionTime: 1452, totalOccurrences: 29 }, { name: "Hola Networks", category: "other", domains: ["*.h-cdn.com"], totalExecutionTime: 83024, totalOccurrences: 42 }, { name: "Hootsuite", category: "analytics", domains: ["*.hootsuite.com"] }, { name: "HotUKDeals", category: "analytics", domains: ["*.hotukdeals.com"] }, { name: "HotWords", company: "Media Response Group", category: "ad", domains: ["*.hotwords.com.br"] }, { name: "HotelsCombined", category: "content", domains: ["*.datahc.com"], totalExecutionTime: 81, totalOccurrences: 2 }, { name: "Hoverr", category: "ad", domains: ["*.hoverr.media"] }, { name: "Hull.js", category: "utility", domains: ["*.hull.io", "*.hullapp.io"] }, { name: "Hupso Website Analyzer", company: "Hupso", category: "analytics", domains: ["*.hupso.com"], totalExecutionTime: 20892, totalOccurrences: 248 }, + { name: "I-Behavior", company: "WPP", category: "ad", domains: ["*.ib-ibi.com"], totalExecutionTime: 23, totalOccurrences: 35 }, { name: "i-mobile", company: "i-mobile", category: "ad", domains: ["*.i-mobile.co.jp"], examples: ["ssp-sync.i-mobile.co.jp"], totalExecutionTime: 3701005, totalOccurrences: 16595 }, { name: "IBM Digital Analytics", company: "IBM", category: "analytics", domains: ["*.cmcore.com", "coremetrics.com", "data.coremetrics.com", "data.de.coremetrics.com", "libs.de.coremetrics.com", "tmscdn.de.coremetrics.com", "iocdn.coremetrics.com", "libs.coremetrics.com", "tmscdn.coremetrics.com", "*.s81c.com", "*.unica.com", "*.coremetrics.eu"], examples: ["data.coremetrics.eu"], totalExecutionTime: 126790, totalOccurrences: 169 }, { name: "IBM Digital Data Exchange", company: "IBM", category: "tag-manager", domains: ["tagmanager.coremetrics.com"] }, { name: "IBM Tealeaf", company: "IBM", category: "analytics", domains: ["*.ibmcloud.com"], examples: ["uscollector.tealeaf.ibm\ +cloud.com"] }, { name: "IBM Acoustic Campaign", company: "IBM", category: "analytics", domains: ["www.sc.pages01.net", "www.sc.pages02.net", "www.sc.pages03.net", "www.sc.pages04.net", "www.sc.pages05.net", "www.sc.pages06.net", "www.sc.pages07.net", "www.sc.pages08.net", "www.sc.pages09.net", "www.sc.pagesA.net"], examples: ["https://www.sc.pages01.net/lp/static/js/iMAWebCookie.js"], totalExecutionTime: 51361, totalOccurrences: 417 }, { name: "ICF Technology", category: "content", domains: ["*.camads.net"] }, { name: "IFDNRG", category: "hosting", domains: ["*.ifdnrg.com"] }, { name: "IMRG", category: "analytics", domains: ["*.peermap.com", "*.imrg.org"], examples: ["benchmarking.imrg.org"] }, { name: "IPONWEB", category: "ad", domains: ["*.company-target.com", "*.liadm.com", "*.iponweb.net", "*.p161.net"], examples: ["pool.udsp.iponweb.net"], totalExecutionTime: 8924906, totalOccurrences: 39154 }, { name: "IQ Mobile", category: "utility", domains: ["*.iqm.cc"] }, { name: "IS Group", category: "\ +hosting", domains: ["*.creative-serving.com"], totalExecutionTime: 2127, totalOccurrences: 29 }, { name: "IT Dienstleistungen Tim Prinzkosky", category: "utility", domains: ["*.flaticons.net"] }, { name: "IXI Digital", company: "Equifax", category: "ad", domains: ["*.ixiaa.com"] }, { name: "IcoMoon", category: "cdn", domains: ["d19ayerf5ehaab.cloudfront.net", "d1azc1qln24ryf.cloudfront.net"], totalExecutionTime: 54286, totalOccurrences: 180 }, { name: "IdenTrust", category: "utility", domains: ["*.identrust.com"], totalExecutionTime: 2334, totalOccurrences: 1 }, { name: "Ido", category: "customer-success", domains: ["*.idio.co"], totalExecutionTime: 2222, totalOccurrences: 12 }, { name: "Ignition One", category: "marketing", domains: ["*.searchignite.com"] }, { name: "ImageShack", category: "content", domains: ["*.yfrog.com"] }, { name: "Imagen Studio", category: "utility", domains: ["*.telephonesky.com"] }, { name: "Imagini Holdings", category: "ad", domains: ["*.vdna-assets.com"] }, { + name: "Img Safe", category: "content", domains: ["*.imgsafe.org"] }, { name: "Imgur", category: "utility", domains: ["*.imgur.com"], totalExecutionTime: 3538, totalOccurrences: 30 }, { name: "Impact Radius", category: "ad", domains: ["*.impactradius-event.com", "*.impactradius-go.com", "*.7eer.net", "d3cxv97fi8q177.cloudfront.net", "*.evyy.net", "*.ojrq.net", "utt.impactcdn.com", "*.sjv.io"], examples: ["a.impactradius-go.com", "microsoft-uk.evyy.net"], totalExecutionTime: 612310, totalOccurrences: 4274 }, { name: "Improve Digital", category: "ad", domains: ["*.360yield.com"], totalExecutionTime: 28784, totalOccurrences: 732 }, { name: "Improvely", category: "analytics", domains: ["*.iljmp.com"], totalExecutionTime: 129, totalOccurrences: 3 }, { name: "InMobi", category: "ad", domains: ["*.inmobi.com"], totalExecutionTime: 24607375, totalOccurrences: 126087 }, { name: "InSkin Media", category: "ad", domains: ["*.inskinad.com", "*.inskinmedia.com"] }, { name: "Inbenta", category: "c\ +ustomer-success", domains: ["*.inbenta.com"], totalExecutionTime: 3923, totalOccurrences: 7 }, { name: "Incisive Media", category: "content", domains: ["*.incisivemedia.com"] }, { name: "Indeed", category: "content", domains: ["*.indeed.com"], totalExecutionTime: 81347, totalOccurrences: 55 }, { name: "Index Exchange", company: "WPP", category: "ad", domains: ["*.casalemedia.com", "*.indexww.com"], totalExecutionTime: 892351, totalOccurrences: 32324 }, { name: "Indoona", category: "other", domains: ["*.indoona.com"] }, { name: "Infectious Media", category: "ad", domains: ["*.impdesk.com", "*.impressiondesk.com", "*.inmz.net"] }, { name: "Inference Mobile", category: "ad", domains: ["*.inferencemobile.com"] }, { name: "Infinity Tracking", category: "analytics", domains: ["*.infinity-tracking.net"], totalExecutionTime: 24308, totalOccurrences: 250 }, { name: "Infoline", category: "analytics", domains: ["*.ioam.de"], totalExecutionTime: 8983, totalOccurrences: 95 }, { name: "Infolinks", category: "\ +ad", domains: ["*.infolinks.com"], totalExecutionTime: 7995389, totalOccurrences: 5950 }, { name: "Infopark", category: "hosting", domains: ["*.scrvt.com"] }, { name: "Infusionsoft", category: "ad", domains: ["*.infusionsoft.com"], totalExecutionTime: 345182, totalOccurrences: 723 }, { name: "Ink", category: "ad", domains: ["*.inktad.com"] }, { name: "Inktel Contact Center Solutions", company: "Inktel", category: "customer-success", domains: ["*.inktel.com"] }, { name: "Inneractive", category: "ad", domains: ["*.inner-active.mobi"] }, { name: "Innovid", category: "ad", homepage: "https://www.innovid.com/", domains: ["*.innovid.com"], examples: ["ag.innovid.com", "rtr.innovid.com"], totalExecutionTime: 115267, totalOccurrences: 1363 }, { name: "Insight Express", category: "analytics", domains: ["*.insightexpressai.com"], totalExecutionTime: 1, totalOccurrences: 2 }, { name: "Insipio", category: "other", domains: ["*.insipio.com"] }, { name: "Inspectlet", category: "analytics", domains: [ + "*.inspectlet.com"], totalExecutionTime: 7622183, totalOccurrences: 5346 }, { name: "Instansive", category: "utility", domains: ["*.instansive.com"] }, { name: "Instart", homepage: "https://www.instart.com/", category: "utility", domains: ["*.insnw.net"] }, { name: "Instembedder", category: "content", domains: ["*.instaembedder.com"] }, { name: "Instinctive", category: "ad", domains: ["*.instinctiveads.com"] }, { name: "Intelligent Reach", category: "ad", domains: ["*.ist-track.com"] }, { name: "Intent HQ", category: "analytics", domains: ["*.intenthq.com"] }, { name: "Intent IQ", category: "ad", domains: ["*.intentiq.com"], totalExecutionTime: 48447, totalOccurrences: 1146 }, { name: "Intercept Interactive", category: "ad", domains: ["*.undertone.com"], totalExecutionTime: 2293921, totalOccurrences: 21012 }, { name: "Interest Graph", company: "AOL", category: "ad", domains: ["*.gravity.com"] }, { name: "Internet Brands", category: "content", domains: ["*.ibpxl.com"] }, { name: "In\ +terpublic Group", category: "ad", domains: ["*.mbww.com"] }, { name: "Interstate", category: "analytics", domains: ["*.interstateanalytics.com"] }, { name: "Interview", category: "analytics", domains: ["*.efm.me"] }, { name: "Intilery", category: "customer-success", domains: ["*.intilery-analytics.com"] }, { name: "Investis", category: "utility", domains: ["*.investis.com"], totalExecutionTime: 244162, totalOccurrences: 282 }, { name: "Investis Flife", category: "hosting", domains: ["*.quartalflife.com"] }, { name: "Invodo", category: "ad", domains: ["*.invodo.com"], examples: ["e.invodo.com"] }, { name: "iSite", category: "analytics", domains: ["*.isitetv.com"], examples: ["static.isitetv.com", "events.isitetv.com"] }, { name: "Issue", category: "content", domains: ["*.issue.by"] }, { name: "J.D. Williams & Co", category: "content", domains: ["*.drct2u.com"] }, { name: "Janrain", category: "analytics", domains: ["*.janrain.com", "*.janrainbackplane.com", "*.rpxnow.com", "d3hmp0045zy3c\ +s.cloudfront.net"], totalExecutionTime: 4006, totalOccurrences: 21 }, { name: "Jellyfish", category: "ad", domains: ["*.jellyfish.net"] }, { name: "JetStream", category: "content", domains: ["*.xlcdn.com"] }, { name: "JingDong", category: "content", domains: ["*.3.com", "*.jd.com"], totalExecutionTime: 119043, totalOccurrences: 84 }, { name: "Jivox", category: "ad", domains: ["*.jivox.com"], totalExecutionTime: 31166, totalOccurrences: 65 }, { name: "Jobvite", category: "content", domains: ["*.jobvite.com"], totalExecutionTime: 6667, totalOccurrences: 4 }, { name: "Johnston Press", category: "content", domains: ["*.johnstonpress.co.uk", "*.jpress.co.uk"] }, { name: "Join the Dots (Research)", category: "social", domains: ["*.jtdiscuss.com"] }, { name: "JotForm", category: "utility", domains: ["*.jotformpro.com"] }, { name: "JuicyAds", category: "ad", domains: ["*.juicyads.com"], totalExecutionTime: 543292, totalOccurrences: 2092 }, { name: "JustPremium", category: "ad", domains: ["*.ne\ +t.net"], examples: ["d2nvliyzbo36lk.cloudfrontd2nvliyzbo36lk.cloudfront.net.net"] }, { name: "JustPremium Ads", company: "JustPremium", category: "ad", domains: ["*.justpremium.com"], totalExecutionTime: 1061, totalOccurrences: 35 }, { name: "JustUno", category: "ad", domains: ["*.justuno.com", "d2j3qa5nc37287.cloudfront.net"], totalExecutionTime: 773949, totalOccurrences: 1448 }, { name: "KINX (Korea Internet Neutral eXchange)", category: "other", domains: ["*.kinxcdn.com"], totalExecutionTime: 1433, totalOccurrences: 4 }, { name: "KISSmetrics", category: "analytics", domains: ["*.kissmetrics.com", "doug1izaerwt3.cloudfront.net", "dsyszv14g9ymi.cloudfront.net"], totalExecutionTime: 3896, totalOccurrences: 46 }, { name: "Kaizen Platform", category: "analytics", domains: ["*.kaizenplatform.net"], examples: ["cdn.kaizenplatform.net", "log-v4.kaizenplatform.net"], totalExecutionTime: 85284, totalOccurrences: 183 }, { name: "Kakao", category: "social", domains: ["*.daum.net", "*.daumcdn.ne\ +t"], totalExecutionTime: 38351047, totalOccurrences: 62730 }, { name: "Kaltura Video Platform", company: "Kaltura", category: "content", domains: ["*.kaltura.com"], examples: ["cdnsecakmi.kaltura.com"], totalExecutionTime: 2164237, totalOccurrences: 1017 }, { name: "Kameleoon", homepage: "https://www.kameleoon.com/", category: "analytics", domains: ["*.kameleoon.com", "*.kameleoon.eu", "*.kameleoon.io"], examples: ["data.kameleoon.io", "kdm3fpv6il.kameleoon.eu"], totalExecutionTime: 2217218, totalOccurrences: 2337 }, { name: "Kampyle", category: "analytics", domains: ["*.kampyle.com"], totalExecutionTime: 413304, totalOccurrences: 702 }, { name: "Kantar", category: "analytics", domains: ["*.sesamestats.com"] }, { name: "Kargo", category: "marketing", domains: ["*.kargo.com"], totalExecutionTime: 48285, totalOccurrences: 1135 }, { name: "KARTE", company: "Plaid", homepage: "https://karte.io/", category: "marketing", domains: ["*.karte.io"], examples: ["static.karte.io", "t.karte.io"], totalExecutionTime: 1712123, + totalOccurrences: 1729 }, { name: "Kauli", category: "ad", domains: ["*.kau.li"] }, { name: "Keen", company: "Keen", homepage: "https://keen.io/", category: "analytics", domains: ["*.keen.io", "d26b395fwzu5fz.cloudfront.net"], totalExecutionTime: 24210, totalOccurrences: 416 }, { name: "Kelkoo", category: "hosting", domains: ["*.kelkoo.com"] }, { name: "Kenshoo", category: "marketing", domains: ["*.xg4ken.com"], totalExecutionTime: 710, totalOccurrences: 18 }, { name: "Key CDN", category: "utility", domains: ["*.kxcdn.com"], totalExecutionTime: 4814875, totalOccurrences: 10025 }, { name: "Keynote", company: "Dynatrace", category: "analytics", domains: ["*.keynote.com"] }, { name: "Keywee", category: "ad", domains: ["*.keywee.co"], totalExecutionTime: 44984, totalOccurrences: 259 }, { name: "Kiosked", category: "ad", domains: ["*.kiosked.com"], totalExecutionTime: 343355, totalOccurrences: 173 }, { name: "Klarna", category: "utility", domains: ["*.klarna.com"], totalExecutionTime: 1374032, + totalOccurrences: 10759 }, { name: "Klaviyo", category: "ad", domains: ["*.klaviyo.com"], totalExecutionTime: 113130218, totalOccurrences: 161289 }, { name: "Klevu Search", company: "Klevu", category: "utility", domains: ["*.klevu.com"], totalExecutionTime: 1124647, totalOccurrences: 1463 }, { name: "Klick2Contact", category: "customer-success", domains: ["*.klick2contact.com"] }, { name: "Knight Lab", company: "Northwestern University", category: "utility", domains: ["*.knightlab.com"], totalExecutionTime: 350550, totalOccurrences: 448 }, { name: "Kodajo", category: "other", domains: ["*.kodajo.com"] }, { name: "Komoona", category: "ad", domains: ["*.komoona.com"] }, { name: "Korrelate", company: "JD Power", category: "analytics", domains: ["*.korrelate.net"] }, { name: "LKQD", category: "ad", domains: ["*.lkqd.net"] }, { name: "Layer0", category: "cdn", domains: ["*.layer0.co"], examples: ["rum.layer0.co"] }, { name: "Layershift", category: "hosting", domains: ["109.109.138.174"] }, + { name: "Lead Forensics", category: "ad", domains: ["*.200summit.com", "*.baw5tracker.com", "*.business-path-55.com", "*.bux1le001.com", "*.central-core-7.com", "*.direct-azr-78.com", "*.explore-123.com", "*.forensics1000.com", "*.gldsta-02-or.com", "*.green-bloc9.com", "*.lansrv040.com", "*.lead-123.com", "*.leadforensics.com", "*.mavic852.com", "*.mon-com-net.com", "*.peak-ip-54.com", "*.snta0034.com", "*.svr-prc-01.com", "*.syntace-094.com", "*.tghbn12.com", "*.trail-web.com", "*.web-01-gbl.com", "*.web-cntr-07.com", "*.trackdiscovery.net"], examples: ["www.baw5tracker.com", "www.lansrv040.com", "www.mon-com-net.com", "www.peak-ip-54.com", "www.tghbn12.com", "www.web-01-gbl.com"], totalExecutionTime: 45938, totalOccurrences: 307 }, { name: "Lead Intelligence", company: "Magnetise Solutions", category: "ad", domains: ["*.leadintelligence.co.uk"] }, { name: "LeadLander", category: "analytics", domains: ["*.formalyzer.com", "*.trackalyzer.com"] }, { name: "Leaflet", category: "util\ +ity", domains: ["*.leafletjs.com"], totalExecutionTime: 3668, totalOccurrences: 69 }, { name: "LeasdBoxer", company: "LeadBoxer", category: "ad", domains: ["*.leadboxer.com"], totalExecutionTime: 15328, totalOccurrences: 118 }, { name: "LeaseWeb", homepage: "https://www.leaseweb.com/", category: "cdn", domains: ["*.lswcdn.net", "*.leasewebcdn.com"] }, { name: "Leboncoin", category: "content", domains: ["*.leboncoin.fr"] }, { name: "Lengow", category: "hosting", domains: ["*.lengow.com"] }, { name: "Lessbuttons", category: "social", domains: ["*.lessbuttons.com"] }, { name: "Letter Press", category: "ad", domains: ["*.getletterpress.com"] }, { name: "Level 3 Communications", category: "utility", domains: ["footprint.net"] }, { name: "Level3", category: "other", domains: ["secure.footprint.net"] }, { name: "Lifestreet Media", category: "social", domains: ["*.lfstmedia.com"] }, { name: "LiftSuggest", category: "analytics", domains: ["d2blwevgjs7yom.cloudfront.net"] }, { name: "Ligatus", category: "\ +ad", domains: ["*.ligadx.com"] }, { name: "LightStep", category: "analytics", domains: ["*.lightstep.com"] }, { name: "LightWidget", category: "utility", domains: ["*.lightwidget.com"], totalExecutionTime: 1825559, totalOccurrences: 9383 }, { name: "Likelihood", company: "LIkeihood", category: "hosting", domains: ["*.likelihood.com"], examples: ["client.likelihood.com"] }, { name: "LikeShop", company: "Dash Hudson", category: "content", domains: ["likeshop.me"], examples: ["likeshop.me"] }, { name: "LINE Corporation", category: "ad", domains: ["*.line-scdn.net", "*.line.me"], examples: ["d.line-scdn.net", "tr.line.me"], totalExecutionTime: 3858282, totalOccurrences: 26881 }, { name: "Linkcious", category: "analytics", domains: ["*.linkcious.com"] }, { name: "Linking Mobile", category: "ad", domains: ["*.linkingmobile.com"] }, { name: "LittleData", category: "analytics", homepage: "https://www.littledata.io/", domains: ["*.littledata.io"], examples: ["transactions.littledata.io"], totalExecutionTime: 832, + totalOccurrences: 1 }, { name: "LiveBurst", category: "ad", domains: ["*.liveburst.com"] }, { name: "LiveClicker", category: "ad", domains: ["*.liveclicker.net"] }, { name: "LiveHelpNow", category: "customer-success", domains: ["*.livehelpnow.net"], totalExecutionTime: 284671, totalOccurrences: 819 }, { name: "LiveInternet", category: "analytics", domains: ["*.yadro.ru"] }, { name: "LiveJournal", category: "social", domains: ["*.livejournal.com", "*.livejournal.net"], totalExecutionTime: 63532309, totalOccurrences: 9109 }, { name: "LivePerson", category: "customer-success", homepage: "https://www.liveperson.com/", domains: ["*.liveperson.com", "*.look.io", "*.liveperson.net", "*.lpsnmedia.net"], totalExecutionTime: 1930619, totalOccurrences: 2544 }, { name: "LiveRail", company: "Facebook", category: "ad", domains: ["*.liverail.com", "*.lrcdn.net"], examples: ["scontent.lrcdn.net"] }, { name: "LiveTex", category: "customer-success", domains: ["*.livetex.ru"], totalExecutionTime: 476954, + totalOccurrences: 1911 }, { name: "Livefyre", category: "content", domains: ["*.fyre.co", "*.livefyre.com"] }, { name: "Living Map Company", category: "utility", domains: ["*.livingmap.com"] }, { name: "Local World", category: "content", domains: ["*.thelocalpeople.co.uk"] }, { name: "LockerDome", category: "analytics", domains: ["*.lockerdome.com"], totalExecutionTime: 244, totalOccurrences: 3 }, { name: "Logentries", company: "Rapid", category: "utility", domains: ["*.logentries.com"], examples: ["js.logentries.com"] }, { name: "Logicalis", category: "analytics", domains: ["*.trovus.co.uk"] }, { name: "LoginRadius", company: "LoginRadius", homepage: "https://www.loginradius.com/", category: "ad", domains: ["*.loginradius.com", "*.lrcontent.com"], examples: ["config.lrcontent.com"], totalExecutionTime: 15746, totalOccurrences: 131 }, { name: "LongTail Ad Solutions", category: "ad", domains: ["*.jwpcdn.com", "*.jwplatform.com", "*.jwplayer.com", "*.jwpltx.com", "*.jwpsrv.com", "*.l\ +ongtailvideo.com"], totalExecutionTime: 4531393, totalOccurrences: 5572 }, { name: "Loop Commerce", category: "other", domains: ["*.loopassets.net"] }, { name: "Loop11", category: "analytics", domains: ["*.loop11.com"], totalExecutionTime: 22278, totalOccurrences: 28 }, { name: "LoopMe", category: "ad", domains: ["*.loopme.biz", "*.loopme.com", "*.vntsm.com", "*.loopme.me"], totalExecutionTime: 2112781, totalOccurrences: 11752 }, { name: "Looper", category: "content", domains: ["*.looper.com"] }, { name: "Loyalty Point", category: "ad", domains: ["*.loyaltypoint.pl"] }, { name: "LoyaltyLion", category: "ad", domains: ["*.loyaltylion.com", "*.loyaltylion.net", "dg1f2pfrgjxdq.cloudfront.net"], totalExecutionTime: 2971522, totalOccurrences: 4114 }, { name: "Luma Tag", category: "analytics", domains: ["*.lumatag.co.uk"] }, { name: "Lumesse", category: "content", domains: ["*.recruitmentplatform.com"] }, { name: "Luminate", category: "ad", domains: ["*.luminate.com"] }, { name: "Lynchpin An\ +alytics", category: "analytics", domains: ["*.lypn.net"] }, { name: "Lyris", category: "ad", domains: ["*.clicktracks.com"] }, { name: "Lytics", category: "ad", domains: ["*.lytics.io"], totalExecutionTime: 272463, totalOccurrences: 857 }, { name: "MEC WebTrack", company: "MEC", category: "ad", domains: ["*.e-webtrack.net"] }, { name: "MECLABS Institute", category: "analytics", domains: ["*.meclabs.com", "*.meclabsdata.com"] }, { name: "MLveda", category: "utility", domains: ["*.mlveda.com"], examples: ["www.mlveda.com"], totalExecutionTime: 109345, totalOccurrences: 229 }, { name: "Macromill", company: "Macromill", category: "analytics", homepage: "https://group.macromill.com/", domains: ["*.macromill.com"], examples: ["img.macromill.com/js/us000131vfg/4000000570-56/lognos.js"], totalExecutionTime: 5731, totalOccurrences: 9 }, { name: "Macropod BugHerd", company: "Macropod", category: "utility", domains: ["*.bugherd.com"], examples: ["www.bugherd.com"], totalExecutionTime: 512091, totalOccurrences: 3523 }, + { name: "Madison Logic", category: "marketing", domains: ["*.ml314.com"], totalExecutionTime: 101, totalOccurrences: 3 }, { name: "Madmetrics", company: "Keyade", category: "analytics", domains: ["*.keyade.com"] }, { name: "Magnetic", category: "ad", domains: ["*.domdex.com", "d3ezl4ajpp2zy8.cloudfront.net"] }, { name: "Magnetic Platform", company: "Magnetic", category: "ad", domains: ["*.magnetic.is"] }, { name: "MailMunch", category: "ad", domains: ["*.mailmunch.co"], totalExecutionTime: 1414543, totalOccurrences: 19969 }, { name: "MailPlus", category: "ad", domains: ["*.mailplus.nl"], totalExecutionTime: 83524, totalOccurrences: 304 }, { name: "Mapbox", category: "utility", domains: ["*.mapbox.com"], totalExecutionTime: 13815633, totalOccurrences: 19555 }, { name: "Maptive", category: "utility", domains: ["*.maptive.com"] }, { name: "Marcaria.com", category: "other", domains: ["*.gooo.al"] }, { name: "Marchex", category: "analytics", domains: ["*.voicestar.com", "*.marchex.io"], + totalExecutionTime: 1378181, totalOccurrences: 7390 }, { name: "Mark and Mini", category: "ad", domains: ["*.markandmini.com"], examples: ["www.markandmini.com"] }, { name: "Marker", category: "utility", domains: ["*.marker.io"], examples: ["edge.marker.io"], totalExecutionTime: 2331726, totalOccurrences: 1722 }, { name: "Marketing Dashboards", company: "GroupM", category: "analytics", domains: ["*.m-decision.com"] }, { name: "Marketizator", category: "analytics", domains: ["*.marketizator.com"] }, { name: "Marketplace Web Service", company: "Amazon", category: "other", domains: ["*.ssl-images-amazon.com"], totalExecutionTime: 234709, totalOccurrences: 451 }, { name: "Mashable", category: "social", domains: ["*.mshcdn.com"] }, { name: "MatchWork", category: "utility", domains: ["*.matchwork.com"] }, { name: "MathJax", category: "utility", domains: ["*.mathjax.org"], totalExecutionTime: 84751, totalOccurrences: 743 }, { name: "Mather Economics", category: "analytics", domains: ["*.m\ +atheranalytics.com"], totalExecutionTime: 262501, totalOccurrences: 507 }, { name: "MaxCDN Enterprise", company: "MaxCDN", category: "utility", domains: ["*.netdna-cdn.com", "*.netdna-ssl.com"] }, { name: "MaxMind", category: "utility", domains: ["*.maxmind.com"], totalExecutionTime: 855332, totalOccurrences: 831 }, { name: "MaxPoint Interactive", category: "ad", domains: ["*.mxptint.net"], totalExecutionTime: 20140, totalOccurrences: 23834 }, { name: "Maxsi", category: "analytics", domains: ["*.evisitanalyst.com"] }, { name: "Maxymiser", category: "analytics", domains: ["*.maxymiser.net, maxymiser.hs.llnwd.net"] }, { name: "McAffee", category: "utility", domains: ["*.mcafeesecure.com", "*.scanalert.com"] }, { name: "Measured", category: "analytics", domains: ["*.measured.com"], examples: ["tag.measured.com"], homepage: "https://www.measured.com/" }, { name: "Media IQ", category: "analytics", domains: ["*.mediaiqdigital.com"] }, { name: "Media Management Technologies", category: "ad", domains: [ + "*.speedshiftmedia.com"], totalExecutionTime: 27147, totalOccurrences: 161 }, { name: "Media Temple", category: "hosting", domains: ["*.goodlayers2.com"] }, { name: "Mediabong", category: "ad", domains: ["*.mediabong.net"] }, { name: "Mediahawk", category: "analytics", domains: ["*.mediahawk.co.uk"], totalExecutionTime: 51393, totalOccurrences: 239 }, { name: "Mediahub", category: "ad", domains: ["*.hubverifyandoptimize.com", "*.projectwatchtower.com"] }, { name: "Mediasyndicator", category: "ad", domains: ["*.creativesyndicator.com"] }, { name: "Medium", category: "content", domains: ["*.medium.com"], totalExecutionTime: 216923262, totalOccurrences: 17027 }, { name: "Meetrics", category: "ad", domains: ["*.de.com", "*.meetrics.net", "*.mxcdn.net"], examples: ["research.de.com"], totalExecutionTime: 102809, totalOccurrences: 63 }, { name: "Mega", company: "Mega Information Technology", category: "other", domains: ["*.mgcdn.com"] }, { name: "Melt", category: "ad", domains: ["*.meltd\ +sp.com", "*.mesp.com"] }, { name: "Meltwater Group", category: "customer-success", domains: ["*.meltwaternews.com"] }, { name: "Meme", category: "ad", domains: ["*.viewwonder.com"] }, { name: "MentAd", category: "ad", domains: ["*.mentad.com"] }, { name: "Mention Me", category: "ad", domains: ["*.mention-me.com"], examples: ["tag.mention-me.com"], totalExecutionTime: 15233, totalOccurrences: 44 }, { name: "Merchant Equipment Store", category: "utility", domains: ["*.merchantequip.com"], totalExecutionTime: 268, totalOccurrences: 1 }, { name: "Merchenta", category: "customer-success", domains: ["*.merchenta.com"] }, { name: "Merkle Digital Data Exchange", company: "Merkle", category: "ad", domains: ["*.brilig.com"] }, { name: "Merkle Paid Search", company: "Merkle", category: "ad", domains: ["*.rkdms.com"], totalExecutionTime: 69291, totalOccurrences: 407 }, { name: "Met Office", category: "content", domains: ["*.metoffice.gov.uk"], totalExecutionTime: 15029, totalOccurrences: 19 }, { name: "\ +Meta Broadcast", category: "social", domains: ["*.metabroadcast.com"], examples: ["voila.metabroadcast.com"] }, { name: "Michael Associates", category: "ad", domains: ["*.checktestsite.com"], examples: ["www.checktestsite.com"] }, { name: "Michelin", category: "content", domains: ["*.viamichelin.com"], totalExecutionTime: 8087, totalOccurrences: 7 }, { name: "Microad", category: "ad", domains: ["*.microad.jp"], totalExecutionTime: 14626755, totalOccurrences: 23909 }, { name: "Microsoft Certificate Services", company: "Microsoft", category: "utility", domains: ["*.msocsp.com"] }, { name: "Microsoft Hosted Libs", company: "Microsoft", category: "cdn", domains: ["*.aspnetcdn.com"], examples: ["ajax.aspnetcdn.com"], totalExecutionTime: 4562478, totalOccurrences: 20042 }, { name: "Microsoft XBox Live", company: "Microsoft", category: "marketing", domains: ["*.xboxlive.com"] }, { name: "Mightypop", category: "ad", domains: ["*.mightypop.ca"] }, { name: "Mika Tuupola", category: "utility", domains: [ + "*.appelsiini.net"] }, { name: "Millennial Media", category: "ad", domains: ["*.jumptap.com"] }, { name: "Mirror Image Internet", category: "utility", domains: ["*.miisolutions.net"] }, { name: "Mobify", category: "utility", domains: ["*.mobify.com", "*.mobify.net"] }, { name: "Mobile Nations", category: "social", domains: ["*.mobilenations.com"] }, { name: "Mobivate", category: "ad", domains: ["*.mobivatebulksms.com"] }, { name: "Momondo", category: "content", domains: ["*.momondo.dk"] }, { name: "Momondo Group", category: "content", domains: ["*.momondogrouo.com", "*.momondogroup.com"] }, { name: "Monarch Ads", category: "ad", domains: ["*.monarchads.com"] }, { name: "Monetate", category: "analytics", domains: ["*.monetate.net"], totalExecutionTime: 260345, totalOccurrences: 599 }, { name: "MonetizeMore", category: "ad", domains: ["*.m2.ai"], totalExecutionTime: 8896, totalOccurrences: 47 }, { name: "Monitor", company: "Econda", category: "analytics", domains: ["*.econda-monitor.\ +de"], examples: ["www.econda-monitor.de"] }, { name: "Monkey Frog Media", category: "content", domains: ["*.monkeyfrogmedia.com"] }, { name: "Monotype", category: "cdn", domains: ["*.fonts.com", "*.fonts.net"], totalExecutionTime: 729465, totalOccurrences: 3185 }, { name: "Moore-Wilson", category: "ad", domains: ["*.mwdev.co.uk"] }, { name: "Moovweb", category: "utility", domains: ["*.moovweb.net"] }, { name: "Mopinion", category: "analytics", domains: ["*.mopinion.com"], totalExecutionTime: 171681, totalOccurrences: 177 }, { name: "MotionPoint", category: "other", domains: ["*.convertlanguage.com"], totalExecutionTime: 1843, totalOccurrences: 35 }, { name: "Mouse3K", category: "analytics", domains: ["*.mouse3k.com"] }, { name: "MouseStats", category: "analytics", domains: ["*.mousestats.com"] }, { name: "Mouseflow", homepage: "https://mouseflow.com/", category: "analytics", domains: ["*.mouseflow.com"], totalExecutionTime: 331345, totalOccurrences: 6786 }, { name: "Movable Ink", category: "\ +analytics", domains: ["*.micpn.com"], totalExecutionTime: 439979, totalOccurrences: 4949 }, { name: "MovingIMAGE24", category: "content", domains: ["*.edge-cdn.net"] }, { name: "Moxielinks", category: "ad", domains: ["*.moxielinks.com"] }, { name: "Moz Recommended Companies", company: "Moz", category: "analytics", domains: ["d2eeipcrcdle6.cloudfront.net"] }, { name: "Mozilla", category: "utility", domains: ["*.mozilla.org"], examples: ["aus5.mozilla.org"], totalExecutionTime: 21085, totalOccurrences: 32 }, { name: "Multiview", category: "content", domains: ["*.multiview.com", "*.track-mv.com"], totalExecutionTime: 8831, totalOccurrences: 58 }, { name: "Mux", category: "analytics", domains: ["*.litix.io"], totalExecutionTime: 91580, totalOccurrences: 249 }, { name: "MyAds", company: "MyBuys", category: "analytics", domains: ["*.veruta.com"] }, { name: "MyBuys", category: "analytics", domains: ["*.mybuys.com"] }, { name: "MyFonts", category: "cdn", domains: ["*.myfonts.net"], totalExecutionTime: 78, + totalOccurrences: 4 }, { name: "MyRegistry", category: "other", domains: ["*.myregistry.com"], totalExecutionTime: 164086, totalOccurrences: 621 }, { name: "MySpace", company: "Specific Media", category: "social", domains: ["*.myspace.com"] }, { name: "Mynewsdesk", category: "utility", domains: ["*.mynewsdesk.com"], totalExecutionTime: 564, totalOccurrences: 31 }, { name: "NAVIS", category: "content", domains: ["*.navistechnologies.info"] }, { name: "NCC Group Real User Monitoring", company: "NCC Group", category: "analytics", domains: ["*.nccgroup-webperf.com"], examples: ["beacon-rumlive.rum.nccgroup-webperf.com", "config-rumlive.rum.nccgroup-webperf.com", "script-rumlive.rum.nccgroup-webperf.com"] }, { name: "NEORY Marketing Cloud", company: "NEORY", category: "marketing", domains: ["*.ad-srv.net"], totalExecutionTime: 10976, totalOccurrences: 240 }, { name: "Nanigans", category: "ad", domains: ["*.nanigans.com"] }, { name: "Nano Interactive", category: "ad", domains: ["*.audien\ +cemanager.de"], totalExecutionTime: 780, totalOccurrences: 10 }, { name: "Nanorep", company: "Nanorep Technologies", category: "customer-success", domains: ["*.nanorep.com"] }, { name: "Narrative", category: "ad", domains: ["*.narrative.io"], totalExecutionTime: 1228, totalOccurrences: 2 }, { name: "Native Ads", category: "ad", domains: ["*.nativeads.com"] }, { name: "Nativo", category: "ad", domains: ["*.postrelease.com"], totalExecutionTime: 28260, totalOccurrences: 35852 }, { name: "Navegg", category: "ad", domains: ["*.navdmp.com"], totalExecutionTime: 51915, totalOccurrences: 805 }, { name: "NaviStone", category: "ad", domains: ["*.murdoog.com"] }, { name: "Naytev", category: "analytics", domains: ["*.naytev.com"] }, { name: "Needle", category: "analytics", domains: ["*.needle.com"] }, { name: "Neiman Marcus", category: "content", domains: ["*.ctscdn.com"] }, { name: "Nend", category: "ad", domains: ["*.nend.net"] }, { name: "Neodata", category: "ad", domains: ["*.neodatagroup.com"], + totalExecutionTime: 12827, totalOccurrences: 86 }, { name: "Net Applications", category: "analytics", domains: ["*.hitsprocessor.com"] }, { name: "Net Reviews", category: "analytics", domains: ["*.avis-verifies.com"], examples: ["www.avis-verifies.com"], totalExecutionTime: 1143140, totalOccurrences: 2442 }, { name: "NetAffiliation", company: "Kwanco", category: "ad", domains: ["*.metaffiliation.com"], totalExecutionTime: 18519, totalOccurrences: 127 }, { name: "NetDirector", company: "G-Forces Web Management", category: "other", domains: ["*.netdirector.co.uk"], totalExecutionTime: 3931, totalOccurrences: 1 }, { name: "NetFlix", category: "content", domains: ["*.nflxext.com", "*.nflximg.net"], totalExecutionTime: 4364, totalOccurrences: 5 }, { name: "Nielsen NetRatings SiteCensus", company: "The Nielsen Company", homepage: "http://www.nielsen-online.com/intlpage.html", category: "analytics", domains: ["*.imrworldwide.com"], totalExecutionTime: 6840006, totalOccurrences: 19525 }, { + name: "NetSeer", category: "ad", domains: ["*.netseer.com", "*.ns-cdn.com"] }, { name: "NetShelter", company: "Ziff Davis Tech", category: "ad", domains: ["*.netshelter.net"] }, { name: "Netmining", company: "Ignition One", category: "ad", domains: ["*.netmng.com"], totalExecutionTime: 7746, totalOccurrences: 92 }, { name: "Netop", category: "customer-success", domains: ["*.netop.com"] }, { name: "Network Solutions", category: "utility", domains: ["*.netsolssl.com", "*.networksolutions.com"], examples: ["ocsp.netsolssl.com"], totalExecutionTime: 2415, totalOccurrences: 2 }, { name: "Neustar AdAdvisor", company: "Neustar", category: "ad", domains: ["*.adadvisor.net"] }, { name: "New Approach Media", category: "ad", domains: ["*.newapproachmedia.co.uk"] }, { name: "NewShareCounts", category: "social", domains: ["*.newsharecounts.com"] }, { name: "News", category: "social", domains: ["*.news.com.au", "*.newsanalytics.com.au", "*.newsapi.com.au", "*.newscdn.com.au", "*.newsdata.com.au", + "*.newsdiscover.com.au", "*.news-static.com"], totalExecutionTime: 69261, totalOccurrences: 46 }, { name: "Newsquest", category: "content", domains: ["*.newsquestdigital.co.uk"] }, { name: "Newzulu", category: "content", domains: ["*.filemobile.com", "*.projects.fm"] }, { name: "Nexcess.Net", category: "hosting", domains: ["*.nexcesscdn.net"] }, { name: "Nexstar Media Group", category: "ad", domains: ["*.yashi.com"] }, { name: "NextPerf", company: "Rakuten Marketing", category: "ad", domains: ["*.nxtck.com"] }, { name: "Nine.com.au", company: "Nine Digital", category: "content", domains: ["*.9msn.com.au"] }, { name: "NitroSell", category: "hosting", domains: ["*.nitrosell.com"] }, { name: "Nochex", category: "utility", domains: ["*.nochex.com"] }, { name: "Northern & Shell Media Group", category: "content", domains: ["*.northernandshell.co.uk"] }, { name: "Nosto", category: "analytics", domains: ["*.nosto.com"], totalExecutionTime: 703736, totalOccurrences: 1189 }, { name: "Now\ + Interact", category: "analytics", domains: ["*.nowinteract.com"] }, { name: "Numberly", company: "1000mercis", category: "ad", domains: ["*.mmtro.com", "*.nzaza.com"], totalExecutionTime: 1827, totalOccurrences: 19 }, { name: "NyaConcepts", category: "analytics", domains: ["*.xclusive.ly"] }, { name: "O2", category: "other", domains: ["*.o2.co.uk"], examples: ["servedby.o2.co.uk"] }, { name: "GoDaddy", homepage: "https://www.godaddy.com/", category: "utility", domains: ["*.godaddy.com", "*.wsimg.com"], examples: ["ocsp.godaddy.com", "seal.godaddy.com"], totalExecutionTime: 94698135, totalOccurrences: 110342 }, { name: "ObjectPlanet", category: "analytics", domains: ["*.easypolls.net"], totalExecutionTime: 28470, totalOccurrences: 70 }, { name: "OhMyAd", category: "ad", domains: ["*.ohmyad.co"], examples: ["pr.ohmyad.co"] }, { name: "Okas Concepts", category: "utility", domains: ["*.okasconcepts.com"], totalExecutionTime: 1483515, totalOccurrences: 661 }, { name: "Okta", category: "ana\ +lytics", domains: ["*.okta.com"], totalExecutionTime: 1464920, totalOccurrences: 3542 }, { name: "Olapic", category: "content", domains: ["*.photorank.me"], totalExecutionTime: 115, totalOccurrences: 2 }, { name: "Ometria", category: "analytics", domains: ["*.ometria.com"], totalExecutionTime: 16630, totalOccurrences: 204 }, { name: "Omniconvert", category: "analytics", domains: ["*.omniconvert.com", "d2tgfbvjf3q6hn.cloudfront.net", "d3vbj265bmdenw.cloudfront.net"], totalExecutionTime: 85855, totalOccurrences: 381 }, { name: "Omniroot", company: "Verizon", category: "utility", domains: ["*.omniroot.com"], examples: ["ocsp.omniroot.com", "vassg142.ocsp.omniroot.com"] }, { name: "OnAudience", company: "Cloud Technologies", category: "ad", domains: ["*.onaudience.com"] }, { name: "OnScroll", category: "ad", domains: ["*.onscroll.com"] }, { name: "OnState", category: "ad", domains: ["*.onstate.co.uk"] }, { name: "OnYourMap", category: "utility", domains: ["*.onyourmap.com"] }, { name: "One\ + by AOL", company: "AOL", category: "ad", domains: ["*.adtechjp.com", "*.adtech.de"], totalExecutionTime: 1140, totalOccurrences: 17 }, { name: "One by AOL:Mobile", company: "AOL", category: "ad", domains: ["*.nexage.com"], examples: ["ads.nexage.com", "hb.nexage.com"] }, { name: "OneAll", category: "analytics", domains: ["*.oneall.com"], totalExecutionTime: 104501, totalOccurrences: 623 }, { name: "OneSoon", category: "analytics", domains: ["*.adalyser.com"], totalExecutionTime: 33037, totalOccurrences: 437 }, { name: "OneTag", category: "ad", domains: ["*.onetag-sys.com"] }, { name: "Onet", category: "ad", domains: ["*.onet.pl"], totalExecutionTime: 531334, totalOccurrences: 760 }, { name: "Online Rewards", company: "Mastercard", category: "ad", domains: ["*.loyaltygateway.com"] }, { name: "Online republic", category: "content", domains: ["*.imallcdn.net"], totalExecutionTime: 67122, totalOccurrences: 58 }, { name: "Ooyala", category: "ad", domains: ["*.ooyala.com"] }, { name: "OpenT\ +able", company: "Priceline Group", category: "content", domains: ["*.opentable.com", "*.opentable.co.uk", "*.toptable.co.uk"], examples: ["www.toptable.co.uk"], totalExecutionTime: 412090, totalOccurrences: 4314 }, { name: "OpenX Ad Exchange", company: "OpenX Technologies", category: "ad", domains: ["*.liftdna.com"] }, { name: "Opinion Stage", category: "analytics", domains: ["*.opinionstage.com"], examples: ["www.opinionstage.com"], totalExecutionTime: 113206, totalOccurrences: 145 }, { name: "OpinionBar", category: "analytics", domains: ["*.opinionbar.com"] }, { name: "Opta", company: "Perform Group", category: "content", domains: ["*.opta.net"], totalExecutionTime: 302785, totalOccurrences: 272 }, { name: "OptiMonk", category: "ad", domains: ["*.optimonk.com"], totalExecutionTime: 10318415, totalOccurrences: 10615 }, { name: "Optilead", category: "analytics", domains: ["*.dyn-img.com", "*.leadcall.co.uk", "*.optilead.co.uk"] }, { name: "Optimatic", category: "ad", domains: ["*.optim\ +atic.com"], examples: ["synch.optimatic.com"] }, { name: "Optimise Media Group", category: "utility", domains: ["*.omguk.com"], totalExecutionTime: 6691, totalOccurrences: 41 }, { name: "Optimost", company: "OpenText", category: "ad", domains: ["*.optimost.com"] }, { name: "Optimove", company: "Mobius Solutions", category: "analytics", domains: ["*.optimove.net"], totalExecutionTime: 22679, totalOccurrences: 293 }, { name: "Optorb", category: "ad", domains: ["*.optorb.com"] }, { name: "Oracle", category: "marketing", domains: ["*.custhelp.com", "*.eloqua.com", "*.en25.com", "*.estara.com", "*.instantservice.com"], totalExecutionTime: 684920, totalOccurrences: 569 }, { name: "Oracle Recommendations On Demand", company: "Oracle", category: "analytics", domains: ["*.atgsvcs.com"], totalExecutionTime: 8696, totalOccurrences: 96 }, { name: "Oracle Responsys", company: "Oracle", category: "marketing", domains: ["*.adrsp.net", "*.responsys.net"] }, { name: "Order Security-VOID", company: "Ord\ +er Security", category: "analytics", domains: ["*.order-security.com"] }, { name: "Oriel", category: "ad", domains: ["*.oriel.io"] }, { name: "Outbrain", homepage: "https://www.outbrain.com/", category: "ad", domains: ["*.outbrain.com", "*.outbrainimg.com", "*.visualrevenue.com"], totalExecutionTime: 3373858, totalOccurrences: 13287 }, { name: "OverStream", company: "Coull", category: "ad", domains: ["*.coull.com"], examples: ["ex1.coull.com"] }, { name: "Overdrive", category: "content", domains: ["*.contentreserve.com"] }, { name: "Overstock", category: "utility", domains: ["*.ostkcdn.com"] }, { name: "OwnerIQ", category: "ad", domains: ["*.owneriq.net"], totalExecutionTime: 305561, totalOccurrences: 2173 }, { name: "OzCart", category: "utility", domains: ["*.ozcart.com.au"] }, { name: "Ozone Media", category: "ad", domains: ["*.adadyn.com"] }, { name: "Loqate", company: "Loqate", category: "other", domains: ["*.pcapredict.com", "*.postcodeanywhere.co.uk"], totalExecutionTime: 136866, + totalOccurrences: 777 }, { name: "PEER 1 Hosting", category: "hosting", domains: ["*.peer1.com"] }, { name: "PERFORM", category: "content", domains: ["*.performgroup.com"] }, { name: "PICnet", category: "hosting", domains: ["*.nonprofitsoapbox.com"] }, { name: "Pacnet", company: "Telstra", category: "other", domains: ["*.cdndelivery.net"], examples: ["682968324.r.cdndelivery.net"] }, { name: "Pagefair", category: "ad", domains: ["*.pagefair.com", "*.pagefair.net"] }, { name: "Pagely", category: "other", domains: ["*.optnmstr.com"], totalExecutionTime: 99314, totalOccurrences: 487 }, { name: "Pagesuite", category: "ad", domains: ["*.pagesuite-professional.co.uk"], totalExecutionTime: 12, totalOccurrences: 1 }, { name: "Pardot", category: "marketing", domains: ["*.pardot.com"], totalExecutionTime: 73880, totalOccurrences: 550 }, { name: "Parse.ly", category: "analytics", domains: ["*.parsely.com", "d1z2jf7jlzjs58.cloudfront.net"], totalExecutionTime: 1122662, totalOccurrences: 5204 }, + { name: "Pay per Click", company: "Eysys", category: "ad", domains: ["*.eysys.com"], examples: ["pla27.eysys.com"] }, { name: "PayPal Ads", category: "ad", domains: ["*.where.com"] }, { name: "Peaks & Pies", category: "analytics", domains: ["*.bunchbox.co"] }, { name: "PebblePost", category: "ad", domains: ["*.pbbl.co"], totalExecutionTime: 147945, totalOccurrences: 725 }, { name: "Peerius", category: "analytics", domains: ["*.peerius.com"] }, { name: "Peermap", company: "IMRG", category: "analytics", domains: ["peermapcontent.affino.com"] }, { name: "Penske Media", category: "content", domains: ["*.pmc.com"] }, { name: "Penton", category: "utility", domains: ["*.pisces-penton.com"] }, { name: "Pepper", category: "ad", domains: ["*.peppercorp.com"] }, { name: "Perfect Audience", company: "Marin Software", category: "ad", domains: ["*.prfct.co", "*.marinsm.com", "*.perfectaudience.com"], totalExecutionTime: 405, totalOccurrences: 7 }, { name: "Perfect Market", category: "ad", domains: [ + "*.perfectmarket.com"] }, { name: "Perfect Privacy", category: "other", domains: ["*.suitesmart.com"] }, { name: "Perform Group", category: "content", domains: ["*.performfeeds.com", "*.premiumtv.co.uk"] }, { name: "Performio", category: "ad", domains: ["*.performax.cz"], examples: ["ut.performax.cz"], totalExecutionTime: 117591, totalOccurrences: 337 }, { name: "PerimeterX Bot Defender", company: "PerimeterX", category: "utility", domains: ["*.perimeterx.net", "*.pxi.pub"], totalExecutionTime: 172605, totalOccurrences: 68 }, { name: "Periscope", category: "content", domains: ["*.periscope.tv"] }, { name: "Permutive", category: "ad", domains: ["*.permutive.com", "d3alqb8vzo7fun.cloudfront.net"], totalExecutionTime: 1406714, totalOccurrences: 1124 }, { name: "Petametrics", category: "analytics", domains: ["*.petametrics.com"] }, { name: "PhotoBucket", category: "content", domains: ["*.photobucket.com"], totalExecutionTime: 2383529, totalOccurrences: 338 }, { name: "Picreel", category: "\ +analytics", domains: ["*.pcrl.co", "*.picreel.com"], totalExecutionTime: 45437, totalOccurrences: 300 }, { name: "Pictela (AOL)", category: "analytics", domains: ["*.pictela.net"] }, { name: "PistonHeads", category: "social", domains: ["*.pistonheads.com"] }, { name: "Piwik", category: "analytics", domains: ["*.drtvtracker.com", "*.piwikpro.com", "*.raac33.net"], totalExecutionTime: 2813, totalOccurrences: 32 }, { name: "Pixalate", category: "utility", domains: ["*.adrta.com"], totalExecutionTime: 4187, totalOccurrences: 13 }, { name: "Pixlee", category: "social", domains: ["*.pixlee.com"], totalExecutionTime: 137281, totalOccurrences: 341 }, { name: "Placed", category: "analytics", domains: ["*.placed.com"], totalExecutionTime: 691, totalOccurrences: 1 }, { name: "Planning-inc", category: "analytics", domains: ["*.planning-inc.co.uk"] }, { name: "PlayAd Media Group", category: "ad", domains: ["*.youplay.se"] }, { name: "Playbuzz", category: "hosting", domains: ["*.playbuzz.com"], totalExecutionTime: 58184, + totalOccurrences: 89 }, { name: "Pleenq", category: "ad", domains: ["*.pleenq.com"] }, { name: "Plentific", category: "content", domains: ["*.plentific.com"] }, { name: "PluginDetect", category: "other", domains: ["dtlilztwypawv.cloudfront.net"] }, { name: "Po.st", company: "RadiumOne", category: "utility", domains: ["*.po.st"], totalExecutionTime: 178, totalOccurrences: 3 }, { name: "Pointpin", category: "utility", domains: ["*.pointp.in"] }, { name: "Pointroll (Garnett)", category: "ad", domains: ["*.pointroll.com"] }, { name: "Polar", homepage: "https://polar.me/", category: "ad", domains: ["*.polarmobile.ca", "*.mediaeverywhere.com", "*.mediavoice.com", "*.plrsrvcs.com", "*.polarcdn-engine.com", "*.polarcdn-meraxes.com", "*.polarcdn-pentos.com", "*.polarcdn-static.com", "*.polarcdn-terrax.com", "*.polarcdn.com", "*.polarmobile.com", "*.poweredbypolar.com", "*.mediaconductor.me", "*.polaracademy.me"], totalExecutionTime: 66280, totalOccurrences: 223 }, { name: "PollDaddy (Automa\ +ttic)", category: "ad", domains: ["static.polldaddy.com", "*.poll.fm"], totalExecutionTime: 4752, totalOccurrences: 37 }, { name: "Polldaddy", company: "Automattic", category: "analytics", domains: ["polldaddy.com", "*.polldaddy.com"], totalExecutionTime: 294207, totalOccurrences: 2715 }, { name: "Polyfill service", company: "Polyfill.io", category: "other", domains: ["*.polyfill.io"] }, { name: "MegaPopAds", category: "ad", domains: ["*.megapopads.com"] }, { name: "Populis", category: "ad", domains: ["*.populisengage.com"] }, { name: "Postimage.org", category: "content", domains: ["*.postimg.org"] }, { name: "PowerFront", category: "hosting", domains: ["*.inside-graph.com"], totalExecutionTime: 220331, totalOccurrences: 370 }, { name: "PowerReviews", category: "analytics", domains: ["*.powerreviews.com"], totalExecutionTime: 1208993, totalOccurrences: 1324 }, { name: "Powerlinks.com", category: "ad", domains: ["*.powerlinks.com"] }, { name: "Press+", category: "ad", domains: ["*.pipol\ +.com", "*.ppjol.com", "*.ppjol.net"] }, { name: "PressArea", category: "utility", domains: ["*.pressarea.com"], examples: ["www.pressarea.com"] }, { name: "Pretio Interactive", category: "ad", domains: ["*.pretio.in"] }, { name: "Prezi", category: "utility", domains: ["*.prezi.com"], totalExecutionTime: 72394, totalOccurrences: 79 }, { name: "PriceGrabber", category: "content", domains: ["*.pgcdn.com", "*.pricegrabber.com"] }, { name: "PriceRunner", category: "content", domains: ["*.pricerunner.com"], totalExecutionTime: 200, totalOccurrences: 6 }, { name: "PrintFriendly", category: "utility", domains: ["*.printfriendly.com"], totalExecutionTime: 39464, totalOccurrences: 381 }, { name: "Privy", category: "ad", domains: ["*.privy.com", "*.privymktg.com"], totalExecutionTime: 14992809, totalOccurrences: 18961 }, { name: "Proclivity Media", category: "analytics", domains: ["*.pswec.com"] }, { name: "Profitshare", category: "ad", domains: ["*.profitshare.ro"], totalExecutionTime: 60087, totalOccurrences: 194 }, + { name: "Programattik", category: "ad", domains: ["*.programattik.com"], totalExecutionTime: 95, totalOccurrences: 9 }, { name: "Proper Media", category: "content", domains: ["*.proper.io"], totalExecutionTime: 253672, totalOccurrences: 109 }, { name: "Property Week", category: "content", domains: ["*.propertyweek.com"], examples: ["www.propertyweek.com"] }, { name: "Provide Support", category: "customer-success", domains: ["*.providesupport.com"], totalExecutionTime: 79281, totalOccurrences: 989 }, { name: "Proweb Uk", category: "hosting", domains: ["*.proweb.net"] }, { name: "Proximic (ComScore)", category: "ad", domains: ["*.proximic.com"] }, { name: "Psyma", category: "ad", domains: ["*.psyma.com"], totalExecutionTime: 2496, totalOccurrences: 5 }, { name: "PubFactory", company: "Safari Books Online", category: "content", domains: ["*.pubfactory.com"] }, { name: "PubNation", category: "ad", domains: ["*.pubnation.com"], totalExecutionTime: 625439, totalOccurrences: 132 }, { name: "\ +Publicidad.net", category: "ad", domains: ["*.publicidad.tv"] }, { name: "PublishThis", company: "Ultra Unlimited", category: "ad", domains: ["*.publishthis.com"] }, { name: "Pulse Insights", category: "analytics", domains: ["*.pulseinsights.com"], totalExecutionTime: 5757, totalOccurrences: 53 }, { name: "Pulsepoint", category: "marketing", domains: ["*.displaymarketplace.com"] }, { name: "Purch", category: "ad", domains: ["*.bestofmedia.com", "*.purch.com"], examples: ["ramp.purch.com"] }, { name: "Pure Chat", category: "customer-success", domains: ["*.purechat.com"], totalExecutionTime: 1129392, totalOccurrences: 3105 }, { name: "PushCrew", category: "ad", domains: ["*.pushcrew.com"], totalExecutionTime: 170011, totalOccurrences: 823 }, { name: "Q1Media", category: "ad", domains: ["*.q1media.com", "*.q1mediahydraplatform.com"] }, { name: "Qbase Software Development", category: "hosting", domains: ["*.smartwebportal.co.uk"] }, { name: "Qeryz", category: "analytics", domains: ["*.qery\ +z.com"] }, { name: "Qode Interactive", category: "hosting", domains: ["*.qodeinteractive.com"], totalExecutionTime: 2503828, totalOccurrences: 147 }, { name: "Qrius", category: "social", domains: ["*.qrius.me"] }, { name: "Qualaroo", category: "analytics", domains: ["*.qualaroo.com"], totalExecutionTime: 54960, totalOccurrences: 347 }, { name: "Qualtrics", category: "analytics", domains: ["*.qualtrics.com"], totalExecutionTime: 4907219, totalOccurrences: 7134 }, { name: "Qubit", company: "Qubit", category: "analytics", domains: ["*.qubit.com", "*.qutics.com", "d3c3cq33003psk.cloudfront.net", "*.goqubit.com", "*.qubitproducts.com"], totalExecutionTime: 50060, totalOccurrences: 43 }, { name: "Qubit Deliver", company: "Qubit", category: "analytics", domains: ["d1m54pdnjzjnhe.cloudfront.net", "d22rutvoghj3db.cloudfront.net", "dd6zx4ibq538k.cloudfront.net"] }, { name: "QuestionPro", category: "analytics", domains: ["*.questionpro.com"], totalExecutionTime: 60868, totalOccurrences: 152 }, { name: "\ +Queue-it", category: "other", domains: ["*.queue-it.net"], totalExecutionTime: 60031, totalOccurrences: 143 }, { name: "QuinStreet", category: "ad", domains: ["*.Quinstreet.com", "*.b2btechleadform.com", "*.qnsr.com", "*.qsstats.com"], examples: ["www.qsstats.com"] }, { name: "QuoVadis", category: "utility", domains: ["*.quovadisglobal.com"] }, { name: "Qzzr", category: "analytics", domains: ["*.movementventures.com", "*.qzzr.com"], examples: ["www.qzzr.com"] }, { name: "RapidAPI", category: "utility", domains: ["*.rapidapi.com"], examples: ["telize-v1.p.rapidapi.com"], totalExecutionTime: 4218, totalOccurrences: 2 }, { name: "RCS Media Group", category: "ad", domains: ["*.rcsadv.it"] }, { name: "REVIVVE", category: "ad", domains: ["*.revivve.com"] }, { name: "RSSinclude", category: "social", domains: ["*.rssinclude.com"] }, { name: "RTB House AdPilot", company: "RTB House", category: "ad", domains: ["*.erne.co", "*.creativecdn.com"], totalExecutionTime: 1677125, totalOccurrences: 13287 }, + { name: "RTB Media", category: "ad", domains: ["*.rtb-media.me"] }, { name: "RUN", category: "ad", domains: ["*.runadtag.com", "*.rundsp.com"] }, { name: "Rackspace", category: "hosting", domains: ["*.rackcdn.com", "*.rackspacecloud.com", "*.raxcdn.com", "*.websitetestlink.com"], totalExecutionTime: 3573460, totalOccurrences: 2624 }, { name: "RadiumOne", category: "ad", domains: ["*.gwallet.com", "*.r1-cdn.net"] }, { name: "Rakuten DC Storm", company: "Rakuten", category: "analytics", domains: ["*.dc-storm.com", "*.h4k5.com", "*.stormiq.com"] }, { name: "Rakuten LinkShare", company: "Rakuten", category: "ad", domains: ["*.linksynergy.com"], totalExecutionTime: 23285, totalOccurrences: 151 }, { name: "Rakuten Marketing", company: "Rakuten", category: "ad", domains: ["*.rakuten-static.com", "*.rmtag.com", "tag.rmp.rakuten.com"], totalExecutionTime: 462276, totalOccurrences: 3399 }, { name: "Rakuten MediaForge", company: "Rakuten", category: "ad", domains: ["*.mediaforge.com"], totalExecutionTime: 1650, + totalOccurrences: 20 }, { name: "Rambler", company: "Rambler & Co", category: "utility", domains: ["*.rambler.ru"], totalExecutionTime: 54521084, totalOccurrences: 15831 }, { name: "Ranker", category: "content", domains: ["*.ranker.com", "*.rnkr-static.com"] }, { name: "Ravelin", category: "utility", domains: ["*.ravelin.com"] }, { name: "Raygun", category: "utility", domains: ["*.raygun.io", "*.rapidzebra.io"], totalExecutionTime: 245714, totalOccurrences: 2539 }, { name: "ReCollect", category: "utility", domains: ["*.recollect.net"], totalExecutionTime: 229879, totalOccurrences: 135 }, { name: "ReSRC", category: "utility", domains: ["*.resrc.it"] }, { name: "ReTargeter", category: "ad", domains: ["*.retargeter.com"] }, { name: "Reach Group", category: "ad", domains: ["*.redintelligence.net"], totalExecutionTime: 1449, totalOccurrences: 199 }, { name: "ReachDynamics", category: "ad", domains: ["*.rdcdn.com"] }, { name: "ReachForce", category: "ad", domains: ["*.reachforce.com"] }, + { name: "ReachLocal", category: "ad", domains: ["*.rtrk.co.nz"], examples: ["rtsys.rtrk.co.nz"] }, { name: "ReachMee", category: "content", domains: ["*.reachmee.com"], totalExecutionTime: 133135, totalOccurrences: 40 }, { name: "Reactful", category: "analytics", domains: ["*.reactful.com"], totalExecutionTime: 12497, totalOccurrences: 42 }, { name: "Realtime", company: "internet business technologies", category: "utility", domains: ["*.realtime.co"] }, { name: "Realtime Media (Brian Communications)", category: "ad", domains: ["*.rtm.com"] }, { name: "Realtime Targeting", category: "ad", domains: ["*.idtargeting.com"] }, { name: "Realytics", category: "analytics", domains: ["dcniko1cv0rz.cloudfront.net", "*.realytics.net"], totalExecutionTime: 38343, totalOccurrences: 276 }, { name: "RebelMouse", category: "ad", domains: ["*.rebelmouse.com", "*.rbl.ms"], examples: ["www.rebelmouse.com"], totalExecutionTime: 3876, totalOccurrences: 22 }, { name: "Receiptful", category: "utility", domains: [ + "*.receiptful.com"], totalExecutionTime: 58254, totalOccurrences: 361 }, { name: "Recite Me", category: "other", domains: ["*.reciteme.com"], totalExecutionTime: 22320, totalOccurrences: 142 }, { name: "RecoBell", category: "analytics", domains: ["*.recobell.io"] }, { name: "Recommend", category: "analytics", domains: ["*.recommend.pro"] }, { name: "Red Eye International", category: "ad", domains: ["*.pajmc.com"] }, { name: "Redfish Group", category: "ad", domains: ["*.wmps.com"] }, { name: "Reevoo", category: "analytics", domains: ["*.reevoo.com"], totalExecutionTime: 87323, totalOccurrences: 133 }, { name: "Refersion", category: "ad", domains: ["*.refersion.com"], totalExecutionTime: 564360, totalOccurrences: 2170 }, { name: "Refined Ads", category: "ad", domains: ["*.refinedads.com"] }, { name: "Reflektion", category: "analytics", domains: ["*.reflektion.com", "d26opx5dl8t69i.cloudfront.net"] }, { name: "Reflow", company: "Scenestealer", category: "ad", domains: ["*.reflow.tv"] }, + { name: "Reklama", category: "ad", domains: ["*.o2.pl", "*.wp.pl"], examples: ["dot.wp.pl", "px.o2.pl", "px.wp.pl"], totalExecutionTime: 846563, totalOccurrences: 1054 }, { name: "Relevad ReleStar", company: "Relevad", category: "ad", domains: ["*.relestar.com"] }, { name: "Remarketing Pixel", company: "Adsterra Network", category: "ad", domains: ["*.datadbs.com", "*.remarketingpixel.com"] }, { name: "Remintrex", company: "SmartUp Venture", category: "ad", domains: ["*.remintrex.com"] }, { name: "Republer", category: "ad", domains: ["*.republer.com"], examples: ["sync.republer.com"] }, { name: "Research Now", category: "analytics", domains: ["*.researchgnow.com", "*.researchnow.com"], examples: ["tag.researchgnow.com"] }, { name: "Research Online", company: "Skills Development Scotland", category: "content", domains: ["*.researchonline.org.uk"], examples: ["www.researchonline.org.uk"] }, { name: "Resonance Insights", category: "analytics", domains: ["*.res-x.com"], totalExecutionTime: 2277, + totalOccurrences: 20 }, { name: "Resonate Networks", category: "analytics", domains: ["*.reson8.com"], totalExecutionTime: 1739, totalOccurrences: 1 }, { name: "Response Team", category: "ad", domains: ["*.i-transactads.com"] }, { name: "ResponseTap", category: "analytics", domains: ["*.adinsight.com", "*.responsetap.com"], totalExecutionTime: 84074, totalOccurrences: 274 }, { name: "ResponsiveVoice", category: "other", domains: ["*.responsivevoice.org"], totalExecutionTime: 851397, totalOccurrences: 6863 }, { name: "Retention Science", category: "ad", domains: ["*.retentionscience.com", "d1stxfv94hrhia.cloudfront.net"], totalExecutionTime: 17276, totalOccurrences: 209 }, { name: "Revcontent", category: "content", domains: ["*.revcontent.com"], totalExecutionTime: 1153469, totalOccurrences: 1251 }, { name: "Revee", category: "ad", domains: ["*.revee.com"] }, { name: "Revenue Conduit", category: "utility", domains: ["*.revenueconduit.com"] }, { name: "RevenueMantra", category: "ad", + domains: ["*.revenuemantra.com"] }, { name: "Reviews.co.uk", category: "analytics", domains: ["*.reviews.co.uk"], totalExecutionTime: 425151, totalOccurrences: 1883 }, { name: "Reviews.io", category: "analytics", domains: ["*.reviews.io"], totalExecutionTime: 1713955, totalOccurrences: 4516 }, { name: "Revolver Maps", category: "analytics", domains: ["*.revolvermaps.com"], totalExecutionTime: 2132297, totalOccurrences: 2305 }, { name: "Revv", category: "utility", domains: ["*.revv.co"], totalExecutionTime: 26667, totalOccurrences: 11 }, { name: "RichRelevance", category: "analytics", domains: ["*.richrelevance.com"], totalExecutionTime: 3496, totalOccurrences: 19 }, { name: "RightNow Service Cloud", company: "Oracle", category: "customer-success", domains: ["*.rightnowtech.com", "*.rnengage.com"], totalExecutionTime: 8970, totalOccurrences: 122 }, { name: "Rightster", category: "ad", domains: ["*.ads-creativesyndicator.com"] }, { name: "Riskified", category: "utility", domains: ["*\ +.riskified.com"], totalExecutionTime: 373865, totalOccurrences: 1643 }, { name: "Rockerbox", category: "analytics", homepage: "https://www.rockerbox.com/", domains: ["getrockerbox.com"], examples: ["getrockerbox.com"], totalExecutionTime: 19742, totalOccurrences: 162 }, { name: "Rocket Fuel", category: "ad", domains: ["*.rfihub.com", "*.ru4.com", "*.rfihub.net", "*.ad1x.com"], totalExecutionTime: 356189, totalOccurrences: 3247 }, { name: "Rollbar", category: "utility", domains: ["*.rollbar.com", "d37gvrvc0wt4s1.cloudfront.net"], examples: ["api.rollbar.com"], totalExecutionTime: 190180, totalOccurrences: 2349 }, { name: "RomanCart", category: "utility", domains: ["*.romancart.com"], totalExecutionTime: 510, totalOccurrences: 5 }, { name: "Rondavu", category: "ad", domains: ["*.rondavu.com"] }, { name: "Roomkey", category: "content", domains: ["*.roomkey.com"], examples: ["www.roomkey.com"] }, { name: "Roost", category: "utility", domains: ["*.goroost.com"] }, { name: "Roxot", category: "\ +ad", domains: ["*.rxthdr.com"] }, { name: "Roxr Software", category: "analytics", domains: ["*.getclicky.com"], totalExecutionTime: 851573, totalOccurrences: 12877 }, { name: "Rtoaster", company: "Brainpad", homepage: "https://www.brainpad.co.jp/rtoaster/", category: "marketing", domains: ["*.rtoaster.jp"], examples: ["rt.rtoaster.jp"], totalExecutionTime: 15065, totalOccurrences: 91 }, { name: "Rubikloud.com", category: "analytics", domains: ["*.rubikloud.com"] }, { name: "Ruler Analytics", company: "Ruler", category: "analytics", domains: ["*.nyltx.com", "*.ruleranalytics.com"], examples: ["www.ruleranalytics.com"], totalExecutionTime: 41074, totalOccurrences: 436 }, { name: "Runner", company: "Rambler & Co", category: "content", domains: ["*.begun.ru"], totalExecutionTime: 26, totalOccurrences: 1 }, { name: "S4M", category: "ad", domains: ["*.sam4m.com"] }, { name: "SAP Hybris Marketing Convert", company: "SAP", category: "ad", domains: ["*.seewhy.com"] }, { name: "SAS Institute", category: "\ +ad", domains: ["*.aimatch.com", "*.sas.com"], totalExecutionTime: 59419, totalOccurrences: 29 }, { name: "SATORI", homepage: "https://satori.marketing/", category: "marketing", domains: ["satori.segs.jp"], examples: ["satori.segs.jp/s.js"], totalExecutionTime: 62202, totalOccurrences: 816 }, { name: "SC ShopMania Net SRL", category: "content", domains: ["*.shopmania.com"] }, { name: "SDL Media Manager", company: "SDL", category: "other", domains: ["*.sdlmedia.com"] }, { name: "SFR", category: "other", domains: ["*.sfr.fr"], examples: ["elr.sfr.fr"], totalExecutionTime: 22751, totalOccurrences: 22 }, { name: "SLI Systems", category: "utility", domains: ["*.resultslist.com", "*.resultspage.com", "*.sli-spark.com"], totalExecutionTime: 2909, totalOccurrences: 33 }, { name: "SMARTASSISTANT", company: "Smart Information Systems", category: "customer-success", domains: ["*.smartassistant.com"] }, { name: "SMARTSTREAM.TV", category: "ad", domains: ["*.smartstream.tv"] }, { name: "SPX", company: "\ +Smaato", category: "ad", domains: ["*.smaato.net"], totalExecutionTime: 519, totalOccurrences: 13 }, { name: "Sabio", category: "customer-success", domains: ["*.sabio.co.uk"], examples: ["www.sabio.co.uk"] }, { name: "Sailthru", category: "analytics", domains: ["*.sail-horizon.com", "*.sail-personalize.com", "*.sail-track.com"], totalExecutionTime: 59245, totalOccurrences: 678 }, { name: "Sailthru Sightlines", company: "Sailthru", category: "marketing", domains: ["*.sailthru.com"], totalExecutionTime: 6772, totalOccurrences: 18 }, { name: "Sajari Pty", category: "utility", domains: ["*.sajari.com"], totalExecutionTime: 70019, totalOccurrences: 197 }, { name: "SaleCycle", category: "ad", domains: ["*.salecycle.com", "d16fk4ms6rqz1v.cloudfront.net", "d22j4fzzszoii2.cloudfront.net", "d30ke5tqu2tkyx.cloudfront.net", "dn1i8v75r669j.cloudfront.net"], totalExecutionTime: 146399, totalOccurrences: 641 }, { name: "Salesforce Live Agent", company: "Salesforce.com", category: "customer-success", domains: [ + "*.salesforceliveagent.com"], totalExecutionTime: 100033, totalOccurrences: 675 }, { name: "Salesforce.com", category: "ad", domains: ["*.force.com", "*.salesforce.com"], examples: ["secure.force.com"], totalExecutionTime: 1614051, totalOccurrences: 4970 }, { name: "Samba TV", company: "Samba", category: "content", domains: ["*.samba.tv"], totalExecutionTime: 1690, totalOccurrences: 7 }, { name: "Samplicio.us", category: "analytics", domains: ["*.samplicio.us"], totalExecutionTime: 1727, totalOccurrences: 5 }, { name: "Say Media", category: "ad", domains: ["*.saymedia.com"] }, { name: "Scenario", category: "analytics", domains: ["*.getscenario.com"] }, { name: "Schuh (image shard)", company: "Schuh", category: "other", domains: ["d2ob0iztsaxy5v.cloudfront.net"] }, { name: "Science Rockstars", category: "analytics", domains: ["*.persuasionapi.com"] }, { name: "ScientiaMobile", category: "analytics", domains: ["*.wurflcloud.com", "*.wurfl.io"], totalExecutionTime: 627, totalOccurrences: 3 }, + { name: "Scoota", category: "ad", domains: ["*.rockabox.co", "*.scoota.co", "d31i2625d5nv27.cloudfront.net", "dyjnzf8evxrp2.cloudfront.net"] }, { name: "ScribbleLive", category: "ad", domains: ["*.scribblelive.com"] }, { name: "SearchForce", category: "ad", domains: ["*.searchforce.net"], totalExecutionTime: 118, totalOccurrences: 3 }, { name: "SearchSpring", category: "utility", domains: ["*.searchspring.net"], totalExecutionTime: 1175588, totalOccurrences: 309 }, { name: "Searchanise", category: "analytics", domains: ["*.searchanise.com"], examples: ["www.searchanise.com"], totalExecutionTime: 63519, totalOccurrences: 420 }, { name: "Sears Holdings", category: "content", domains: ["*.shld.net"] }, { name: "Secomapp", category: "utility", domains: ["*.secomapp.com"], totalExecutionTime: 2151952, totalOccurrences: 2137 }, { name: "SecuredVisit", company: "4Cite Marketing", category: "ad", domains: ["*.securedvisit.com"], totalExecutionTime: 41054, totalOccurrences: 369 }, { name: "\ +SecurityMetrics", category: "utility", domains: ["*.securitymetrics.com"], totalExecutionTime: 8413, totalOccurrences: 2 }, { name: "Segmento", category: "ad", domains: ["*.rutarget.ru"], totalExecutionTime: 17111, totalOccurrences: 226 }, { name: "Segmint", category: "analytics", domains: ["*.segmint.net"], totalExecutionTime: 14122, totalOccurrences: 109 }, { name: "Sekindo", category: "content", domains: ["*.sekindo.com"], totalExecutionTime: 376, totalOccurrences: 4 }, { name: "Seldon", category: "analytics", domains: ["*.rummblelabs.com"] }, { name: "SelectMedia International", category: "content", domains: ["*.selectmedia.asia"], totalExecutionTime: 186574, totalOccurrences: 68 }, { name: "Selligent", category: "ad", domains: ["*.emsecure.net", "*.slgnt.eu", "targetemsecure.blob.core.windows.net"], totalExecutionTime: 163886, totalOccurrences: 506 }, { name: "Sellpoints", category: "analytics", domains: ["*.sellpoints.com"] }, { name: "Semantics3", category: "analytics", domains: [ + "*.hits.io"] }, { name: "Semasio", category: "analytics", domains: ["*.semasio.net"] }, { name: "Semcasting Site Visitor Attribution", company: "Semcasting", category: "ad", domains: ["*.smartzonessva.com"] }, { name: "Sentifi", category: "social", domains: ["*.sentifi.com"] }, { name: "ServMetric", category: "analytics", domains: ["*.servmetric.com"] }, { name: "ServiceSource International", category: "marketing", domains: ["*.scoutanalytics.net"], examples: ["scout.scoutanalytics.net"] }, { name: "ServiceTick", category: "analytics", domains: ["*.servicetick.com"] }, { name: "Servo", company: "Xervo", category: "hosting", domains: ["*.onmodulus.net"] }, { name: "SessionCam", company: "ServiceTick", category: "analytics", domains: ["*.sessioncam.com", "d2oh4tlt9mrke9.cloudfront.net"] }, { name: "Seznam", category: "utility", domains: ["*.imedia.cz"], totalExecutionTime: 1323711, totalOccurrences: 6863 }, { name: "Sharethrough", category: "ad", domains: ["*.sharethrough.com"], totalExecutionTime: 46730, + totalOccurrences: 833 }, { name: "SharpSpring", category: "marketing", domains: ["*.sharpspring.com", "*.marketingautomation.services"], totalExecutionTime: 632191, totalOccurrences: 2080 }, { name: "ShopRunner", category: "content", domains: ["*.shoprunner.com", "*.s-9.us"], totalExecutionTime: 35573, totalOccurrences: 32 }, { name: "ShopStorm", category: "utility", domains: ["*.shopstorm.com"] }, { name: "Shopatron", category: "hosting", domains: ["*.shopatron.com"] }, { name: "Shopgate", category: "utility", domains: ["*.shopgate.com"], totalExecutionTime: 15293, totalOccurrences: 25 }, { name: "ShopiMind", company: "ShopIMind", category: "ad", domains: ["*.shopimind.com"] }, { name: "Shopkeeper Tools", category: "utility", domains: ["*.shopkeepertools.com"], totalExecutionTime: 500, totalOccurrences: 6 }, { name: "Sidecar", category: "other", domains: ["*.getsidecar.com", "d3v27wwd40f0xu.cloudfront.net"] }, { name: "Sidereel", category: "analytics", domains: ["*.sidereel.com"] }, + { name: "Sift Science", category: "utility", domains: ["*.siftscience.com"], totalExecutionTime: 90167, totalOccurrences: 355 }, { name: "Signal", category: "tag-manager", domains: ["*.sitetagger.co.uk"] }, { name: "Signyfyd", category: "utility", domains: ["*.signifyd.com"], totalExecutionTime: 4752892, totalOccurrences: 2608 }, { name: "Silktide", category: "hosting", domains: ["*.silktide.com"], totalExecutionTime: 132707, totalOccurrences: 390 }, { name: "Silverpop", company: "IBM", category: "ad", domains: ["*.mkt912.com", "*.mkt922.com", "*.mkt932.com", "*.mkt941.com", "*.mkt51.net", "*.mkt61.net", "*.pages01.net", "*.pages02.net", "*.pages03.net", "*.pages04.net", "*.pages05.net"], totalExecutionTime: 4144, totalOccurrences: 58 }, { name: "Simplaex", category: "marketing", domains: ["*.simplaex.net"] }, { name: "SimpleReach", category: "analytics", domains: ["*.simplereach.com", "d8rk54i4mohrb.cloudfront.net"] }, { name: "Simplestream", category: "content", domains: ["*.simp\ +lestream.com"], examples: ["player.simplestream.com"] }, { name: "Simpli.fi", category: "ad", domains: ["*.simpli.fi"], totalExecutionTime: 974218, totalOccurrences: 16378 }, { name: "Simplicity Marketing", category: "ad", domains: ["*.flashtalking.com"], totalExecutionTime: 579126, totalOccurrences: 2927 }, { name: "SinnerSchrader Deutschland", category: "ad", domains: ["*.s2Betrieb.de"] }, { name: "Sirv", category: "other", domains: ["*.sirv.com"], totalExecutionTime: 604262, totalOccurrences: 1034 }, { name: "Site Meter", category: "analytics", domains: ["*.sitemeter.com"] }, { name: "Site24x7 Real User Monitoring", company: "Site24x7", category: "analytics", domains: ["*.site24x7rum.com"], totalExecutionTime: 124283, totalOccurrences: 1007 }, { name: "SiteGainer", category: "analytics", domains: ["*.sitegainer.com", "d191y0yd6d0jy4.cloudfront.net"] }, { name: "SiteScout", company: "Centro", category: "ad", domains: ["*.pixel.ad", "*.sitescout.com"], totalExecutionTime: 256082, totalOccurrences: 3401 }, + { name: "Siteimprove", category: "utility", domains: ["*.siteimprove.com", "*.siteimproveanalytics.com"], totalExecutionTime: 28494, totalOccurrences: 361 }, { name: "Six Degrees Group", category: "hosting", domains: ["*.fstech.co.uk"] }, { name: "Skimbit", category: "ad", domains: ["*.redirectingat.com", "*.skimresources.com", "*.skimresources.net"], totalExecutionTime: 32940093, totalOccurrences: 86270 }, { name: "Skimlinks", category: "ad", domains: ["*.skimlinks.com"] }, { name: "SkyGlue Technology", category: "analytics", domains: ["*.skyglue.com"], totalExecutionTime: 2567, totalOccurrences: 24 }, { name: "SkyScanner", category: "content", domains: ["*.skyscanner.net"], examples: ["api.skyscanner.net"], totalExecutionTime: 98147, totalOccurrences: 370 }, { name: "Skybet", company: "Bonne Terre t/a Sky Vegas (Sky)", category: "other", domains: ["*.skybet.com"] }, { name: "Skype", category: "other", domains: ["*.skype.com"], totalExecutionTime: 121901, totalOccurrences: 625 }, { + name: "Slate Group", category: "content", domains: ["*.cdnslate.com"] }, { name: "SlimCut Media Outstream", company: "SlimCut Media", category: "ad", domains: ["*.freeskreen.com"] }, { name: "Smart Insight Tracking", company: "Emarsys", category: "analytics", domains: ["*.scarabresearch.com"], totalExecutionTime: 361811, totalOccurrences: 1779 }, { name: "Smart AdServer", category: "ad", domains: ["*.01net.com", "*.sascdn.com", "*.sasqos.com", "*.smartadserver.com"], examples: ["securite.01net.com"], totalExecutionTime: 22356737, totalOccurrences: 107812 }, { name: "SmartFocus", category: "analytics", domains: ["*.emv2.com", "*.emv3.com", "*.predictiveintent.com", "*.smartfocus.com", "*.themessagecloud.com"] }, { name: "Smarter Click", category: "ad", domains: ["*.smct.co", "*.smarterclick.co.uk"], totalExecutionTime: 761, totalOccurrences: 11 }, { name: "SmarterHQ", category: "analytics", domains: ["*.smarterhq.io", "d1n00d49gkbray.cloudfront.net", "*.smarterremarketer.net"], totalExecutionTime: 2636, + totalOccurrences: 28 }, { name: "Smarttools", category: "customer-success", domains: ["*.smartertrack.com"] }, { name: "Smartzer", category: "ad", domains: ["*.smartzer.com"] }, { name: "Snack Media", category: "content", domains: ["*.snack-media.com"], totalExecutionTime: 575613, totalOccurrences: 423 }, { name: "Snacktools", category: "ad", domains: ["*.bannersnack.com"], totalExecutionTime: 162327, totalOccurrences: 303 }, { name: "SnapEngage", category: "customer-success", domains: ["*.snapengage.com"], totalExecutionTime: 147012, totalOccurrences: 1038 }, { name: "SnapWidget", category: "content", domains: ["*.snapwidget.com"] }, { name: "Soasta", category: "analytics", domains: ["*.lognormal.net"] }, { name: "SociableLabs", category: "ad", domains: ["*.sociablelabs.net", "*.sociablelabs.com"] }, { name: "Social Annex", category: "customer-success", domains: ["*.socialannex.com"] }, { name: "SocialShopWave", category: "social", domains: ["*.socialshopwave.com"], totalExecutionTime: 4962079, + totalOccurrences: 3720 }, { name: "Socialphotos", category: "social", domains: ["*.slpht.com"], totalExecutionTime: 12590, totalOccurrences: 120 }, { name: "Sociomantic Labs", company: "DunnHumby", category: "ad", domains: ["*.sociomantic.com"] }, { name: "SodaHead", category: "analytics", domains: ["*.sodahead.com"], examples: ["pollware-cdn.sodahead.com"] }, { name: "Softwebzone", category: "hosting", domains: ["*.softwebzone.com"], examples: ["www.softwebzone.com"] }, { name: "Sojern", category: "marketing", domains: ["*.sojern.com"], totalExecutionTime: 2086952, totalOccurrences: 4422 }, { name: "Sokrati", category: "marketing", domains: ["*.sokrati.com"] }, { name: "Sonobi", category: "ad", domains: ["*.sonobi.com"], totalExecutionTime: 4682222, totalOccurrences: 81682 }, { name: "Sooqr Search", company: "Sooqr", category: "utility", domains: ["*.sooqr.com"], totalExecutionTime: 176199, totalOccurrences: 396 }, { name: "Sophus3", category: "analytics", domains: ["*.s3ae.com", "\ +*.sophus3.com"], totalExecutionTime: 5605, totalOccurrences: 11 }, { name: "Sorenson Media", category: "content", domains: ["*.sorensonmedia.com"] }, { name: "Sortable", category: "ad", domains: ["*.deployads.com"] }, { name: "Sotic", category: "hosting", domains: ["*.sotic.net", "*.soticservers.net"] }, { name: "Soundest", category: "ad", domains: ["*.soundestlink.com", "*.soundest.net"], totalExecutionTime: 835, totalOccurrences: 102 }, { name: "Sourcepoint", category: "ad", domains: ["*.decenthat.com", "*.fallingfalcon.com", "*.summerhamster.com", "d2lv4zbk7v5f93.cloudfront.net", "d3qxwzhswv93jk.cloudfront.net"], examples: ["www.decenthat.com", "www.fallingfalcon.com", "www.summerhamster.com"] }, { name: "SourceKnowledge", homepage: "https://www.sourceknowledge.com", category: "ad", domains: ["*.provenpixel.com"], totalExecutionTime: 505, totalOccurrences: 8 }, { name: "SpaceNet", category: "hosting", domains: ["*.nmm.de"] }, { name: "Sparkflow", company: "Intercept Interactive", category: "\ +ad", domains: ["*.sparkflow.net"] }, { name: "Specific Media", category: "ad", domains: ["*.specificmedia.com", "*.adviva.net", "*.specificclick.net"] }, { name: "Spicy", company: "Data-Centric Alliance", category: "ad", domains: ["*.sspicy.ru"] }, { name: "Spoke", category: "customer-success", domains: ["*.121d8.com"] }, { name: "Spongecell", category: "ad", domains: ["*.spongecell.com"] }, { name: "Spot.IM", category: "social", domains: ["*.spot.im", "*.spotim.market"], totalExecutionTime: 192547, totalOccurrences: 342 }, { name: "SpotXchange", category: "ad", domains: ["*.spotxcdn.com", "*.spotxchange.com", "*.spotx.tv"] }, { name: "SpringServer", category: "ad", domains: ["*.springserve.com"], totalExecutionTime: 1192823, totalOccurrences: 1432 }, { name: "Spylight", category: "other", domains: ["*.spylight.com"] }, { name: "SreamAMG", company: "StreamAMG", category: "other", domains: ["*.streamamg.com"], totalExecutionTime: 85506, totalOccurrences: 62 }, { name: "StackAdapt", category: "\ +ad", domains: ["*.stackadapt.com"], totalExecutionTime: 1338506, totalOccurrences: 14912 }, { name: "StackExchange", category: "social", domains: ["*.sstatic.net"], totalExecutionTime: 187262, totalOccurrences: 217 }, { name: "Stackla PTY", category: "social", domains: ["*.stackla.com"], totalExecutionTime: 271026, totalOccurrences: 175 }, { name: "Stailamedia", category: "ad", domains: ["*.stailamedia.com"] }, { name: "Stamped.io", category: "analytics", domains: ["*.stamped.io"], totalExecutionTime: 1665115, totalOccurrences: 12460 }, { name: "Starfield Services Root Certificate Authority", company: "Starfield Technologies", category: "utility", domains: ["*.starfieldtech.com", "ss2.us", "*.ss2.us"], examples: ["ocsp.starfieldtech.com"], totalExecutionTime: 18156, totalOccurrences: 39 }, { name: "Starfield Technologies", category: "utility", domains: ["*.websiteprotection.com"], examples: ["seals.websiteprotection.com"] }, { name: "StatCounter", category: "analytics", domains: ["*.st\ +atcounter.com"], totalExecutionTime: 5427381, totalOccurrences: 50769 }, { name: "Statful", category: "analytics", domains: ["*.statful.com"] }, { name: "Steelhouse", category: "ad", domains: ["*.steelhousemedia.com"], totalExecutionTime: 66172, totalOccurrences: 452 }, { name: "Steepto", category: "ad", domains: ["*.steepto.com"], totalExecutionTime: 170, totalOccurrences: 1 }, { name: "StellaService", category: "analytics", domains: ["*.stellaservice.com"] }, { name: "StickyADS.tv", category: "ad", domains: ["*.stickyadstv.com"], totalExecutionTime: 2198555, totalOccurrences: 1462 }, { name: "STINGRAY", company: "FlexOne", category: "ad", domains: ["*.impact-ad.jp"], examples: ["y.one.impact-ad.jp"], totalExecutionTime: 1261721, totalOccurrences: 9742 }, { name: "Storify", company: "Adobe Systems", category: "social", domains: ["*.storify.com"] }, { name: "Storm Tag Manager", company: "Rakuten", category: "tag-manager", domains: ["*.stormcontainertag.com"] }, { name: "Storygize", category: "\ +ad", domains: ["*.storygize.net"], examples: ["www.storygize.net"], totalExecutionTime: 60468, totalOccurrences: 154 }, { name: "Strands", category: "utility", domains: ["*.strands.com"] }, { name: "StreamRail", category: "ad", domains: ["*.streamrail.com", "*.streamrail.net"] }, { name: "StrikeAd", category: "ad", domains: ["*.strikead.com"] }, { name: "Struq", company: "Quantcast", category: "ad", domains: ["*.struq.com"] }, { name: "Ströer Digital Media", category: "ad", domains: ["*.stroeerdigitalmedia.de"] }, { name: "StumbleUpon", category: "content", domains: ["*.stumble-upon.com", "*.stumbleupon.com"], totalExecutionTime: 18653, totalOccurrences: 17 }, { name: "Sub2 Technologies", category: "analytics", domains: ["*.sub2tech.com"], totalExecutionTime: 6667, totalOccurrences: 31 }, { name: "SublimeSkinz", category: "ad", domains: ["*.ayads.co"], totalExecutionTime: 339456, totalOccurrences: 772 }, { name: "Sumo Logic", category: "utility", domains: ["*.sumologic.com"], totalExecutionTime: 19322, + totalOccurrences: 9 }, { name: "Sunday Times Driving", category: "content", domains: ["*.driving.co.uk"] }, { name: "SundaySky", category: "ad", domains: ["*.sundaysky.com", "dds6m601du5ji.cloudfront.net"], totalExecutionTime: 7435, totalOccurrences: 10 }, { name: "Sunrise Integration", category: "utility", domains: ["*.sunriseintegration.com"] }, { name: "Supertool Network Technology", category: "analytics", domains: ["*.miaozhen.com"], totalExecutionTime: 6166, totalOccurrences: 49 }, { name: "Survata", category: "analytics", domains: ["*.survata.com"] }, { name: "SurveyGizmo", category: "analytics", domains: ["*.surveygizmo.eu"], examples: ["www.surveygizmo.eu"] }, { name: "SurveyMonkey", category: "analytics", domains: ["*.surveymonkey.com"], totalExecutionTime: 28632, totalOccurrences: 250 }, { name: "Survicate", category: "analytics", domains: ["*.survicate.com"], totalExecutionTime: 933283, totalOccurrences: 3008 }, { name: "Sweet Tooth", category: "ad", domains: ["*.sweetto\ +oth.io"], totalExecutionTime: 2673, totalOccurrences: 41 }, { name: "Swiftype", category: "utility", domains: ["*.swiftype.com", "*.swiftypecdn.com"], totalExecutionTime: 383638, totalOccurrences: 982 }, { name: "Switch Concepts", category: "ad", domains: ["*.switchadhub.com"] }, { name: "SwitchAds", company: "Switch Concepts", category: "ad", domains: ["*.switchads.com"] }, { name: "Swogo", category: "analytics", domains: ["*.xsellapp.com"] }, { name: "Swoop", category: "ad", domains: ["*.swoop.com"], totalExecutionTime: 13511, totalOccurrences: 75 }, { name: "Symantec", category: "utility", domains: ["*.norton.com", "*.symantec.com", "*.symcb.com", "*.symcd.com"], examples: ["extended-validation-ssl.websecurity.symantec.com"], totalExecutionTime: 184600, totalOccurrences: 363 }, { name: "Syncapse", category: "social", domains: ["*.clickable.net"] }, { name: "Synergetic", category: "ad", domains: ["*.synergetic.ag"] }, { name: "Synthetix", category: "customer-success", domains: ["*.sy\ +n-finity.com", "*.synthetix-ec1.com", "*.synthetix.com"], examples: ["www.synthetix-ec1.com"], totalExecutionTime: 6284, totalOccurrences: 27 }, { name: "Syte", category: "other", domains: ["*.syteapi.com"], examples: ["cdn.syteapi.com"], totalExecutionTime: 109749, totalOccurrences: 106 }, { name: "TINT", category: "content", domains: ["*.71n7.com", "d33w9bm0n1egwm.cloudfront.net", "d36hc0p18k1aoc.cloudfront.net", "d3l7tj34e9fc43.cloudfront.net"], examples: ["www.71n7.com"] }, { name: "TNS (Kantar Group)", category: "analytics", domains: ["*.tns-counter.ru"] }, { name: "TRUSTe", category: "utility", domains: ["*.truste.com"], totalExecutionTime: 123425, totalOccurrences: 613 }, { name: "TV Genius", company: "Ericcson Media Services", category: "content", domains: ["*.tvgenius.net"] }, { name: "TVSquared", category: "ad", domains: ["*.tvsquared.com"], totalExecutionTime: 548667, totalOccurrences: 4082 }, { name: "TVTY", category: "ad", domains: ["*.distribeo.com", "*.ogigl.com"] }, { name: "\ +Tactics bvba", category: "hosting", domains: ["*.influid.co"] }, { name: "Tag Inspector", company: "InfoTrust", category: "analytics", domains: ["d22xmn10vbouk4.cloudfront.net"], totalExecutionTime: 51386, totalOccurrences: 171 }, { name: "TagCommander", category: "tag-manager", domains: ["*.commander1.com", "*.tagcommander.com"], totalExecutionTime: 448164, totalOccurrences: 1509 }, { name: "Tagboard", category: "social", domains: ["*.tagboard.com"], totalExecutionTime: 106499, totalOccurrences: 49 }, { name: "Taggstar", company: "Taggstar UK", category: "ad", domains: ["*.taggstar.com"], totalExecutionTime: 16168, totalOccurrences: 68 }, { name: "Tail Target", company: "Tail", category: "ad", domains: ["*.tailtarget.com"], totalExecutionTime: 176612, totalOccurrences: 873 }, { name: "Tailored", category: "other", domains: ["d24qm7bu56swjs.cloudfront.net", "dw3vahmen1rfy.cloudfront.net", "*.tailored.to"] }, { name: "Taleo Enterprise Cloud Service", company: "Oracle", category: "conten\ +t", domains: ["*.taleo.net"], totalExecutionTime: 4178, totalOccurrences: 68 }, { name: "Talkable", category: "ad", domains: ["*.talkable.com", "d2jjzw81hqbuqv.cloudfront.net"], examples: ["www.talkable.com"], totalExecutionTime: 154019, totalOccurrences: 601 }, { name: "TapSense", category: "ad", domains: ["*.tapsense.com"] }, { name: "Tapad", category: "ad", domains: ["*.tapad.com"], totalExecutionTime: 976, totalOccurrences: 54 }, { name: "Teads", category: "ad", domains: ["*.teads.tv"], totalExecutionTime: 2295585, totalOccurrences: 7565 }, { name: "Team Internet Tonic", company: "Team Internet", category: "ad", domains: ["*.dntrax.com"] }, { name: "TechTarget", category: "content", domains: ["*.techtarget.com", "*.ttgtmedia.com"], totalExecutionTime: 11857, totalOccurrences: 24 }, { name: "Technorati", company: "Synacor", category: "ad", domains: ["*.technoratimedia.com"], totalExecutionTime: 5382653, totalOccurrences: 27186 }, { name: "Teedhaze", category: "content", domains: ["*\ +.fuel451.com"] }, { name: "Tell Apart", category: "analytics", domains: ["*.tellapart.com", "*.tellaparts.com"] }, { name: "Tencent", category: "content", domains: ["*.qq.com", "*.ywxi.net"], totalExecutionTime: 2265040, totalOccurrences: 8726 }, { name: "Thanx Media", category: "utility", domains: ["*.hawksearch.info"] }, { name: "Thawte", category: "utility", domains: ["*.thawte.com"], examples: ["ocsp.thawte.com", "seal.thawte.com"], totalExecutionTime: 307, totalOccurrences: 1 }, { name: "Thesis", category: "analytics", homepage: "https://www.thesistesting.com/", domains: ["*.ttsep.com"], examples: ["thix.ttsep.com"] }, { name: "The AA", category: "ad", domains: ["*.adstheaa.com"] }, { name: "The ADEX", category: "ad", domains: ["*.theadex.com"], totalExecutionTime: 13554, totalOccurrences: 129 }, { name: "The Best Day", category: "social", domains: ["*.thebestday.com"] }, { name: "The Filter", company: "Exabre", category: "analytics", domains: ["*.thefilter.com"] }, { name: "The G\ +uardian", category: "analytics", domains: ["*.ophan.co.uk"] }, { name: "The Hut Group", category: "content", domains: ["*.thcdn.com"], totalExecutionTime: 497181, totalOccurrences: 281 }, { name: "The Numa Group", category: "other", domains: ["*.hittail.com"] }, { name: "The Publisher Desk", category: "ad", domains: ["*.206ads.com", "*.publisherdesk.com"] }, { name: "The Sydney Morning Herald", company: "Fairfax Media", category: "content", domains: ["*.smh.com.au"] }, { name: "The Wall Street Jounal", category: "content", domains: ["*.wsj.net"], totalExecutionTime: 3036, totalOccurrences: 5 }, { name: "The Wall Street Journal", category: "content", domains: ["*.marketwatch.com"] }, { name: "TheFind", category: "content", domains: ["*.thefind.com"] }, { name: "Thinglink", category: "utility", domains: ["*.thinglink.com"], totalExecutionTime: 2987, totalOccurrences: 53 }, { name: "Thirdpresence", category: "ad", domains: ["*.thirdpresence.com"] }, { name: "ThreatMetrix", category: "util\ +ity", domains: ["*.online-metrix.net"], totalExecutionTime: 1901757, totalOccurrences: 3530 }, { name: "Throtle", homepage: "https://throtle.io/", category: "analytics", domains: ["*.thrtle.com", "*.v12group.com"] }, { name: "TicketMaster", category: "content", domains: ["*.t-x.io", "*.tmcs.net"] }, { name: "TikTok", company: "ByteDance Ltd", homepage: "https://www.tiktok.com/en/", category: "social", domains: ["*.tiktok.com", "*.ipstatp.com"], examples: ["analytics.tiktok.com", "https://s0.ipstatp.com/ad/business/track-log.js"], totalExecutionTime: 111182189, totalOccurrences: 256224 }, { name: "Tidio Live Chat", company: "Tidio", homepage: "https://www.tidiochat.com/en/", category: "customer-success", domains: ["*.tidiochat.com"], totalExecutionTime: 26584634, totalOccurrences: 24598 }, { name: "Tiledesk Live Chat", company: "Tiledesk SRL", homepage: "https://www.tiledesk.com/", category: "customer-success", domains: ["*.tiledesk.com"], examples: ["widget.tiledesk.com"], totalExecutionTime: 253744, + totalOccurrences: 103 }, { name: "Time", category: "content", domains: ["*.timeinc.net"] }, { name: "Time2Perf", category: "ad", domains: ["*.time2perf.com"] }, { name: "TinyURL", category: "utility", domains: ["*.tinyurl.com"] }, { name: "Tivo", category: "analytics", domains: ["*.rovicorp.com"] }, { name: "Tom&Co", category: "hosting", domains: ["*.tomandco.uk"] }, { name: "Toms Native Ads", company: "Purch", category: "ad", domains: ["*.natoms.com"] }, { name: "ToneMedia", category: "ad", domains: ["*.clickfuse.com"] }, { name: "Tonic", company: "Team Internet", category: "ad", domains: ["*.dntx.com"] }, { name: "Touch Commerce", category: "customer-success", domains: ["*.inq.com", "*.touchcommerce.com"], totalExecutionTime: 12673, totalOccurrences: 74 }, { name: "ToutApp", category: "ad", domains: ["*.toutapp.com"] }, { name: "TraceView", company: "Solarwinds", category: "analytics", domains: ["*.tracelytics.com", "d2gfdmu30u15x7.cloudfront.net"] }, { name: "TrackJS", category: "\ +analytics", domains: ["*.trackjs.com", "d2zah9y47r7bi2.cloudfront.net"], examples: ["usage.trackjs.com"], totalExecutionTime: 2112335, totalOccurrences: 2268 }, { name: "Tradedoubler", category: "ad", domains: ["*.pvnsolutions.com", "*.tradedoubler.com"], totalExecutionTime: 31870, totalOccurrences: 165 }, { name: "Tradelab", category: "ad", domains: ["*.tradelab.fr"], totalExecutionTime: 5013, totalOccurrences: 44 }, { name: "TrafficFactory", category: "ad", domains: ["*.trafficfactory.biz"] }, { name: "TrafficHunt", category: "ad", domains: ["*.traffichunt.com"] }, { name: "TrafficStars", category: "ad", domains: ["*.trafficstars.com", "*.tsyndicate.com"], totalExecutionTime: 3435101, totalOccurrences: 7430 }, { name: "Transifex", category: "utility", domains: ["*.transifex.com"], totalExecutionTime: 193259, totalOccurrences: 546 }, { name: "Travelex", category: "utility", domains: ["*.travelex.net", "*.travelex.co.uk"], examples: ["api.travelex.net", "travelmoney.travelex.co.uk"] }, + { name: "Travelocity Canada", company: "Travelocity", category: "content", domains: ["*.travelocity.ca"], examples: ["www.travelocity.ca"] }, { name: "Travelocity USA", company: "Travelocity", category: "content", domains: ["*.travelocity.com"], examples: ["www.travelocity.com"] }, { name: "Travelzoo", category: "content", domains: ["*.travelzoo.com"] }, { name: "Treasure Data", category: "analytics", domains: ["*.treasuredata.com"], totalExecutionTime: 1404314, totalOccurrences: 14403 }, { name: "Tremor Video", category: "ad", domains: ["*.tremorhub.com", "*.videohub.tv"] }, { name: "Trialfire", category: "analytics", domains: ["*.trialfire.com"], totalExecutionTime: 44579, totalOccurrences: 198 }, { name: "Tribal Fusion", company: "Exponential Interactive", category: "ad", domains: ["*.tribalfusion.com"], totalExecutionTime: 96569, totalOccurrences: 158016 }, { name: "Triblio", category: "marketing", domains: ["*.tribl.io"] }, { name: "Triggered Messaging", company: "Fresh Releva\ +nce", category: "ad", domains: ["*.triggeredmessaging.com"] }, { name: "Trinity Mirror", category: "content", domains: ["*.mirror.co.uk"], totalExecutionTime: 13841, totalOccurrences: 41 }, { name: "Trinity Mirror Digital Media", category: "social", domains: ["*.tm-aws.com", "*.icnetwork.co.uk"] }, { name: "TripAdvisor", category: "content", domains: ["*.jscache.com", "*.tacdn.com", "*.tamgrt.com", "*.tripadvisor.com", "*.viator.com", "*.tripadvisor.co.uk"], examples: ["www.jscache.com", "www.tamgrt.com"], totalExecutionTime: 749303, totalOccurrences: 2354 }, { name: "TripleLift", category: "ad", domains: ["*.3lift.com"], totalExecutionTime: 8396, totalOccurrences: 4812 }, { name: "Tru Optik", category: "ad", domains: ["*.truoptik.com"] }, { name: "TruConversion", category: "analytics", domains: ["*.truconversion.com"], totalExecutionTime: 487670, totalOccurrences: 1008 }, { name: "Trueffect", category: "marketing", domains: ["*.adlegend.com"] }, { name: "Truefit", category: "analytics", + domains: ["*.truefitcorp.com"], examples: ["cdn.truefitcorp.com", "fitrec.truefitcorp.com", "sch-cdn.truefitcorp.com"], totalExecutionTime: 4647, totalOccurrences: 20 }, { name: "Trust Guard", category: "utility", domains: ["*.trust-guard.com"], totalExecutionTime: 3346, totalOccurrences: 35 }, { name: "Trust Pilot", category: "analytics", domains: ["*.trustpilot.com"], totalExecutionTime: 14795265, totalOccurrences: 54942 }, { name: "Amazon Trust Services", company: "Amazon", category: "utility", domains: ["*.amazontrust.com", "o.ss2.us"], examples: ["ocsp.rootca1.amazontrust.com"], totalExecutionTime: 107, totalOccurrences: 1 }, { name: "Google Trust Services", company: "Google", category: "utility", domains: ["*.pki.goog"], examples: ["ocsp.pki.goog"], totalExecutionTime: 18, totalOccurrences: 1 }, { name: "Let's Encrypt", homepage: "https://letsencrypt.org/", category: "utility", domains: ["*.letsencrypt.org"], examples: ["ocsp.int-x3.letsencrypt.org"], totalExecutionTime: 76, totalOccurrences: 3 }, + { name: "TrustX", category: "ad", domains: ["*.trustx.org"] }, { name: "Trusted Shops", category: "utility", domains: ["*.trustedshops.com"], totalExecutionTime: 7373870, totalOccurrences: 17267 }, { name: "Trustev", company: "TransUnion", category: "utility", domains: ["*.trustev.com"], totalExecutionTime: 3272, totalOccurrences: 22 }, { name: "Trustwave", category: "utility", domains: ["*.trustwave.com"], totalExecutionTime: 4600, totalOccurrences: 7 }, { name: "Tryzens TradeState", company: "Tryzens", category: "analytics", domains: ["*.tryzens-analytics.com"], totalExecutionTime: 969, totalOccurrences: 9 }, { name: "TubeMogul", category: "ad", domains: ["*.tubemogul.com"], totalExecutionTime: 24151, totalOccurrences: 51 }, { name: "Turn", category: "ad", domains: ["*.turn.com"], totalExecutionTime: 4802, totalOccurrences: 72 }, { name: "Tutorialize", category: "customer-success", domains: ["*.tutorialize.me"] }, { name: "Twenga", category: "content", domains: ["*.twenga.fr", "*\ +.c4tw.net", "*.twenga.co.uk"], examples: ["tracker.twenga.co.uk"] }, { name: "Twitframe", company: "Superblock", category: "utility", domains: ["*.twitframe.com"] }, { name: "Twitter Online Conversion Tracking", company: "Twitter", category: "ad", domains: ["*.ads-twitter.com", "analytics.twitter.com"], examples: ["static.ads-twitter.com"], totalExecutionTime: 6170585, totalOccurrences: 73452 }, { name: "Twitter Short URL", company: "Twitter", category: "social", domains: ["*.t.co"] }, { name: "Twyn Group", category: "ad", domains: ["*.twyn.com"] }, { name: "Tynt", company: "33 Across", category: "ad", domains: ["*.tynt.com"], totalExecutionTime: 41643525, totalOccurrences: 212415 }, { name: "Typepad", category: "hosting", domains: ["*.typepad.com"], totalExecutionTime: 834082, totalOccurrences: 813 }, { name: "TyrbooBytes", category: "utility", domains: ["*.turbobytes.net"] }, { name: "UPS i-parcel", company: "UPS", category: "other", domains: ["*.i-parcel.com"] }, { name: "US Media C\ +onsulting", category: "ad", domains: ["*.mediade.sk"] }, { name: "Ubertags", category: "tag-manager", domains: ["*.ubertags.com"] }, { name: "Umbel", category: "analytics", domains: ["*.umbel.com"] }, { name: "Unanimis", company: "Switch", category: "ad", domains: ["*.unanimis.co.uk"] }, { name: "Unbounce", category: "ad", domains: ["*.ubembed.com", "*.unbounce.com", "d2xxq4ijfwetlm.cloudfront.net", "d9hhrg4mnvzow.cloudfront.net"], totalExecutionTime: 2902422, totalOccurrences: 8808 }, { name: "Underdog Media", category: "ad", domains: ["*.underdog.media", "*.udmserve.net"], totalExecutionTime: 524141, totalOccurrences: 289 }, { name: "Understand Digital", category: "ad", domains: ["*.redirecting2.net"] }, { name: "Undertone", company: "Perion", category: "ad", domains: ["*.legolas-media.com"], examples: ["rt.legolas-media.com"] }, { name: "Unidays", category: "ad", domains: ["*.myunidays.com", "*.unidays.world"] }, { name: "Uniqodo", category: "ad", domains: ["*.uniqodo.com"] }, { name: "\ +Unite", category: "ad", domains: ["*.uadx.com"] }, { name: "United Card Services", category: "utility", domains: ["*.ucs.su"] }, { name: "United Internet", category: "hosting", domains: ["*.uicdn.com"], totalExecutionTime: 14225, totalOccurrences: 75 }, { name: "United Internet Media", category: "ad", domains: ["*.ui-portal.de"], totalExecutionTime: 20307, totalOccurrences: 59 }, { name: "United Internet Media AG", category: "hosting", domains: ["*.tifbs.net", "*.uicdn.net", "*.uimserv.net"], totalExecutionTime: 1737, totalOccurrences: 48 }, { name: "Unknown", category: "other", domains: [] }, { name: "Unruly Media", category: "ad", domains: ["*.unrulymedia.com"], totalExecutionTime: 679, totalOccurrences: 1789 }, { name: "UpBuild", category: "ad", domains: ["*.upbuild.io"], examples: ["www.upbuild.io"] }, { name: "UpSellit", category: "analytics", domains: ["*.upsellit.com"], examples: ["www.upsellit.com"], totalExecutionTime: 289920, totalOccurrences: 1013 }, { name: "Upland Software", + category: "hosting", domains: ["*.clickability.com"] }, { name: "Airship", category: "marketing", domains: ["*.urbanairship.com", "*.aswpsdkus.com"], totalExecutionTime: 4666, totalOccurrences: 37 }, { name: "UsabilityTools", category: "analytics", domains: ["*.usabilitytools.com"] }, { name: "Usablenet.net", category: "utility", domains: ["*.usablenet.net"] }, { name: "Use It Better", category: "analytics", domains: ["*.useitbetter.com"] }, { name: "User Replay", category: "analytics", domains: ["*.userreplay.net"] }, { name: "UserReport", category: "analytics", domains: ["*.userreport.com"], totalExecutionTime: 133479, totalOccurrences: 476 }, { name: "Userneeds", category: "analytics", domains: ["*.userneeds.dk"] }, { name: "Userzoom", category: "analytics", domains: ["*.userzoom.com"], totalExecutionTime: 5093, totalOccurrences: 4 }, { name: "V12 Retail Finance", category: "utility", domains: ["*.v12finance.com"] }, { name: "Vacaciones eDreams", category: "content", domains: ["\ +*.odistatic.net"] }, { name: "Varick Media Management", category: "ad", domains: ["*.vmmpxl.com"] }, { name: "Vdopia Chocolate", company: "Vdopia", category: "ad", domains: ["*.vdopia.com"] }, { name: "Ve", company: "Ve", homepage: "https://www.ve.com/", category: "marketing", domains: ["*.veinteractive.com", "*.ve.com"] }, { name: "Ve Interactive", company: "Ve", category: "ad", domains: ["*.vepxl1.net", "*.adgenie.co.uk"] }, { name: "Vee24", category: "customer-success", domains: ["*.vee24.com"], totalExecutionTime: 20941, totalOccurrences: 38 }, { name: "Veeseo", category: "content", domains: ["*.veeseo.com"] }, { name: "Venatus Media", category: "marketing", domains: ["*.alcvid.com", "*.venatusmedia.com"] }, { name: "Veoxa", category: "ad", domains: ["*.veoxa.com"] }, { name: "Vergic AB", category: "customer-success", domains: ["*.psplugin.com"], totalExecutionTime: 48232, totalOccurrences: 71 }, { name: "Vergic Engage Platform", company: "Vergic", category: "customer-success", domains: [ + "*.vergic.com"], totalExecutionTime: 41524, totalOccurrences: 57 }, { name: "Verisign (Symantec)", category: "utility", domains: ["*.verisign.com"] }, { name: "Verizon", category: "utility", domains: ["*.public-trust.com"], examples: ["www.public-trust.com"] }, { name: "Verizon Digital Media CDN", homepage: "https://www.verizondigitalmedia.com/", category: "cdn", domains: ["*.edgecastcdn.net", "*.edgecastdns.net"], totalExecutionTime: 98698, totalOccurrences: 108 }, { name: "Verizon Uplynk", company: "Verizon", category: "content", domains: ["*.uplynk.com"], totalExecutionTime: 572, totalOccurrences: 4 }, { name: "Vero", company: "Semblance", category: "ad", domains: ["*.getvero.com", "d3qxef4rp70elm.cloudfront.net"], totalExecutionTime: 613, totalOccurrences: 10 }, { name: "VertaMedia", category: "ad", domains: ["*.vertamedia.com"] }, { name: "Vertical Mass", category: "ad", domains: ["*.vmweb.net"] }, { name: "Vestorly", category: "ad", domains: ["*.oodalab.com"] }, { name: "Vext\ +ras", category: "other", domains: ["*.vextras.com"], totalExecutionTime: 4484, totalOccurrences: 42 }, { name: "Viacom", category: "content", domains: ["*.mtvnservices.com"], totalExecutionTime: 15501, totalOccurrences: 44 }, { name: "Vibrant Media", category: "ad", domains: ["*.intellitxt.com", "*.picadmedia.com"] }, { name: "VidPulse", category: "analytics", domains: ["*.vidpulse.com"] }, { name: "Video Media Groep", category: "ad", domains: ["*.vmg.host", "*.inpagevideo.nl"] }, { name: "VideoHub", company: "Tremor Video", category: "ad", domains: ["*.scanscout.com"], examples: ["dt.scanscout.com"] }, { name: "Videology", category: "ad", domains: ["*.tidaltv.com"] }, { name: "Vidible", category: "ad", domains: ["*.vidible.tv"] }, { name: "VigLink", category: "ad", domains: ["*.viglink.com"], totalExecutionTime: 3670311, totalOccurrences: 6219 }, { name: "Vindico", company: "Viant", category: "ad", domains: ["*.vindicosuite.com"] }, { name: "Viocorp International", category: "content", + domains: ["*.vioapi.com"] }, { name: "ViralNinjas", category: "ad", domains: ["*.viralninjas.com"] }, { name: "Virool", category: "ad", domains: ["*.virool.com"] }, { name: "Virtual Earth", company: "Microsoft", category: "utility", domains: ["*.virtualearth.net"], totalExecutionTime: 54315, totalOccurrences: 312 }, { name: "Visely", company: "Visely", category: "other", homepage: "https://visely.io/", domains: ["*.visely.io"] }, { name: "VisScore", category: "analytics", domains: ["*.visscore.com", "d2hkbi3gan6yg6.cloudfront.net"] }, { name: "Visible Measures", category: "ad", domains: ["*.visiblemeasures.com"], totalExecutionTime: 11, totalOccurrences: 13 }, { name: "Visual Studio", company: "Microsoft", category: "utility", domains: ["*.visualstudio.com"], totalExecutionTime: 3464, totalOccurrences: 3 }, { name: "VisualDNA", category: "ad", domains: ["*.visualdna.com"] }, { name: "VisualVisitor", category: "ad", domains: ["*.id-visitors.com"], examples: ["frontend.id-visitors.co\ +m"], totalExecutionTime: 871, totalOccurrences: 14 }, { name: "Vivocha S.p.A", category: "customer-success", domains: ["*.vivocha.com"], totalExecutionTime: 65471, totalOccurrences: 38 }, { name: "Vizu (Nielsen)", category: "analytics", domains: ["*.vizu.com"] }, { name: "Vizury", category: "ad", domains: ["*.vizury.com"], totalExecutionTime: 1296, totalOccurrences: 20 }, { name: "VoiceFive", category: "analytics", domains: ["*.voicefive.com"] }, { name: "Volvelle", company: "Optomaton", category: "ad", domains: ["*.volvelle.tech"] }, { name: "VouchedFor", category: "analytics", domains: ["*.vouchedfor.co.uk"], totalExecutionTime: 30557, totalOccurrences: 18 }, { name: "WARPCACHE", category: "utility", domains: ["*.warpcache.net"] }, { name: "WISHLIST", company: "Shopapps", category: "social", domains: ["*.shopapps.in"] }, { name: "WP Engine", category: "hosting", domains: ["*.wpengine.com"], totalExecutionTime: 651034, totalOccurrences: 341 }, { name: "WalkMe", category: "customer-suc\ +cess", domains: ["*.walkme.com"], totalExecutionTime: 636459, totalOccurrences: 495 }, { name: "Watching That", category: "other", domains: ["*.watchingthat.com"] }, { name: "Wayfair", category: "analytics", domains: ["*.wayfair.com"], examples: ["t.wayfair.com"] }, { name: "Web CEO", category: "other", domains: ["*.websiteceo.com"], examples: ["www.websiteceo.com"] }, { name: "Web Dissector", company: "Beijing Gridsum Technologies", category: "analytics", domains: ["*.gridsumdissector.com", "*.webdissector.com"], examples: ["www.webdissector.com"] }, { name: "Web Forensics", category: "analytics", domains: ["*.webforensics.co.uk"] }, { name: "Web Security and Performance", company: "NCC Group", category: "utility", domains: ["*.nccgroup.trust"] }, { name: "WebEngage", category: "customer-success", domains: ["*.webengage.co", "*.webengage.com", "d23nd6ymopvz52.cloudfront.net", "d3701cc9l7v9a6.cloudfront.net"], totalExecutionTime: 789975, totalOccurrences: 2283 }, { name: "WebInsight", company: "\ +dotMailer", category: "analytics", domains: ["*.trackedlink.net", "*.trackedweb.net"], totalExecutionTime: 21241, totalOccurrences: 277 }, { name: "WebPageOne Solutions", category: "other", domains: ["*.webpageone.com"] }, { name: "WebSpectator", category: "ad", domains: ["*.webspectator.com"] }, { name: "WebTuna", company: "Application Performance", category: "analytics", domains: ["*.webtuna.com"] }, { name: "WebVideoCore", company: "StreamingVideoProvider", category: "content", domains: ["*.webvideocore.net"], totalExecutionTime: 74152, totalOccurrences: 38 }, { name: "WebWombat", category: "utility", domains: ["*.ic.com.au"] }, { name: "Webcollage", category: "customer-success", domains: ["*.webcollage.net"] }, { name: "Webcore", category: "ad", domains: ["*.onefeed.co.uk"] }, { name: "Webkul", company: "Webkul Software", category: "utility", domains: ["*.webkul.com"], totalExecutionTime: 172788, totalOccurrences: 490 }, { name: "Webmarked", category: "utility", domains: ["*.webmar\ +ked.net"], totalExecutionTime: 72467, totalOccurrences: 1077 }, { name: "Weborama", category: "ad", domains: ["*.weborama.com", "*.weborama.fr"], totalExecutionTime: 45883, totalOccurrences: 372 }, { name: "WebpageFX", category: "ad", domains: ["*.leadmanagerfx.com"], totalExecutionTime: 241118, totalOccurrences: 946 }, { name: "Webphone", company: "IP WEB SERVICES", category: "customer-success", domains: ["*.webphone.net"], totalExecutionTime: 4605, totalOccurrences: 20 }, { name: "Webselect selectcommerce", company: "Webselect Internet", category: "hosting", domains: ["*.webselect.net"] }, { name: "Webthinking", category: "hosting", domains: ["*.webthinking.co.uk"] }, { name: "Webtrekk", category: "analytics", domains: ["*.wbtrk.net", "*.webtrekk-asia.net", "*.webtrekk.net", "*.wt-eu02.net", "*.wt-safetag.com"], totalExecutionTime: 85572, totalOccurrences: 428 }, { name: "Webtrends", category: "analytics", domains: ["*.webtrends.com", "*.webtrendslive.com", "d1q62gfb8siqnm.cloudfront\ +.net"], totalExecutionTime: 1437, totalOccurrences: 6 }, { name: "Webtype", category: "cdn", domains: ["*.webtype.com"], totalExecutionTime: 0, totalOccurrences: 1 }, { name: "White Ops", category: "utility", domains: ["*.acexedge.com", "*.tagsrvcs.com"] }, { name: "Whitespace", category: "ad", domains: ["*.whitespacers.com"] }, { name: "WhosOn Live Chat Software", category: "customer-success", domains: ["*.whoson.com"], totalExecutionTime: 20753, totalOccurrences: 112 }, { name: "Wibbitz", category: "other", domains: ["*.wibbitz.com"] }, { name: "Wide Area Communications", category: "hosting", domains: ["*.widearea.co.uk"] }, { name: "WideOrbit", category: "marketing", domains: ["*.admaym.com"] }, { name: "William Reed", category: "content", domains: ["*.wrbm.com"], totalExecutionTime: 50, totalOccurrences: 1 }, { name: "WillyFogg.com", category: "content", domains: ["*.willyfogg.com"] }, { name: "Windows", company: "Microsoft", category: "utility", domains: ["*.windowsupdate.com"], examples: [ + "ctldl.windowsupdate.com"] }, { name: "WisePops", category: "utility", domains: ["*.wisepops.com"], totalExecutionTime: 2631328, totalOccurrences: 1950 }, { name: "Wishlist King", company: "Appmate", category: "other", homepage: "https://appmate.io/", domains: ["*.appmate.io"], examples: ["api.appmate.io"], totalExecutionTime: 130543, totalOccurrences: 235 }, { name: "Wishpond Technologies", category: "marketing", domains: ["*.wishpond.com", "*.wishpond.net"], totalExecutionTime: 771888, totalOccurrences: 1691 }, { name: "WizRocket Technologies", category: "analytics", domains: ["*.wzrkt.com"], totalExecutionTime: 138, totalOccurrences: 2 }, { name: "Woopra", category: "analytics", domains: ["*.woopra.com"], totalExecutionTime: 120767, totalOccurrences: 1366 }, { name: "Woosmap", category: "utility", domains: ["*.woosmap.com"], totalExecutionTime: 58710, totalOccurrences: 139 }, { name: "WorkCast", category: "hosting", domains: ["*.workcast.net"] }, { name: "World News Media", category: "\ +content", domains: ["*.wnmedia.co.uk"] }, { name: "Worldpay", category: "utility", domains: ["*.worldpay.com"], totalExecutionTime: 25852, totalOccurrences: 18 }, { name: "Wow Analytics", category: "analytics", domains: ["*.wowanalytics.co.uk"], totalExecutionTime: 11162, totalOccurrences: 73 }, { name: "Wowcher", category: "ad", domains: ["*.wowcher.co.uk"] }, { name: "Wufoo", category: "utility", domains: ["*.wufoo.com"], totalExecutionTime: 381206, totalOccurrences: 1507 }, { name: "Wunderkind", category: "marketing", homepage: "https://www.wunderkind.co/", domains: ["*.bounceexchange.com", "*.bouncex.net", "*.wknd.ai", "*.cdnbasket.net", "*.cdnwidget.com"], examples: ["events.bouncex.net", "tag.wknd.ai", "data.cdnbasket.net", "pix.cdnwidget.com"], totalExecutionTime: 2016506, totalOccurrences: 1278 }, { name: "Wyng", category: "ad", domains: ["*.offerpop.com"] }, { name: "XMLSHOP", category: "hosting", domains: ["*.xmlshop.biz"] }, { name: "XiTi", company: "AT Internet", category: "\ +analytics", domains: ["*.xiti.com", "*.aticdn.net"], homepage: "https://www.atinternet.com/en/", examples: ["tag.aticdn.net/123456789/smarttag.js"], totalExecutionTime: 918257, totalOccurrences: 8483 }, { name: "YUDU", category: "content", domains: ["*.yudu.com"] }, { name: "Yahoo! Ad Exchange", company: "Yahoo!", category: "ad", domains: ["*.yieldmanager.com", "*.browsiprod.com"], examples: ["yield-manager.browsiprod.com"], totalExecutionTime: 12720569, totalOccurrences: 4994 }, { name: "Yahoo! JAPAN Ads", company: "Yahoo! JAPAN", category: "ad", homepage: "https://marketing.yahoo.co.jp/service/yahooads/", domains: ["yads.c.yimg.jp", "s.yimg.jp", "b92.yahoo.co.jp"], examples: ["yads.c.yimg.jp/js/yads-async.js", "s.yimg.jp/images/listing/tool/yads/ydn/creative/video/ytop_video_timeline_sp.min.js", "b92.yahoo.co.jp/js/s_retargeting.js"], totalExecutionTime: 6236624, totalOccurrences: 37464 }, { name: "Yahoo! Tag Manager", company: "Yahoo! JAPAN", category: "tag-manager", homepage: "http\ +s://marketing.yahoo.co.jp/service/tagmanager/", domains: ["*.yjtag.jp"], examples: ["s.yjtag.jp/tag.js"] }, { name: "Yahoo! Small Business", company: "Yahoo!", category: "hosting", domains: ["*.aabacosmallbusiness.com"] }, { name: "Yellow Robot", category: "ad", domains: ["*.backinstock.org"], totalExecutionTime: 15268, totalOccurrences: 508 }, { name: "YieldPartners", category: "ad", domains: ["*.yieldpartners.com"] }, { name: "Yieldbot", category: "ad", domains: ["*.yldbt.com"] }, { name: "Yieldify", category: "ad", domains: ["*.yieldify.com", "*.yieldifylabs.com", "d33wq5gej88ld6.cloudfront.net", "dwmvwp56lzq5t.cloudfront.net"], examples: ["geo.yieldifylabs.com"], totalExecutionTime: 513761, totalOccurrences: 168 }, { name: "Yieldlab", category: "ad", domains: ["*.yieldlab.net"], totalExecutionTime: 54, totalOccurrences: 8 }, { name: "Yieldmo", category: "ad", domains: ["*.yieldmo.com"], totalExecutionTime: 51128, totalOccurrences: 2375 }, { name: "Yieldr", category: "ad", domains: [ + "*.254a.com"] }, { name: "Yo", category: "utility", domains: ["*.yopify.com"] }, { name: "YoYo", category: "utility", domains: ["*.goadservices.com"] }, { name: "Yotpo", homepage: "https://www.yotpo.com/", category: "marketing", domains: ["*.yotpo.com", "*.swellrewards.com"], totalExecutionTime: 16919447, totalOccurrences: 26094 }, { name: "Yottaa", category: "hosting", domains: ["*.yottaa.com", "*.yottaa.net"], totalExecutionTime: 798791, totalOccurrences: 753 }, { name: "YourAmigo", category: "utility", domains: ["*.youramigo.com"] }, { name: "YuMe", category: "ad", domains: ["*.yume.com", "*.yumenetworks.com"], examples: ["cks.yumenetworks.com"] }, { name: "Yummley", category: "other", domains: ["*.yummly.com"], totalExecutionTime: 14163, totalOccurrences: 6 }, { name: "ZEDO", category: "ad", domains: ["*.zedo.com"] }, { name: "Zafu", category: "analytics", domains: ["*.zafu.com"] }, { name: "Zaius", category: "ad", domains: ["*.zaius.com"] }, { name: "Zamplus ad", category: "ad", + domains: ["*.zampda.net"] }, { name: "Zanox", category: "ad", domains: ["*.zanox.com", "*.zanox.ws"] }, { name: "Zapper", category: "utility", domains: ["*.zapper.com"] }, { name: "Zarget", category: "analytics", domains: ["*.zarget.com"] }, { name: "Zemanta", category: "ad", domains: ["*.zemanta.com"], totalExecutionTime: 2735, totalOccurrences: 28 }, { name: "Zen Internet", category: "other", domains: ["*.zyen.com"] }, { name: "Zenovia Digital Exchange", category: "ad", domains: ["*.rhythmxchange.com", "*.zenoviaexchange.com"] }, { name: "ZergNet", category: "content", domains: ["*.zergnet.com"], totalExecutionTime: 186, totalOccurrences: 4 }, { name: "Zerogrey", category: "hosting", domains: ["*.zerogrey.com"] }, { name: "Ziff Davis Tech", category: "ad", domains: ["*.adziff.com", "*.zdbb.net"], totalExecutionTime: 30706, totalOccurrences: 93 }, { name: "Zmags", category: "marketing", domains: ["*.zmags.com"], totalExecutionTime: 262514, totalOccurrences: 119 }, { name: "Zolando", + category: "content", domains: ["*.ztat.net"], totalExecutionTime: 229623, totalOccurrences: 48 }, { name: "Zoover", category: "analytics", domains: ["*.zoover.nl", "*.zoover.co.uk"], totalExecutionTime: 9173, totalOccurrences: 2 }, { name: "Zopim", category: "customer-success", domains: ["*.zopim.io"] }, { name: "[24]7", category: "customer-success", domains: ["*.247-inc.net", "*.247inc.net", "d1af033869koo7.cloudfront.net"], totalExecutionTime: 24965, totalOccurrences: 20 }, { name: "adKernel", category: "ad", domains: ["*.adkernel.com"], totalExecutionTime: 19140, totalOccurrences: 9621 }, { name: "adMarketplace", company: "AMPexchange", category: "ad", domains: ["*.ampxchange.com", "*.admarketplace.net"] }, { name: "addtocalendar", category: "utility", domains: ["*.addtocalendar.com"] }, { name: "adnanny", category: "ad", domains: ["*.adserver01.de"], totalExecutionTime: 2, totalOccurrences: 6 }, { name: "affilinet", category: "ad", domains: ["*.reussissonsensemble.fr", "*.succe\ +ssfultogether.co.uk"] }, { name: "audioBoom", category: "social", domains: ["*.audioboom.com", "*.audioboo.fm"], totalExecutionTime: 136729, totalOccurrences: 57 }, { name: "bPay by Barclaycard", company: "Barclays Bank", category: "utility", domains: ["*.bpay.co.uk"] }, { name: "bRealTime", category: "ad", domains: ["*.brealtime.com"], totalExecutionTime: 4479, totalOccurrences: 76 }, { name: "bd4travel", category: "analytics", domains: ["*.bd4travel.com"] }, { name: "bizinformation-VOID", company: "bizinformation", category: "analytics", domains: ["*.bizinformation.org"] }, { name: "carrot", category: "social", domains: ["*.sharebutton.co"] }, { name: "cloudIQ", category: "analytics", domains: ["*.cloud-iq.com"] }, { name: "comScore", category: "analytics", domains: ["*.adxpose.com", "*.comscore.com", "*.sitestat.com", "*.zqtk.net"], totalExecutionTime: 4938, totalOccurrences: 3 }, { name: "content.ad", category: "ad", domains: ["*.content.ad"] }, { name: "d3 Media", company: "d3 Tec\ +hnologies", category: "other", domains: ["*.d3sv.net"] }, { name: "dexiMEDIA", category: "ad", domains: ["*.deximedia.com"] }, { name: "dianomi", category: "ad", domains: ["*.dianomi.com", "*.dianomioffers.co.uk"], totalExecutionTime: 52461, totalOccurrences: 86 }, { name: "donReach", category: "social", domains: ["*.donreach.com"] }, { name: "dotMailer", category: "ad", domains: ["*.dmtrk.com", "*.dotmailer.com", "*.emlfiles.com"] }, { name: "dotMailer Surveys", company: "dotMailer", category: "analytics", domains: ["*.dotmailer-surveys.com"] }, { name: "dstillery", category: "ad", domains: ["*.dstillery.com", "*.media6degrees.com"], totalExecutionTime: 1160, totalOccurrences: 12 }, { name: "eBay", category: "ad", domains: ["*.ebay.com", "*.ebayimg.com", "*.fetchback.com"], totalExecutionTime: 600826, totalOccurrences: 1026 }, { name: "eBay Enterprise", category: "hosting", domains: ["*.csdata1.com", "*.gsipartners.com"] }, { name: "eBuzzing", company: "Teads Managed Services", category: "\ +ad", domains: ["*.ebz.io"] }, { name: "eDigital Research", category: "customer-success", domains: ["*.edigitalresearch.com", "*.edigitalsurvey.com", "*.edrcdn.com", "*.ecustomeropinions.com"] }, { name: "eGain", category: "analytics", domains: ["*.analytics-egain.com", "*.egain.com"], totalExecutionTime: 8418, totalOccurrences: 74 }, { name: "eHost", category: "hosting", domains: ["*.ehosts.net"] }, { name: "eKomi", category: "analytics", domains: ["*.ekomi.com", "*.ekomi.de"], totalExecutionTime: 51192, totalOccurrences: 17 }, { name: "eWAY", company: "Web Active Pty", category: "utility", domains: ["*.eway.com.au"], examples: ["www.eway.com.au"], totalExecutionTime: 11094, totalOccurrences: 1 }, { name: "eXTReMe digital", category: "analytics", domains: ["*.extreme-dm.com"], totalExecutionTime: 3491, totalOccurrences: 78 }, { name: "eXelate", category: "ad", domains: ["*.exelator.com"], totalExecutionTime: 17905, totalOccurrences: 246 }, { name: "ecommercefeed.net", category: "market\ +ing", domains: ["*.ecommercefeed.net"] }, { name: "engage:BDR", category: "ad", domains: ["*.bnmla.com", "*.ebdr3.com"] }, { name: "epago", category: "ad", domains: ["*.adaos-ads.net"] }, { name: "epoq internet services", category: "analytics", domains: ["*.epoq.de"], totalExecutionTime: 84260, totalOccurrences: 122 }, { name: "etouches", category: "hosting", domains: ["*.etouches.com"], examples: ["www.etouches.com"] }, { name: "etracker", category: "analytics", domains: ["*.etracker.com", "*.etracker.de"], examples: ["www.etracker.com"], totalExecutionTime: 2076262, totalOccurrences: 5626 }, { name: "everestads.com", category: "content", domains: ["*.verestads.net"] }, { name: "exebid.DCA", company: "Data-Centric Alliance", category: "ad", domains: ["*.exe.bid"] }, { name: "eyeReturn Marketing", category: "marketing", domains: ["*.eyereturn.com"] }, { name: "feedoptimise", category: "hosting", domains: ["*.feedoptimise.com", "d1w78njrm56n7g.cloudfront.net"], totalExecutionTime: 126, totalOccurrences: 2 }, + { name: "fifty-five", category: "ad", domains: ["*.55labs.com"] }, { name: "fluct", category: "ad", domains: ["*.adingo.jp"], totalExecutionTime: 5114249, totalOccurrences: 12890 }, { name: "freegeoip.net", company: "(community-funded)", category: "utility", domains: ["*.freegeoip.net"] }, { name: "freewheel.tv", category: "content", domains: ["*.fwmrm.net"], totalExecutionTime: 3847, totalOccurrences: 42 }, { name: "gnatta", category: "customer-success", domains: ["*.gnatta.com"] }, { name: "home.pl", category: "hosting", domains: ["*.nscontext.eu"] }, { name: "hyfn", category: "ad", domains: ["*.hyfn.com"] }, { name: "iAdvize SAS", category: "customer-success", domains: ["*.iadvize.com"], totalExecutionTime: 286995, totalOccurrences: 844 }, { name: "iBillboard", category: "ad", domains: ["*.ibillboard.com"], totalExecutionTime: 303, totalOccurrences: 2 }, { name: "iCrossing", category: "ad", domains: ["*.ic-live.com"] }, { name: "iFactory", company: "RDW Group", category: "hostin\ +g", domains: ["*.ifactory.com"] }, { name: "iGoDigital", category: "analytics", domains: ["*.igodigital.com"], totalExecutionTime: 1800, totalOccurrences: 21 }, { name: "iJento", company: "Fopsha", category: "ad", domains: ["*.ijento.com"] }, { name: "iPage", category: "hosting", domains: ["*.ipage.com"], examples: ["www.ipage.com"], totalExecutionTime: 490, totalOccurrences: 6 }, { name: "iPerceptions", category: "customer-success", domains: ["*.iperceptions.com"], totalExecutionTime: 626044, totalOccurrences: 4662 }, { name: "iTunes", company: "Apple", category: "content", domains: ["*.mzstatic.com"] }, { name: "imgix", company: "Zebrafish Labs", category: "utility", domains: ["*.imgix.net"], totalExecutionTime: 40073, totalOccurrences: 98 }, { name: "infogr.am", category: "utility", domains: ["*.infogr.am", "*.jifo.co"], totalExecutionTime: 2008949, totalOccurrences: 233 }, { name: "iotec", category: "analytics", domains: ["*.dsp.io"] }, { name: "iovation", category: "utility", domains: [ + "*.iesnare.com"], totalExecutionTime: 270232, totalOccurrences: 2159 }, { name: "ipinfo.io", category: "utility", domains: ["*.ipinfo.io"] }, { name: "issuu", category: "content", domains: ["*.issuu.com", "*.isu.pub"], totalExecutionTime: 5607951, totalOccurrences: 2714 }, { name: "iubenda", category: "utility", domains: ["*.iubenda.com"], examples: ["www.iubenda.com"], totalExecutionTime: 69911073, totalOccurrences: 97074 }, { name: "j2 Cloud Services", category: "ad", domains: ["*.campaigner.com"], totalExecutionTime: 12708, totalOccurrences: 28 }, { name: "jsonip.com", category: "analytics", domains: ["*.jsonip.com"] }, { name: "linkpulse", category: "analytics", domains: ["*.lp4.io"] }, { name: "loGo_net", category: "analytics", domains: ["*.logo-net.co.uk"] }, { name: "mainADV", category: "ad", domains: ["*.httptrack.com", "*.solocpm.com"] }, { name: "mbr targeting", category: "ad", domains: ["*.m6r.eu"], totalExecutionTime: 17, totalOccurrences: 1 }, { name: "media.ventive", category: "\ +ad", domains: ["*.contentspread.net"] }, { name: "metrigo", category: "ad", domains: ["*.metrigo.com"] }, { name: "minicabit.com", category: "content", domains: ["*.minicabit.com"] }, { name: "mobiManage", category: "hosting", domains: ["*.mobimanage.com"] }, { name: "moving-pictures", category: "other", domains: ["*.moving-pictures.biz", "*.v6-moving-pictures.com", "*.vtstat.com", "*.moving-pictures.de"] }, { name: "my6sense", category: "ad", domains: ["*.mynativeplatform.com"] }, { name: "myThings", category: "ad", domains: ["*.mythings.com", "*.mythingsmedia.net"] }, { name: "mymovies", category: "content", domains: ["*.mymovies.net"] }, { name: "nRelate-VOID", company: "nRelate", category: "content", domains: ["*.nrelate.com"] }, { name: "nToklo", category: "analytics", domains: ["*.ntoklo.com"] }, { name: "neXeps", category: "ad", domains: ["*.nexeps.com"] }, { name: "ninemsn Pty.", category: "utility", domains: ["*.ninemsn.com.au"] }, { name: "nugg.ad", category: "ad", domains: [ + "*.nuggad.net"] }, { name: "numero interactive", company: "numero", category: "ad", domains: ["*.numerointeractive.com"] }, { name: "optMD", company: "Optimax Media Delivery", category: "ad", domains: ["*.optmd.com"] }, { name: "otracking.com", category: "analytics", domains: ["*.otracking.com"] }, { name: "paysafecard", company: "Paysafe Group", category: "utility", domains: ["*.paysafecard.com"] }, { name: "piano", category: "ad", domains: ["*.npttech.com", "*.tinypass.com"], examples: ["www.npttech.com"], totalExecutionTime: 1016108, totalOccurrences: 1146 }, { name: "piclike", category: "ad", domains: ["*.piclike.us"] }, { name: "placehold.it", category: "utility", domains: ["*.placehold.it"] }, { name: "plista", category: "ad", domains: ["*.plista.com"] }, { name: "prebid.org", category: "utility", domains: ["*.prebid.org"], totalExecutionTime: 462, totalOccurrences: 1 }, { name: "reEmbed", category: "other", domains: ["*.reembed.com"] }, { name: "reddit", category: "social", domains: [ + "*.reddit.com", "*.redditstatic.com"], examples: ["www.redditstatic.com"], totalExecutionTime: 4113522, totalOccurrences: 18483 }, { name: "rewardStyle.com", category: "ad", domains: ["*.rewardstyle.com"], totalExecutionTime: 280999, totalOccurrences: 1491 }, { name: "rss2json", category: "utility", domains: ["*.rss2json.com"], totalExecutionTime: 1380, totalOccurrences: 18 }, { name: "sage Pay", company: "Sage Pay Europe", category: "utility", domains: ["*.sagepay.com"], totalExecutionTime: 4481, totalOccurrences: 40 }, { name: "section.io", category: "utility", domains: ["*.squixa.net"], examples: ["beacon.squixa.net", "s.squixa.net"] }, { name: "smartclip", category: "ad", domains: ["*.smartclip.net"], totalExecutionTime: 41051, totalOccurrences: 21 }, { name: "sovrn", category: "ad", domains: ["*.lijit.com"], totalExecutionTime: 2389059, totalOccurrences: 27306 }, { name: "stackpile.io", company: "StackPile", category: "tag-manager", domains: ["*.stackpile.io"] }, { name: "temp\ +late-help.com", category: "hosting", domains: ["*.template-help.com"], totalExecutionTime: 16016, totalOccurrences: 13 }, { name: "test", company: "test only", category: "other", domains: ["*.testtesttest.com"] }, { name: "trueAnthem", category: "social", domains: ["*.tru.am"] }, { name: "tweetmeme-VOID", company: "tweetmeme", category: "analytics", domains: ["*.tweetmeme.com"] }, { name: "uLogin", category: "other", domains: ["*.ulogin.ru"] }, { name: "uLogix", category: "ad", domains: ["*.ulogix.ru"] }, { name: "ucfunnel ucX", company: "ucfunnel", category: "ad", domains: ["*.aralego.com"], totalExecutionTime: 1469345, totalOccurrences: 7945 }, { name: "up-value", category: "ad", domains: ["*.up-value.de"] }, { name: "wywy", category: "ad", domains: ["*.wywy.com", "*.wywyuserservice.com"] }, { name: "CDK Dealer Management", company: "CDK Global", homepage: "https://www.cdkglobal.com/us", category: "hosting", domains: ["*.assets-cdk.com"], examples: ["media-cf.assets-cdk.com"], totalExecutionTime: 1052, + totalOccurrences: 4 }, { name: "fam", company: "Fing Co Ltd.", homepage: "http://admin.fam-ad.com/report/", category: "ad", domains: ["*.fam-ad.com"], examples: ["img.fam-ad.com"], totalExecutionTime: 1816, totalOccurrences: 10 }, { name: "zypmedia", category: "ad", domains: ["*.extend.tv"] }, { name: "codigo", homepage: "https://www.codigo.se", category: "analytics", domains: ["*.codigo.se"], examples: ["analytics.codigo.se"], totalExecutionTime: 469, totalOccurrences: 10 }, { name: "Playground", homepage: "https://playground.xyz", category: "ad", domains: ["*.playground.xyz"], examples: ["ads.playground.xyz"], totalExecutionTime: 2767, totalOccurrences: 26 }, { name: "RAM", homepage: "https://www2.rampanel.com/", category: "analytics", domains: ["*.rampanel.com"], examples: ["inviso.rampanel.com"], totalExecutionTime: 15413, totalOccurrences: 1 }, { name: "Adition", homepage: "https://www.adition.com", category: "ad", domains: ["*.adition.com"], examples: ["dsp.adfarm1.adition.co\ +m"], totalExecutionTime: 74399, totalOccurrences: 491 }, { name: "Widespace", homepage: "https://www.widespace.com", category: "ad", domains: ["*.widespace.com"], examples: ["sync.widespace.com"] }, { name: "Colpirio", homepage: "https://www.widespace.com", category: "analytics", domains: ["*.colpirio.com"], examples: ["proxy-tracker.colpirio.com"] }, { name: "Brandmetrics", homepage: "https://www.brandmetrics.com", category: "analytics", domains: ["*.brandmetrics.com"], examples: ["collector.brandmetrics.com", "cdn.brandmetrics.com"], totalExecutionTime: 3689914, totalOccurrences: 30850 }, { name: "EasyAd", homepage: "https://web.easy-ads.com/", category: "ad", domains: ["*.easy-ads.com"], examples: ["ads.easy-ads.com"] }, { name: "Glimr", homepage: "https://glimr.io/", category: "analytics", domains: ["*.glimr.io"], examples: ["pixel.glimr.io"] }, { name: "Webtreck", homepage: "https://www.webtrekk.com/en/home/", category: "analytics", domains: ["*.wcfbc.net"], examples: ["fbc.wcfbc.\ +net"] }, { name: "DigiTrust", homepage: "http://www.digitru.st/", category: "analytics", domains: ["*.digitru.st"], examples: ["cdn.digitru.st"] }, { name: "Kantar Sifo", homepage: "https://www.kantarsifo.se", category: "analytics", domains: ["*.research-int.se"], examples: ["trafficgateway.research-int.se"], totalExecutionTime: 375, totalOccurrences: 1 }, { name: "Concert", homepage: "https://concert.io/", category: "ad", domains: ["*.concert.io"], examples: ["cdn.concert.io"], totalExecutionTime: 317481, totalOccurrences: 336 }, { name: "Emerse", homepage: "https://www.emerse.com/", category: "ad", domains: ["*.emerse.com"], examples: ["tracking.emerse.com"], totalExecutionTime: 2872, totalOccurrences: 13 }, { name: "Iterate", homepage: "https://iteratehq.com/", category: "analytics", domains: ["*.iteratehq.com"], totalExecutionTime: 8751, totalOccurrences: 72 }, { name: "Cookiebot", homepage: "https://www.cookiebot.com/", category: "utility", domains: ["*.cookiebot.com"], examples: [ + "consent.cookiebot.com"], totalExecutionTime: 64865019, totalOccurrences: 187732 }, { name: "Netlify", homepage: "https://www.netlify.com/", category: "utility", domains: ["*.netlify.com", "*.netlifyusercontent.com"], examples: ["cloud.netlifyusercontent.com"], totalExecutionTime: 299527, totalOccurrences: 1323 }, { name: "Scroll", homepage: "https://scroll.com/", category: "utility", domains: ["*.scroll.com"], examples: ["static.scroll.com", "connect.scroll.com"] }, { name: "Consumable", homepage: "https://consumable.com/", category: "ad", domains: ["*.serverbid.com"], totalExecutionTime: 15203, totalOccurrences: 266 }, { name: "DMD Marketing", homepage: "https://www.dmdconnects.com/", category: "ad", domains: ["*.medtargetsystem.com"], totalExecutionTime: 257224, totalOccurrences: 846 }, { name: "Catchpoint", homepage: "https://www.catchpoint.com/", category: "analytics", domains: ["*.3gl.net", "*.3genlabs.net"], totalExecutionTime: 14822, totalOccurrences: 160 }, { name: "Termin\ +us", homepage: "https://terminus.com/", category: "ad", domains: ["*.terminus.services"], totalExecutionTime: 28077, totalOccurrences: 207 }, { name: "Acceptable Ads", homepage: "https://acceptableads.com/", category: "ad", domains: ["*.aaxads.com", "*.aaxdetect.com"], totalExecutionTime: 2200, totalOccurrences: 34 }, { name: "ClearBrain", homepage: "https://www.clearbrain.com/", category: "analytics", domains: ["*.clearbrain.com"], examples: ["api.clearbrain.com"] }, { name: "Optanon", homepage: "https://www.cookielaw.org/", category: "consent-provider", domains: ["*.onetrust.com", "*.cookielaw.org"], examples: ["cdn.cookielaw.org", "geolocation.onetrust.com"], totalExecutionTime: 55293468, totalOccurrences: 113700 }, { name: "TrustArc", homepage: "https://www.trustarc.com/", category: "utility", domains: ["*.trustarc.com"], examples: ["choices.trustarc.com", "consent.trustarc.com"], totalExecutionTime: 2429376, totalOccurrences: 5941 }, { name: "iSpot.tv", homepage: "https://www.ispo\ +t.tv/", category: "ad", domains: ["*.ispot.tv"], examples: ["pt.ispot.tv"], totalExecutionTime: 2947, totalOccurrences: 10 }, { name: "RevJet", homepage: "https://www.revjet.com/", category: "ad", domains: ["*.revjet.com"], examples: ["pix.revjet.com", "ads.revjet.com"], totalExecutionTime: 54608, totalOccurrences: 36 }, { name: "atlasRTX", homepage: "https://www.atlasrtx.com/", category: "customer-success", domains: ["*.atlasrtx.com"], examples: ["app.atlasrtx.com", "cdn.atlasrtx.com", "dev.atlasrtx.com"], totalExecutionTime: 52386, totalOccurrences: 46 }, { name: "ContactAtOnce", homepage: "https://www.contactatonce.com/", category: "customer-success", domains: ["*.contactatonce.com"], examples: ["tag.contactatonce.com", "agentpresence.contactatonce.com"] }, { name: "Algolia", homepage: "https://www.algolia.com/", category: "utility", domains: ["*.algolianet.com", "*.algolia.net", "*.algolia.io"], totalExecutionTime: 5603, totalOccurrences: 20 }, { name: "EMX Digital", homepage: "htt\ +ps://emxdigital.com", category: "ad", domains: ["*.emxdgt.com"], totalExecutionTime: 9160, totalOccurrences: 166 }, { name: "Moxie", homepage: "https://www.gomoxie.com/", category: "utility", domains: ["*.gomoxie.solutions"], totalExecutionTime: 24183, totalOccurrences: 28 }, { name: "Scripps Network Digital", homepage: "https://www.scrippsnetworksdigital.com/", category: "ad", domains: ["*.snidigital.com"] }, { name: "TurnTo", homepage: "https://www.turntonetworks.com/", category: "utility", domains: ["*.turnto.com"], totalExecutionTime: 4666, totalOccurrences: 32 }, { name: "Quantum Metric", homepage: "https://www.quantummetric.com/", category: "analytics", domains: ["*.quantummetric.com"], totalExecutionTime: 1699724, totalOccurrences: 1140 }, { name: "Carbon Ads", homepage: "https://www.carbonads.net/", category: "ad", domains: ["*.carbonads.net", "*.carbonads.com"], totalExecutionTime: 12059, totalOccurrences: 224 }, { name: "Ably", homepage: "https://www.ably.io/", category: "uti\ +lity", domains: ["*.ably.io"], totalExecutionTime: 17031, totalOccurrences: 125 }, { name: "Sectigo", homepage: "https://sectigo.com/", category: "utility", domains: ["*.sectigo.com"], totalExecutionTime: 4576, totalOccurrences: 3 }, { name: "Specless", homepage: "https://gospecless.com/", category: "ad", domains: ["*.specless.tech"] }, { name: "Loggly", homepage: "https://www.loggly.com/", category: "analytics", domains: ["*.loggly.com", "d9jmv9u00p0mv.cloudfront.net"], examples: ["logs-01.loggly.com"], totalExecutionTime: 943, totalOccurrences: 5 }, { name: "Intent Media", homepage: "https://intent.com/", category: "ad", domains: ["*.intentmedia.net"] }, { name: "Supership", homepage: "https://supership.jp/", category: "ad", domains: ["*.socdm.com"], totalExecutionTime: 10809246, totalOccurrences: 17934 }, { name: "F@N Communications", homepage: "https://www.fancs.com/", category: "ad", domains: ["*.ladsp.com"], examples: ["px.ladsp.com"], totalExecutionTime: 258835, totalOccurrences: 1768 }, + { name: "Vidyard", homepage: "https://www.vidyard.com/", category: "utility", domains: ["*.vidyard.com"], totalExecutionTime: 1165600, totalOccurrences: 1097 }, { name: "RapidSSL", homepage: "https://www.rapidssl.com/", category: "utility", domains: ["*.rapidssl.com"], totalExecutionTime: 845, totalOccurrences: 2 }, { name: "Coherent Path", homepage: "https://coherentpath.com/", category: "utility", domains: ["*.coherentpath.com"] }, { name: "Attentive", homepage: "https://attentivemobile.com/", category: "ad", domains: ["*.attn.tv", "*.attentivemobile.com"], totalExecutionTime: 5554871, totalOccurrences: 9099 }, { name: "emetriq", homepage: "https://www.emetriq.com/", category: "ad", domains: ["*.emetriq.de", "*.xplosion.de"], totalExecutionTime: 1917, totalOccurrences: 24 }, { name: "Bonzai", homepage: "https://www.bonzai.co/", category: "ad", domains: ["*.bonzai.co"] }, { name: "Freshchat", homepage: "https://www.freshworks.com/live-chat-software/", category: "customer-success", + domains: ["*.freshchat.com", "*.freshworksapi.com"], products: [{ name: "Freshdesk Messaging", urlPatterns: ["wchat.freshchat.com"], facades: [{ name: "Freshdesk Messaging (formerly Freshchat) Facade", repo: "https://github.com/coliff/freshdesk-messaging-facade/" }] }], totalExecutionTime: 23350324, totalOccurrences: 7081 }, { name: "Contentful", homepage: "https://www.contentful.com/", category: "utility", domains: ["*.contentful.com"], examples: ["cdn.contentful.com"], totalExecutionTime: 4826, totalOccurrences: 2 }, { name: "PureCars", homepage: "https://www.purecars.com/", category: "marketing", domains: ["*.purecars.com"], examples: ["cdn.purecars.com"], totalExecutionTime: 969442, totalOccurrences: 1292 }, { name: "Tray Commerce", homepage: "https://www.tray.com.br/", category: "marketing", domains: ["*.tcdn.com.br"], examples: ["images.tcdn.com.br"], totalExecutionTime: 68362173, totalOccurrences: 14071 }, { name: "AdScore", homepage: "https://www.adscore.com/", category: "a\ +d", domains: ["*.adsco.re"], examples: ["c.adsco.re"], totalExecutionTime: 2812771, totalOccurrences: 4394 }, { name: "WebsiteBuilder.com", homepage: "https://www.websitebuilder.com", category: "hosting", domains: ["*.mywebsitebuilder.com"], totalExecutionTime: 19568135, totalOccurrences: 4688 }, { name: "mParticle", homepage: "https://www.mparticle.com/", category: "utility", domains: ["*.mparticle.com"], examples: ["jssdks.mparticle.com", "identity.mparticle.com"], totalExecutionTime: 403503, totalOccurrences: 1029 }, { name: "Ada", homepage: "https://www.ada.support/", category: "customer-success", domains: ["*.ada.support"], examples: ["static.ada.support"], totalExecutionTime: 695777, totalOccurrences: 985 }, { name: "Quora Ads", homepage: "https://www.quora.com/business/", category: "ad", domains: ["*.quora.com"], examples: ["q.quora.com"], totalExecutionTime: 1338719, totalOccurrences: 10614 }, { name: "Auth0", homepage: "https://auth0.com/", category: "utility", domains: ["*.au\ +th0.com"], examples: ["cdn.auth0.com"], totalExecutionTime: 245638, totalOccurrences: 816 }, { name: "Bridgewell DSP", homepage: "https://www.bridgewell.com/", category: "ad", domains: ["*.scupio.com"], examples: ["img.scupio.com"], totalExecutionTime: 63728, totalOccurrences: 354 }, { name: "Wicked Reports", homepage: "https://www.wickedreports.com/", category: "marketing", domains: ["*.wickedreports.com"], examples: ["widget.wickedreports.com"], totalExecutionTime: 148754, totalOccurrences: 483 }, { name: "Jaywing", homepage: "https://jaywing.com/", category: "marketing", domains: ["*.jaywing.com"], examples: ["amazon.almanac.jaywing.com"] }, { name: "Holimetrix", homepage: "https://u360.d-bi.fr/", category: "marketing", domains: ["*.d-bi.fr"], examples: ["u360.d-bi.fr"] }, { name: "iZooto", homepage: "https://www.izooto.com", category: "marketing", domains: ["*.izooto.com"], examples: ["cdn.izooto.com"], totalExecutionTime: 1111125, totalOccurrences: 2022 }, { name: "Ordergroove", homepage: "\ +https://www.ordergroove.com/", category: "marketing", domains: ["*.ordergroove.com"], examples: ["static.ordergroove.com"], totalExecutionTime: 99990, totalOccurrences: 274 }, { name: "PageSense", homepage: "https://www.zoho.com/pagesense/", category: "analytics", domains: ["*.pagesense.io"], examples: ["cdn.pagesense.io"], totalExecutionTime: 1996537, totalOccurrences: 6219 }, { name: "Vizzit", homepage: "https://www.vizzit.se", category: "analytics", domains: ["*.vizzit.se"], examples: ["www.vizzit.se", "tag.vizzit.se"], totalExecutionTime: 739, totalOccurrences: 7 }, { name: "Click Guardian", homepage: "https://www.clickguardian.co.uk/", category: "ad", domains: ["*.clickguardian.app", "*.clickguardian.co.uk"], examples: ["v2.clickguardian.app", "protection.clickguardian.co.uk"], totalExecutionTime: 202620, totalOccurrences: 1101 }, { name: "Smartsupp", company: "Smartsupp.com", homepage: "https://www.smartsupp.com", category: "customer-success", domains: ["*.smartsuppchat.com", "*.\ +smartsupp.com", "smartsupp-widget-161959.c.cdn77.org", "*.smartsuppcdn.com"], examples: ["widget-v1.smartsuppcdn.com"], totalExecutionTime: 9998165, totalOccurrences: 21505 }, { name: "Smartlook", company: "Smartsupp.com", homepage: "https://www.smartlook.com/", category: "analytics", domains: ["*.smartlook.com"], totalExecutionTime: 1386251, totalOccurrences: 16221 }, { name: "Luigis Box", company: "Luigis Box", homepage: "https://www.luigisbox.com/", category: "utility", domains: ["*.luigisbox.com"], totalExecutionTime: 2975273, totalOccurrences: 2356 }, { name: "Targito", company: "VIVmail.cz", homepage: "https://www.targito.com", category: "marketing", domains: ["*.targito.com"], totalExecutionTime: 3145, totalOccurrences: 29 }, { name: "Foxentry", company: "AVANTRO", homepage: "https://foxentry.cz/", category: "utility", domains: ["*.foxentry.cz"], totalExecutionTime: 758854, totalOccurrences: 2313 }, { name: "Pendo", homepage: "https://www.pendo.io", category: "analytics", domains: [ + "*.pendo.io"], examples: ["app.pendo.io"], totalExecutionTime: 4935190, totalOccurrences: 12203 }, { name: "Braze", homepage: "https://www.braze.com", category: "analytics", domains: ["*.appboycdn.com"], examples: ["js.appboycdn.com"], totalExecutionTime: 399216, totalOccurrences: 2014 }, { name: "Usersnap", homepage: "https://usersnap.com", category: "customer-success", domains: ["*.usersnap.com"], examples: ["api.usersnap.com", "cdn.usersnap.com"], totalExecutionTime: 334324, totalOccurrences: 437 }, { name: "Rewardful", homepage: "https://www.getrewardful.com", category: "analytics", domains: ["*.wdfl.co"], examples: ["r.wdfl.co"], totalExecutionTime: 9094, totalOccurrences: 161 }, { name: "Launch Darkly", homepage: "https://launchdarkly.com", category: "utility", domains: ["*.launchdarkly.com"], examples: ["app.launchdarkly.com", "events.launchdarkly.com"], totalExecutionTime: 10547, totalOccurrences: 6 }, { name: "Statuspage", company: "Atlassian", homepage: "https://www.statu\ +spage.io", category: "utility", domains: ["*.statuspage.io"], examples: ["1k6wzpspjf99.statuspage.io"], totalExecutionTime: 43124, totalOccurrences: 1212 }, { name: "HyperInzerce", homepage: "https://hyperinzerce.cz", category: "ad", domains: ["*.hyperinzerce.cz"], examples: ["motorky.hyperinzerce.cz"], totalExecutionTime: 1035, totalOccurrences: 39 }, { name: "POWr", homepage: "https://www.powr.io", category: "utility", domains: ["*.powr.io"], examples: ["www.powr.io"], totalExecutionTime: 191534674, totalOccurrences: 39716 }, { name: "Coral", company: "Coral", homepage: "https://coralproject.net", category: "content", domains: ["*.coral.coralproject.net"], examples: ["company.coral.coralproject.net"], totalExecutionTime: 61135, totalOccurrences: 250 }, { name: "Bolt", homepage: "https://www.bolt.com/", category: "utility", domains: ["*.bolt.com"], examples: ["connect.bolt.com"], totalExecutionTime: 513689, totalOccurrences: 217 }, { name: "Judge.me", homepage: "https://judge.me/", category: "\ +marketing", domains: ["*.judge.me"], examples: ["cdn.judge.me"], totalExecutionTime: 31886982, totalOccurrences: 27483 }, { name: "Tilda", homepage: "https://tilda.cc/", category: "hosting", domains: ["*.tildacdn.com"], examples: ["stat.tildacdn.com", "static.tildacdn.com", "upwidget.tildacdn.com"], totalExecutionTime: 94734169, totalOccurrences: 70321 }, { name: "SalesLoft", homepage: "https://salesloft.com/", category: "marketing", domains: ["*.salesloft.com"], examples: ["scout-cdn.salesloft.com"], totalExecutionTime: 42987, totalOccurrences: 705 }, { name: "Accessibe Accessibility Overlay", company: "Accessibe", homepage: "https://accessibe.com/", category: "utility", domains: ["*.accessibe.com", "*.acsbapp.com", "*.acsbap.com"], examples: ["accessibe.com", "acsbapp.com"], totalExecutionTime: 285765, totalOccurrences: 808 }, { name: "Builder", homepage: "https://www.builder.io/", category: "hosting", domains: ["*.builder.io"], examples: ["cdn.builder.io"], totalExecutionTime: 412358, + totalOccurrences: 261 }, { name: "Pepperjam", homepage: "https://www.pepperjam.com/", category: "marketing", domains: ["*.pepperjam.com", "*.affiliatetechnology.com"], examples: ["container.pepperjam.com"], totalExecutionTime: 2308, totalOccurrences: 35 }, { name: "Reach", homepage: "https://withreach.com/", category: "utility", domains: ["*.gointerpay.net"], examples: ["checkout.gointerpay.net"] }, { name: "Chameleon", homepage: "https://www.trychameleon.com/", category: "marketing", domains: ["*.trychameleon.com"], examples: ["fast.trychameleon.com"], totalExecutionTime: 24218, totalOccurrences: 8 }, { name: "Matomo", company: "InnoCraft", homepage: "https://matomo.org/", category: "analytics", domains: ["*.matomo.cloud"], totalExecutionTime: 3115176, totalOccurrences: 14345 }, { name: "Segmanta", homepage: "https://segmanta.com/", category: "marketing", domains: ["*.segmanta.com"], examples: ["clientName.segmanta.com"] }, { name: "Podsights", homepage: "https://podsights.com/", category: "\ +marketing", domains: ["*.pdst.fm", "us-central1-adaptive-growth.cloudfunctions.net"], examples: ["cdn.pdst.fm", "sink.pdst.fm"], totalExecutionTime: 71990, totalOccurrences: 1140 }, { name: "Chatwoot", homepage: "https://www.chatwoot.com/", category: "customer-success", domains: ["*.chatwoot.com"], examples: ["cdn.chatwoot.com", "app.chatwoot.com"], totalExecutionTime: 31973, totalOccurrences: 444 }, { name: "Crisp", homepage: "https://crisp.chat/", category: "customer-success", domains: ["*.crisp.chat"], examples: ["client.crisp.chat", "client.relay.crisp.chat"], totalExecutionTime: 33757, totalOccurrences: 1052 }, { name: "Admiral CMP", homepage: "https://www.getadmiral.com", category: "consent-provider", domains: ["admiral.mgr.consensu.org", "*.admiral.mgr.consensu.org"] }, { name: "Adnuntius CMP", homepage: "https://adnuntius.com", category: "consent-provider", domains: ["adnuntiusconsent.mgr.consensu.org", "*.adnuntiusconsent.mgr.consensu.org"] }, { name: "Clickio CMP", homepage: "\ +https://clickio.com", category: "consent-provider", domains: ["clickio.mgr.consensu.org", "*.clickio.mgr.consensu.org"] }, { name: "AppConsent CMP", homepage: "https://appconsent.io/en", category: "consent-provider", domains: ["appconsent.mgr.consensu.org", "*.appconsent.mgr.consensu.org"] }, { name: "DMG Media CMP", homepage: "https://www.dmgmedia.co.uk", category: "consent-provider", domains: ["dmgmedia.mgr.consensu.org", "*.dmgmedia.mgr.consensu.org"] }, { name: "Axel Springer CMP", homepage: "https://www.axelspringer.com", category: "consent-provider", domains: ["axelspringer.mgr.consensu.org", "*.axelspringer.mgr.consensu.org"] }, { name: "Bedrock CMP", homepage: "https://www.bedrockstreaming.com", category: "consent-provider", domains: ["bedrock.mgr.consensu.org", "*.bedrock.mgr.consensu.org"] }, { name: "BMIND CMP", homepage: "https://www.bmind.es", category: "consent-provider", domains: ["bmind.mgr.consensu.org", "*.bmind.mgr.consensu.org"] }, { name: "Borlabs CMP", homepage: "\ +https://borlabs.io", category: "consent-provider", domains: ["borlabs.mgr.consensu.org", "*.borlabs.mgr.consensu.org"] }, { name: "Civic CMP", homepage: "https://www.civicuk.com", category: "consent-provider", domains: ["cookiecontrol.mgr.consensu.org", "*.cookiecontrol.mgr.consensu.org"] }, { name: "Commanders Act CMP", homepage: "https://www.commandersact.com", category: "consent-provider", domains: ["commandersact.mgr.consensu.org", "*.commandersact.mgr.consensu.org"] }, { name: "Complianz CMP", homepage: "https://complianz.io/", category: "consent-provider", domains: ["complianz.mgr.consensu.org", "*.complianz.mgr.consensu.org"] }, { name: "Consent Desk CMP", homepage: "https://www.consentdesk.com/", category: "consent-provider", domains: ["consentdesk.mgr.consensu.org", "*.consentdesk.mgr.consensu.org"] }, { name: "Consent Manager CMP", homepage: "https://consentmanager.net", category: "consent-provider", domains: ["consentmanager.mgr.consensu.org", "*.consentmanager.mgr.consensu.\ +org"] }, { name: "Conversant CMP", homepage: "https://www.conversantmedia.eu/", category: "consent-provider", domains: ["conversant.mgr.consensu.org", "*.conversant.mgr.consensu.org"] }, { name: "Cookie Information CMP", homepage: "https://www.cookieinformation.com/", category: "consent-provider", domains: ["cookieinformation.mgr.consensu.org", "*.cookieinformation.mgr.consensu.org"] }, { name: "Cookiebot CMP", homepage: "https://www.cookiebot.com", category: "consent-provider", domains: ["cookiebot.mgr.consensu.org", "*.cookiebot.mgr.consensu.org"] }, { name: "Truendo CMP", homepage: "https://truendo.com/", category: "consent-provider", domains: ["truendo.mgr.consensu.org", "*.truendo.mgr.consensu.org"] }, { name: "Dentsu CMP", homepage: "https://www.dentsuaegisnetwork.de/", category: "consent-provider", domains: ["dan.mgr.consensu.org", "*.dan.mgr.consensu.org"] }, { name: "Didomi CMP", homepage: "https://www.didomi.io/en/", category: "consent-provider", domains: ["didomi.mgr.consens\ +u.org", "*.didomi.mgr.consensu.org"] }, { name: "Ensighten CMP", homepage: "https://www.ensighten.com/", category: "consent-provider", domains: ["ensighten.mgr.consensu.org", "*.ensighten.mgr.consensu.org"] }, { name: "Evidon CMP", homepage: "https://evidon.com", category: "consent-provider", domains: ["evidon.mgr.consensu.org", "*.evidon.mgr.consensu.org"] }, { name: "Ezoic CMP", homepage: "https://www.ezoic.com/", category: "consent-provider", domains: ["ezoic.mgr.consensu.org", "*.ezoic.mgr.consensu.org"] }, { name: "Gemius CMP", homepage: "https://www.gemius.com", category: "consent-provider", domains: ["gemius.mgr.consensu.org", "*.gemius.mgr.consensu.org"] }, { name: "NitroPay CMP", homepage: "https://nitropay.com/", category: "consent-provider", domains: ["nitropay.mgr.consensu.org", "*.nitropay.mgr.consensu.org"] }, { name: "Google FundingChoices", homepage: "https://fundingchoices.google.com/start/", category: "consent-provider", domains: ["fundingchoices.mgr.consensu.org", "*\ +.fundingchoices.mgr.consensu.org", "fundingchoicesmessages.google.com", "*.fundingchoicesmessages.google.com"], totalExecutionTime: 257806056, totalOccurrences: 400016 }, { name: "Gravito CMP", homepage: "https://www.gravito.net/", category: "consent-provider", domains: ["gravito.mgr.consensu.org", "*.gravito.mgr.consensu.org"] }, { name: "ID Ward CMP", homepage: "https://id-ward.com/enterprise", category: "consent-provider", domains: ["idward.mgr.consensu.org", "*.idward.mgr.consensu.org"] }, { name: "iubenda CMP", homepage: "https://www.iubenda.com", category: "consent-provider", domains: ["iubenda.mgr.consensu.org", "*.iubenda.mgr.consensu.org"] }, { name: "Jump CMP", homepage: "https://jumpgroup.it/", category: "consent-provider", domains: ["avacy.mgr.consensu.org", "*.avacy.mgr.consensu.org"] }, { name: "LiveRamp CMP", homepage: "https://liveramp.com/", category: "consent-provider", domains: ["faktor.mgr.consensu.org", "*.faktor.mgr.consensu.org"] }, { name: "Madvertise CMP", homepage: "\ +https://madvertise.com/en/", category: "consent-provider", domains: ["madvertise.mgr.consensu.org", "*.madvertise.mgr.consensu.org"] }, { name: "Mairdumont Netletic CMP", homepage: "https://www.mairdumont-netletix.com/", category: "consent-provider", domains: ["mdnxmp.mgr.consensu.org", "*.mdnxmp.mgr.consensu.org"] }, { name: "Marfeel CMP", homepage: "https://www.marfeel.com/", category: "consent-provider", domains: ["marfeel.mgr.consensu.org", "*.marfeel.mgr.consensu.org"] }, { name: "Mediavine CMP", homepage: "https://www.mediavine.com/", category: "consent-provider", domains: ["mediavine.mgr.consensu.org", "*.mediavine.mgr.consensu.org"] }, { name: "ConsentServe CMP", homepage: "https://www.consentserve.com/", category: "consent-provider", domains: ["consentserve.mgr.consensu.org", "*.consentserve.mgr.consensu.org"] }, { name: "Next14 CMP", homepage: "https://www.next14.com/", category: "consent-provider", domains: ["next14.mgr.consensu.org", "*.next14.mgr.consensu.org"] }, { name: "\ +AdRoll CMP", homepage: "https://www.adroll.com/", category: "consent-provider", domains: ["adroll.mgr.consensu.org", "*.adroll.mgr.consensu.org"] }, { name: "Ogury CMP", homepage: "https://www.ogury.com/", category: "consent-provider", domains: ["ogury.mgr.consensu.org", "*.ogury.mgr.consensu.org"] }, { name: "OneTag CMP", homepage: "https://onetag.net", category: "consent-provider", domains: ["onetag.mgr.consensu.org", "*.onetag.mgr.consensu.org"] }, { name: "OneTrust CMP", homepage: "https://onetrust.com", category: "consent-provider", domains: ["onetrust.mgr.consensu.org", "*.onetrust.mgr.consensu.org"] }, { name: "optAd360 CMP", homepage: "https://www.optad360.com/", category: "consent-provider", domains: ["optad360.mgr.consensu.org", "*.optad360.mgr.consensu.org"] }, { name: "Osano CMP", homepage: "https://www.osano.com", category: "consent-provider", domains: ["osano.mgr.consensu.org", "*.osano.mgr.consensu.org"] }, { name: "Playwire CMP", homepage: "https://www.playwire.com", category: "\ +consent-provider", domains: ["playwire.mgr.consensu.org", "*.playwire.mgr.consensu.org"] }, { name: "Pulselive CMP", homepage: "https://www.pulselive.com", category: "consent-provider", domains: ["pulselive.mgr.consensu.org", "*.pulselive.mgr.consensu.org"] }, { name: "Quantcast Choice", homepage: "https://quantcast.com", category: "consent-provider", domains: ["quantcast.mgr.consensu.org", "*.quantcast.mgr.consensu.org"] }, { name: "RCS Pubblicita CMP", homepage: "http://www.rcspubblicita.it/site/home.html", category: "consent-provider", domains: ["rcsmediagroup.mgr.consensu.org", "*.rcsmediagroup.mgr.consensu.org"] }, { name: "Rich Audience CMP", homepage: "https://richaudience.com", category: "consent-provider", domains: ["richaudience.mgr.consensu.org", "*.richaudience.mgr.consensu.org"] }, { name: "Ringier Axel Springer CMP", homepage: "https://www.ringieraxelspringer.pl/en/home/", category: "consent-provider", domains: ["rasp.mgr.consensu.org", "*.rasp.mgr.consensu.org"] }, { name: "\ +Secure Privacy CMP", homepage: "https://secureprivacy.ai/", category: "consent-provider", domains: ["secureprivacy.mgr.consensu.org", "*.secureprivacy.mgr.consensu.org"] }, { name: "Securiti CMP", homepage: "https://securiti.ai/", category: "consent-provider", domains: ["securiti.mgr.consensu.org", "*.securiti.mgr.consensu.org"] }, { name: "Seznam.cz CMP", homepage: "https://www.seznam.cz/", category: "consent-provider", domains: ["seznam.mgr.consensu.org", "*.seznam.mgr.consensu.org"] }, { name: "ShareThis CMP", homepage: "https://sharethis.com", category: "consent-provider", domains: ["sharethis.mgr.consensu.org", "*.sharethis.mgr.consensu.org"] }, { name: "ShinyStat CMP", homepage: "https://www.shinystat.com", category: "consent-provider", domains: ["shinystat.mgr.consensu.org", "*.shinystat.mgr.consensu.org"] }, { name: "Sibbo CMP", homepage: "https://sibboventures.com/en/", category: "consent-provider", domains: ["sibboventures.mgr.consensu.org", "*.sibboventures.mgr.consensu.org"] }, + { name: "Singlespot CMP", homepage: "https://www.singlespot.com/en", category: "consent-provider", domains: ["singlespot.mgr.consensu.org", "*.singlespot.mgr.consensu.org"] }, { name: "Sirdata CMP", homepage: "https://www.sirdata.com", category: "consent-provider", domains: ["sddan.mgr.consensu.org", "*.sddan.mgr.consensu.org"] }, { name: "Snigel CMP", homepage: "https://snigel.com", category: "consent-provider", domains: ["snigelweb.mgr.consensu.org", "*.snigelweb.mgr.consensu.org"] }, { name: "Sourcepoint CMP", homepage: "https://sourcepoint.com", category: "consent-provider", domains: ["sourcepoint.mgr.consensu.org", "*.sourcepoint.mgr.consensu.org"] }, { name: "Pubtech CMP", homepage: "https://www.pubtech.ai/", category: "consent-provider", domains: ["pubtech.mgr.consensu.org", "*.pubtech.mgr.consensu.org"] }, { name: "AdMetrics Pro CMP", homepage: "https://admetricspro.com", category: "consent-provider", domains: ["cmp.mgr.consensu.org", "*.cmp.mgr.consensu.org"] }, { name: "T\ +raffective CMP", homepage: "https://traffective.com", category: "consent-provider", domains: ["traffective.mgr.consensu.org", "*.traffective.mgr.consensu.org"] }, { name: "UniConsent CMP", homepage: "https://www.uniconsent.com", category: "consent-provider", domains: ["uniconsent.mgr.consensu.org", "*.uniconsent.mgr.consensu.org", "cmp.uniconsent.com", "*.uniconsent.com"], totalExecutionTime: 829870, totalOccurrences: 1336 }, { name: "TrustArc CMP", homepage: "https://trustarc.com/", category: "consent-provider", domains: ["trustarc.mgr.consensu.org", "*.trustarc.mgr.consensu.org"] }, { name: "Usercentrics CMP", homepage: "https://usercentrics.com", category: "consent-provider", domains: ["usercentrics.mgr.consensu.org", "*.usercentrics.mgr.consensu.org", "*.usercentrics.eu", "*.services.usercentrics.eu"], totalExecutionTime: 53008518, totalOccurrences: 49602 }, { name: "WebAds CMP", homepage: "https://www.webads.nl/", category: "consent-provider", domains: ["webads.mgr.consensu.org", "\ +*.webads.mgr.consensu.org"] }, { name: "Trustcommander", company: "Commandersact", homepage: "https://www.commandersact.com", category: "consent-provider", domains: ["*.trustcommander.net"], examples: ["cdn.trustcommander.net", "privacy.trustcommander.net"], totalExecutionTime: 324770, totalOccurrences: 1713 }, { name: "Hubvisor", homepage: "https://www.hubvisor.io", category: "ad", domains: ["*.hubvisor.io"], examples: ["cdn.hubvisor.io", "stream.hubvisor.io"], totalExecutionTime: 404737, totalOccurrences: 492 }, { name: "Castle", homepage: "https://castle.io", category: "utility", domains: ["*.castle.io", "d2t77mnxyo7adj.cloudfront.net"], examples: ["t.castle.io"] }, { name: "Wigzo", homepage: "https://www.wigzo.com/", category: "marketing", domains: ["*.wigzo.com", "*.wigzopush.com"], examples: ["app.wigzo.com", "tracker.wigzopush.com"], totalExecutionTime: 215280, totalOccurrences: 762 }, { name: "Convertful", homepage: "https://convertful.com/", category: "marketing", domains: ["*\ +.convertful.com"], examples: ["app.convertful.com"], totalExecutionTime: 215317, totalOccurrences: 1534 }, { name: "OpenLink", company: "MediaWallah", homepage: "https://www.mediawallah.com/", category: "ad", domains: ["*.mediawallahscript.com"], examples: ["partner.mediawallahscript.com"] }, { name: "TPMN", company: "TPMN", homepage: "http://tpmn.io/", category: "ad", domains: ["*.tpmn.co.kr"], examples: ["ad.tpmn.co.kr"], totalExecutionTime: 354, totalOccurrences: 10 }, { name: "HERO", company: "Klarna", homepage: "https://www.usehero.com/", category: "customer-success", domains: ["*.usehero.com"], examples: ["api.usehero.com", "cdn.usehero.com"], totalExecutionTime: 32092, totalOccurrences: 42 }, { name: "Zync", company: "Zeta Global", homepage: "https://zetaglobal.com/", category: "marketing", domains: ["*.rezync.com"], examples: ["live.rezync.com"], totalExecutionTime: 25978, totalOccurrences: 246 }, { name: "AdFuel Video", company: "AdFuel", homepage: "https://goadfuel.com/", category: "\ +ad", domains: ["*.videoplayerhub.com"], examples: ["customer.videoplayerhub.com"], totalExecutionTime: 82951, totalOccurrences: 1407 }, { name: "Prefix Box AI Search", company: "Prefix Box", homepage: "https://www.prefixbox.com/", category: "utility", domains: ["*.prefixbox.com"], examples: ["cdn.prefixbox.com"], totalExecutionTime: 51608, totalOccurrences: 58 }, { name: "SpeedSize Service Worker", company: "SpeedSize", homepage: "https://speedsize.com/", category: "utility", domains: ["di6367dava8ow.cloudfront.net", "d2d22nphq0yz8t.cloudfront.net"], examples: ["di6367dava8ow.cloudfront.net"] }, { name: "Vonage Video API", company: "Vonage", homepage: "https://www.vonage.com/communications-apis/video/", category: "video", domains: ["*.opentok.com"], examples: ["static.opentok.com"], totalExecutionTime: 220760, totalOccurrences: 304 }, { name: "Checkout.com", company: "Checkout.com", homepage: "https://www.checkout.com", category: "utility", domains: ["*.checkout.com"], examples: ["cdn.\ +checkout.com"], totalExecutionTime: 184372, totalOccurrences: 1367 }, { name: "Noibu", company: "Noibu", homepage: "https://www.noibu.com", category: "utility", domains: ["*.noibu.com"], examples: ["input.noibu.com"], totalExecutionTime: 1453903, totalOccurrences: 613 }, { name: "Clarity", company: "Microsoft", homepage: "https://clarity.microsoft.com/", category: "utility", domains: ["*.clarity.ms"], examples: ["c.clarity.ms"], totalExecutionTime: 208824616, totalOccurrences: 456309 }, { name: "goinstore", company: "Emplifi", homepage: "https://goinstore.com/", category: "customer-success", domains: ["*.goinstore.com"], examples: ["gis.goinstore.com"] }, { name: "SegmentStream", company: "SegmentStream", homepage: "https://segmentstream.com/", category: "marketing", domains: ["*.segmentstream.com"], examples: ["track.segmentstream.com"], totalExecutionTime: 8628, totalOccurrences: 13 }, { name: "Amazon Associates", company: "Amazon", homepage: "https://affiliate-program.amazon.co.uk/", + category: "marketing", domains: ["*.associates-amazon.com"], examples: ["assoc-na.associates-amazon.com"], totalExecutionTime: 50, totalOccurrences: 1 }, { name: "DotMetrics", company: "Ipsos", homepage: "https://www.dotmetrics.net/", category: "analytics", domains: ["*.dotmetrics.net"], examples: ["uk-script.dotmetrics.net"], totalExecutionTime: 159255, totalOccurrences: 817 }, { name: "Truffle Bid", company: "Truffle", homepage: "https://truffle.bid/", category: "ad", domains: ["*.truffle.bid"], examples: ["matching.truffle.bid"], totalExecutionTime: 24026, totalOccurrences: 39 }, { name: "Hybrid", company: "Hybrid", homepage: "https://hybrid.ai/", category: "ad", domains: ["*.hybrid.ai"], examples: ["dm-eu.hybrid.ai"], totalExecutionTime: 219740, totalOccurrences: 2326 }, { name: "AdMan Media", company: "AdMan", homepage: "https://admanmedia.com/", category: "video", domains: ["*.admanmedia.com"], examples: ["cs.admanmedia.com"], totalExecutionTime: 1924, totalOccurrences: 202 }, + { name: "ID5 Identity Cloud", company: "ID5", homepage: "https://id5.io/", category: "ad", domains: ["id5-sync.com", "*.id5-sync.com"], examples: ["id5-sync.com"], totalExecutionTime: 26134069, totalOccurrences: 119336 }, { name: "Audience Rate", company: "Audience Rate Limited", homepage: "https://www.audiencerate.com/", category: "ad", domains: ["*.audrte.com"], examples: ["a.audrte.com"] }, { name: "Seedtag", company: "Seedtag Advertising", homepage: "https://www.seedtag.com/", category: "ad", domains: ["*.seedtag.com"], examples: ["s.seedtag.com"], totalExecutionTime: 3342567, totalOccurrences: 1503 }, { name: "IVI", company: "IVI Technologies", homepage: "http://ivitechnologies.com/", category: "ad", domains: ["*.ivitrack.com"], examples: ["matching.ivitrack.com"], totalExecutionTime: 3746, totalOccurrences: 34 }, { name: "Sportradar", company: "Sportradar", homepage: "https://www.sportradar.com/", category: "ad", domains: ["*.sportradarserving.com"], examples: ["a.sportradars\ +erving.com"], totalExecutionTime: 520, totalOccurrences: 11 }, { name: "ZEOTAP", company: "ZEOTAP", homepage: "https://zeotap.com/", category: "ad", domains: ["*.zeotap.com"], examples: ["spl.zeotap.com"], totalExecutionTime: 14368, totalOccurrences: 96 }, { name: "Web Content Assessor", company: "TMT Digital", homepage: "https://mediatrust.com/", category: "ad", domains: ["*.webcontentassessor.com"], examples: ["scripts.webcontentassessor.com"], totalExecutionTime: 314249, totalOccurrences: 633 }, { name: "Genie", company: "Media Force", homepage: "https://hellogenie.com/", category: "ad", domains: ["*.mfadsrvr.com"], examples: ["rtb.mfadsrvr.com"], totalExecutionTime: 37, totalOccurrences: 2 }, { name: "mediarithmics", company: "mediarithmics", homepage: "https://www.mediarithmics.com/", category: "ad", domains: ["*.mediarithmics.com"], examples: ["cookie-matching.mediarithmics.com"], totalExecutionTime: 25799, totalOccurrences: 144 }, { name: "Ozone Project", company: "The Ozone Pro\ +ject", homepage: "https://www.ozoneproject.com/", category: "ad", domains: ["*.the-ozone-project.com"], examples: ["elb.the-ozone-project.com"], totalExecutionTime: 152768, totalOccurrences: 910 }, { name: "FiftyAurora", company: "Fifty", homepage: "https://fifty.io/", category: "ad", domains: ["*.fiftyt.com"], examples: ["visitor.fiftyt.com"] }, { name: "smadex", company: "entravision", homepage: "https://smadex.com/", category: "ad", domains: ["*.smadex.com"], examples: ["cm.smadex.com"], totalExecutionTime: 5, totalOccurrences: 1 }, { name: "AWX", company: "Trinity Mirror", category: "ad", domains: ["*.tm-awx.com"], examples: ["felix.data.tm-awx.com"], totalExecutionTime: 68744, totalOccurrences: 54 }, { name: "XPO", company: "Knorex", category: "ad", homepage: "https://www.knorex.com/", domains: ["*.brand-display.com"], examples: ["dmp.brand-display.com"], totalExecutionTime: 388629, totalOccurrences: 477 }, { name: "Viafoura", company: "Viafoura", category: "ad", homepage: "https:\ +//viafoura.com/", domains: ["*.viafoura.co", "*.viafoura.net"], examples: ["api.viafoura.co", "cdn.viafoura.net"], totalExecutionTime: 307404, totalOccurrences: 446 }, { name: "Adnami", company: "Adnami", category: "ad", homepage: "https://www.adnami.io/", domains: ["*.adnami.io"], examples: ["macro.adnami.io"], totalExecutionTime: 272668, totalOccurrences: 1639 }, { name: "LiveRamp Privacy Manager", company: "LiveRamp", category: "ad", homepage: "https://liveramp.com/privacy-legal-compliance/", domains: ["*.privacymanager.io"], examples: ["geo.privacymanager.io"], totalExecutionTime: 6546055, totalOccurrences: 22295 }, { name: "Onfocus", company: "Onfocus SAS", category: "ad", domains: ["*.4dex.io"], examples: ["script.4dex.io"], totalExecutionTime: 4240761, totalOccurrences: 8836 }, { name: "viewTag", company: "Advanced Store", category: "ad", domains: ["*.ad4m.at"], examples: ["ad4m.at", "as.ad4m.at"], totalExecutionTime: 458, totalOccurrences: 21 }, { name: "MRP Prelytics", company: "\ +Market Resource Partners", category: "ad", homepage: "https://www.mrpfd.com/", domains: ["*.mrpdata.net"], examples: ["j.mrpdata.net"] }, { name: "iPROM", company: "iPROM", category: "ad", homepage: "https://iprom.eu/", domains: ["*.iprom.net"], examples: ["core.iprom.net"], totalExecutionTime: 114801, totalOccurrences: 72099 }, { name: "Plausible", company: "Plausible", homepage: "https://plausible.io/", category: "analytics", domains: ["*.plausible.io"] }, { name: "Micro Analytics", company: "Micro Analytics", homepage: "https://microanalytics.io/", category: "analytics", domains: ["padmin.microanalytics.io", "www.microanalytics.io", "dev.microanalytics.io", "status.microanalytics.io"] }, { name: "Scale8", company: "Scale8", homepage: "https://scale8.com/", category: "analytics", domains: ["www.scale8.com", "api-dev.scale8.com", "cdn.scale8.com", "ui.scale8.com"] }, { name: "Cabin", company: "Cabin", homepage: "https://withcabin.com/", category: "analytics", domains: ["*.withcabin.co\ +m"], totalExecutionTime: 3843, totalOccurrences: 100 }, { name: "Appcues", company: "Appcues", homepage: "https://www.appcues.com/", category: "analytics", domains: ["*.appcues.com"], totalExecutionTime: 2154145, totalOccurrences: 2831 }, { name: "Fathom Analytics", company: "Fathom", homepage: "https://usefathom.com/", category: "analytics", domains: ["*.usefathom.com"], totalExecutionTime: 145389, totalOccurrences: 1141 }, { name: "Clearbit", company: "Clearbit", homepage: "https://clearbit.com/", category: "analytics", domains: ["*.clearbitjs.com", "*.clearbitscripts.com", "*.clearbit.com"], totalExecutionTime: 967253, totalOccurrences: 4171 }, { name: "G2", company: "G2", homepage: "https://www.g2.com/", category: "utility", domains: ["*.g2.com", "*.g2crowd.com"], totalExecutionTime: 195752, totalOccurrences: 406 }, { name: "Navu", company: "Navu", homepage: "https://navu.co/", category: "ad", domains: ["*.navu.co"] }, { name: "InZynk", company: "InZynk", homepage: "https://inzynk.\ +com/", category: "ad", domains: ["*.inzynk.com", "*.inzynk.io"], totalExecutionTime: 541, totalOccurrences: 8 }, { name: "Integrate", company: "Integrate", homepage: "https://www.integrate.com/", category: "ad", domains: ["*.integrate.com", "*.listenloop.com"], totalExecutionTime: 14260, totalOccurrences: 39 }, { name: "Ad Lightning", company: "Boltive", homepage: "https://www.adlightning.com/", category: "ad", domains: ["*.adlightning.com"], totalExecutionTime: 6879067, totalOccurrences: 3795 }, { name: "GeoEdge", company: "GeoEdge", homepage: "https://www.geoedge.com/", category: "ad", domains: ["*.geoedge.com", "*.geoedge.be"], totalExecutionTime: 1039615, totalOccurrences: 1796 }, { name: "Doofinder", company: "Doofinder", homepage: "https://www.doofinder.com/", category: "utility", domains: ["cdn.doofinder.com"], totalExecutionTime: 1750777, totalOccurrences: 12550 }, { name: "Revlifter", company: "Revlifter", homepage: "https://www.revlifter.com/", category: "utility", domains: [ + "assets.revlifter.com"] }, { name: "Didomi", company: "Didomi", homepage: "https://www.didomi.io/", category: "consent-provider", domains: ["sdk.privacy-center.org", "api.privacy-center.org"], totalExecutionTime: 85132161, totalOccurrences: 84206 }, { name: "Pubperf Analytics", company: "Pubperf", homepage: "https://www.pubperf.com/", category: "analytics", domains: ["*.pubperf.com"], totalExecutionTime: 51392, totalOccurrences: 400 }]; + } +}); + +// node_modules/@paulirish/trace_engine/node_modules/third-party-web/lib/index.js +var require_lib = __commonJS({ + "node_modules/@paulirish/trace_engine/node_modules/third-party-web/lib/index.js"(exports2, module2) { + init_process_global(); + var { createAPIFromDataset } = require_create_entity_finder_api(); + var entities = require_entities(); + module2.exports = createAPIFromDataset(entities); + } +}); + +// node_modules/@paulirish/trace_engine/third_party/third-party-web/third-party-web.js +var import_third_party_web; +var init_third_party_web = __esm({ + "node_modules/@paulirish/trace_engine/third_party/third-party-web/third-party-web.js"() { + init_process_global(); + import_third_party_web = __toESM(require_lib(), 1); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/types/Configuration.js +var Configuration_exports = {}; +__export(Configuration_exports, { + configToCacheKey: () => configToCacheKey, + defaults: () => defaults +}); +function configToCacheKey(config3) { + return JSON.stringify(config3); +} +var defaults; +var init_Configuration = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/types/Configuration.js"() { + init_process_global(); + defaults = /* @__PURE__ */ __name(() => ({ + includeRuntimeCallStats: false, + showAllEvents: false, + debugMode: false, + maxInvalidationEventsPerEvent: 20, + enableAnimationsFrameHandler: false + }), "defaults"); + __name(configToCacheKey, "configToCacheKey"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/types/Extensions.js +var Extensions_exports = {}; +__export(Extensions_exports, { + extensionPalette: () => extensionPalette, + isConsoleTimestampPayloadTrackEntry: () => isConsoleTimestampPayloadTrackEntry, + isExtensionEntryObj: () => isExtensionEntryObj, + isExtensionPayloadMarker: () => isExtensionPayloadMarker, + isSyntheticExtensionEntry: () => isSyntheticExtensionEntry, + isValidExtensionPayload: () => isValidExtensionPayload +}); +function isExtensionPayloadMarker(payload) { + return payload.dataType === "marker"; +} +function isExtensionEntryObj(payload) { + const hasTrack = "track" in payload && Boolean(payload.track); + const validEntryType = payload.dataType === "track-entry" || payload.dataType === void 0; + return validEntryType && hasTrack; +} +function isConsoleTimestampPayloadTrackEntry(payload) { + return payload.url !== void 0 && payload.description !== void 0; +} +function isValidExtensionPayload(payload) { + return isExtensionPayloadMarker(payload) || isExtensionEntryObj(payload) || isConsoleTimestampPayloadTrackEntry(payload); +} +function isSyntheticExtensionEntry(entry) { + return entry.cat === "devtools.extension"; +} +var extensionPalette; +var init_Extensions = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/types/Extensions.js"() { + init_process_global(); + extensionPalette = [ + "primary", + "primary-light", + "primary-dark", + "secondary", + "secondary-light", + "secondary-dark", + "tertiary", + "tertiary-light", + "tertiary-dark", + "error", + "warning" + ]; + __name(isExtensionPayloadMarker, "isExtensionPayloadMarker"); + __name(isExtensionEntryObj, "isExtensionEntryObj"); + __name(isConsoleTimestampPayloadTrackEntry, "isConsoleTimestampPayloadTrackEntry"); + __name(isValidExtensionPayload, "isValidExtensionPayload"); + __name(isSyntheticExtensionEntry, "isSyntheticExtensionEntry"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/types/File.js +var File_exports = {}; +__export(File_exports, { + DataOrigin: () => DataOrigin, + EntriesLinkState: () => EntriesLinkState, + EventKeyType: () => EventKeyType, + isEntriesLinkAnnotation: () => isEntriesLinkAnnotation, + isEntryLabelAnnotation: () => isEntryLabelAnnotation, + isTimeRangeAnnotation: () => isTimeRangeAnnotation, + traceEventKeyToValues: () => traceEventKeyToValues +}); +function isTimeRangeAnnotation(annotation) { + return annotation.type === "TIME_RANGE"; +} +function isEntryLabelAnnotation(annotation) { + return annotation.type === "ENTRY_LABEL"; +} +function isEntriesLinkAnnotation(annotation) { + return annotation.type === "ENTRIES_LINK"; +} +function traceEventKeyToValues(key) { + const parts = key.split("-"); + const type = parts[0]; + switch (type) { + case EventKeyType.PROFILE_CALL: + if (parts.length !== 5 || !parts.every((part, i) => i === 0 || typeof part === "number" || !isNaN(parseInt(part, 10)))) { + throw new Error(`Invalid ProfileCallKey: ${key}`); + } + return { + type: parts[0], + processID: parseInt(parts[1], 10), + threadID: parseInt(parts[2], 10), + sampleIndex: parseInt(parts[3], 10), + protocol: parseInt(parts[4], 10) + }; + case EventKeyType.RAW_EVENT: + if (parts.length !== 2 || !(typeof parts[1] === "number" || !isNaN(parseInt(parts[1], 10)))) { + throw new Error(`Invalid RawEvent Key: ${key}`); + } + return { + type: parts[0], + rawIndex: parseInt(parts[1], 10) + }; + case EventKeyType.SYNTHETIC_EVENT: + if (parts.length !== 2 || !(typeof parts[1] === "number" || !isNaN(parseInt(parts[1], 10)))) { + throw new Error(`Invalid SyntheticEvent Key: ${key}`); + } + return { + type: parts[0], + rawIndex: parseInt(parts[1], 10) + }; + case EventKeyType.LEGACY_TIMELINE_FRAME: { + if (parts.length !== 2 || Number.isNaN(parseInt(parts[1], 10))) { + throw new Error(`Invalid LegacyTimelineFrame Key: ${key}`); + } + return { + type, + rawIndex: parseInt(parts[1], 10) + }; + } + default: + throw new Error(`Unknown trace event key: ${key}`); + } +} +var DataOrigin, EntriesLinkState, EventKeyType; +var init_File = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/types/File.js"() { + init_process_global(); + (function(DataOrigin2) { + DataOrigin2["CPU_PROFILE"] = "CPUProfile"; + DataOrigin2["TRACE_EVENTS"] = "TraceEvents"; + })(DataOrigin || (DataOrigin = {})); + (function(EntriesLinkState2) { + EntriesLinkState2["CREATION_NOT_STARTED"] = "creation_not_started"; + EntriesLinkState2["PENDING_TO_EVENT"] = "pending_to_event"; + EntriesLinkState2["CONNECTED"] = "connected"; + })(EntriesLinkState || (EntriesLinkState = {})); + (function(EventKeyType2) { + EventKeyType2["RAW_EVENT"] = "r"; + EventKeyType2["SYNTHETIC_EVENT"] = "s"; + EventKeyType2["PROFILE_CALL"] = "p"; + EventKeyType2["LEGACY_TIMELINE_FRAME"] = "l"; + })(EventKeyType || (EventKeyType = {})); + __name(isTimeRangeAnnotation, "isTimeRangeAnnotation"); + __name(isEntryLabelAnnotation, "isEntryLabelAnnotation"); + __name(isEntriesLinkAnnotation, "isEntriesLinkAnnotation"); + __name(traceEventKeyToValues, "traceEventKeyToValues"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/types/Overlays.js +var init_Overlays = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/types/Overlays.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/types/Timing.js +var Timing_exports = {}; +__export(Timing_exports, { + Micro: () => Micro, + Milli: () => Milli, + Seconds: () => Seconds +}); +function Micro(value) { + return value; +} +function Milli(value) { + return value; +} +function Seconds(value) { + return value; +} +var init_Timing = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/types/Timing.js"() { + init_process_global(); + __name(Micro, "Micro"); + __name(Milli, "Milli"); + __name(Seconds, "Seconds"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/types/TraceEvents.js +var TraceEvents_exports = {}; +__export(TraceEvents_exports, { + AuctionWorkletType: () => AuctionWorkletType, + CallFrameID: () => CallFrameID, + Categories: () => Categories, + InvalidationEventType: () => InvalidationEventType, + LayoutInvalidationReason: () => LayoutInvalidationReason, + MarkerName: () => MarkerName, + NO_NAVIGATION: () => NO_NAVIGATION, + Name: () => Name, + Phase: () => Phase, + ProcessID: () => ProcessID, + ProfileID: () => ProfileID, + SampleIndex: () => SampleIndex, + Scope: () => Scope, + SelectorTimingsKey: () => SelectorTimingsKey, + StyleRecalcInvalidationReason: () => StyleRecalcInvalidationReason, + ThreadID: () => ThreadID, + WorkerId: () => WorkerId, + eventIsPageLoadEvent: () => eventIsPageLoadEvent, + isAbortPostTaskCallback: () => isAbortPostTaskCallback, + isActivateLayerTree: () => isActivateLayerTree, + isAnimation: () => isAnimation, + isAnimationFrameAsyncEnd: () => isAnimationFrameAsyncEnd, + isAnimationFrameAsyncStart: () => isAnimationFrameAsyncStart, + isAnimationFramePresentation: () => isAnimationFramePresentation, + isAnyScriptSourceEvent: () => isAnyScriptSourceEvent, + isAuctionWorkletDoneWithProcess: () => isAuctionWorkletDoneWithProcess, + isAuctionWorkletRunningInProcess: () => isAuctionWorkletRunningInProcess, + isBegin: () => isBegin, + isBeginCommitCompositorFrame: () => isBeginCommitCompositorFrame, + isBeginFrame: () => isBeginFrame, + isBeginMainThreadFrame: () => isBeginMainThreadFrame, + isBeginRemoteFontLoad: () => isBeginRemoteFontLoad, + isCommit: () => isCommit, + isCommitLoad: () => isCommitLoad, + isComplete: () => isComplete, + isCompositeLayers: () => isCompositeLayers, + isConsoleRunTask: () => isConsoleRunTask, + isConsoleTime: () => isConsoleTime, + isConsoleTimeStamp: () => isConsoleTimeStamp, + isDOMStats: () => isDOMStats, + isDebuggerAsyncTaskRun: () => isDebuggerAsyncTaskRun, + isDebuggerAsyncTaskScheduled: () => isDebuggerAsyncTaskScheduled, + isDecodeImage: () => isDecodeImage, + isDecodeLazyPixelRef: () => isDecodeLazyPixelRef, + isDidCommitSameDocumentNavigation: () => isDidCommitSameDocumentNavigation, + isDispatch: () => isDispatch, + isDisplayListItemListSnapshot: () => isDisplayListItemListSnapshot, + isDomLoading: () => isDomLoading, + isDrawFrame: () => isDrawFrame, + isDrawLazyPixelRef: () => isDrawLazyPixelRef, + isDroppedFrame: () => isDroppedFrame, + isEnd: () => isEnd, + isEventTiming: () => isEventTiming, + isEventTimingEnd: () => isEventTimingEnd, + isEventTimingStart: () => isEventTimingStart, + isFireAnimationFrame: () => isFireAnimationFrame, + isFireIdleCallback: () => isFireIdleCallback, + isFirstContentfulPaint: () => isFirstContentfulPaint, + isFirstPaint: () => isFirstPaint, + isFlowPhase: () => isFlowPhase, + isFlowPhaseEvent: () => isFlowPhaseEvent, + isFrameCommittedInBrowser: () => isFrameCommittedInBrowser, + isFunctionCall: () => isFunctionCall, + isGPUTask: () => isGPUTask, + isHandlePostMessage: () => isHandlePostMessage, + isInstant: () => isInstant, + isInteractiveTime: () => isInteractiveTime, + isInvalidateLayout: () => isInvalidateLayout, + isInvalidationTracking: () => isInvalidationTracking, + isJSInvocationEvent: () => isJSInvocationEvent, + isLargestContentfulPaintCandidate: () => isLargestContentfulPaintCandidate, + isLargestImagePaintCandidate: () => isLargestImagePaintCandidate, + isLargestTextPaintCandidate: () => isLargestTextPaintCandidate, + isLayerTreeHostImplSnapshot: () => isLayerTreeHostImplSnapshot, + isLayout: () => isLayout, + isLayoutImageUnsized: () => isLayoutImageUnsized, + isLayoutInvalidationTracking: () => isLayoutInvalidationTracking, + isLayoutShift: () => isLayoutShift, + isLegacyScreenshot: () => isLegacyScreenshot, + isLegacySyntheticScreenshot: () => isLegacySyntheticScreenshot, + isLegacyTimelineFrame: () => isLegacyTimelineFrame, + isLinkPreconnect: () => isLinkPreconnect, + isMainFrameViewport: () => isMainFrameViewport, + isMarkDOMContent: () => isMarkDOMContent, + isMarkLoad: () => isMarkLoad, + isMarkerEvent: () => isMarkerEvent, + isNavigationStart: () => isNavigationStart, + isNeedsBeginFrameChanged: () => isNeedsBeginFrameChanged, + isNestableAsyncPhase: () => isNestableAsyncPhase, + isNetworkTrackEntry: () => isNetworkTrackEntry, + isPaint: () => isPaint, + isPaintImage: () => isPaintImage, + isPairableAsyncBegin: () => isPairableAsyncBegin, + isPairableAsyncEnd: () => isPairableAsyncEnd, + isPairableAsyncInstant: () => isPairableAsyncInstant, + isParseAuthorStyleSheetEvent: () => isParseAuthorStyleSheetEvent, + isParseHTML: () => isParseHTML, + isParseMetaViewport: () => isParseMetaViewport, + isPerformanceMark: () => isPerformanceMark, + isPerformanceMeasure: () => isPerformanceMeasure, + isPerformanceMeasureBegin: () => isPerformanceMeasureBegin, + isPhaseAsync: () => isPhaseAsync, + isPipelineReporter: () => isPipelineReporter, + isPrePaint: () => isPrePaint, + isProcessName: () => isProcessName, + isProfile: () => isProfile, + isProfileCall: () => isProfileCall, + isProfileChunk: () => isProfileChunk, + isRasterTask: () => isRasterTask, + isRecalcStyle: () => isRecalcStyle, + isReceivedDataEvent: () => isReceivedDataEvent, + isRemoteFontLoaded: () => isRemoteFontLoaded, + isRenderFrameImplCreateChildFrame: () => isRenderFrameImplCreateChildFrame, + isRendererEvent: () => isRendererEvent, + isRequestIdleCallback: () => isRequestIdleCallback, + isRequestMainThreadFrame: () => isRequestMainThreadFrame, + isResourceChangePriority: () => isResourceChangePriority, + isResourceFinish: () => isResourceFinish, + isResourceMarkAsCached: () => isResourceMarkAsCached, + isResourceReceiveResponse: () => isResourceReceiveResponse, + isResourceReceivedData: () => isResourceReceivedData, + isResourceSendRequest: () => isResourceSendRequest, + isResourceWillSendRequest: () => isResourceWillSendRequest, + isRunPostTaskCallback: () => isRunPostTaskCallback, + isRunTask: () => isRunTask, + isRundownScript: () => isRundownScript, + isRundownScriptCompiled: () => isRundownScriptCompiled, + isRundownScriptSource: () => isRundownScriptSource, + isRundownScriptSourceLarge: () => isRundownScriptSourceLarge, + isSchedulePostMessage: () => isSchedulePostMessage, + isSchedulePostTaskCallback: () => isSchedulePostTaskCallback, + isScheduleStyleInvalidationTracking: () => isScheduleStyleInvalidationTracking, + isScheduleStyleRecalculation: () => isScheduleStyleRecalculation, + isScreenshot: () => isScreenshot, + isScrollLayer: () => isScrollLayer, + isSelectorStats: () => isSelectorStats, + isSetLayerId: () => isSetLayerId, + isStyleInvalidatorInvalidationTracking: () => isStyleInvalidatorInvalidationTracking, + isStyleRecalcInvalidationTracking: () => isStyleRecalcInvalidationTracking, + isSyntheticAnimation: () => isSyntheticAnimation, + isSyntheticBased: () => isSyntheticBased, + isSyntheticConsoleTiming: () => isSyntheticConsoleTiming, + isSyntheticCpuProfile: () => isSyntheticCpuProfile, + isSyntheticInteraction: () => isSyntheticInteraction, + isSyntheticLayoutShift: () => isSyntheticLayoutShift, + isSyntheticLayoutShiftCluster: () => isSyntheticLayoutShiftCluster, + isSyntheticNetworkRequest: () => isSyntheticNetworkRequest, + isSyntheticUserTiming: () => isSyntheticUserTiming, + isSyntheticWebSocketConnection: () => isSyntheticWebSocketConnection, + isThreadName: () => isThreadName, + isTimerFire: () => isTimerFire, + isTimerInstall: () => isTimerInstall, + isTracingSessionIdForWorker: () => isTracingSessionIdForWorker, + isTracingStartedInBrowser: () => isTracingStartedInBrowser, + isUpdateCounters: () => isUpdateCounters, + isUpdateLayer: () => isUpdateLayer, + isUserTiming: () => isUserTiming, + isUserTimingMeasure: () => isUserTimingMeasure, + isV8Compile: () => isV8Compile, + isWebSocketCreate: () => isWebSocketCreate, + isWebSocketDestroy: () => isWebSocketDestroy, + isWebSocketEvent: () => isWebSocketEvent, + isWebSocketInfo: () => isWebSocketInfo, + isWebSocketReceiveHandshakeResponse: () => isWebSocketReceiveHandshakeResponse, + isWebSocketSendHandshakeRequest: () => isWebSocketSendHandshakeRequest, + isWebSocketTraceEvent: () => isWebSocketTraceEvent, + isWebSocketTransfer: () => isWebSocketTransfer, + objectIsCallFrame: () => objectIsCallFrame +}); +function isNestableAsyncPhase(phase) { + return phase === Phase.ASYNC_NESTABLE_START || phase === Phase.ASYNC_NESTABLE_END || phase === Phase.ASYNC_NESTABLE_INSTANT; +} +function isPhaseAsync(phase) { + return isNestableAsyncPhase(phase) || phase === Phase.ASYNC_BEGIN || phase === Phase.ASYNC_STEP_INTO || phase === Phase.ASYNC_END || phase === Phase.ASYNC_STEP_PAST; +} +function isFlowPhase(phase) { + return phase === Phase.FLOW_START || phase === Phase.FLOW_STEP || phase === Phase.FLOW_END; +} +function objectIsCallFrame(object) { + return "functionName" in object && typeof object.functionName === "string" && ("scriptId" in object && (typeof object.scriptId === "string" || typeof object.scriptId === "number")) && ("columnNumber" in object && typeof object.columnNumber === "number") && ("lineNumber" in object && typeof object.lineNumber === "number") && ("url" in object && typeof object.url === "string"); +} +function isRunTask(event) { + return event.name === Name.RUN_TASK && event.ph === Phase.COMPLETE; +} +function isAuctionWorkletRunningInProcess(event) { + return event.name === "AuctionWorkletRunningInProcess"; +} +function isAuctionWorkletDoneWithProcess(event) { + return event.name === "AuctionWorkletDoneWithProcess"; +} +function isLegacyScreenshot(event) { + return event.name === Name.SCREENSHOT && "id" in event; +} +function isLegacySyntheticScreenshot(event) { + return event.name === Name.SCREENSHOT && "dataUri" in (event.args ?? {}); +} +function isScreenshot(event) { + return event.name === Name.SCREENSHOT && "source_id" in (event.args ?? {}); +} +function isMarkerEvent(event) { + if (event.ph === Phase.INSTANT || event.ph === Phase.MARK) { + return markerTypeGuards.some((fn) => fn(event)); + } + return false; +} +function eventIsPageLoadEvent(event) { + if (event.ph === Phase.INSTANT || event.ph === Phase.MARK) { + return pageLoadEventTypeGuards.some((fn) => fn(event)); + } + return false; +} +function isTracingSessionIdForWorker(event) { + return event.name === "TracingSessionIdForWorker"; +} +function isScheduleStyleInvalidationTracking(event) { + return event.name === Name.SCHEDULE_STYLE_INVALIDATION_TRACKING; +} +function isStyleRecalcInvalidationTracking(event) { + return event.name === Name.STYLE_RECALC_INVALIDATION_TRACKING; +} +function isStyleInvalidatorInvalidationTracking(event) { + return event.name === Name.STYLE_INVALIDATOR_INVALIDATION_TRACKING; +} +function isBeginCommitCompositorFrame(event) { + return event.name === Name.BEGIN_COMMIT_COMPOSITOR_FRAME; +} +function isParseMetaViewport(event) { + return event.name === Name.PARSE_META_VIEWPORT; +} +function isLinkPreconnect(event) { + return event.name === Name.LINK_PRECONNECT; +} +function isScheduleStyleRecalculation(event) { + return event.name === Name.SCHEDULE_STYLE_RECALCULATION; +} +function isRenderFrameImplCreateChildFrame(event) { + return event.name === Name.RENDER_FRAME_IMPL_CREATE_CHILD_FRAME; +} +function isLayoutImageUnsized(event) { + return event.name === Name.LAYOUT_IMAGE_UNSIZED; +} +function isPairableAsyncBegin(e) { + return e.ph === Phase.ASYNC_NESTABLE_START; +} +function isPairableAsyncEnd(e) { + return e.ph === Phase.ASYNC_NESTABLE_END; +} +function isPairableAsyncInstant(e) { + return e.ph === Phase.ASYNC_NESTABLE_INSTANT; +} +function isAnimationFrameAsyncStart(data31) { + return data31.name === Name.ANIMATION_FRAME && data31.ph === Phase.ASYNC_NESTABLE_START; +} +function isAnimationFrameAsyncEnd(data31) { + return data31.name === Name.ANIMATION_FRAME && data31.ph === Phase.ASYNC_NESTABLE_END; +} +function isAnimationFramePresentation(data31) { + return data31.name === Name.ANIMATION_FRAME_PRESENTATION; +} +function isPipelineReporter(event) { + return event.name === Name.PIPELINE_REPORTER; +} +function isSyntheticBased(event) { + return "rawSourceEvent" in event; +} +function isSyntheticInteraction(event) { + return Boolean("interactionId" in event && event.args?.data && "beginEvent" in event.args.data && "endEvent" in event.args.data); +} +function isDrawFrame(event) { + return event.name === Name.DRAW_FRAME && event.ph === Phase.INSTANT; +} +function isBeginFrame(event) { + return Boolean(event.name === Name.BEGIN_FRAME && event.args && "frameSeqId" in event.args); +} +function isDroppedFrame(event) { + return Boolean(event.name === Name.DROPPED_FRAME && event.args && "frameSeqId" in event.args); +} +function isRequestMainThreadFrame(event) { + return event.name === Name.REQUEST_MAIN_THREAD_FRAME; +} +function isBeginMainThreadFrame(event) { + return event.name === Name.BEGIN_MAIN_THREAD_FRAME; +} +function isNeedsBeginFrameChanged(event) { + return event.name === Name.NEEDS_BEGIN_FRAME_CHANGED; +} +function isCommit(event) { + return Boolean(event.name === Name.COMMIT && event.args && "frameSeqId" in event.args); +} +function isRasterTask(event) { + return event.name === Name.RASTER_TASK; +} +function isCompositeLayers(event) { + return event.name === Name.COMPOSITE_LAYERS; +} +function isActivateLayerTree(event) { + return event.name === Name.ACTIVATE_LAYER_TREE; +} +function isInvalidationTracking(event) { + return isScheduleStyleInvalidationTracking(event) || isStyleRecalcInvalidationTracking(event) || isStyleInvalidatorInvalidationTracking(event) || isLayoutInvalidationTracking(event); +} +function isDrawLazyPixelRef(event) { + return event.name === Name.DRAW_LAZY_PIXEL_REF; +} +function isDecodeLazyPixelRef(event) { + return event.name === Name.DECODE_LAZY_PIXEL_REF; +} +function isDecodeImage(event) { + return event.name === Name.DECODE_IMAGE; +} +function isSelectorStats(event) { + return event.name === Name.SELECTOR_STATS; +} +function isRecalcStyle(event) { + return event.name === Name.RECALC_STYLE; +} +function isLayout(event) { + return event.name === Name.LAYOUT && Boolean(event.args && "beginData" in event.args); +} +function isInvalidateLayout(event) { + return event.name === Name.INVALIDATE_LAYOUT; +} +function isDebuggerAsyncTaskScheduled(event) { + return event.name === Name.DEBUGGER_ASYNC_TASK_SCHEDULED; +} +function isDebuggerAsyncTaskRun(event) { + return event.name === Name.DEBUGGER_ASYNC_TASK_RUN; +} +function ProfileID(value) { + return value; +} +function CallFrameID(value) { + return value; +} +function SampleIndex(value) { + return value; +} +function ProcessID(value) { + return value; +} +function ThreadID(value) { + return value; +} +function WorkerId(value) { + return value; +} +function isComplete(event) { + return event.ph === Phase.COMPLETE; +} +function isBegin(event) { + return event.ph === Phase.BEGIN; +} +function isEnd(event) { + return event.ph === Phase.END; +} +function isDispatch(event) { + return event.name === "EventDispatch" && event.ph === Phase.COMPLETE; +} +function isInstant(event) { + return event.ph === Phase.INSTANT; +} +function isRendererEvent(event) { + return isInstant(event) || isComplete(event); +} +function isFireIdleCallback(event) { + return event.name === "FireIdleCallback" && event.ph === Phase.COMPLETE; +} +function isSchedulePostMessage(event) { + return event.name === Name.SCHEDULE_POST_MESSAGE; +} +function isHandlePostMessage(event) { + return event.name === Name.HANDLE_POST_MESSAGE && event.ph === Phase.COMPLETE; +} +function isUpdateCounters(event) { + return event.name === "UpdateCounters"; +} +function isDOMStats(event) { + return event.name === "DOMStats"; +} +function isThreadName(event) { + return event.name === Name.THREAD_NAME; +} +function isProcessName(event) { + return event.name === "process_name"; +} +function isTracingStartedInBrowser(event) { + return event.name === Name.TRACING_STARTED_IN_BROWSER; +} +function isFrameCommittedInBrowser(event) { + return event.name === "FrameCommittedInBrowser"; +} +function isCommitLoad(event) { + return event.name === "CommitLoad"; +} +function isAnimation(event) { + return event.name === "Animation" && event.cat.includes("devtools.timeline"); +} +function isSyntheticAnimation(event) { + if (event.name !== "Animation" || !event.cat.includes("devtools.timeline")) { + return false; + } + const data31 = event.args?.data; + if (!data31) { + return false; + } + return "beginEvent" in data31 && "endEvent" in data31; +} +function isLayoutShift(event) { + return event.name === Name.LAYOUT_SHIFT; +} +function isLayoutInvalidationTracking(event) { + return event.name === Name.LAYOUT_INVALIDATION_TRACKING; +} +function isFirstContentfulPaint(event) { + return event.name === "firstContentfulPaint"; +} +function isLargestContentfulPaintCandidate(event) { + return event.name === Name.MARK_LCP_CANDIDATE; +} +function isLargestImagePaintCandidate(event) { + return event.name === "LargestImagePaint::Candidate"; +} +function isLargestTextPaintCandidate(event) { + return event.name === "LargestTextPaint::Candidate"; +} +function isMarkLoad(event) { + return event.name === "MarkLoad"; +} +function isFirstPaint(event) { + return event.name === "firstPaint"; +} +function isMarkDOMContent(event) { + return event.name === "MarkDOMContent"; +} +function isInteractiveTime(event) { + return event.name === "InteractiveTime"; +} +function isEventTiming(event) { + return event.name === Name.EVENT_TIMING; +} +function isEventTimingEnd(event) { + return isEventTiming(event) && event.ph === Phase.ASYNC_NESTABLE_END; +} +function isEventTimingStart(event) { + return isEventTiming(event) && event.ph === Phase.ASYNC_NESTABLE_START; +} +function isGPUTask(event) { + return event.name === "GPUTask"; +} +function isProfile(event) { + return event.name === Name.PROFILE; +} +function isSyntheticCpuProfile(event) { + return event.name === Name.CPU_PROFILE && event.ph === Phase.COMPLETE; +} +function isProfileChunk(event) { + return event.name === Name.PROFILE_CHUNK; +} +function isResourceChangePriority(event) { + return event.name === "ResourceChangePriority"; +} +function isResourceSendRequest(event) { + return event.name === "ResourceSendRequest"; +} +function isResourceReceiveResponse(event) { + return event.name === "ResourceReceiveResponse"; +} +function isResourceMarkAsCached(event) { + return event.name === "ResourceMarkAsCached"; +} +function isResourceFinish(event) { + return event.name === "ResourceFinish"; +} +function isResourceWillSendRequest(event) { + return event.name === "ResourceWillSendRequest"; +} +function isResourceReceivedData(event) { + return event.name === "ResourceReceivedData"; +} +function isReceivedDataEvent(event) { + return event.name === "ResourceReceivedData" || event.name === "ResourceFinish" || event.name === "ResourceReceiveResponse"; +} +function isSyntheticNetworkRequest(event) { + return event.name === Name.SYNTHETIC_NETWORK_REQUEST; +} +function isSyntheticWebSocketConnection(event) { + return event.name === "SyntheticWebSocketConnection"; +} +function isNetworkTrackEntry(event) { + return isSyntheticNetworkRequest(event) || isSyntheticWebSocketConnection(event) || isWebSocketTraceEvent(event); +} +function isPrePaint(event) { + return event.name === "PrePaint"; +} +function isNavigationStart(event) { + return event.name === "navigationStart" && event.args?.data?.documentLoaderURL !== ""; +} +function isDidCommitSameDocumentNavigation(event) { + return event.name === "RenderFrameHostImpl::DidCommitSameDocumentNavigation" && event.ph === Phase.COMPLETE; +} +function isMainFrameViewport(event) { + return event.name === "PaintTimingVisualizer::Viewport"; +} +function isSyntheticUserTiming(event) { + if (event.cat !== "blink.user_timing") { + return false; + } + const data31 = event.args?.data; + if (!data31) { + return false; + } + return "beginEvent" in data31 && "endEvent" in data31; +} +function isSyntheticConsoleTiming(event) { + if (event.cat !== "blink.console") { + return false; + } + const data31 = event.args?.data; + if (!data31) { + return false; + } + return "beginEvent" in data31 && "endEvent" in data31; +} +function isUserTiming(event) { + return event.cat === "blink.user_timing"; +} +function isDomLoading(event) { + return event.name === Name.DOM_LOADING; +} +function isBeginRemoteFontLoad(event) { + return event.name === Name.BEGIN_REMOTE_FONT_LOAD; +} +function isRemoteFontLoaded(event) { + return event.name === Name.REMOTE_FONT_LOADED; +} +function isPerformanceMeasure(event) { + return isUserTiming(event) && isPhaseAsync(event.ph); +} +function isPerformanceMeasureBegin(event) { + return isPerformanceMeasure(event) && event.ph === Phase.ASYNC_NESTABLE_START; +} +function isPerformanceMark(event) { + return isUserTiming(event) && (event.ph === Phase.MARK || event.ph === Phase.INSTANT); +} +function isConsoleTime(event) { + return event.cat === "blink.console" && isPhaseAsync(event.ph); +} +function isConsoleTimeStamp(event) { + return event.ph === Phase.INSTANT && event.name === Name.TIME_STAMP; +} +function isUserTimingMeasure(event) { + return event.name === Name.USER_TIMING_MEASURE; +} +function isParseHTML(event) { + return event.name === "ParseHTML"; +} +function isSyntheticLayoutShift(event) { + return event.name === Name.SYNTHETIC_LAYOUT_SHIFT; +} +function isSyntheticLayoutShiftCluster(event) { + return event.name === Name.SYNTHETIC_LAYOUT_SHIFT_CLUSTER; +} +function isProfileCall(event) { + return "callFrame" in event; +} +function isPaint(event) { + return event.name === Name.PAINT; +} +function isPaintImage(event) { + return event.name === Name.PAINT_IMAGE && event.ph === Phase.COMPLETE; +} +function isScrollLayer(event) { + return event.name === Name.SCROLL_LAYER && event.ph === Phase.COMPLETE; +} +function isSetLayerId(event) { + return event.name === Name.SET_LAYER_TREE_ID; +} +function isUpdateLayer(event) { + return event.name === Name.UPDATE_LAYER; +} +function isDisplayListItemListSnapshot(event) { + return event.name === Name.DISPLAY_ITEM_LIST_SNAPSHOT; +} +function isLayerTreeHostImplSnapshot(event) { + return event.name === Name.LAYER_TREE_HOST_IMPL_SNAPSHOT; +} +function isFireAnimationFrame(event) { + return event.name === Name.FIRE_ANIMATION_FRAME && event.ph === Phase.COMPLETE; +} +function isTimerInstall(event) { + return event.name === Name.TIMER_INSTALL; +} +function isTimerFire(event) { + return event.name === Name.TIMER_FIRE && event.ph === Phase.COMPLETE; +} +function isRequestIdleCallback(event) { + return event.name === Name.REQUEST_IDLE_CALLBACK; +} +function isWebSocketCreate(event) { + return event.name === Name.WEB_SOCKET_CREATE; +} +function isWebSocketInfo(event) { + return event.name === Name.WEB_SOCKET_SEND_HANDSHAKE_REQUEST || event.name === Name.WEB_SOCKET_RECEIVE_HANDSHAKE_REQUEST || event.name === Name.WEB_SOCKET_DESTROY; +} +function isWebSocketTransfer(event) { + return event.name === Name.WEB_SOCKET_SEND || event.name === Name.WEB_SOCKET_RECEIVE; +} +function isWebSocketSendHandshakeRequest(event) { + return event.name === Name.WEB_SOCKET_SEND_HANDSHAKE_REQUEST; +} +function isWebSocketReceiveHandshakeResponse(event) { + return event.name === Name.WEB_SOCKET_RECEIVE_HANDSHAKE_REQUEST; +} +function isWebSocketDestroy(event) { + return event.name === Name.WEB_SOCKET_DESTROY; +} +function isWebSocketTraceEvent(event) { + return isWebSocketCreate(event) || isWebSocketInfo(event) || isWebSocketTransfer(event); +} +function isWebSocketEvent(event) { + return isWebSocketTraceEvent(event) || isSyntheticWebSocketConnection(event); +} +function isV8Compile(event) { + return event.name === Name.COMPILE && event.ph === Phase.COMPLETE; +} +function isFunctionCall(event) { + return event.name === Name.FUNCTION_CALL && event.ph === Phase.COMPLETE; +} +function isSchedulePostTaskCallback(event) { + return event.name === Name.SCHEDULE_POST_TASK_CALLBACK; +} +function isRunPostTaskCallback(event) { + return event.name === Name.RUN_POST_TASK_CALLBACK && event.ph === Phase.COMPLETE; +} +function isAbortPostTaskCallback(event) { + return event.name === Name.ABORT_POST_TASK_CALLBACK && event.ph === Phase.COMPLETE; +} +function isJSInvocationEvent(event) { + switch (event.name) { + case Name.RUN_MICROTASKS: + case Name.FUNCTION_CALL: + // TODO(paulirish): Define types for these Evaluate* events + case Name.EVALUATE_SCRIPT: + case Name.EVALUATE_MODULE: + case Name.EVENT_DISPATCH: + case Name.V8_EXECUTE: + case Name.V8_CONSOLE_RUN_TASK: + return true; + } + if (event.name.startsWith("v8") || event.name.startsWith("V8")) { + return true; + } + if (isConsoleRunTask(event)) { + return true; + } + return false; +} +function isConsoleRunTask(event) { + return event.name === Name.V8_CONSOLE_RUN_TASK; +} +function isFlowPhaseEvent(event) { + return event.ph === Phase.FLOW_START || event.ph === Phase.FLOW_STEP || event.ph === Phase.FLOW_END; +} +function isParseAuthorStyleSheetEvent(event) { + return event.name === Name.PARSE_AUTHOR_STYLE_SHEET && event.ph === Phase.COMPLETE; +} +function isLegacyTimelineFrame(data31) { + return "idle" in data31 && typeof data31.idle === "boolean"; +} +function isRundownScriptCompiled(event) { + return event.cat === "disabled-by-default-devtools.target-rundown"; +} +function isRundownScript(event) { + return event.cat === "disabled-by-default-devtools.v8-source-rundown" && event.name === "ScriptCatchup"; +} +function isRundownScriptSource(event) { + return event.cat === "disabled-by-default-devtools.v8-source-rundown-sources" && event.name === "ScriptCatchup"; +} +function isRundownScriptSourceLarge(event) { + return event.cat === "disabled-by-default-devtools.v8-source-rundown-sources" && event.name === "LargeScriptCatchup"; +} +function isAnyScriptSourceEvent(event) { + return event.cat === "disabled-by-default-devtools.v8-source-rundown-sources"; +} +var Phase, Scope, AuctionWorkletType, markerTypeGuards, MarkerName, pageLoadEventTypeGuards, NO_NAVIGATION, LayoutInvalidationReason, StyleRecalcInvalidationReason, InvalidationEventType, SelectorTimingsKey, Name, Categories; +var init_TraceEvents = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/types/TraceEvents.js"() { + init_process_global(); + (function(Phase2) { + Phase2["BEGIN"] = "B"; + Phase2["END"] = "E"; + Phase2["COMPLETE"] = "X"; + Phase2["INSTANT"] = "I"; + Phase2["COUNTER"] = "C"; + Phase2["ASYNC_NESTABLE_START"] = "b"; + Phase2["ASYNC_NESTABLE_INSTANT"] = "n"; + Phase2["ASYNC_NESTABLE_END"] = "e"; + Phase2["ASYNC_STEP_INTO"] = "T"; + Phase2["ASYNC_BEGIN"] = "S"; + Phase2["ASYNC_END"] = "F"; + Phase2["ASYNC_STEP_PAST"] = "p"; + Phase2["FLOW_START"] = "s"; + Phase2["FLOW_STEP"] = "t"; + Phase2["FLOW_END"] = "f"; + Phase2["SAMPLE"] = "P"; + Phase2["OBJECT_CREATED"] = "N"; + Phase2["OBJECT_SNAPSHOT"] = "O"; + Phase2["OBJECT_DESTROYED"] = "D"; + Phase2["METADATA"] = "M"; + Phase2["MEMORY_DUMP_GLOBAL"] = "V"; + Phase2["MEMORY_DUMP_PROCESS"] = "v"; + Phase2["MARK"] = "R"; + Phase2["CLOCK_SYNC"] = "c"; + })(Phase || (Phase = {})); + __name(isNestableAsyncPhase, "isNestableAsyncPhase"); + __name(isPhaseAsync, "isPhaseAsync"); + __name(isFlowPhase, "isFlowPhase"); + (function(Scope2) { + Scope2["THREAD"] = "t"; + Scope2["PROCESS"] = "p"; + Scope2["GLOBAL"] = "g"; + })(Scope || (Scope = {})); + __name(objectIsCallFrame, "objectIsCallFrame"); + __name(isRunTask, "isRunTask"); + (function(AuctionWorkletType2) { + AuctionWorkletType2["BIDDER"] = "bidder"; + AuctionWorkletType2["SELLER"] = "seller"; + AuctionWorkletType2["UNKNOWN"] = "unknown"; + })(AuctionWorkletType || (AuctionWorkletType = {})); + __name(isAuctionWorkletRunningInProcess, "isAuctionWorkletRunningInProcess"); + __name(isAuctionWorkletDoneWithProcess, "isAuctionWorkletDoneWithProcess"); + __name(isLegacyScreenshot, "isLegacyScreenshot"); + __name(isLegacySyntheticScreenshot, "isLegacySyntheticScreenshot"); + __name(isScreenshot, "isScreenshot"); + markerTypeGuards = [ + isMarkDOMContent, + isMarkLoad, + isFirstPaint, + isFirstContentfulPaint, + isLargestContentfulPaintCandidate, + isNavigationStart + ]; + MarkerName = ["MarkDOMContent", "MarkLoad", "firstPaint", "firstContentfulPaint", "largestContentfulPaint::Candidate"]; + __name(isMarkerEvent, "isMarkerEvent"); + pageLoadEventTypeGuards = [ + ...markerTypeGuards, + isInteractiveTime + ]; + __name(eventIsPageLoadEvent, "eventIsPageLoadEvent"); + __name(isTracingSessionIdForWorker, "isTracingSessionIdForWorker"); + NO_NAVIGATION = "NO_NAVIGATION"; + (function(LayoutInvalidationReason2) { + LayoutInvalidationReason2["SIZE_CHANGED"] = "Size changed"; + LayoutInvalidationReason2["ATTRIBUTE"] = "Attribute"; + LayoutInvalidationReason2["ADDED_TO_LAYOUT"] = "Added to layout"; + LayoutInvalidationReason2["SCROLLBAR_CHANGED"] = "Scrollbar changed"; + LayoutInvalidationReason2["REMOVED_FROM_LAYOUT"] = "Removed from layout"; + LayoutInvalidationReason2["STYLE_CHANGED"] = "Style changed"; + LayoutInvalidationReason2["FONTS_CHANGED"] = "Fonts changed"; + LayoutInvalidationReason2["UNKNOWN"] = "Unknown"; + })(LayoutInvalidationReason || (LayoutInvalidationReason = {})); + __name(isScheduleStyleInvalidationTracking, "isScheduleStyleInvalidationTracking"); + (function(StyleRecalcInvalidationReason2) { + StyleRecalcInvalidationReason2["ANIMATION"] = "Animation"; + StyleRecalcInvalidationReason2["RELATED_STYLE_RULE"] = "Related style rule"; + })(StyleRecalcInvalidationReason || (StyleRecalcInvalidationReason = {})); + __name(isStyleRecalcInvalidationTracking, "isStyleRecalcInvalidationTracking"); + __name(isStyleInvalidatorInvalidationTracking, "isStyleInvalidatorInvalidationTracking"); + __name(isBeginCommitCompositorFrame, "isBeginCommitCompositorFrame"); + __name(isParseMetaViewport, "isParseMetaViewport"); + __name(isLinkPreconnect, "isLinkPreconnect"); + __name(isScheduleStyleRecalculation, "isScheduleStyleRecalculation"); + __name(isRenderFrameImplCreateChildFrame, "isRenderFrameImplCreateChildFrame"); + __name(isLayoutImageUnsized, "isLayoutImageUnsized"); + __name(isPairableAsyncBegin, "isPairableAsyncBegin"); + __name(isPairableAsyncEnd, "isPairableAsyncEnd"); + __name(isPairableAsyncInstant, "isPairableAsyncInstant"); + __name(isAnimationFrameAsyncStart, "isAnimationFrameAsyncStart"); + __name(isAnimationFrameAsyncEnd, "isAnimationFrameAsyncEnd"); + __name(isAnimationFramePresentation, "isAnimationFramePresentation"); + __name(isPipelineReporter, "isPipelineReporter"); + __name(isSyntheticBased, "isSyntheticBased"); + __name(isSyntheticInteraction, "isSyntheticInteraction"); + __name(isDrawFrame, "isDrawFrame"); + __name(isBeginFrame, "isBeginFrame"); + __name(isDroppedFrame, "isDroppedFrame"); + __name(isRequestMainThreadFrame, "isRequestMainThreadFrame"); + __name(isBeginMainThreadFrame, "isBeginMainThreadFrame"); + __name(isNeedsBeginFrameChanged, "isNeedsBeginFrameChanged"); + __name(isCommit, "isCommit"); + __name(isRasterTask, "isRasterTask"); + __name(isCompositeLayers, "isCompositeLayers"); + __name(isActivateLayerTree, "isActivateLayerTree"); + __name(isInvalidationTracking, "isInvalidationTracking"); + __name(isDrawLazyPixelRef, "isDrawLazyPixelRef"); + __name(isDecodeLazyPixelRef, "isDecodeLazyPixelRef"); + __name(isDecodeImage, "isDecodeImage"); + (function(InvalidationEventType2) { + InvalidationEventType2["StyleInvalidatorInvalidationTracking"] = "StyleInvalidatorInvalidationTracking"; + InvalidationEventType2["StyleRecalcInvalidationTracking"] = "StyleRecalcInvalidationTracking"; + })(InvalidationEventType || (InvalidationEventType = {})); + (function(SelectorTimingsKey2) { + SelectorTimingsKey2["Elapsed"] = "elapsed (us)"; + SelectorTimingsKey2["RejectPercentage"] = "reject_percentage"; + SelectorTimingsKey2["FastRejectCount"] = "fast_reject_count"; + SelectorTimingsKey2["MatchAttempts"] = "match_attempts"; + SelectorTimingsKey2["MatchCount"] = "match_count"; + SelectorTimingsKey2["Selector"] = "selector"; + SelectorTimingsKey2["StyleSheetId"] = "style_sheet_id"; + SelectorTimingsKey2["InvalidationCount"] = "invalidation_count"; + })(SelectorTimingsKey || (SelectorTimingsKey = {})); + __name(isSelectorStats, "isSelectorStats"); + __name(isRecalcStyle, "isRecalcStyle"); + __name(isLayout, "isLayout"); + __name(isInvalidateLayout, "isInvalidateLayout"); + __name(isDebuggerAsyncTaskScheduled, "isDebuggerAsyncTaskScheduled"); + __name(isDebuggerAsyncTaskRun, "isDebuggerAsyncTaskRun"); + __name(ProfileID, "ProfileID"); + __name(CallFrameID, "CallFrameID"); + __name(SampleIndex, "SampleIndex"); + __name(ProcessID, "ProcessID"); + __name(ThreadID, "ThreadID"); + __name(WorkerId, "WorkerId"); + __name(isComplete, "isComplete"); + __name(isBegin, "isBegin"); + __name(isEnd, "isEnd"); + __name(isDispatch, "isDispatch"); + __name(isInstant, "isInstant"); + __name(isRendererEvent, "isRendererEvent"); + __name(isFireIdleCallback, "isFireIdleCallback"); + __name(isSchedulePostMessage, "isSchedulePostMessage"); + __name(isHandlePostMessage, "isHandlePostMessage"); + __name(isUpdateCounters, "isUpdateCounters"); + __name(isDOMStats, "isDOMStats"); + __name(isThreadName, "isThreadName"); + __name(isProcessName, "isProcessName"); + __name(isTracingStartedInBrowser, "isTracingStartedInBrowser"); + __name(isFrameCommittedInBrowser, "isFrameCommittedInBrowser"); + __name(isCommitLoad, "isCommitLoad"); + __name(isAnimation, "isAnimation"); + __name(isSyntheticAnimation, "isSyntheticAnimation"); + __name(isLayoutShift, "isLayoutShift"); + __name(isLayoutInvalidationTracking, "isLayoutInvalidationTracking"); + __name(isFirstContentfulPaint, "isFirstContentfulPaint"); + __name(isLargestContentfulPaintCandidate, "isLargestContentfulPaintCandidate"); + __name(isLargestImagePaintCandidate, "isLargestImagePaintCandidate"); + __name(isLargestTextPaintCandidate, "isLargestTextPaintCandidate"); + __name(isMarkLoad, "isMarkLoad"); + __name(isFirstPaint, "isFirstPaint"); + __name(isMarkDOMContent, "isMarkDOMContent"); + __name(isInteractiveTime, "isInteractiveTime"); + __name(isEventTiming, "isEventTiming"); + __name(isEventTimingEnd, "isEventTimingEnd"); + __name(isEventTimingStart, "isEventTimingStart"); + __name(isGPUTask, "isGPUTask"); + __name(isProfile, "isProfile"); + __name(isSyntheticCpuProfile, "isSyntheticCpuProfile"); + __name(isProfileChunk, "isProfileChunk"); + __name(isResourceChangePriority, "isResourceChangePriority"); + __name(isResourceSendRequest, "isResourceSendRequest"); + __name(isResourceReceiveResponse, "isResourceReceiveResponse"); + __name(isResourceMarkAsCached, "isResourceMarkAsCached"); + __name(isResourceFinish, "isResourceFinish"); + __name(isResourceWillSendRequest, "isResourceWillSendRequest"); + __name(isResourceReceivedData, "isResourceReceivedData"); + __name(isReceivedDataEvent, "isReceivedDataEvent"); + __name(isSyntheticNetworkRequest, "isSyntheticNetworkRequest"); + __name(isSyntheticWebSocketConnection, "isSyntheticWebSocketConnection"); + __name(isNetworkTrackEntry, "isNetworkTrackEntry"); + __name(isPrePaint, "isPrePaint"); + __name(isNavigationStart, "isNavigationStart"); + __name(isDidCommitSameDocumentNavigation, "isDidCommitSameDocumentNavigation"); + __name(isMainFrameViewport, "isMainFrameViewport"); + __name(isSyntheticUserTiming, "isSyntheticUserTiming"); + __name(isSyntheticConsoleTiming, "isSyntheticConsoleTiming"); + __name(isUserTiming, "isUserTiming"); + __name(isDomLoading, "isDomLoading"); + __name(isBeginRemoteFontLoad, "isBeginRemoteFontLoad"); + __name(isRemoteFontLoaded, "isRemoteFontLoaded"); + __name(isPerformanceMeasure, "isPerformanceMeasure"); + __name(isPerformanceMeasureBegin, "isPerformanceMeasureBegin"); + __name(isPerformanceMark, "isPerformanceMark"); + __name(isConsoleTime, "isConsoleTime"); + __name(isConsoleTimeStamp, "isConsoleTimeStamp"); + __name(isUserTimingMeasure, "isUserTimingMeasure"); + __name(isParseHTML, "isParseHTML"); + __name(isSyntheticLayoutShift, "isSyntheticLayoutShift"); + __name(isSyntheticLayoutShiftCluster, "isSyntheticLayoutShiftCluster"); + __name(isProfileCall, "isProfileCall"); + __name(isPaint, "isPaint"); + __name(isPaintImage, "isPaintImage"); + __name(isScrollLayer, "isScrollLayer"); + __name(isSetLayerId, "isSetLayerId"); + __name(isUpdateLayer, "isUpdateLayer"); + __name(isDisplayListItemListSnapshot, "isDisplayListItemListSnapshot"); + __name(isLayerTreeHostImplSnapshot, "isLayerTreeHostImplSnapshot"); + __name(isFireAnimationFrame, "isFireAnimationFrame"); + __name(isTimerInstall, "isTimerInstall"); + __name(isTimerFire, "isTimerFire"); + __name(isRequestIdleCallback, "isRequestIdleCallback"); + __name(isWebSocketCreate, "isWebSocketCreate"); + __name(isWebSocketInfo, "isWebSocketInfo"); + __name(isWebSocketTransfer, "isWebSocketTransfer"); + __name(isWebSocketSendHandshakeRequest, "isWebSocketSendHandshakeRequest"); + __name(isWebSocketReceiveHandshakeResponse, "isWebSocketReceiveHandshakeResponse"); + __name(isWebSocketDestroy, "isWebSocketDestroy"); + __name(isWebSocketTraceEvent, "isWebSocketTraceEvent"); + __name(isWebSocketEvent, "isWebSocketEvent"); + __name(isV8Compile, "isV8Compile"); + __name(isFunctionCall, "isFunctionCall"); + __name(isSchedulePostTaskCallback, "isSchedulePostTaskCallback"); + __name(isRunPostTaskCallback, "isRunPostTaskCallback"); + __name(isAbortPostTaskCallback, "isAbortPostTaskCallback"); + __name(isJSInvocationEvent, "isJSInvocationEvent"); + __name(isConsoleRunTask, "isConsoleRunTask"); + __name(isFlowPhaseEvent, "isFlowPhaseEvent"); + __name(isParseAuthorStyleSheetEvent, "isParseAuthorStyleSheetEvent"); + (function(Name2) { + Name2["THREAD_NAME"] = "thread_name"; + Name2["PROGRAM"] = "Program"; + Name2["RUN_TASK"] = "RunTask"; + Name2["ASYNC_TASK"] = "AsyncTask"; + Name2["RUN_MICROTASKS"] = "RunMicrotasks"; + Name2["XHR_LOAD"] = "XHRLoad"; + Name2["XHR_READY_STATE_CHANGED"] = "XHRReadyStateChange"; + Name2["PARSE_HTML"] = "ParseHTML"; + Name2["PARSE_CSS"] = "ParseAuthorStyleSheet"; + Name2["COMPILE_CODE"] = "V8.CompileCode"; + Name2["COMPILE_MODULE"] = "V8.CompileModule"; + Name2["COMPILE"] = "v8.compile"; + Name2["COMPILE_SCRIPT"] = "V8.CompileScript"; + Name2["OPTIMIZE"] = "V8.OptimizeCode"; + Name2["WASM_STREAM_FROM_RESPONSE_CALLBACK"] = "v8.wasm.streamFromResponseCallback"; + Name2["WASM_COMPILED_MODULE"] = "v8.wasm.compiledModule"; + Name2["WASM_CACHED_MODULE"] = "v8.wasm.cachedModule"; + Name2["WASM_MODULE_CACHE_HIT"] = "v8.wasm.moduleCacheHit"; + Name2["WASM_MODULE_CACHE_INVALID"] = "v8.wasm.moduleCacheInvalid"; + Name2["PROFILE_CALL"] = "ProfileCall"; + Name2["EVALUATE_SCRIPT"] = "EvaluateScript"; + Name2["FUNCTION_CALL"] = "FunctionCall"; + Name2["EVENT_DISPATCH"] = "EventDispatch"; + Name2["EVALUATE_MODULE"] = "v8.evaluateModule"; + Name2["REQUEST_MAIN_THREAD_FRAME"] = "RequestMainThreadFrame"; + Name2["REQUEST_ANIMATION_FRAME"] = "RequestAnimationFrame"; + Name2["CANCEL_ANIMATION_FRAME"] = "CancelAnimationFrame"; + Name2["FIRE_ANIMATION_FRAME"] = "FireAnimationFrame"; + Name2["REQUEST_IDLE_CALLBACK"] = "RequestIdleCallback"; + Name2["CANCEL_IDLE_CALLBACK"] = "CancelIdleCallback"; + Name2["FIRE_IDLE_CALLBACK"] = "FireIdleCallback"; + Name2["TIMER_INSTALL"] = "TimerInstall"; + Name2["TIMER_REMOVE"] = "TimerRemove"; + Name2["TIMER_FIRE"] = "TimerFire"; + Name2["WEB_SOCKET_CREATE"] = "WebSocketCreate"; + Name2["WEB_SOCKET_SEND_HANDSHAKE"] = "WebSocketSendHandshakeRequest"; + Name2["WEB_SOCKET_RECEIVE_HANDSHAKE"] = "WebSocketReceiveHandshakeResponse"; + Name2["WEB_SOCKET_DESTROY"] = "WebSocketDestroy"; + Name2["WEB_SOCKET_SEND"] = "WebSocketSend"; + Name2["WEB_SOCKET_RECEIVE"] = "WebSocketReceive"; + Name2["CRYPTO_DO_ENCRYPT"] = "DoEncrypt"; + Name2["CRYPTO_DO_ENCRYPT_REPLY"] = "DoEncryptReply"; + Name2["CRYPTO_DO_DECRYPT"] = "DoDecrypt"; + Name2["CRYPTO_DO_DECRYPT_REPLY"] = "DoDecryptReply"; + Name2["CRYPTO_DO_DIGEST"] = "DoDigest"; + Name2["CRYPTO_DO_DIGEST_REPLY"] = "DoDigestReply"; + Name2["CRYPTO_DO_SIGN"] = "DoSign"; + Name2["CRYPTO_DO_SIGN_REPLY"] = "DoSignReply"; + Name2["CRYPTO_DO_VERIFY"] = "DoVerify"; + Name2["CRYPTO_DO_VERIFY_REPLY"] = "DoVerifyReply"; + Name2["V8_EXECUTE"] = "V8.Execute"; + Name2["V8_CONSOLE_RUN_TASK"] = "V8Console::runTask"; + Name2["SCHEDULE_POST_TASK_CALLBACK"] = "SchedulePostTaskCallback"; + Name2["RUN_POST_TASK_CALLBACK"] = "RunPostTaskCallback"; + Name2["ABORT_POST_TASK_CALLBACK"] = "AbortPostTaskCallback"; + Name2["DEBUGGER_ASYNC_TASK_RUN"] = "v8::Debugger::AsyncTaskRun"; + Name2["DEBUGGER_ASYNC_TASK_SCHEDULED"] = "v8::Debugger::AsyncTaskScheduled"; + Name2["GC"] = "GCEvent"; + Name2["DOMGC"] = "BlinkGC.AtomicPhase"; + Name2["MAJOR_GC"] = "MajorGC"; + Name2["MINOR_GC"] = "MinorGC"; + Name2["GC_COLLECT_GARBARGE"] = "BlinkGC.AtomicPhase"; + Name2["CPPGC_SWEEP"] = "CppGC.IncrementalSweep"; + Name2["SCHEDULE_STYLE_RECALCULATION"] = "ScheduleStyleRecalculation"; + Name2["LAYOUT"] = "Layout"; + Name2["RECALC_STYLE"] = "UpdateLayoutTree"; + Name2["INVALIDATE_LAYOUT"] = "InvalidateLayout"; + Name2["LAYOUT_INVALIDATION_TRACKING"] = "LayoutInvalidationTracking"; + Name2["COMPUTE_INTERSECTION"] = "ComputeIntersections"; + Name2["HIT_TEST"] = "HitTest"; + Name2["PRE_PAINT"] = "PrePaint"; + Name2["LAYERIZE"] = "Layerize"; + Name2["LAYOUT_SHIFT"] = "LayoutShift"; + Name2["SYNTHETIC_LAYOUT_SHIFT"] = "SyntheticLayoutShift"; + Name2["SYNTHETIC_LAYOUT_SHIFT_CLUSTER"] = "SyntheticLayoutShiftCluster"; + Name2["UPDATE_LAYER_TREE"] = "UpdateLayerTree"; + Name2["SCHEDULE_STYLE_INVALIDATION_TRACKING"] = "ScheduleStyleInvalidationTracking"; + Name2["STYLE_RECALC_INVALIDATION_TRACKING"] = "StyleRecalcInvalidationTracking"; + Name2["STYLE_INVALIDATOR_INVALIDATION_TRACKING"] = "StyleInvalidatorInvalidationTracking"; + Name2["SELECTOR_STATS"] = "SelectorStats"; + Name2["BEGIN_COMMIT_COMPOSITOR_FRAME"] = "BeginCommitCompositorFrame"; + Name2["PARSE_META_VIEWPORT"] = "ParseMetaViewport"; + Name2["SCROLL_LAYER"] = "ScrollLayer"; + Name2["UPDATE_LAYER"] = "UpdateLayer"; + Name2["PAINT_SETUP"] = "PaintSetup"; + Name2["PAINT"] = "Paint"; + Name2["PAINT_IMAGE"] = "PaintImage"; + Name2["COMMIT"] = "Commit"; + Name2["COMPOSITE_LAYERS"] = "CompositeLayers"; + Name2["RASTER_TASK"] = "RasterTask"; + Name2["IMAGE_DECODE_TASK"] = "ImageDecodeTask"; + Name2["IMAGE_UPLOAD_TASK"] = "ImageUploadTask"; + Name2["DECODE_IMAGE"] = "Decode Image"; + Name2["DRAW_LAZY_PIXEL_REF"] = "Draw LazyPixelRef"; + Name2["DECODE_LAZY_PIXEL_REF"] = "Decode LazyPixelRef"; + Name2["GPU_TASK"] = "GPUTask"; + Name2["RASTERIZE"] = "Rasterize"; + Name2["EVENT_TIMING"] = "EventTiming"; + Name2["OPTIMIZE_CODE"] = "V8.OptimizeCode"; + Name2["CACHE_SCRIPT"] = "v8.produceCache"; + Name2["CACHE_MODULE"] = "v8.produceModuleCache"; + Name2["V8_SAMPLE"] = "V8Sample"; + Name2["JIT_CODE_ADDED"] = "JitCodeAdded"; + Name2["JIT_CODE_MOVED"] = "JitCodeMoved"; + Name2["STREAMING_COMPILE_SCRIPT"] = "v8.parseOnBackground"; + Name2["STREAMING_COMPILE_SCRIPT_WAITING"] = "v8.parseOnBackgroundWaiting"; + Name2["STREAMING_COMPILE_SCRIPT_PARSING"] = "v8.parseOnBackgroundParsing"; + Name2["BACKGROUND_DESERIALIZE"] = "v8.deserializeOnBackground"; + Name2["FINALIZE_DESERIALIZATION"] = "V8.FinalizeDeserialization"; + Name2["COMMIT_LOAD"] = "CommitLoad"; + Name2["MARK_LOAD"] = "MarkLoad"; + Name2["MARK_DOM_CONTENT"] = "MarkDOMContent"; + Name2["MARK_FIRST_PAINT"] = "firstPaint"; + Name2["MARK_FCP"] = "firstContentfulPaint"; + Name2["MARK_LCP_CANDIDATE"] = "largestContentfulPaint::Candidate"; + Name2["MARK_LCP_INVALIDATE"] = "largestContentfulPaint::Invalidate"; + Name2["NAVIGATION_START"] = "navigationStart"; + Name2["CONSOLE_TIME"] = "ConsoleTime"; + Name2["USER_TIMING"] = "UserTiming"; + Name2["INTERACTIVE_TIME"] = "InteractiveTime"; + Name2["TIME_STAMP"] = "TimeStamp"; + Name2["BEGIN_FRAME"] = "BeginFrame"; + Name2["NEEDS_BEGIN_FRAME_CHANGED"] = "NeedsBeginFrameChanged"; + Name2["BEGIN_MAIN_THREAD_FRAME"] = "BeginMainThreadFrame"; + Name2["ACTIVATE_LAYER_TREE"] = "ActivateLayerTree"; + Name2["DRAW_FRAME"] = "DrawFrame"; + Name2["DROPPED_FRAME"] = "DroppedFrame"; + Name2["FRAME_STARTED_LOADING"] = "FrameStartedLoading"; + Name2["PIPELINE_REPORTER"] = "PipelineReporter"; + Name2["SCREENSHOT"] = "Screenshot"; + Name2["RESOURCE_WILL_SEND_REQUEST"] = "ResourceWillSendRequest"; + Name2["RESOURCE_SEND_REQUEST"] = "ResourceSendRequest"; + Name2["RESOURCE_RECEIVE_RESPONSE"] = "ResourceReceiveResponse"; + Name2["RESOURCE_RECEIVE_DATA"] = "ResourceReceivedData"; + Name2["RESOURCE_FINISH"] = "ResourceFinish"; + Name2["RESOURCE_MARK_AS_CACHED"] = "ResourceMarkAsCached"; + Name2["WEB_SOCKET_SEND_HANDSHAKE_REQUEST"] = "WebSocketSendHandshakeRequest"; + Name2["WEB_SOCKET_RECEIVE_HANDSHAKE_REQUEST"] = "WebSocketReceiveHandshakeResponse"; + Name2["CPU_PROFILE"] = "CpuProfile"; + Name2["PROFILE"] = "Profile"; + Name2["START_PROFILING"] = "CpuProfiler::StartProfiling"; + Name2["PROFILE_CHUNK"] = "ProfileChunk"; + Name2["UPDATE_COUNTERS"] = "UpdateCounters"; + Name2["JS_SAMPLE"] = "JSSample"; + Name2["ANIMATION"] = "Animation"; + Name2["PARSE_AUTHOR_STYLE_SHEET"] = "ParseAuthorStyleSheet"; + Name2["EMBEDDER_CALLBACK"] = "EmbedderCallback"; + Name2["SET_LAYER_TREE_ID"] = "SetLayerTreeId"; + Name2["TRACING_STARTED_IN_PAGE"] = "TracingStartedInPage"; + Name2["TRACING_STARTED_IN_BROWSER"] = "TracingStartedInBrowser"; + Name2["TRACING_SESSION_ID_FOR_WORKER"] = "TracingSessionIdForWorker"; + Name2["LAZY_PIXEL_REF"] = "LazyPixelRef"; + Name2["LAYER_TREE_HOST_IMPL_SNAPSHOT"] = "cc::LayerTreeHostImpl"; + Name2["PICTURE_SNAPSHOT"] = "cc::Picture"; + Name2["DISPLAY_ITEM_LIST_SNAPSHOT"] = "cc::DisplayItemList"; + Name2["INPUT_LATENCY_MOUSE_MOVE"] = "InputLatency::MouseMove"; + Name2["INPUT_LATENCY_MOUSE_WHEEL"] = "InputLatency::MouseWheel"; + Name2["IMPL_SIDE_FLING"] = "InputHandlerProxy::HandleGestureFling::started"; + Name2["SCHEDULE_POST_MESSAGE"] = "SchedulePostMessage"; + Name2["HANDLE_POST_MESSAGE"] = "HandlePostMessage"; + Name2["RENDER_FRAME_IMPL_CREATE_CHILD_FRAME"] = "RenderFrameImpl::createChildFrame"; + Name2["LAYOUT_IMAGE_UNSIZED"] = "LayoutImageUnsized"; + Name2["DOM_LOADING"] = "domLoading"; + Name2["BEGIN_REMOTE_FONT_LOAD"] = "BeginRemoteFontLoad"; + Name2["REMOTE_FONT_LOADED"] = "RemoteFontLoaded"; + Name2["ANIMATION_FRAME"] = "AnimationFrame"; + Name2["ANIMATION_FRAME_PRESENTATION"] = "AnimationFrame::Presentation"; + Name2["SYNTHETIC_NETWORK_REQUEST"] = "SyntheticNetworkRequest"; + Name2["USER_TIMING_MEASURE"] = "UserTiming::Measure"; + Name2["LINK_PRECONNECT"] = "LinkPreconnect"; + })(Name || (Name = {})); + Categories = { + Console: "blink.console", + UserTiming: "blink.user_timing", + Loading: "loading" + }; + __name(isLegacyTimelineFrame, "isLegacyTimelineFrame"); + __name(isRundownScriptCompiled, "isRundownScriptCompiled"); + __name(isRundownScript, "isRundownScript"); + __name(isRundownScriptSource, "isRundownScriptSource"); + __name(isRundownScriptSourceLarge, "isRundownScriptSourceLarge"); + __name(isAnyScriptSourceEvent, "isAnyScriptSourceEvent"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/types/types.js +var init_types2 = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/types/types.js"() { + init_process_global(); + init_Configuration(); + init_Extensions(); + init_File(); + init_Overlays(); + init_Timing(); + init_TraceEvents(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/helpers.js +var helpers_exports = {}; +__export(helpers_exports, { + addEventToEntityMapping: () => addEventToEntityMapping, + addNetworkRequestToEntityMapping: () => addNetworkRequestToEntityMapping, + getEntityForEvent: () => getEntityForEvent, + getEntityForUrl: () => getEntityForUrl, + getNonResolvedURL: () => getNonResolvedURL, + makeUpEntity: () => makeUpEntity +}); +function getEntityForEvent(event, entityMappings3) { + const url = getNonResolvedURL(event); + if (!url) { + return; + } + return getEntityForUrl(url, entityMappings3); +} +function getEntityForUrl(url, entityMappings3) { + const cachedByUrl = entityMappings3.entityByUrlCache.get(url); + if (cachedByUrl) { + return cachedByUrl; + } + const entity = import_third_party_web.default.getEntity(url) ?? makeUpEntity(entityMappings3.createdEntityCache, url); + if (entity) { + entityMappings3.entityByUrlCache.set(url, entity); + } + return entity; +} +function getNonResolvedURL(entry, handlerData) { + if (TraceEvents_exports.isProfileCall(entry)) { + return entry.callFrame.url; + } + if (TraceEvents_exports.isSyntheticNetworkRequest(entry)) { + return entry.args.data.url; + } + if (TraceEvents_exports.isParseAuthorStyleSheetEvent(entry) && entry.args) { + return entry.args.data.stylesheetUrl; + } + if (entry.args?.data?.stackTrace && entry.args.data.stackTrace.length > 0) { + return entry.args.data.stackTrace[0].url; + } + if (TraceEvents_exports.isParseHTML(entry)) { + return entry.args.beginData.url; + } + if (handlerData) { + if (TraceEvents_exports.isDecodeImage(entry)) { + const paintEvent = handlerData.ImagePainting.paintImageForEvent.get(entry); + return paintEvent ? getNonResolvedURL(paintEvent, handlerData) : null; + } + if (TraceEvents_exports.isDrawLazyPixelRef(entry) && entry.args?.LazyPixelRef) { + const paintEvent = handlerData.ImagePainting.paintImageByDrawLazyPixelRef.get(entry.args.LazyPixelRef); + return paintEvent ? getNonResolvedURL(paintEvent, handlerData) : null; + } + } + if (entry.args?.data?.url) { + return entry.args.data.url; + } + const requestId = entry.args?.data?.requestId; + if (handlerData && requestId) { + const url = handlerData.NetworkRequests.byId.get(requestId)?.args.data.url; + if (url) { + return url; + } + } + return null; +} +function makeUpEntity(entityCache, url) { + if (url.startsWith("chrome-extension:")) { + return makeUpChromeExtensionEntity(entityCache, url); + } + if (!url.startsWith("http")) { + return; + } + const rootDomain = import_third_party_web.default.getRootDomain(url); + if (!rootDomain) { + return; + } + if (entityCache.has(rootDomain)) { + return entityCache.get(rootDomain); + } + const unrecognizedEntity = { + name: rootDomain, + company: rootDomain, + category: "", + categories: [], + domains: [rootDomain], + averageExecutionTime: 0, + totalExecutionTime: 0, + totalOccurrences: 0, + isUnrecognized: true + }; + entityCache.set(rootDomain, unrecognizedEntity); + return unrecognizedEntity; +} +function getChromeExtensionOrigin(url) { + return url.protocol + "//" + url.host; +} +function makeUpChromeExtensionEntity(entityCache, url, extensionName) { + const parsedUrl = new URL(url); + const origin = getChromeExtensionOrigin(parsedUrl); + const host = new URL(origin).host; + const name = extensionName || host; + const cachedEntity = entityCache.get(origin); + if (cachedEntity) { + return cachedEntity; + } + const chromeExtensionEntity = { + name, + company: name, + category: "Chrome Extension", + homepage: "https://chromewebstore.google.com/detail/" + host, + categories: [], + domains: [origin], + averageExecutionTime: 0, + totalExecutionTime: 0, + totalOccurrences: 0 + }; + entityCache.set(origin, chromeExtensionEntity); + return chromeExtensionEntity; +} +function addEventToEntityMapping(event, entityMappings3) { + if (entityMappings3.entityByEvent.has(event)) { + return; + } + const entity = getEntityForEvent(event, entityMappings3); + if (!entity) { + return; + } + const mappedEvents = entityMappings3.eventsByEntity.get(entity); + if (mappedEvents) { + mappedEvents.push(event); + } else { + entityMappings3.eventsByEntity.set(entity, [event]); + } + entityMappings3.entityByEvent.set(event, entity); +} +function addNetworkRequestToEntityMapping(networkRequest, entityMappings3, requestTraceEvents) { + const entity = getEntityForEvent(networkRequest, entityMappings3); + if (!entity) { + return; + } + const eventsToMap = [networkRequest, ...Object.values(requestTraceEvents).flat()]; + const mappedEvents = entityMappings3.eventsByEntity.get(entity); + if (mappedEvents) { + mappedEvents.push(...eventsToMap); + } else { + entityMappings3.eventsByEntity.set(entity, eventsToMap); + } + for (const evt of eventsToMap) { + entityMappings3.entityByEvent.set(evt, entity); + } +} +var init_helpers = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/helpers.js"() { + init_process_global(); + init_third_party_web(); + init_types2(); + __name(getEntityForEvent, "getEntityForEvent"); + __name(getEntityForUrl, "getEntityForUrl"); + __name(getNonResolvedURL, "getNonResolvedURL"); + __name(makeUpEntity, "makeUpEntity"); + __name(getChromeExtensionOrigin, "getChromeExtensionOrigin"); + __name(makeUpChromeExtensionEntity, "makeUpChromeExtensionEntity"); + __name(addEventToEntityMapping, "addEventToEntityMapping"); + __name(addNetworkRequestToEntityMapping, "addNetworkRequestToEntityMapping"); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/ArrayUtilities.js +var ArrayUtilities_exports = {}; +__export(ArrayUtilities_exports, { + DEFAULT_COMPARATOR: () => DEFAULT_COMPARATOR, + arrayDoesNotContainNullOrUndefined: () => arrayDoesNotContainNullOrUndefined, + binaryIndexOf: () => binaryIndexOf, + intersectOrdered: () => intersectOrdered, + lowerBound: () => lowerBound, + mergeOrdered: () => mergeOrdered, + nearestIndexFromBeginning: () => nearestIndexFromBeginning, + nearestIndexFromEnd: () => nearestIndexFromEnd, + removeElement: () => removeElement, + sortRange: () => sortRange, + upperBound: () => upperBound +}); +function swap(array, i1, i2) { + const temp = array[i1]; + array[i1] = array[i2]; + array[i2] = temp; +} +function partition(array, comparator, left, right, pivotIndex) { + const pivotValue = array[pivotIndex]; + swap(array, right, pivotIndex); + let storeIndex = left; + for (let i = left; i < right; ++i) { + if (comparator(array[i], pivotValue) < 0) { + swap(array, storeIndex, i); + ++storeIndex; + } + } + swap(array, right, storeIndex); + return storeIndex; +} +function quickSortRange(array, comparator, left, right, sortWindowLeft, sortWindowRight) { + if (right <= left) { + return; + } + const pivotIndex = Math.floor(Math.random() * (right - left)) + left; + const pivotNewIndex = partition(array, comparator, left, right, pivotIndex); + if (sortWindowLeft < pivotNewIndex) { + quickSortRange(array, comparator, left, pivotNewIndex - 1, sortWindowLeft, sortWindowRight); + } + if (pivotNewIndex < sortWindowRight) { + quickSortRange(array, comparator, pivotNewIndex + 1, right, sortWindowLeft, sortWindowRight); + } +} +function sortRange(array, comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight) { + if (leftBound === 0 && rightBound === array.length - 1 && sortWindowLeft === 0 && sortWindowRight >= rightBound) { + array.sort(comparator); + } else { + quickSortRange(array, comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight); + } + return array; +} +function mergeOrIntersect(array1, array2, comparator, mergeNotIntersect) { + const result = []; + let i = 0; + let j = 0; + while (i < array1.length && j < array2.length) { + const compareValue = comparator(array1[i], array2[j]); + if (mergeNotIntersect || !compareValue) { + result.push(compareValue <= 0 ? array1[i] : array2[j]); + } + if (compareValue <= 0) { + i++; + } + if (compareValue >= 0) { + j++; + } + } + if (mergeNotIntersect) { + while (i < array1.length) { + result.push(array1[i++]); + } + while (j < array2.length) { + result.push(array2[j++]); + } + } + return result; +} +function lowerBound(array, needle, comparator, left, right) { + let l = left || 0; + let r = right !== void 0 ? right : array.length; + while (l < r) { + const m = l + r >> 1; + if (comparator(needle, array[m]) > 0) { + l = m + 1; + } else { + r = m; + } + } + return r; +} +function upperBound(array, needle, comparator, left, right) { + let l = left || 0; + let r = right !== void 0 ? right : array.length; + while (l < r) { + const m = l + r >> 1; + if (comparator(needle, array[m]) >= 0) { + l = m + 1; + } else { + r = m; + } + } + return r; +} +function nearestIndex(arr, predicate, searchStart) { + const searchFromEnd = searchStart === "END"; + if (arr.length === 0) { + return null; + } + let left = 0; + let right = arr.length - 1; + let pivot = 0; + let matchesPredicate = false; + let moveToTheRight = false; + let middle = 0; + do { + middle = left + (right - left) / 2; + pivot = searchFromEnd ? Math.ceil(middle) : Math.floor(middle); + matchesPredicate = predicate(arr[pivot]); + moveToTheRight = matchesPredicate === searchFromEnd; + if (moveToTheRight) { + left = Math.min(right, pivot + (left === pivot ? 1 : 0)); + } else { + right = Math.max(left, pivot + (right === pivot ? -1 : 0)); + } + } while (right !== left); + if (!predicate(arr[left])) { + return null; + } + return left; +} +function nearestIndexFromBeginning(arr, predicate) { + return nearestIndex( + arr, + predicate, + "BEGINNING" + /* NearestSearchStart.BEGINNING */ + ); +} +function nearestIndexFromEnd(arr, predicate) { + return nearestIndex( + arr, + predicate, + "END" + /* NearestSearchStart.END */ + ); +} +function arrayDoesNotContainNullOrUndefined(arr) { + return !arr.includes(null) && !arr.includes(void 0); +} +var removeElement, binaryIndexOf, intersectOrdered, mergeOrdered, DEFAULT_COMPARATOR; +var init_ArrayUtilities = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/ArrayUtilities.js"() { + init_process_global(); + removeElement = /* @__PURE__ */ __name((array, element, firstOnly) => { + let index = array.indexOf(element); + if (index === -1) { + return false; + } + if (firstOnly) { + array.splice(index, 1); + return true; + } + for (let i = index + 1, n = array.length; i < n; ++i) { + if (array[i] !== element) { + array[index++] = array[i]; + } + } + array.length = index; + return true; + }, "removeElement"); + __name(swap, "swap"); + __name(partition, "partition"); + __name(quickSortRange, "quickSortRange"); + __name(sortRange, "sortRange"); + binaryIndexOf = /* @__PURE__ */ __name((array, value, comparator) => { + const index = lowerBound(array, value, comparator); + return index < array.length && comparator(value, array[index]) === 0 ? index : -1; + }, "binaryIndexOf"); + __name(mergeOrIntersect, "mergeOrIntersect"); + intersectOrdered = /* @__PURE__ */ __name((array1, array2, comparator) => { + return mergeOrIntersect(array1, array2, comparator, false); + }, "intersectOrdered"); + mergeOrdered = /* @__PURE__ */ __name((array1, array2, comparator) => { + return mergeOrIntersect(array1, array2, comparator, true); + }, "mergeOrdered"); + DEFAULT_COMPARATOR = /* @__PURE__ */ __name((a, b) => { + return a < b ? -1 : a > b ? 1 : 0; + }, "DEFAULT_COMPARATOR"); + __name(lowerBound, "lowerBound"); + __name(upperBound, "upperBound"); + __name(nearestIndex, "nearestIndex"); + __name(nearestIndexFromBeginning, "nearestIndexFromBeginning"); + __name(nearestIndexFromEnd, "nearestIndexFromEnd"); + __name(arrayDoesNotContainNullOrUndefined, "arrayDoesNotContainNullOrUndefined"); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/Brand.js +var init_Brand = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/Brand.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/Constructor.js +var init_Constructor = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/Constructor.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/DateUtilities.js +var init_DateUtilities = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/DateUtilities.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/DevToolsPath.js +var init_DevToolsPath = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/DevToolsPath.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/DOMUtilities.js +var init_DOMUtilities = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/DOMUtilities.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/KeyboardUtilities.js +var init_KeyboardUtilities = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/KeyboardUtilities.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/MapUtilities.js +var MapUtilities_exports = {}; +__export(MapUtilities_exports, { + Multimap: () => Multimap, + getWithDefault: () => getWithDefault, + inverse: () => inverse +}); +function getWithDefault(map, key, defaultValueFactory) { + let value = map.get(key); + if (value === void 0 || value === null) { + value = defaultValueFactory(key); + map.set(key, value); + } + return value; +} +var inverse, Multimap; +var init_MapUtilities = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/MapUtilities.js"() { + init_process_global(); + inverse = /* @__PURE__ */ __name(function(map) { + const result = new Multimap(); + for (const [key, value] of map.entries()) { + result.set(value, key); + } + return result; + }, "inverse"); + Multimap = class { + static { + __name(this, "Multimap"); + } + map = /* @__PURE__ */ new Map(); + set(key, value) { + let set = this.map.get(key); + if (!set) { + set = /* @__PURE__ */ new Set(); + this.map.set(key, set); + } + set.add(value); + } + get(key) { + return this.map.get(key) || /* @__PURE__ */ new Set(); + } + has(key) { + return this.map.has(key); + } + hasValue(key, value) { + const set = this.map.get(key); + if (!set) { + return false; + } + return set.has(value); + } + get size() { + return this.map.size; + } + delete(key, value) { + const values = this.get(key); + if (!values) { + return false; + } + const result = values.delete(value); + if (!values.size) { + this.map.delete(key); + } + return result; + } + deleteAll(key) { + this.map.delete(key); + } + keysArray() { + return [...this.map.keys()]; + } + keys() { + return this.map.keys(); + } + valuesArray() { + const result = []; + for (const set of this.map.values()) { + result.push(...set.values()); + } + return result; + } + clear() { + this.map.clear(); + } + }; + __name(getWithDefault, "getWithDefault"); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/MimeType.js +var init_MimeType = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/MimeType.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/NumberUtilities.js +var NumberUtilities_exports = {}; +__export(NumberUtilities_exports, { + aspectRatio: () => aspectRatio, + clamp: () => clamp, + floor: () => floor, + greatestCommonDivisor: () => greatestCommonDivisor, + mod: () => mod, + toFixedIfFloating: () => toFixedIfFloating, + withThousandsSeparator: () => withThousandsSeparator +}); +var clamp, mod, toFixedIfFloating, floor, greatestCommonDivisor, commonRatios, aspectRatio, withThousandsSeparator; +var init_NumberUtilities = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/NumberUtilities.js"() { + init_process_global(); + clamp = /* @__PURE__ */ __name((num, min, max) => { + let clampedNumber = num; + if (num < min) { + clampedNumber = min; + } else if (num > max) { + clampedNumber = max; + } + return clampedNumber; + }, "clamp"); + mod = /* @__PURE__ */ __name((m, n) => { + return (m % n + n) % n; + }, "mod"); + toFixedIfFloating = /* @__PURE__ */ __name((value) => { + if (!value || Number.isNaN(Number(value))) { + return value; + } + const number = Number(value); + return number % 1 ? number.toFixed(3) : String(number); + }, "toFixedIfFloating"); + floor = /* @__PURE__ */ __name((value, precision = 0) => { + if (precision > 0 && precision < 1) { + precision = 1 / precision; + return Math.floor(value / precision) * precision; + } + const mult = Math.pow(10, precision); + return Math.floor(value * mult) / mult; + }, "floor"); + greatestCommonDivisor = /* @__PURE__ */ __name((a, b) => { + a = Math.round(a); + b = Math.round(b); + while (b !== 0) { + const t = b; + b = a % b; + a = t; + } + return a; + }, "greatestCommonDivisor"); + commonRatios = /* @__PURE__ */ new Map([ + ["8∶5", "16∶10"] + ]); + aspectRatio = /* @__PURE__ */ __name((width, height) => { + const divisor = greatestCommonDivisor(width, height); + if (divisor !== 0) { + width /= divisor; + height /= divisor; + } + const result = `${width}∶${height}`; + return commonRatios.get(result) || result; + }, "aspectRatio"); + withThousandsSeparator = /* @__PURE__ */ __name(function(num) { + let str = String(num); + const re = /(\d+)(\d{3})/; + while (str.match(re)) { + str = str.replace(re, "$1 $2"); + } + return str; + }, "withThousandsSeparator"); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/StringUtilities.js +var init_StringUtilities = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/StringUtilities.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/Timing.js +var init_Timing2 = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/Timing.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/TypedArrayUtilities.js +var init_TypedArrayUtilities = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/TypedArrayUtilities.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/TypescriptUtilities.js +var TypescriptUtilities_exports = {}; +__export(TypescriptUtilities_exports, { + assertNever: () => assertNever, + assertNotNullOrUndefined: () => assertNotNullOrUndefined, + assertUnhandled: () => assertUnhandled +}); +function assertNotNullOrUndefined(val, message) { + if (val === null || val === void 0) { + throw new Error(`Expected given value to not be null/undefined but it was: ${val}${message ? ` +${message}` : ""}`); + } +} +function assertNever(_type, message) { + throw new Error(message); +} +function assertUnhandled(_caseVariable) { + return _caseVariable; +} +var init_TypescriptUtilities = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/TypescriptUtilities.js"() { + init_process_global(); + __name(assertNotNullOrUndefined, "assertNotNullOrUndefined"); + __name(assertNever, "assertNever"); + __name(assertUnhandled, "assertUnhandled"); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/UIString.js +var init_UIString = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/UIString.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/UserVisibleError.js +var init_UserVisibleError = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/UserVisibleError.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/core/platform/platform.js +var init_platform = __esm({ + "node_modules/@paulirish/trace_engine/core/platform/platform.js"() { + init_process_global(); + init_ArrayUtilities(); + init_Brand(); + init_Constructor(); + init_DateUtilities(); + init_DevToolsPath(); + init_DOMUtilities(); + init_KeyboardUtilities(); + init_MapUtilities(); + init_MimeType(); + init_NumberUtilities(); + init_StringUtilities(); + init_Timing2(); + init_TypedArrayUtilities(); + init_TypescriptUtilities(); + init_UIString(); + init_UserVisibleError(); + init_TypescriptUtilities(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/helpers/SyntheticEvents.js +var SyntheticEvents_exports = {}; +__export(SyntheticEvents_exports, { + SyntheticEventsManager: () => SyntheticEventsManager +}); +var activeManager, SyntheticEventsManager; +var init_SyntheticEvents = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/helpers/SyntheticEvents.js"() { + init_process_global(); + activeManager = null; + SyntheticEventsManager = class _SyntheticEventsManager { + static { + __name(this, "SyntheticEventsManager"); + } + /** + * All synthetic entries created in a trace from a corresponding trace events. + * (ProfileCalls are excluded because they are not based on a real trace event) + */ + #syntheticTraces = []; + /** + * All raw entries from a trace. + */ + #rawTraceEvents = []; + static activate(manager) { + activeManager = manager; + } + static createAndActivate(rawEvents) { + const manager = new _SyntheticEventsManager(rawEvents); + _SyntheticEventsManager.activate(manager); + return manager; + } + static getActiveManager() { + if (!activeManager) { + throw new Error("Attempted to get a SyntheticEventsManager without initializing"); + } + return activeManager; + } + static reset() { + activeManager = null; + } + static registerSyntheticEvent(syntheticEvent) { + try { + return _SyntheticEventsManager.getActiveManager().#registerSyntheticEvent(syntheticEvent); + } catch { + return syntheticEvent; + } + } + constructor(rawEvents) { + this.#rawTraceEvents = rawEvents; + } + /** + * Registers and returns a branded synthetic event. Synthetic events need to + * be created with this method to ensure they are registered and made + * available to load events using serialized keys. + */ + #registerSyntheticEvent(syntheticEvent) { + const rawIndex = this.#rawTraceEvents.indexOf(syntheticEvent.rawSourceEvent); + if (rawIndex < 0) { + throw new Error("Attempted to register a synthetic event paired to an unknown raw event."); + } + const eventAsSynthetic = syntheticEvent; + this.#syntheticTraces[rawIndex] = eventAsSynthetic; + return eventAsSynthetic; + } + syntheticEventForRawEventIndex(rawEventIndex) { + const syntheticEvent = this.#syntheticTraces.at(rawEventIndex); + if (!syntheticEvent) { + throw new Error(`Attempted to get a synthetic event from an unknown raw event index: ${rawEventIndex}`); + } + return syntheticEvent; + } + getSyntheticTraces() { + return this.#syntheticTraces; + } + getRawTraceEvents() { + return this.#rawTraceEvents; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/helpers/Timing.js +var Timing_exports3 = {}; +__export(Timing_exports3, { + boundsIncludeTimeRange: () => boundsIncludeTimeRange, + combineTraceWindowsMicro: () => combineTraceWindowsMicro, + eventIsInBounds: () => eventIsInBounds, + eventTimingsMicroSeconds: () => eventTimingsMicroSeconds, + eventTimingsMilliSeconds: () => eventTimingsMilliSeconds, + expandWindowByPercentOrToOneMillisecond: () => expandWindowByPercentOrToOneMillisecond, + microToMilli: () => microToMilli, + microToSeconds: () => microToSeconds, + milliToMicro: () => milliToMicro, + secondsToMicro: () => secondsToMicro, + secondsToMilli: () => secondsToMilli, + timeStampForEventAdjustedByClosestNavigation: () => timeStampForEventAdjustedByClosestNavigation, + timestampIsInBounds: () => timestampIsInBounds, + traceWindowFromEvent: () => traceWindowFromEvent, + traceWindowFromMicroSeconds: () => traceWindowFromMicroSeconds, + traceWindowFromMilliSeconds: () => traceWindowFromMilliSeconds, + traceWindowFromOverlay: () => traceWindowFromOverlay, + traceWindowMicroSecondsToMilliSeconds: () => traceWindowMicroSecondsToMilliSeconds, + traceWindowMilliSeconds: () => traceWindowMilliSeconds, + windowFitsInsideBounds: () => windowFitsInsideBounds, + windowsEqual: () => windowsEqual +}); +function timeStampForEventAdjustedByClosestNavigation(event, traceBounds2, navigationsByNavigationId2, navigationsByFrameId2) { + let eventTimeStamp = event.ts - traceBounds2.min; + if (event.args?.data?.navigationId) { + const navigationForEvent = navigationsByNavigationId2.get(event.args.data.navigationId); + if (navigationForEvent) { + eventTimeStamp = event.ts - navigationForEvent.ts; + } + } else if (event.args?.data?.frame) { + const navigationForEvent = getNavigationForTraceEvent(event, event.args.data.frame, navigationsByFrameId2); + if (navigationForEvent) { + eventTimeStamp = event.ts - navigationForEvent.ts; + } + } + return Timing_exports.Micro(eventTimeStamp); +} +function expandWindowByPercentOrToOneMillisecond(annotationWindow, maxTraceWindow, percentage) { + let newMin = annotationWindow.min - annotationWindow.range * (percentage / 100) / 2; + let newMax = annotationWindow.max + annotationWindow.range * (percentage / 100) / 2; + if (newMax - newMin < 1e3) { + const rangeMiddle = (annotationWindow.min + annotationWindow.max) / 2; + newMin = rangeMiddle - 500; + newMax = rangeMiddle + 500; + } + newMin = Math.max(newMin, maxTraceWindow.min); + newMax = Math.min(newMax, maxTraceWindow.max); + const expandedWindow = { + min: Timing_exports.Micro(newMin), + max: Timing_exports.Micro(newMax), + range: Timing_exports.Micro(newMax - newMin) + }; + return expandedWindow; +} +function eventTimingsMicroSeconds(event) { + return { + startTime: event.ts, + endTime: event.ts + (event.dur ?? 0), + duration: event.dur || 0 + }; +} +function eventTimingsMilliSeconds(event) { + return { + startTime: event.ts / 1e3, + endTime: (event.ts + (event.dur ?? 0)) / 1e3, + duration: (event.dur || 0) / 1e3 + }; +} +function traceWindowMilliSeconds(bounds) { + return { + min: microToMilli(bounds.min), + max: microToMilli(bounds.max), + range: microToMilli(bounds.range) + }; +} +function traceWindowMicroSecondsToMilliSeconds(bounds) { + return { + min: microToMilli(bounds.min), + max: microToMilli(bounds.max), + range: microToMilli(bounds.range) + }; +} +function traceWindowFromMilliSeconds(min, max) { + const traceWindow = { + min: milliToMicro(min), + max: milliToMicro(max), + range: Timing_exports.Micro(milliToMicro(max) - milliToMicro(min)) + }; + return traceWindow; +} +function traceWindowFromMicroSeconds(min, max) { + const traceWindow = { + min, + max, + range: max - min + }; + return traceWindow; +} +function traceWindowFromEvent(event) { + return { + min: event.ts, + max: event.ts + (event.dur ?? 0), + range: event.dur ?? 0 + }; +} +function traceWindowFromOverlay(overlay) { + switch (overlay.type) { + case "ENTRY_LABEL": + case "ENTRY_OUTLINE": + case "ENTRY_SELECTED": { + return traceWindowFromEvent(overlay.entry); + } + case "TIMESPAN_BREAKDOWN": { + const windows = overlay.sections.map((s) => s.bounds); + if (overlay.entry) { + windows.push(traceWindowFromEvent(overlay.entry)); + } + return combineTraceWindowsMicro(windows); + } + case "CANDY_STRIPED_TIME_RANGE": + case "TIME_RANGE": { + return structuredClone(overlay.bounds); + } + case "ENTRIES_LINK": { + const from = traceWindowFromEvent(overlay.entryFrom); + if (!overlay.entryTo) { + return from; + } + const to = traceWindowFromEvent(overlay.entryTo); + return combineTraceWindowsMicro([from, to]); + } + case "TIMESTAMP_MARKER": + return traceWindowFromMicroSeconds(overlay.timestamp, overlay.timestamp); + case "TIMINGS_MARKER": + return traceWindowFromMicroSeconds(overlay.adjustedTimestamp, overlay.adjustedTimestamp); + case "BOTTOM_INFO_BAR": + return null; + default: + TypescriptUtilities_exports.assertNever(overlay, `Unexpected overlay ${overlay}`); + } +} +function combineTraceWindowsMicro(windows) { + if (!windows.length) { + return null; + } + const result = structuredClone(windows[0]); + for (const bounds of windows.slice(1)) { + result.min = Math.min(result.min, bounds.min); + result.max = Math.max(result.max, bounds.max); + } + result.range = result.max - result.min; + return result; +} +function boundsIncludeTimeRange(data31) { + const { min: visibleMin, max: visibleMax } = data31.bounds; + const { min: rangeMin, max: rangeMax } = data31.timeRange; + return visibleMin <= rangeMax && visibleMax >= rangeMin; +} +function eventIsInBounds(event, bounds) { + const startTime = event.ts; + return startTime <= bounds.max && bounds.min < startTime + (event.dur ?? 0); +} +function timestampIsInBounds(bounds, timestamp) { + return timestamp >= bounds.min && timestamp <= bounds.max; +} +function windowFitsInsideBounds(data31) { + return data31.window.min >= data31.bounds.min && data31.window.max <= data31.bounds.max; +} +function windowsEqual(w1, w2) { + return w1.min === w2.min && w1.max === w2.max; +} +var milliToMicro, secondsToMilli, secondsToMicro, microToMilli, microToSeconds; +var init_Timing3 = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/helpers/Timing.js"() { + init_process_global(); + init_platform(); + init_types2(); + init_Trace(); + milliToMicro = /* @__PURE__ */ __name((value) => Timing_exports.Micro(value * 1e3), "milliToMicro"); + secondsToMilli = /* @__PURE__ */ __name((value) => Timing_exports.Milli(value * 1e3), "secondsToMilli"); + secondsToMicro = /* @__PURE__ */ __name((value) => milliToMicro(secondsToMilli(value)), "secondsToMicro"); + microToMilli = /* @__PURE__ */ __name((value) => Timing_exports.Milli(value / 1e3), "microToMilli"); + microToSeconds = /* @__PURE__ */ __name((value) => Timing_exports.Seconds(value / 1e3 / 1e3), "microToSeconds"); + __name(timeStampForEventAdjustedByClosestNavigation, "timeStampForEventAdjustedByClosestNavigation"); + __name(expandWindowByPercentOrToOneMillisecond, "expandWindowByPercentOrToOneMillisecond"); + __name(eventTimingsMicroSeconds, "eventTimingsMicroSeconds"); + __name(eventTimingsMilliSeconds, "eventTimingsMilliSeconds"); + __name(traceWindowMilliSeconds, "traceWindowMilliSeconds"); + __name(traceWindowMicroSecondsToMilliSeconds, "traceWindowMicroSecondsToMilliSeconds"); + __name(traceWindowFromMilliSeconds, "traceWindowFromMilliSeconds"); + __name(traceWindowFromMicroSeconds, "traceWindowFromMicroSeconds"); + __name(traceWindowFromEvent, "traceWindowFromEvent"); + __name(traceWindowFromOverlay, "traceWindowFromOverlay"); + __name(combineTraceWindowsMicro, "combineTraceWindowsMicro"); + __name(boundsIncludeTimeRange, "boundsIncludeTimeRange"); + __name(eventIsInBounds, "eventIsInBounds"); + __name(timestampIsInBounds, "timestampIsInBounds"); + __name(windowFitsInsideBounds, "windowFitsInsideBounds"); + __name(windowsEqual, "windowsEqual"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/helpers/Trace.js +var Trace_exports = {}; +__export(Trace_exports, { + VISIBLE_TRACE_EVENT_TYPES: () => VISIBLE_TRACE_EVENT_TYPES, + activeURLForFrameAtTime: () => activeURLForFrameAtTime, + addEventToProcessThread: () => addEventToProcessThread, + compareBeginAndEnd: () => compareBeginAndEnd, + createMatchedSortedSyntheticEvents: () => createMatchedSortedSyntheticEvents, + eventContainsTimestamp: () => eventContainsTimestamp, + eventHasCategory: () => eventHasCategory, + eventTimeComparator: () => eventTimeComparator, + extractId: () => extractId, + extractOriginFromTrace: () => extractOriginFromTrace, + extractSampleTraceId: () => extractSampleTraceId, + findNextEventAfterTimestamp: () => findNextEventAfterTimestamp, + findPreviousEventBeforeTimestamp: () => findPreviousEventBeforeTimestamp, + findRecalcStyleEvents: () => findRecalcStyleEvents, + forEachEvent: () => forEachEvent, + frameIDForEvent: () => frameIDForEvent, + getNavigationForTraceEvent: () => getNavigationForTraceEvent, + getStackTraceTopCallFrameInEventPayload: () => getStackTraceTopCallFrameInEventPayload, + getSyntheticId: () => getSyntheticId, + getZeroIndexedLineAndColumnForEvent: () => getZeroIndexedLineAndColumnForEvent, + getZeroIndexedStackTraceInEventPayload: () => getZeroIndexedStackTraceInEventPayload, + isExtensionUrl: () => isExtensionUrl, + isMatchingCallFrame: () => isMatchingCallFrame, + isTopLevelEvent: () => isTopLevelEvent, + makeProfileCall: () => makeProfileCall, + makeZeroBasedCallFrame: () => makeZeroBasedCallFrame, + mergeEventsInOrder: () => mergeEventsInOrder, + parseDevtoolsDetails: () => parseDevtoolsDetails, + sortTraceEventsInPlace: () => sortTraceEventsInPlace, + stackTraceInEvent: () => stackTraceInEvent +}); +function stackTraceInEvent(event) { + if (event.args?.data?.stackTrace) { + return event.args.data.stackTrace; + } + if (event.args?.stackTrace) { + return event.args.stackTrace; + } + if (TraceEvents_exports.isRecalcStyle(event)) { + return event.args.beginData?.stackTrace || null; + } + if (TraceEvents_exports.isLayout(event)) { + return event.args.beginData.stackTrace ?? null; + } + if (TraceEvents_exports.isFunctionCall(event)) { + const data31 = event.args.data; + if (!data31) { + return null; + } + const { columnNumber, lineNumber, url, scriptId, functionName } = data31; + if (lineNumber === void 0 || functionName === void 0 || columnNumber === void 0 || scriptId === void 0 || url === void 0) { + return null; + } + return [{ columnNumber, lineNumber, url, scriptId, functionName }]; + } + if (TraceEvents_exports.isProfileCall(event)) { + const callFrame = event.callFrame; + if (!callFrame) { + return null; + } + const { columnNumber, lineNumber, url, scriptId, functionName } = callFrame; + if (lineNumber === void 0 || functionName === void 0 || columnNumber === void 0 || scriptId === void 0 || url === void 0) { + return null; + } + return [{ columnNumber, lineNumber, url, scriptId, functionName }]; + } + return null; +} +function extractOriginFromTrace(firstNavigationURL) { + const url = new URL(firstNavigationURL); + if (url) { + if (url.host.startsWith("www.")) { + return url.host.slice(4); + } + return url.host; + } + return null; +} +function addEventToProcessThread(event, eventsInProcessThread2) { + const { tid, pid } = event; + let eventsInThread = eventsInProcessThread2.get(pid); + if (!eventsInThread) { + eventsInThread = /* @__PURE__ */ new Map(); + } + let events = eventsInThread.get(tid); + if (!events) { + events = []; + } + events.push(event); + eventsInThread.set(event.tid, events); + eventsInProcessThread2.set(event.pid, eventsInThread); +} +function compareBeginAndEnd(aBeginTime, bBeginTime, aEndTime, bEndTime) { + if (aBeginTime < bBeginTime) { + return -1; + } + if (aBeginTime > bBeginTime) { + return 1; + } + if (aEndTime > bEndTime) { + return -1; + } + if (aEndTime < bEndTime) { + return 1; + } + return 0; +} +function eventTimeComparator(a, b) { + const aBeginTime = a.ts; + const bBeginTime = b.ts; + const aDuration = a.dur ?? 0; + const bDuration = b.dur ?? 0; + const aEndTime = aBeginTime + aDuration; + const bEndTime = bBeginTime + bDuration; + const timeDifference = compareBeginAndEnd(aBeginTime, bBeginTime, aEndTime, bEndTime); + if (timeDifference) { + return timeDifference; + } + if (TraceEvents_exports.isProfileCall(a) && !TraceEvents_exports.isProfileCall(b)) { + return -1; + } + if (TraceEvents_exports.isProfileCall(b) && !TraceEvents_exports.isProfileCall(a)) { + return 1; + } + return 0; +} +function sortTraceEventsInPlace(events) { + events.sort(eventTimeComparator); +} +function mergeEventsInOrder(eventsArray1, eventsArray2) { + const result = []; + let i = 0; + let j = 0; + while (i < eventsArray1.length && j < eventsArray2.length) { + const event1 = eventsArray1[i]; + const event2 = eventsArray2[j]; + const compareValue = eventTimeComparator(event1, event2); + if (compareValue <= 0) { + result.push(event1); + i++; + } + if (compareValue === 1) { + result.push(event2); + j++; + } + } + while (i < eventsArray1.length) { + result.push(eventsArray1[i++]); + } + while (j < eventsArray2.length) { + result.push(eventsArray2[j++]); + } + return result; +} +function parseDevtoolsDetails(timingDetail, key) { + try { + const detailObj = JSON.parse(timingDetail); + if (!(key in detailObj)) { + return null; + } + if (!Extensions_exports.isValidExtensionPayload(detailObj[key])) { + return null; + } + return detailObj[key]; + } catch { + return null; + } +} +function getNavigationForTraceEvent(event, eventFrameId, navigationsByFrameId2) { + const navigations = navigationsByFrameId2.get(eventFrameId); + if (!navigations || eventFrameId === "") { + return null; + } + const eventNavigationIndex = ArrayUtilities_exports.nearestIndexFromEnd(navigations, (navigation2) => navigation2.ts <= event.ts); + if (eventNavigationIndex === null) { + return null; + } + return navigations[eventNavigationIndex]; +} +function extractId(event) { + return event.id ?? event.id2?.global ?? event.id2?.local; +} +function activeURLForFrameAtTime(frameId, time, rendererProcessesByFrame) { + const processData = rendererProcessesByFrame.get(frameId); + if (!processData) { + return null; + } + for (const processes2 of processData.values()) { + for (const processInfo of processes2) { + if (processInfo.window.min > time || processInfo.window.max < time) { + continue; + } + return processInfo.frame.url; + } + } + return null; +} +function makeProfileCall(node, profileId, sampleIndex, ts, pid, tid) { + return { + cat: "", + name: "ProfileCall", + nodeId: node.id, + args: {}, + ph: TraceEvents_exports.Phase.COMPLETE, + pid, + tid, + ts, + dur: Timing_exports.Micro(0), + callFrame: node.callFrame, + sampleIndex, + profileId + }; +} +function matchEvents(unpairedEvents) { + sortTraceEventsInPlace(unpairedEvents); + const matches = []; + const beginEventsById = /* @__PURE__ */ new Map(); + const instantEventsById = /* @__PURE__ */ new Map(); + for (const event of unpairedEvents) { + const id = getSyntheticId(event); + if (id === void 0) { + continue; + } + if (TraceEvents_exports.isPairableAsyncBegin(event)) { + const existingEvents = beginEventsById.get(id) ?? []; + existingEvents.push(event); + beginEventsById.set(id, existingEvents); + } else if (TraceEvents_exports.isPairableAsyncInstant(event)) { + const existingEvents = instantEventsById.get(id) ?? []; + existingEvents.push(event); + instantEventsById.set(id, existingEvents); + } else if (TraceEvents_exports.isPairableAsyncEnd(event)) { + const beginEventsWithMatchingId = beginEventsById.get(id) ?? []; + const beginEvent = beginEventsWithMatchingId.pop(); + if (!beginEvent) { + continue; + } + const instantEventsWithMatchingId = instantEventsById.get(id) ?? []; + const instantEventsForThisGroup = []; + while (instantEventsWithMatchingId.length > 0) { + if (instantEventsWithMatchingId[0].ts >= beginEvent.ts) { + const event2 = instantEventsWithMatchingId.pop(); + if (event2) { + instantEventsForThisGroup.push(event2); + } + } else { + break; + } + } + const matchingGroup = { + begin: beginEvent, + end: event, + instant: instantEventsForThisGroup, + syntheticId: id + }; + matches.push(matchingGroup); + } + } + for (const [id, beginEvents] of beginEventsById) { + const beginEvent = beginEvents.pop(); + if (!beginEvent) { + continue; + } + const matchingInstantEvents = instantEventsById.get(id); + if (matchingInstantEvents?.length) { + matches.push({ + syntheticId: id, + begin: beginEvent, + end: null, + instant: matchingInstantEvents + }); + } + } + return matches; +} +function getSyntheticId(event) { + const id = extractId(event); + return id && `${event.cat}:${id}:${event.name}`; +} +function createSortedSyntheticEvents(matchedPairs) { + const syntheticEvents2 = []; + for (const eventsTriplet of matchedPairs) { + let eventsArePairable = function(data31) { + const instantEventsMatch = data31.instantEvents ? data31.instantEvents.some((e) => id === getSyntheticId(e)) : false; + const endEventMatch = data31.endEvent ? id === getSyntheticId(data31.endEvent) : false; + return Boolean(id) && (instantEventsMatch || endEventMatch); + }; + __name(eventsArePairable, "eventsArePairable"); + const id = eventsTriplet.syntheticId; + const beginEvent = eventsTriplet.begin; + const endEvent = eventsTriplet.end; + const instantEvents = eventsTriplet.instant; + if (!beginEvent || !(endEvent || instantEvents)) { + continue; + } + const triplet = { beginEvent, endEvent, instantEvents }; + if (!eventsArePairable(triplet)) { + continue; + } + const targetEvent = endEvent || beginEvent; + const event = SyntheticEventsManager.registerSyntheticEvent({ + rawSourceEvent: triplet.beginEvent, + cat: targetEvent.cat, + ph: targetEvent.ph, + pid: targetEvent.pid, + tid: targetEvent.tid, + id, + // Both events have the same name, so it doesn't matter which we pick to + // use as the description + name: beginEvent.name, + dur: Timing_exports.Micro(targetEvent.ts - beginEvent.ts), + ts: beginEvent.ts, + args: { + data: triplet + } + }); + if (event.dur < 0) { + continue; + } + syntheticEvents2.push(event); + } + sortTraceEventsInPlace(syntheticEvents2); + return syntheticEvents2; +} +function createMatchedSortedSyntheticEvents(unpairedAsyncEvents2) { + const matchedPairs = matchEvents(unpairedAsyncEvents2); + const syntheticEvents2 = createSortedSyntheticEvents(matchedPairs); + return syntheticEvents2; +} +function getZeroIndexedLineAndColumnForEvent(event) { + const numbers = getRawLineAndColumnNumbersForEvent(event); + const { lineNumber, columnNumber } = numbers; + switch (event.name) { + // All these events have line/column numbers which are 1 indexed; so we + // subtract to make them 0 indexed. + case TraceEvents_exports.Name.FUNCTION_CALL: + case TraceEvents_exports.Name.EVALUATE_SCRIPT: + case TraceEvents_exports.Name.COMPILE: + case TraceEvents_exports.Name.CACHE_SCRIPT: { + return { + lineNumber: typeof lineNumber === "number" ? lineNumber - 1 : void 0, + columnNumber: typeof columnNumber === "number" ? columnNumber - 1 : void 0 + }; + } + case TraceEvents_exports.Name.PROFILE_CALL: { + const callFrame = event.callFrame; + return { + lineNumber: typeof lineNumber === "number" ? callFrame.lineNumber - 1 : void 0, + columnNumber: typeof columnNumber === "number" ? callFrame.columnNumber - 1 : void 0 + }; + } + default: { + return numbers; + } + } +} +function getZeroIndexedStackTraceInEventPayload(event) { + const stack = stackTraceInEvent(event); + if (!stack) { + return null; + } + switch (event.name) { + case TraceEvents_exports.Name.SCHEDULE_STYLE_RECALCULATION: + case TraceEvents_exports.Name.INVALIDATE_LAYOUT: + case TraceEvents_exports.Name.FUNCTION_CALL: + case TraceEvents_exports.Name.LAYOUT: + case TraceEvents_exports.Name.RECALC_STYLE: { + return stack.map(makeZeroBasedCallFrame); + } + default: { + if (TraceEvents_exports.isUserTiming(event) || Extensions_exports.isSyntheticExtensionEntry(event)) { + return stack.map(makeZeroBasedCallFrame); + } + return stack; + } + } +} +function getStackTraceTopCallFrameInEventPayload(event) { + const stack = stackTraceInEvent(event); + if (!stack || stack.length === 0) { + return null; + } + switch (event.name) { + case TraceEvents_exports.Name.SCHEDULE_STYLE_RECALCULATION: + case TraceEvents_exports.Name.INVALIDATE_LAYOUT: + case TraceEvents_exports.Name.FUNCTION_CALL: + case TraceEvents_exports.Name.LAYOUT: + case TraceEvents_exports.Name.RECALC_STYLE: { + return makeZeroBasedCallFrame(stack[0]); + } + default: { + if (TraceEvents_exports.isUserTiming(event) || Extensions_exports.isSyntheticExtensionEntry(event)) { + return makeZeroBasedCallFrame(stack[0]); + } + return stack[0]; + } + } +} +function makeZeroBasedCallFrame(callFrame) { + const normalizedCallFrame = { ...callFrame }; + normalizedCallFrame.lineNumber = callFrame.lineNumber && callFrame.lineNumber - 1; + normalizedCallFrame.columnNumber = callFrame.columnNumber && callFrame.columnNumber - 1; + return normalizedCallFrame; +} +function getRawLineAndColumnNumbersForEvent(event) { + if (!event.args?.data) { + return { + lineNumber: void 0, + columnNumber: void 0 + }; + } + let lineNumber = void 0; + let columnNumber = void 0; + if ("lineNumber" in event.args.data && typeof event.args.data.lineNumber === "number") { + lineNumber = event.args.data.lineNumber; + } + if ("columnNumber" in event.args.data && typeof event.args.data.columnNumber === "number") { + columnNumber = event.args.data.columnNumber; + } + return { lineNumber, columnNumber }; +} +function frameIDForEvent(event) { + if (event.args && "beginData" in event.args && typeof event.args.beginData === "object" && event.args.beginData !== null && "frame" in event.args.beginData && typeof event.args.beginData.frame === "string") { + return event.args.beginData.frame; + } + if (event.args?.data?.frame) { + return event.args.data.frame; + } + return null; +} +function isTopLevelEvent(event) { + return event.cat.includes(DevToolsTimelineEventCategory) && event.name === TraceEvents_exports.Name.RUN_TASK; +} +function isExtensionUrl(url) { + return url.startsWith("extensions:") || url.startsWith("chrome-extension:"); +} +function topLevelEventIndexEndingAfter(events, time) { + let index = ArrayUtilities_exports.upperBound(events, time, (time2, event) => time2 - event.ts) - 1; + while (index > 0 && !isTopLevelEvent(events[index])) { + index--; + } + return Math.max(index, 0); +} +function findRecalcStyleEvents(events, startTime, endTime) { + const foundEvents = []; + const startEventIndex = topLevelEventIndexEndingAfter(events, startTime); + for (let i = startEventIndex; i < events.length; i++) { + const event = events[i]; + if (!TraceEvents_exports.isRecalcStyle(event)) { + continue; + } + if (event.ts >= (endTime || Infinity)) { + continue; + } + foundEvents.push(event); + } + return foundEvents; +} +function findNextEventAfterTimestamp(candidates, ts) { + const index = ArrayUtilities_exports.nearestIndexFromBeginning(candidates, (candidate) => ts < candidate.ts); + return index === null ? null : candidates[index]; +} +function findPreviousEventBeforeTimestamp(candidates, ts) { + const index = ArrayUtilities_exports.nearestIndexFromEnd(candidates, (candidate) => candidate.ts < ts); + return index === null ? null : candidates[index]; +} +function forEachEvent(events, config3) { + const globalStartTime = config3.startTime ?? Timing_exports.Micro(0); + const globalEndTime = config3.endTime || Timing_exports.Micro(Infinity); + const ignoreAsyncEvents = config3.ignoreAsyncEvents === false ? false : true; + const stack = []; + const startEventIndex = topLevelEventIndexEndingAfter(events, globalStartTime); + for (let i = startEventIndex; i < events.length; i++) { + const currentEvent = events[i]; + const currentEventTimings = eventTimingsMicroSeconds(currentEvent); + if (currentEventTimings.endTime < globalStartTime) { + continue; + } + if (currentEventTimings.startTime > globalEndTime) { + break; + } + const isIgnoredAsyncEvent = ignoreAsyncEvents && TraceEvents_exports.isPhaseAsync(currentEvent.ph); + if (isIgnoredAsyncEvent || TraceEvents_exports.isFlowPhase(currentEvent.ph)) { + continue; + } + let lastEventOnStack = stack.at(-1); + let lastEventEndTime = lastEventOnStack ? eventTimingsMicroSeconds(lastEventOnStack).endTime : null; + while (lastEventOnStack && lastEventEndTime && lastEventEndTime <= currentEventTimings.startTime) { + stack.pop(); + config3.onEndEvent(lastEventOnStack); + lastEventOnStack = stack.at(-1); + lastEventEndTime = lastEventOnStack ? eventTimingsMicroSeconds(lastEventOnStack).endTime : null; + } + if (config3.eventFilter && !config3.eventFilter(currentEvent)) { + continue; + } + if (currentEventTimings.duration) { + config3.onStartEvent(currentEvent); + stack.push(currentEvent); + } else if (config3.onInstantEvent) { + config3.onInstantEvent(currentEvent); + } + } + while (stack.length) { + const last = stack.pop(); + if (last) { + config3.onEndEvent(last); + } + } +} +function eventHasCategory(event, category) { + let parsedCategoriesForEvent = parsedCategories.get(event.cat); + if (!parsedCategoriesForEvent) { + parsedCategoriesForEvent = new Set(event.cat.split(",") || []); + } + return parsedCategoriesForEvent.has(category); +} +function isMatchingCallFrame(eventFrame, nodeFrame) { + return eventFrame.columnNumber === nodeFrame.columnNumber && eventFrame.lineNumber === nodeFrame.lineNumber && String(eventFrame.scriptId) === nodeFrame.scriptId && eventFrame.url === nodeFrame.url && eventFrame.functionName === nodeFrame.functionName; +} +function eventContainsTimestamp(event, ts) { + return event.ts <= ts && event.ts + (event.dur || 0) >= ts; +} +function extractSampleTraceId(event) { + if (!event.args) { + return null; + } + if ("beginData" in event.args) { + const beginData = event.args["beginData"]; + return beginData.sampleTraceId ?? null; + } + return event.args?.sampleTraceId ?? event.args?.data?.sampleTraceId ?? null; +} +var DevToolsTimelineEventCategory, parsedCategories, VISIBLE_TRACE_EVENT_TYPES; +var init_Trace = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/helpers/Trace.js"() { + init_process_global(); + init_platform(); + init_types2(); + init_SyntheticEvents(); + init_Timing3(); + __name(stackTraceInEvent, "stackTraceInEvent"); + __name(extractOriginFromTrace, "extractOriginFromTrace"); + __name(addEventToProcessThread, "addEventToProcessThread"); + __name(compareBeginAndEnd, "compareBeginAndEnd"); + __name(eventTimeComparator, "eventTimeComparator"); + __name(sortTraceEventsInPlace, "sortTraceEventsInPlace"); + __name(mergeEventsInOrder, "mergeEventsInOrder"); + __name(parseDevtoolsDetails, "parseDevtoolsDetails"); + __name(getNavigationForTraceEvent, "getNavigationForTraceEvent"); + __name(extractId, "extractId"); + __name(activeURLForFrameAtTime, "activeURLForFrameAtTime"); + __name(makeProfileCall, "makeProfileCall"); + __name(matchEvents, "matchEvents"); + __name(getSyntheticId, "getSyntheticId"); + __name(createSortedSyntheticEvents, "createSortedSyntheticEvents"); + __name(createMatchedSortedSyntheticEvents, "createMatchedSortedSyntheticEvents"); + __name(getZeroIndexedLineAndColumnForEvent, "getZeroIndexedLineAndColumnForEvent"); + __name(getZeroIndexedStackTraceInEventPayload, "getZeroIndexedStackTraceInEventPayload"); + __name(getStackTraceTopCallFrameInEventPayload, "getStackTraceTopCallFrameInEventPayload"); + __name(makeZeroBasedCallFrame, "makeZeroBasedCallFrame"); + __name(getRawLineAndColumnNumbersForEvent, "getRawLineAndColumnNumbersForEvent"); + __name(frameIDForEvent, "frameIDForEvent"); + DevToolsTimelineEventCategory = "disabled-by-default-devtools.timeline"; + __name(isTopLevelEvent, "isTopLevelEvent"); + __name(isExtensionUrl, "isExtensionUrl"); + __name(topLevelEventIndexEndingAfter, "topLevelEventIndexEndingAfter"); + __name(findRecalcStyleEvents, "findRecalcStyleEvents"); + __name(findNextEventAfterTimestamp, "findNextEventAfterTimestamp"); + __name(findPreviousEventBeforeTimestamp, "findPreviousEventBeforeTimestamp"); + __name(forEachEvent, "forEachEvent"); + parsedCategories = /* @__PURE__ */ new Map(); + __name(eventHasCategory, "eventHasCategory"); + __name(isMatchingCallFrame, "isMatchingCallFrame"); + __name(eventContainsTimestamp, "eventContainsTimestamp"); + __name(extractSampleTraceId, "extractSampleTraceId"); + VISIBLE_TRACE_EVENT_TYPES = /* @__PURE__ */ new Set([ + TraceEvents_exports.Name.ABORT_POST_TASK_CALLBACK, + TraceEvents_exports.Name.ANIMATION, + TraceEvents_exports.Name.ASYNC_TASK, + TraceEvents_exports.Name.BACKGROUND_DESERIALIZE, + TraceEvents_exports.Name.CACHE_MODULE, + TraceEvents_exports.Name.CACHE_SCRIPT, + TraceEvents_exports.Name.CANCEL_ANIMATION_FRAME, + TraceEvents_exports.Name.CANCEL_IDLE_CALLBACK, + TraceEvents_exports.Name.COMMIT, + TraceEvents_exports.Name.COMPILE_CODE, + TraceEvents_exports.Name.COMPILE_MODULE, + TraceEvents_exports.Name.COMPILE, + TraceEvents_exports.Name.COMPOSITE_LAYERS, + TraceEvents_exports.Name.COMPUTE_INTERSECTION, + TraceEvents_exports.Name.CONSOLE_TIME, + TraceEvents_exports.Name.CPPGC_SWEEP, + TraceEvents_exports.Name.CRYPTO_DO_DECRYPT_REPLY, + TraceEvents_exports.Name.CRYPTO_DO_DECRYPT, + TraceEvents_exports.Name.CRYPTO_DO_DIGEST_REPLY, + TraceEvents_exports.Name.CRYPTO_DO_DIGEST, + TraceEvents_exports.Name.CRYPTO_DO_ENCRYPT_REPLY, + TraceEvents_exports.Name.CRYPTO_DO_ENCRYPT, + TraceEvents_exports.Name.CRYPTO_DO_SIGN_REPLY, + TraceEvents_exports.Name.CRYPTO_DO_SIGN, + TraceEvents_exports.Name.CRYPTO_DO_VERIFY_REPLY, + TraceEvents_exports.Name.CRYPTO_DO_VERIFY, + TraceEvents_exports.Name.DECODE_IMAGE, + TraceEvents_exports.Name.EMBEDDER_CALLBACK, + TraceEvents_exports.Name.EVALUATE_MODULE, + TraceEvents_exports.Name.EVALUATE_SCRIPT, + TraceEvents_exports.Name.EVENT_DISPATCH, + TraceEvents_exports.Name.EVENT_TIMING, + TraceEvents_exports.Name.FINALIZE_DESERIALIZATION, + TraceEvents_exports.Name.FIRE_ANIMATION_FRAME, + TraceEvents_exports.Name.FIRE_IDLE_CALLBACK, + TraceEvents_exports.Name.FUNCTION_CALL, + TraceEvents_exports.Name.GC_COLLECT_GARBARGE, + TraceEvents_exports.Name.GC, + TraceEvents_exports.Name.GPU_TASK, + TraceEvents_exports.Name.HANDLE_POST_MESSAGE, + TraceEvents_exports.Name.HIT_TEST, + TraceEvents_exports.Name.JS_SAMPLE, + TraceEvents_exports.Name.LAYERIZE, + TraceEvents_exports.Name.LAYOUT, + TraceEvents_exports.Name.MAJOR_GC, + TraceEvents_exports.Name.MINOR_GC, + TraceEvents_exports.Name.OPTIMIZE_CODE, + TraceEvents_exports.Name.PAINT_SETUP, + TraceEvents_exports.Name.PAINT, + TraceEvents_exports.Name.PARSE_AUTHOR_STYLE_SHEET, + TraceEvents_exports.Name.PARSE_HTML, + TraceEvents_exports.Name.PRE_PAINT, + TraceEvents_exports.Name.PROFILE_CALL, + TraceEvents_exports.Name.PROGRAM, + TraceEvents_exports.Name.RASTER_TASK, + TraceEvents_exports.Name.REQUEST_ANIMATION_FRAME, + TraceEvents_exports.Name.REQUEST_IDLE_CALLBACK, + TraceEvents_exports.Name.RESOURCE_FINISH, + TraceEvents_exports.Name.RESOURCE_RECEIVE_DATA, + TraceEvents_exports.Name.RESOURCE_RECEIVE_RESPONSE, + TraceEvents_exports.Name.RESOURCE_SEND_REQUEST, + TraceEvents_exports.Name.RESOURCE_WILL_SEND_REQUEST, + TraceEvents_exports.Name.RUN_MICROTASKS, + TraceEvents_exports.Name.RUN_POST_TASK_CALLBACK, + TraceEvents_exports.Name.RUN_TASK, + TraceEvents_exports.Name.SCHEDULE_POST_MESSAGE, + TraceEvents_exports.Name.SCHEDULE_POST_TASK_CALLBACK, + TraceEvents_exports.Name.SCHEDULE_STYLE_RECALCULATION, + TraceEvents_exports.Name.SCROLL_LAYER, + TraceEvents_exports.Name.START_PROFILING, + TraceEvents_exports.Name.STREAMING_COMPILE_SCRIPT_PARSING, + TraceEvents_exports.Name.STREAMING_COMPILE_SCRIPT_WAITING, + TraceEvents_exports.Name.STREAMING_COMPILE_SCRIPT, + TraceEvents_exports.Name.SYNTHETIC_LAYOUT_SHIFT_CLUSTER, + TraceEvents_exports.Name.SYNTHETIC_LAYOUT_SHIFT, + TraceEvents_exports.Name.TIME_STAMP, + TraceEvents_exports.Name.TIMER_FIRE, + TraceEvents_exports.Name.TIMER_INSTALL, + TraceEvents_exports.Name.TIMER_REMOVE, + TraceEvents_exports.Name.UPDATE_LAYER_TREE, + TraceEvents_exports.Name.RECALC_STYLE, + TraceEvents_exports.Name.USER_TIMING, + TraceEvents_exports.Name.V8_CONSOLE_RUN_TASK, + TraceEvents_exports.Name.WASM_CACHED_MODULE, + TraceEvents_exports.Name.WASM_COMPILED_MODULE, + TraceEvents_exports.Name.WASM_MODULE_CACHE_HIT, + TraceEvents_exports.Name.WASM_MODULE_CACHE_INVALID, + TraceEvents_exports.Name.WASM_STREAM_FROM_RESPONSE_CALLBACK, + TraceEvents_exports.Name.WEB_SOCKET_CREATE, + TraceEvents_exports.Name.WEB_SOCKET_DESTROY, + TraceEvents_exports.Name.WEB_SOCKET_RECEIVE_HANDSHAKE_REQUEST, + TraceEvents_exports.Name.WEB_SOCKET_RECEIVE, + TraceEvents_exports.Name.WEB_SOCKET_SEND_HANDSHAKE_REQUEST, + TraceEvents_exports.Name.WEB_SOCKET_SEND, + TraceEvents_exports.Name.XHR_LOAD, + TraceEvents_exports.Name.XHR_READY_STATE_CHANGED + ]); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/helpers/TreeHelpers.js +var TreeHelpers_exports = {}; +__export(TreeHelpers_exports, { + canBuildTreesFromEvents: () => canBuildTreesFromEvents, + makeEmptyTraceEntryNode: () => makeEmptyTraceEntryNode, + makeEmptyTraceEntryTree: () => makeEmptyTraceEntryTree, + makeTraceEntryNodeId: () => makeTraceEntryNodeId, + treify: () => treify, + walkEntireTree: () => walkEntireTree, + walkTreeFromEntry: () => walkTreeFromEntry +}); +function treify(entries, options) { + const entryToNode4 = /* @__PURE__ */ new Map(); + const stack = []; + nodeIdCount = -1; + const tree = makeEmptyTraceEntryTree(); + for (let i = 0; i < entries.length; i++) { + const event = entries[i]; + if (options && !options.filter.has(event.name)) { + continue; + } + const duration = event.dur || 0; + const nodeId = makeTraceEntryNodeId(); + const node = makeEmptyTraceEntryNode(event, nodeId); + if (stack.length === 0) { + tree.roots.add(node); + node.selfTime = Timing_exports.Micro(duration); + stack.push(node); + tree.maxDepth = Math.max(tree.maxDepth, stack.length); + entryToNode4.set(event, node); + continue; + } + const parentNode = stack.at(-1); + if (parentNode === void 0) { + throw new Error("Impossible: no parent node found in the stack"); + } + const parentEvent = parentNode.entry; + const begin = event.ts; + const parentBegin = parentEvent.ts; + const parentDuration = parentEvent.dur || 0; + const end = begin + duration; + const parentEnd = parentBegin + parentDuration; + const startsBeforeParent = begin < parentBegin; + if (startsBeforeParent) { + throw new Error("Impossible: current event starts before the parent event"); + } + const startsAfterParent = begin >= parentEnd; + if (startsAfterParent) { + stack.pop(); + i--; + nodeIdCount--; + continue; + } + const endsAfterParent = end > parentEnd; + if (endsAfterParent) { + continue; + } + node.depth = stack.length; + node.parent = parentNode; + parentNode.children.push(node); + node.selfTime = Timing_exports.Micro(duration); + if (parentNode.selfTime !== void 0) { + parentNode.selfTime = Timing_exports.Micro(parentNode.selfTime - (event.dur || 0)); + } + stack.push(node); + tree.maxDepth = Math.max(tree.maxDepth, stack.length); + entryToNode4.set(event, node); + } + return { tree, entryToNode: entryToNode4 }; +} +function walkTreeFromEntry(entryToNode4, rootEntry, onEntryStart, onEntryEnd) { + const startNode = entryToNode4.get(rootEntry); + if (!startNode) { + return; + } + walkTreeByNode(entryToNode4, startNode, onEntryStart, onEntryEnd); +} +function walkEntireTree(entryToNode4, tree, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration) { + for (const rootNode of tree.roots) { + walkTreeByNode(entryToNode4, rootNode, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration); + } +} +function walkTreeByNode(entryToNode4, rootNode, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration) { + if (traceWindowToInclude && !treeNodeIsInWindow(rootNode, traceWindowToInclude)) { + return; + } + if (typeof minDuration !== "undefined") { + const duration = Timing_exports.Micro(rootNode.entry.ts + Timing_exports.Micro(rootNode.entry.dur ?? 0)); + if (duration < minDuration) { + return; + } + } + onEntryStart(rootNode.entry); + for (const child of rootNode.children) { + walkTreeByNode(entryToNode4, child, onEntryStart, onEntryEnd, traceWindowToInclude, minDuration); + } + onEntryEnd(rootNode.entry); +} +function treeNodeIsInWindow(node, traceWindow) { + return eventIsInBounds(node.entry, traceWindow); +} +function canBuildTreesFromEvents(events) { + const stack = []; + for (const event of events) { + const startTime = event.ts; + const endTime = event.ts + (event.dur ?? 0); + let parent = stack.at(-1); + if (parent === void 0) { + stack.push(event); + continue; + } + let parentEndTime = parent.ts + (parent.dur ?? 0); + while (stack.length && startTime >= parentEndTime) { + stack.pop(); + parent = stack.at(-1); + if (parent === void 0) { + break; + } + parentEndTime = parent.ts + (parent.dur ?? 0); + } + if (stack.length && endTime > parentEndTime) { + return false; + } + stack.push(event); + } + return true; +} +var nodeIdCount, makeTraceEntryNodeId, makeEmptyTraceEntryTree, makeEmptyTraceEntryNode; +var init_TreeHelpers = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/helpers/TreeHelpers.js"() { + init_process_global(); + init_types2(); + init_Timing3(); + nodeIdCount = 0; + makeTraceEntryNodeId = /* @__PURE__ */ __name(() => ++nodeIdCount, "makeTraceEntryNodeId"); + makeEmptyTraceEntryTree = /* @__PURE__ */ __name(() => ({ + roots: /* @__PURE__ */ new Set(), + maxDepth: 0 + }), "makeEmptyTraceEntryTree"); + makeEmptyTraceEntryNode = /* @__PURE__ */ __name((entry, id) => ({ + entry, + id, + parent: null, + children: [], + depth: 0 + }), "makeEmptyTraceEntryNode"); + __name(treify, "treify"); + __name(walkTreeFromEntry, "walkTreeFromEntry"); + __name(walkEntireTree, "walkEntireTree"); + __name(walkTreeByNode, "walkTreeByNode"); + __name(treeNodeIsInWindow, "treeNodeIsInWindow"); + __name(canBuildTreesFromEvents, "canBuildTreesFromEvents"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/helpers/Extensions.js +var Extensions_exports2 = {}; +__export(Extensions_exports2, { + buildTrackDataFromExtensionEntries: () => buildTrackDataFromExtensionEntries +}); +function buildTrackDataFromExtensionEntries(extensionEntries, extensionTrackData2, entryToNode4) { + const dataByTrack = /* @__PURE__ */ new Map(); + for (const entry of extensionEntries) { + const key = entry.devtoolsObj.trackGroup || `track-name-${entry.devtoolsObj.track}`; + const batchedData = MapUtilities_exports.getWithDefault(dataByTrack, key, () => ({ + name: entry.devtoolsObj.trackGroup || entry.devtoolsObj.track, + isTrackGroup: Boolean(entry.devtoolsObj.trackGroup), + entriesByTrack: { [entry.devtoolsObj.track]: [] } + })); + if (!batchedData.entriesByTrack[entry.devtoolsObj.track]) { + batchedData.entriesByTrack[entry.devtoolsObj.track] = []; + } + const entriesInTrack = batchedData.entriesByTrack[entry.devtoolsObj.track]; + entriesInTrack.push(entry); + } + for (const trackData of dataByTrack.values()) { + for (const entries of Object.values(trackData.entriesByTrack)) { + sortTraceEventsInPlace(entries); + if (canBuildTreesFromEvents(entries)) { + for (const [entry, node] of treify(entries).entryToNode) { + entryToNode4.set(entry, node); + } + } + } + extensionTrackData2.push(trackData); + } + return { extensionTrackData: extensionTrackData2, entryToNode: entryToNode4 }; +} +var init_Extensions2 = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/helpers/Extensions.js"() { + init_process_global(); + init_platform(); + init_Trace(); + init_TreeHelpers(); + __name(buildTrackDataFromExtensionEntries, "buildTrackDataFromExtensionEntries"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/helpers/Network.js +var Network_exports = {}; +__export(Network_exports, { + CACHEABLE_STATUS_CODES: () => CACHEABLE_STATUS_CODES, + NON_NETWORK_SCHEMES: () => NON_NETWORK_SCHEMES2, + STATIC_RESOURCE_TYPES: () => STATIC_RESOURCE_TYPES, + isSyntheticNetworkRequestEventRenderBlocking: () => isSyntheticNetworkRequestEventRenderBlocking, + isSyntheticNetworkRequestHighPriority: () => isSyntheticNetworkRequestHighPriority, + isSyntheticNetworkRequestLocalhost: () => isSyntheticNetworkRequestLocalhost, + parseCacheControl: () => parseCacheControl +}); +function isSyntheticNetworkRequestEventRenderBlocking(event) { + return !NON_RENDER_BLOCKING_VALUES.has(event.args.data.renderBlocking); +} +function isSyntheticNetworkRequestHighPriority(event) { + return HIGH_NETWORK_PRIORITIES.has(event.args.data.priority); +} +function parseCacheControl(header) { + if (!header) { + return null; + } + const directives = header.split(",").map((directive) => directive.trim()); + const cacheControlOptions = {}; + for (const directive of directives) { + const [key, value] = directive.split("=").map((part) => part.trim()); + switch (key) { + case "max-age": { + const maxAge = parseInt(value, 10); + if (!isNaN(maxAge)) { + cacheControlOptions["max-age"] = maxAge; + } + break; + } + case "no-cache": + cacheControlOptions["no-cache"] = true; + break; + case "no-store": + cacheControlOptions["no-store"] = true; + break; + case "must-revalidate": + cacheControlOptions["must-revalidate"] = true; + break; + case "private": + cacheControlOptions["private"] = true; + break; + default: + break; + } + } + return cacheControlOptions; +} +function isSyntheticNetworkRequestLocalhost(event) { + try { + const hostname = new URL(event.args.data.url).hostname; + return SECURE_LOCALHOST_DOMAINS.includes(hostname) || hostname.endsWith(".localhost"); + } catch { + return false; + } +} +var NON_RENDER_BLOCKING_VALUES, HIGH_NETWORK_PRIORITIES, CACHEABLE_STATUS_CODES, STATIC_RESOURCE_TYPES, NON_NETWORK_SCHEMES2, SECURE_LOCALHOST_DOMAINS; +var init_Network = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/helpers/Network.js"() { + init_process_global(); + NON_RENDER_BLOCKING_VALUES = /* @__PURE__ */ new Set([ + "non_blocking", + "dynamically_injected_non_blocking", + "potentially_blocking" + ]); + __name(isSyntheticNetworkRequestEventRenderBlocking, "isSyntheticNetworkRequestEventRenderBlocking"); + HIGH_NETWORK_PRIORITIES = /* @__PURE__ */ new Set([ + "VeryHigh", + "High", + "Medium" + ]); + __name(isSyntheticNetworkRequestHighPriority, "isSyntheticNetworkRequestHighPriority"); + CACHEABLE_STATUS_CODES = /* @__PURE__ */ new Set([200, 203, 206]); + STATIC_RESOURCE_TYPES = /* @__PURE__ */ new Set([ + "Font", + "Image", + "Media", + "Script", + "Stylesheet" + ]); + NON_NETWORK_SCHEMES2 = [ + "blob", + // @see https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL + "data", + // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs + "intent", + // @see https://developer.chrome.com/docs/multidevice/android/intents/ + "file", + // @see https://en.wikipedia.org/wiki/File_URI_scheme + "filesystem", + // @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystem + "chrome-extension" + ]; + __name(parseCacheControl, "parseCacheControl"); + SECURE_LOCALHOST_DOMAINS = ["localhost", "127.0.0.1"]; + __name(isSyntheticNetworkRequestLocalhost, "isSyntheticNetworkRequestLocalhost"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/helpers/SamplesIntegrator.js +var SamplesIntegrator_exports = {}; +__export(SamplesIntegrator_exports, { + SamplesIntegrator: () => SamplesIntegrator +}); +var _a, SamplesIntegrator; +var init_SamplesIntegrator = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/helpers/SamplesIntegrator.js"() { + init_process_global(); + init_types2(); + init_Timing3(); + init_Trace(); + SamplesIntegrator = class { + static { + __name(this, "SamplesIntegrator"); + } + /** + * The result of running the samples integrator. Holds the JS calls + * with their approximated duration after integrating samples into the + * trace event tree. + */ + #constructedProfileCalls = []; + /** + * tracks the state of the JS stack at each point in time to update + * the profile call durations as new events arrive. This doesn't only + * happen with new profile calls (in which case we would compare the + * stack in them) but also with trace events (in which case we would + * update the duration of the events we are tracking at the moment). + */ + #currentJSStack = []; + /** + * Process holding the CPU profile and trace events. + */ + #processId; + /** + * Thread holding the CPU profile and trace events. + */ + #threadId; + /** + * Tracks the depth of the JS stack at the moment a trace event starts + * or ends. It is assumed that for the duration of a trace event, the + * JS stack's depth cannot decrease, since JS calls that started + * before a trace event cannot end during the trace event. So as trace + * events arrive, we store the "locked" amount of JS frames that were + * in the stack before the event came. + */ + #lockedJsStackDepth = []; + /** + * Used to keep track when samples should be integrated even if they + * are not children of invocation trace events. This is useful in + * cases where we can be missing the start of JS invocation events if + * we start tracing half-way through. + */ + #fakeJSInvocation = false; + /** + * The parsed CPU profile, holding the tree hierarchy of JS frames and + * the sample data. + */ + #profileModel; + /** + * Because GC nodes don't have a stack, we artificially add a stack to + * them which corresponds to that of the previous sample. This map + * tracks which node is used for the stack of a GC call. + * Note that GC samples are not shown in the flamechart, however they + * are used during the construction of for profile calls, as we can + * infer information about the duration of the executed code when a + * GC node is sampled. + */ + #nodeForGC = /* @__PURE__ */ new Map(); + #engineConfig; + #profileId; + /** + * Keeps track of the individual samples from the CPU Profile. + * Only used with Debug Mode experiment enabled. + */ + jsSampleEvents = []; + constructor(profileModel, profileId, pid, tid, configuration) { + this.#profileModel = profileModel; + this.#threadId = tid; + this.#processId = pid; + this.#engineConfig = configuration || Configuration_exports.defaults(); + this.#profileId = profileId; + } + buildProfileCalls(traceEvents) { + const mergedEvents = mergeEventsInOrder(traceEvents, this.callsFromProfileSamples()); + const stack = []; + for (let i = 0; i < mergedEvents.length; i++) { + const event = mergedEvents[i]; + if (event.ph === TraceEvents_exports.Phase.INSTANT && !extractSampleTraceId(event)) { + continue; + } + if (stack.length === 0) { + if (TraceEvents_exports.isProfileCall(event)) { + this.#onProfileCall(event); + continue; + } + stack.push(event); + this.#onTraceEventStart(event); + continue; + } + const parentEvent = stack.at(-1); + if (parentEvent === void 0) { + continue; + } + const begin = event.ts; + const parentBegin = parentEvent.ts; + const parentDuration = parentEvent.dur || 0; + const parentEnd = parentBegin + parentDuration; + const startsAfterParent = begin >= parentEnd; + if (startsAfterParent) { + this.#onTraceEventEnd(parentEvent); + stack.pop(); + i--; + continue; + } + if (TraceEvents_exports.isProfileCall(event)) { + this.#onProfileCall(event, parentEvent); + continue; + } + this.#onTraceEventStart(event); + stack.push(event); + } + while (stack.length) { + const last = stack.pop(); + if (last) { + this.#onTraceEventEnd(last); + } + } + sortTraceEventsInPlace(this.jsSampleEvents); + return this.#constructedProfileCalls; + } + #onTraceEventStart(event) { + if (event.name === TraceEvents_exports.Name.RUN_MICROTASKS || event.name === TraceEvents_exports.Name.RUN_TASK) { + this.#lockedJsStackDepth = []; + this.#truncateJSStack(0, event.ts); + this.#fakeJSInvocation = false; + } + if (this.#fakeJSInvocation) { + this.#truncateJSStack(this.#lockedJsStackDepth.pop() || 0, event.ts); + this.#fakeJSInvocation = false; + } + this.#extractStackTrace(event); + this.#lockedJsStackDepth.push(this.#currentJSStack.length); + } + #onProfileCall(event, parent) { + if (parent && TraceEvents_exports.isJSInvocationEvent(parent) || this.#fakeJSInvocation) { + this.#extractStackTrace(event); + } else if (TraceEvents_exports.isProfileCall(event) && this.#currentJSStack.length === 0) { + this.#fakeJSInvocation = true; + const stackDepthBefore = this.#currentJSStack.length; + this.#extractStackTrace(event); + this.#lockedJsStackDepth.push(stackDepthBefore); + } + } + #onTraceEventEnd(event) { + const endTime = Timing_exports.Micro(event.ts + (event.dur ?? 0)); + this.#truncateJSStack(this.#lockedJsStackDepth.pop() || 0, endTime); + } + /** + * Builds the initial calls with no duration from samples. Their + * purpose is to be merged with the trace event array being parsed so + * that they can be traversed in order with them and their duration + * can be updated as the SampleIntegrator callbacks are invoked. + */ + callsFromProfileSamples() { + const samples = this.#profileModel.samples; + const timestamps = this.#profileModel.timestamps; + if (!samples) { + return []; + } + const calls = []; + let prevNode; + for (let i = 0; i < samples.length; i++) { + const node = this.#profileModel.nodeByIndex(i); + const timestamp = milliToMicro(Timing_exports.Milli(timestamps[i])); + if (!node) { + continue; + } + const call = makeProfileCall(node, this.#profileId, i, timestamp, this.#processId, this.#threadId); + calls.push(call); + if (this.#engineConfig.debugMode) { + const traceId = this.#profileModel.traceIds?.[i]; + this.jsSampleEvents.push(this.#makeJSSampleEvent(call, timestamp, traceId)); + } + if (node.id === this.#profileModel.gcNode?.id && prevNode) { + this.#nodeForGC.set(call, prevNode); + continue; + } + prevNode = node; + } + return calls; + } + /** + * Given a synthetic profile call, returns an array of profile calls + * representing the stack trace that profile call belongs to based on + * its nodeId. The input profile call will be at the top of the + * returned stack (last position), meaning that any other frames that + * were effectively above it are omitted. + * @param profileCall + * @param overrideTimeStamp a custom timestamp to use for the returned + * profile calls. If not defined, the timestamp of the input + * profileCall is used instead. This param is useful for example when + * creating the profile calls for a sample with a trace id, since the + * timestamp of the corresponding trace event should be used instead + * of the sample's. + */ + #makeProfileCallsForStack(profileCall, overrideTimeStamp) { + let node = this.#profileModel.nodeById(profileCall.nodeId); + const isGarbageCollection = node?.id === this.#profileModel.gcNode?.id; + if (isGarbageCollection) { + node = this.#nodeForGC.get(profileCall) || null; + } + if (!node) { + return []; + } + const callFrames = new Array(node.depth + 1 + Number(isGarbageCollection)); + let i = callFrames.length - 1; + if (isGarbageCollection) { + callFrames[i--] = profileCall; + } + while (node) { + callFrames[i--] = makeProfileCall(node, profileCall.profileId, profileCall.sampleIndex, overrideTimeStamp ?? profileCall.ts, this.#processId, this.#threadId); + node = node.parent; + } + return callFrames; + } + #getStackForSampleTraceId(traceId, timestamp) { + const nodeId = this.#profileModel.traceIds?.[traceId]; + const node = nodeId && this.#profileModel.nodeById(nodeId); + const maybeCallForTraceId = node && makeProfileCall(node, this.#profileId, -1, timestamp, this.#processId, this.#threadId); + if (!maybeCallForTraceId) { + return null; + } + if (this.#engineConfig.debugMode) { + this.jsSampleEvents.push(this.#makeJSSampleEvent(maybeCallForTraceId, timestamp, traceId)); + } + return this.#makeProfileCallsForStack(maybeCallForTraceId); + } + /** + * Update tracked stack using this event's call stack. + */ + #extractStackTrace(event) { + let stackTrace = this.#currentJSStack; + if (TraceEvents_exports.isProfileCall(event)) { + stackTrace = this.#makeProfileCallsForStack(event); + } + const traceId = extractSampleTraceId(event); + const maybeCallForTraceId = traceId && this.#getStackForSampleTraceId(traceId, event.ts); + if (maybeCallForTraceId) { + stackTrace = maybeCallForTraceId; + } + _a.filterStackFrames(stackTrace, this.#engineConfig); + const endTime = event.ts + (event.dur || 0); + const minFrames = Math.min(stackTrace.length, this.#currentJSStack.length); + let i; + for (i = this.#lockedJsStackDepth.at(-1) || 0; i < minFrames; ++i) { + const newFrame = stackTrace[i].callFrame; + const oldFrame = this.#currentJSStack[i].callFrame; + if (!_a.framesAreEqual(newFrame, oldFrame)) { + break; + } + this.#currentJSStack[i].dur = Timing_exports.Micro(Math.max(this.#currentJSStack[i].dur || 0, endTime - this.#currentJSStack[i].ts)); + } + this.#truncateJSStack(i, event.ts); + for (; i < stackTrace.length; ++i) { + const call = stackTrace[i]; + if (call.nodeId === this.#profileModel.programNode?.id || call.nodeId === this.#profileModel.root?.id || call.nodeId === this.#profileModel.idleNode?.id || call.nodeId === this.#profileModel.gcNode?.id) { + continue; + } + this.#currentJSStack.push(call); + this.#constructedProfileCalls.push(call); + } + } + /** + * When a call stack that differs from the one we are tracking has + * been detected in the samples, the latter is "truncated" by + * setting the ending time of its call frames and removing the top + * call frames that aren't shared with the new call stack. This way, + * we can update the tracked stack with the new call frames on top. + * @param depth the amount of call frames from bottom to top that + * should be kept in the tracking stack trace. AKA amount of shared + * call frames between two stacks. + * @param time the new end of the call frames in the stack. + */ + #truncateJSStack(depth, time) { + if (this.#lockedJsStackDepth.length) { + const lockedDepth = this.#lockedJsStackDepth.at(-1); + if (lockedDepth && depth < lockedDepth) { + console.error(`Child stack is shallower (${depth}) than the parent stack (${lockedDepth}) at ${time}`); + depth = lockedDepth; + } + } + if (this.#currentJSStack.length < depth) { + console.error(`Trying to truncate higher than the current stack size at ${time}`); + depth = this.#currentJSStack.length; + } + for (let k = 0; k < this.#currentJSStack.length; ++k) { + this.#currentJSStack[k].dur = Timing_exports.Micro(Math.max(time - this.#currentJSStack[k].ts, 0)); + } + this.#currentJSStack.length = depth; + } + #makeJSSampleEvent(call, timestamp, traceId) { + const JSSampleEvent = { + name: TraceEvents_exports.Name.JS_SAMPLE, + cat: "devtools.timeline", + args: { + data: { traceId, stackTrace: this.#makeProfileCallsForStack(call).map((e) => e.callFrame) } + }, + ph: TraceEvents_exports.Phase.INSTANT, + ts: timestamp, + dur: Timing_exports.Micro(0), + pid: this.#processId, + tid: this.#threadId + }; + return JSSampleEvent; + } + static framesAreEqual(frame1, frame2) { + return frame1.scriptId === frame2.scriptId && frame1.functionName === frame2.functionName && frame1.lineNumber === frame2.lineNumber; + } + static showNativeName(name, runtimeCallStatsEnabled) { + return runtimeCallStatsEnabled && Boolean(_a.nativeGroup(name)); + } + static nativeGroup(nativeName) { + if (nativeName.startsWith("Parse")) { + return _a.NativeGroups.PARSE; + } + if (nativeName.startsWith("Compile") || nativeName.startsWith("Recompile")) { + return _a.NativeGroups.COMPILE; + } + return null; + } + static isNativeRuntimeFrame(frame) { + return frame.url === "native V8Runtime"; + } + static filterStackFrames(stack, engineConfig) { + const showAllEvents = engineConfig.showAllEvents; + if (showAllEvents) { + return; + } + let previousNativeFrameName = null; + let j = 0; + for (let i = 0; i < stack.length; ++i) { + const frame = stack[i].callFrame; + const nativeRuntimeFrame = _a.isNativeRuntimeFrame(frame); + if (nativeRuntimeFrame && !_a.showNativeName(frame.functionName, engineConfig.includeRuntimeCallStats)) { + continue; + } + const nativeFrameName = nativeRuntimeFrame ? _a.nativeGroup(frame.functionName) : null; + if (previousNativeFrameName && previousNativeFrameName === nativeFrameName) { + continue; + } + previousNativeFrameName = nativeFrameName; + stack[j++] = stack[i]; + } + stack.length = j; + } + static createFakeTraceFromCpuProfile(profile, tid) { + if (!profile) { + return { traceEvents: [], metadata: {} }; + } + const cpuProfileEvent = { + cat: "disabled-by-default-devtools.timeline", + name: TraceEvents_exports.Name.CPU_PROFILE, + ph: TraceEvents_exports.Phase.COMPLETE, + pid: TraceEvents_exports.ProcessID(1), + tid, + ts: Timing_exports.Micro(profile.startTime), + dur: Timing_exports.Micro(profile.endTime - profile.startTime), + args: { data: { cpuProfile: profile } }, + // Create an arbitrary profile id. + id: "0x1" + }; + return { + traceEvents: [cpuProfileEvent], + metadata: { + dataOrigin: File_exports.DataOrigin.CPU_PROFILE + } + }; + } + static extractCpuProfileFromFakeTrace(traceEvents) { + const profileEvent = traceEvents.find((e) => TraceEvents_exports.isSyntheticCpuProfile(e)); + const profile = profileEvent?.args.data.cpuProfile; + if (!profile) { + throw new Error("Missing cpuProfile data"); + } + return profile; + } + }; + _a = SamplesIntegrator; + (function(SamplesIntegrator2) { + let NativeGroups; + (function(NativeGroups2) { + NativeGroups2["COMPILE"] = "Compile"; + NativeGroups2["PARSE"] = "Parse"; + })(NativeGroups = SamplesIntegrator2.NativeGroups || (SamplesIntegrator2.NativeGroups = {})); + })(SamplesIntegrator || (SamplesIntegrator = {})); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/helpers/helpers.js +var init_helpers2 = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/helpers/helpers.js"() { + init_process_global(); + init_Extensions2(); + init_Network(); + init_SamplesIntegrator(); + init_SyntheticEvents(); + init_Timing3(); + init_Trace(); + init_TreeHelpers(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/AnimationFramesHandler.js +var AnimationFramesHandler_exports = {}; +__export(AnimationFramesHandler_exports, { + data: () => data, + deps: () => deps, + finalize: () => finalize, + handleEvent: () => handleEvent, + handleUserConfig: () => handleUserConfig, + reset: () => reset +}); +function threadKey(data31) { + return `${data31.pid}-${data31.tid}`; +} +function reset() { + animationFrameStarts = /* @__PURE__ */ new Map(); + animationFrameEnds = /* @__PURE__ */ new Map(); + animationFrames = []; + presentationForFrame = /* @__PURE__ */ new Map(); + animationFramePresentations = /* @__PURE__ */ new Map(); + isEnabled = false; +} +function handleUserConfig(config3) { + isEnabled = config3.enableAnimationsFrameHandler; +} +function handleEvent(event) { + if (!isEnabled) { + return; + } + if (TraceEvents_exports.isAnimationFrameAsyncStart(event)) { + const key = threadKey(event); + const existing = animationFrameStarts.get(key) ?? []; + existing.push(event); + animationFrameStarts.set(key, existing); + } else if (TraceEvents_exports.isAnimationFrameAsyncEnd(event)) { + const key = threadKey(event); + const existing = animationFrameEnds.get(key) ?? []; + existing.push(event); + animationFrameEnds.set(key, existing); + } else if (TraceEvents_exports.isAnimationFramePresentation(event) && event.args?.id) { + animationFramePresentations.set(event.args.id, event); + } +} +async function finalize() { + for (const [key, startEvents] of animationFrameStarts.entries()) { + const endEvents = animationFrameEnds.get(key); + if (!endEvents) { + continue; + } + Trace_exports.sortTraceEventsInPlace(startEvents); + Trace_exports.sortTraceEventsInPlace(endEvents); + for (let i = 0; i < startEvents.length; i++) { + const endEvent = endEvents.at(i); + if (!endEvent) { + break; + } + const startEvent = startEvents[i]; + const syntheticEvent = SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent({ + rawSourceEvent: startEvent, + ...startEvent, + dur: Timing_exports.Micro(endEvent.ts - startEvent.ts), + args: { + data: { + beginEvent: startEvent, + endEvent + } + } + }); + animationFrames.push(syntheticEvent); + const id = startEvent.args?.id; + if (id) { + const presentationEvent = animationFramePresentations.get(id); + if (presentationEvent) { + presentationForFrame.set(syntheticEvent, presentationEvent); + } + } + } + } +} +function data() { + return { + animationFrames, + presentationForFrame + }; +} +function deps() { + return ["Meta"]; +} +var animationFrameStarts, animationFrameEnds, animationFramePresentations, animationFrames, presentationForFrame, isEnabled; +var init_AnimationFramesHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/AnimationFramesHandler.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + __name(threadKey, "threadKey"); + animationFrameStarts = /* @__PURE__ */ new Map(); + animationFrameEnds = /* @__PURE__ */ new Map(); + animationFramePresentations = /* @__PURE__ */ new Map(); + animationFrames = []; + presentationForFrame = /* @__PURE__ */ new Map(); + __name(reset, "reset"); + isEnabled = false; + __name(handleUserConfig, "handleUserConfig"); + __name(handleEvent, "handleEvent"); + __name(finalize, "finalize"); + __name(data, "data"); + __name(deps, "deps"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/AnimationHandler.js +var AnimationHandler_exports = {}; +__export(AnimationHandler_exports, { + data: () => data2, + finalize: () => finalize2, + handleEvent: () => handleEvent2, + reset: () => reset2 +}); +function reset2() { + animations = []; + animationsSyntheticEvents = []; +} +function handleEvent2(event) { + if (TraceEvents_exports.isAnimation(event)) { + animations.push(event); + return; + } +} +async function finalize2() { + const syntheticEvents2 = Trace_exports.createMatchedSortedSyntheticEvents(animations); + animationsSyntheticEvents.push(...syntheticEvents2); +} +function data2() { + return { + animations: animationsSyntheticEvents + }; +} +var animations, animationsSyntheticEvents; +var init_AnimationHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/AnimationHandler.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + animations = []; + animationsSyntheticEvents = []; + __name(reset2, "reset"); + __name(handleEvent2, "handleEvent"); + __name(finalize2, "finalize"); + __name(data2, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/FlowsHandler.js +var FlowsHandler_exports = {}; +__export(FlowsHandler_exports, { + data: () => data3, + finalize: () => finalize3, + handleEvent: () => handleEvent3, + reset: () => reset3 +}); +function reset3() { + flows = []; + flowEvents = []; + nonFlowEvents = []; + flowDataByGroupToken = /* @__PURE__ */ new Map(); + boundFlowData = /* @__PURE__ */ new Map(); + flowsById = /* @__PURE__ */ new Map(); +} +function handleEvent3(event) { + if (TraceEvents_exports.isFlowPhaseEvent(event)) { + flowEvents.push(event); + return; + } + nonFlowEvents.push(event); +} +function processNonFlowEvent(event) { + const flowDataForEvent = boundFlowData.get(event.ts)?.get(event.pid)?.get(event.tid)?.get(event.cat); + if (!flowDataForEvent) { + return; + } + const { flows: flows2, bindingParsed } = flowDataForEvent; + if (bindingParsed) { + return; + } + for (const flowId of flows2) { + const flow = MapUtilities_exports.getWithDefault(flowsById, flowId, () => /* @__PURE__ */ new Map()); + flow.set(event.ts, event); + } + flowDataForEvent.bindingParsed = true; +} +function processFlowEvent(flowPhaseEvent) { + const flowGroup = flowGroupTokenForFlowPhaseEvent(flowPhaseEvent); + switch (flowPhaseEvent.ph) { + case TraceEvents_exports.Phase.FLOW_START: { + const flowMetadata = { flowId: flowPhaseEvent.id, times: /* @__PURE__ */ new Map([[flowPhaseEvent.ts, void 0]]) }; + flowDataByGroupToken.set(flowGroup, flowPhaseEvent.id); + addFlowIdToEventBinding(flowPhaseEvent, flowMetadata.flowId); + return; + } + case TraceEvents_exports.Phase.FLOW_STEP: { + const flowId = flowDataByGroupToken.get(flowGroup); + if (flowId === void 0) { + return; + } + addFlowIdToEventBinding(flowPhaseEvent, flowId); + return; + } + case TraceEvents_exports.Phase.FLOW_END: { + const flowId = flowDataByGroupToken.get(flowGroup); + if (flowId === void 0) { + return; + } + addFlowIdToEventBinding(flowPhaseEvent, flowId); + flowDataByGroupToken.delete(flowGroup); + } + } +} +function addFlowIdToEventBinding(event, flowId) { + const flowsByPid = MapUtilities_exports.getWithDefault(boundFlowData, event.ts, () => /* @__PURE__ */ new Map()); + const flowsByTid = MapUtilities_exports.getWithDefault(flowsByPid, event.pid, () => /* @__PURE__ */ new Map()); + const flowsByCat = MapUtilities_exports.getWithDefault(flowsByTid, event.tid, () => /* @__PURE__ */ new Map()); + const flowData = MapUtilities_exports.getWithDefault(flowsByCat, event.cat, () => ({ flows: /* @__PURE__ */ new Set(), bindingParsed: false })); + flowData.flows.add(flowId); +} +function flowGroupTokenForFlowPhaseEvent(event) { + return `${event.cat}${ID_COMPONENT_SEPARATOR}${event.name}${ID_COMPONENT_SEPARATOR}${event.id}`; +} +async function finalize3() { + flowEvents.forEach(processFlowEvent); + nonFlowEvents.forEach(processNonFlowEvent); + flows = [...flowsById.values()].map((flowMapping) => [...flowMapping.values()]).map((flow) => flow.filter((event) => event !== void 0)).filter((flow) => flow.length > 1); +} +function data3() { + return { + flows + }; +} +var flowDataByGroupToken, boundFlowData, flowsById, flowEvents, nonFlowEvents, flows, ID_COMPONENT_SEPARATOR; +var init_FlowsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/FlowsHandler.js"() { + init_process_global(); + init_platform(); + init_types2(); + flowDataByGroupToken = /* @__PURE__ */ new Map(); + boundFlowData = /* @__PURE__ */ new Map(); + flowsById = /* @__PURE__ */ new Map(); + flowEvents = []; + nonFlowEvents = []; + flows = []; + ID_COMPONENT_SEPARATOR = "-$-"; + __name(reset3, "reset"); + __name(handleEvent3, "handleEvent"); + __name(processNonFlowEvent, "processNonFlowEvent"); + __name(processFlowEvent, "processFlowEvent"); + __name(addFlowIdToEventBinding, "addFlowIdToEventBinding"); + __name(flowGroupTokenForFlowPhaseEvent, "flowGroupTokenForFlowPhaseEvent"); + __name(finalize3, "finalize"); + __name(data3, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/AuctionWorkletsHandler.js +var AuctionWorkletsHandler_exports = {}; +__export(AuctionWorkletsHandler_exports, { + data: () => data4, + finalize: () => finalize4, + handleEvent: () => handleEvent4, + reset: () => reset4 +}); +function reset4() { + runningInProcessEvents = /* @__PURE__ */ new Map(); + doneWithProcessEvents = /* @__PURE__ */ new Map(); + createdSyntheticEvents = /* @__PURE__ */ new Map(); + utilityThreads = /* @__PURE__ */ new Map(); + v8HelperThreads = /* @__PURE__ */ new Map(); +} +function handleEvent4(event) { + if (TraceEvents_exports.isAuctionWorkletRunningInProcess(event)) { + runningInProcessEvents.set(event.args.data.pid, event); + return; + } + if (TraceEvents_exports.isAuctionWorkletDoneWithProcess(event)) { + doneWithProcessEvents.set(event.args.data.pid, event); + return; + } + if (TraceEvents_exports.isThreadName(event)) { + if (event.args.name === "auction_worklet.CrUtilityMain") { + utilityThreads.set(event.pid, event); + return; + } + if (event.args.name === "AuctionV8HelperThread") { + v8HelperThreads.set(event.pid, event); + } + } +} +function workletType(input) { + switch (input) { + case "seller": + return TraceEvents_exports.AuctionWorkletType.SELLER; + case "bidder": + return TraceEvents_exports.AuctionWorkletType.BIDDER; + default: + return TraceEvents_exports.AuctionWorkletType.UNKNOWN; + } +} +function makeSyntheticEventBase(event) { + return SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent({ + rawSourceEvent: event, + name: "SyntheticAuctionWorklet", + s: TraceEvents_exports.Scope.THREAD, + cat: event.cat, + tid: event.tid, + ts: event.ts, + ph: TraceEvents_exports.Phase.INSTANT, + pid: event.args.data.pid, + host: event.args.data.host, + target: event.args.data.target, + type: workletType(event.args.data.type) + }); +} +async function finalize4() { + for (const [pid, utilityThreadNameEvent] of utilityThreads) { + const v8HelperEvent = v8HelperThreads.get(pid); + if (!v8HelperEvent) { + continue; + } + const runningEvent = runningInProcessEvents.get(pid); + const doneWithEvent = doneWithProcessEvents.get(pid); + let syntheticEvent = null; + if (runningEvent) { + syntheticEvent = { + ...makeSyntheticEventBase(runningEvent), + args: { + data: { + runningInProcessEvent: runningEvent, + utilityThread: utilityThreadNameEvent, + v8HelperThread: v8HelperEvent + } + } + }; + if (doneWithEvent) { + syntheticEvent.args.data.doneWithProcessEvent = doneWithEvent; + } + } else if (doneWithEvent) { + syntheticEvent = { + ...makeSyntheticEventBase(doneWithEvent), + args: { + data: { + doneWithProcessEvent: doneWithEvent, + utilityThread: utilityThreadNameEvent, + v8HelperThread: v8HelperEvent + } + } + }; + if (runningEvent) { + syntheticEvent.args.data.runningInProcessEvent = runningEvent; + } + } + if (syntheticEvent === null) { + continue; + } + createdSyntheticEvents.set(pid, syntheticEvent); + } +} +function data4() { + return { + worklets: createdSyntheticEvents + }; +} +var runningInProcessEvents, doneWithProcessEvents, createdSyntheticEvents, utilityThreads, v8HelperThreads; +var init_AuctionWorkletsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/AuctionWorkletsHandler.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + runningInProcessEvents = /* @__PURE__ */ new Map(); + doneWithProcessEvents = /* @__PURE__ */ new Map(); + createdSyntheticEvents = /* @__PURE__ */ new Map(); + utilityThreads = /* @__PURE__ */ new Map(); + v8HelperThreads = /* @__PURE__ */ new Map(); + __name(reset4, "reset"); + __name(handleEvent4, "handleEvent"); + __name(workletType, "workletType"); + __name(makeSyntheticEventBase, "makeSyntheticEventBase"); + __name(finalize4, "finalize"); + __name(data4, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/MetaHandler.js +var MetaHandler_exports = {}; +__export(MetaHandler_exports, { + data: () => data5, + finalize: () => finalize5, + handleEvent: () => handleEvent5, + reset: () => reset5 +}); +function makeNewTraceBounds() { + return { + min: Timing_exports.Micro(Number.POSITIVE_INFINITY), + max: Timing_exports.Micro(Number.NEGATIVE_INFINITY), + range: Timing_exports.Micro(Number.POSITIVE_INFINITY) + }; +} +function reset5() { + navigationsByFrameId = /* @__PURE__ */ new Map(); + navigationsByNavigationId = /* @__PURE__ */ new Map(); + finalDisplayUrlByNavigationId = /* @__PURE__ */ new Map(); + processNames = /* @__PURE__ */ new Map(); + mainFrameNavigations = []; + browserProcessId = TraceEvents_exports.ProcessID(-1); + browserThreadId = TraceEvents_exports.ThreadID(-1); + gpuProcessId = TraceEvents_exports.ProcessID(-1); + gpuThreadId = TraceEvents_exports.ThreadID(-1); + viewportRect = null; + topLevelRendererIds = /* @__PURE__ */ new Set(); + threadsInProcess = /* @__PURE__ */ new Map(); + rendererProcessesByFrameId = /* @__PURE__ */ new Map(); + framesByProcessId = /* @__PURE__ */ new Map(); + traceBounds = makeNewTraceBounds(); + traceStartedTimeFromTracingStartedEvent = Timing_exports.Micro(-1); + traceIsGeneric = true; +} +function updateRendererProcessByFrame(event, frame) { + const framesInProcessById = MapUtilities_exports.getWithDefault(framesByProcessId, frame.processId, () => /* @__PURE__ */ new Map()); + framesInProcessById.set(frame.frame, frame); + const rendererProcessInFrame = MapUtilities_exports.getWithDefault(rendererProcessesByFrameId, frame.frame, () => /* @__PURE__ */ new Map()); + const rendererProcessInfo = MapUtilities_exports.getWithDefault(rendererProcessInFrame, frame.processId, () => { + return []; + }); + const lastProcessData = rendererProcessInfo.at(-1); + if (lastProcessData && lastProcessData.frame.url === frame.url) { + return; + } + rendererProcessInfo.push({ + frame, + window: { + min: event.ts, + max: Timing_exports.Micro(0), + range: Timing_exports.Micro(0) + } + }); +} +function handleEvent5(event) { + if (traceIsGeneric && CHROME_WEB_TRACE_EVENTS.has(event.name)) { + traceIsGeneric = false; + } + if (TraceEvents_exports.isProcessName(event)) { + processNames.set(event.pid, event); + } + if (event.ts !== 0 && !event.name.endsWith("::UMA") && eventPhasesOfInterestForTraceBounds.has(event.ph)) { + traceBounds.min = Timing_exports.Micro(Math.min(event.ts, traceBounds.min)); + const eventDuration = event.dur ?? Timing_exports.Micro(0); + traceBounds.max = Timing_exports.Micro(Math.max(event.ts + eventDuration, traceBounds.max)); + } + if (TraceEvents_exports.isProcessName(event) && (event.args.name === "Browser" || event.args.name === "HeadlessBrowser")) { + browserProcessId = event.pid; + return; + } + if (TraceEvents_exports.isProcessName(event) && (event.args.name === "Gpu" || event.args.name === "GPU Process")) { + gpuProcessId = event.pid; + return; + } + if (TraceEvents_exports.isThreadName(event) && event.args.name === "CrGpuMain") { + gpuThreadId = event.tid; + return; + } + if (TraceEvents_exports.isThreadName(event) && event.args.name === "CrBrowserMain") { + browserThreadId = event.tid; + } + if (TraceEvents_exports.isMainFrameViewport(event) && viewportRect === null) { + const rectAsArray = event.args.data.viewport_rect; + const viewportX = rectAsArray[0]; + const viewportY = rectAsArray[1]; + const viewportWidth = rectAsArray[2]; + const viewportHeight = rectAsArray[5]; + viewportRect = { x: viewportX, y: viewportY, width: viewportWidth, height: viewportHeight }; + devicePixelRatio2 = event.args.data.dpr; + } + if (TraceEvents_exports.isTracingStartedInBrowser(event)) { + traceStartedTimeFromTracingStartedEvent = event.ts; + if (!event.args.data) { + throw new Error("No frames found in trace data"); + } + for (const frame of event.args.data.frames ?? []) { + updateRendererProcessByFrame(event, frame); + if (!frame.parent) { + topLevelRendererIds.add(frame.processId); + } + const traceHasPrimaryMainFrameFlag = "isInPrimaryMainFrame" in frame; + const traceHasOutermostMainFrameFlag = "isOutermostMainFrame" in frame; + if (traceHasPrimaryMainFrameFlag && traceHasOutermostMainFrameFlag) { + if (frame.isInPrimaryMainFrame && frame.isOutermostMainFrame) { + mainFrameId = frame.frame; + mainFrameURL = frame.url; + } + } else if (traceHasOutermostMainFrameFlag) { + if (frame.isOutermostMainFrame) { + mainFrameId = frame.frame; + mainFrameURL = frame.url; + } + } else if (!frame.parent && frame.url) { + mainFrameId = frame.frame; + mainFrameURL = frame.url; + } + } + return; + } + if (TraceEvents_exports.isFrameCommittedInBrowser(event)) { + const frame = event.args.data; + if (!frame) { + return; + } + updateRendererProcessByFrame(event, frame); + if (frame.parent) { + return; + } + topLevelRendererIds.add(frame.processId); + return; + } + if (TraceEvents_exports.isCommitLoad(event)) { + const frameData = event.args.data; + if (!frameData) { + return; + } + const { frame, name, url } = frameData; + updateRendererProcessByFrame(event, { processId: event.pid, frame, name, url }); + return; + } + if (TraceEvents_exports.isThreadName(event)) { + const threads = MapUtilities_exports.getWithDefault(threadsInProcess, event.pid, () => /* @__PURE__ */ new Map()); + threads.set(event.tid, event); + return; + } + if (TraceEvents_exports.isNavigationStart(event) && event.args.data) { + const navigationId = event.args.data.navigationId; + if (navigationsByNavigationId.has(navigationId)) { + return; + } + navigationsByNavigationId.set(navigationId, event); + finalDisplayUrlByNavigationId.set(navigationId, event.args.data.documentLoaderURL); + const frameId = event.args.frame; + const existingFrameNavigations = navigationsByFrameId.get(frameId) || []; + existingFrameNavigations.push(event); + navigationsByFrameId.set(frameId, existingFrameNavigations); + if (frameId === mainFrameId) { + mainFrameNavigations.push(event); + } + return; + } + if (TraceEvents_exports.isResourceSendRequest(event)) { + if (event.args.data.resourceType !== "Document") { + return; + } + const maybeNavigationId = event.args.data.requestId; + const navigation2 = navigationsByNavigationId.get(maybeNavigationId); + if (!navigation2) { + return; + } + finalDisplayUrlByNavigationId.set(maybeNavigationId, event.args.data.url); + return; + } + if (TraceEvents_exports.isDidCommitSameDocumentNavigation(event)) { + if (event.args.render_frame_host.frame_type !== "PRIMARY_MAIN_FRAME") { + return; + } + const navigation2 = mainFrameNavigations.at(-1); + const key = navigation2?.args.data?.navigationId ?? ""; + finalDisplayUrlByNavigationId.set(key, event.args.url); + return; + } +} +async function finalize5() { + if (traceStartedTimeFromTracingStartedEvent >= 0) { + traceBounds.min = traceStartedTimeFromTracingStartedEvent; + } + traceBounds.range = Timing_exports.Micro(traceBounds.max - traceBounds.min); + for (const [, processWindows] of rendererProcessesByFrameId) { + const processWindowValues = [...processWindows.values()].flat().sort((a, b) => { + return a.window.min - b.window.min; + }); + for (let i = 0; i < processWindowValues.length; i++) { + const currentWindow = processWindowValues[i]; + const nextWindow = processWindowValues[i + 1]; + if (!nextWindow) { + currentWindow.window.max = Timing_exports.Micro(traceBounds.max); + currentWindow.window.range = Timing_exports.Micro(traceBounds.max - currentWindow.window.min); + } else { + currentWindow.window.max = Timing_exports.Micro(nextWindow.window.min - 1); + currentWindow.window.range = Timing_exports.Micro(currentWindow.window.max - currentWindow.window.min); + } + } + } + for (const [frameId, navigations] of navigationsByFrameId) { + if (rendererProcessesByFrameId.has(frameId)) { + continue; + } + navigationsByFrameId.delete(frameId); + for (const navigation2 of navigations) { + if (!navigation2.args.data) { + continue; + } + navigationsByNavigationId.delete(navigation2.args.data.navigationId); + } + } + const firstMainFrameNav = mainFrameNavigations.at(0); + const firstNavTimeThreshold = Timing_exports3.secondsToMicro(Timing_exports.Seconds(0.5)); + if (firstMainFrameNav) { + const navigationIsWithinThreshold = firstMainFrameNav.ts - traceBounds.min < firstNavTimeThreshold; + if (firstMainFrameNav.args.data?.isOutermostMainFrame && firstMainFrameNav.args.data?.documentLoaderURL && navigationIsWithinThreshold) { + mainFrameURL = firstMainFrameNav.args.data.documentLoaderURL; + } + } +} +function data5() { + return { + traceBounds, + browserProcessId, + browserThreadId, + processNames, + gpuProcessId, + gpuThreadId: gpuThreadId === TraceEvents_exports.ThreadID(-1) ? void 0 : gpuThreadId, + viewportRect: viewportRect || void 0, + devicePixelRatio: devicePixelRatio2 ?? void 0, + mainFrameId, + mainFrameURL, + navigationsByFrameId, + navigationsByNavigationId, + finalDisplayUrlByNavigationId, + threadsInProcess, + rendererProcessesByFrame: rendererProcessesByFrameId, + topLevelRendererIds, + frameByProcessId: framesByProcessId, + mainFrameNavigations, + traceIsGeneric + }; +} +var rendererProcessesByFrameId, mainFrameId, mainFrameURL, framesByProcessId, browserProcessId, browserThreadId, gpuProcessId, gpuThreadId, viewportRect, devicePixelRatio2, processNames, topLevelRendererIds, traceBounds, navigationsByFrameId, navigationsByNavigationId, finalDisplayUrlByNavigationId, mainFrameNavigations, threadsInProcess, traceStartedTimeFromTracingStartedEvent, eventPhasesOfInterestForTraceBounds, traceIsGeneric, CHROME_WEB_TRACE_EVENTS; +var init_MetaHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/MetaHandler.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + rendererProcessesByFrameId = /* @__PURE__ */ new Map(); + mainFrameId = ""; + mainFrameURL = ""; + framesByProcessId = /* @__PURE__ */ new Map(); + browserProcessId = TraceEvents_exports.ProcessID(-1); + browserThreadId = TraceEvents_exports.ThreadID(-1); + gpuProcessId = TraceEvents_exports.ProcessID(-1); + gpuThreadId = TraceEvents_exports.ThreadID(-1); + viewportRect = null; + devicePixelRatio2 = null; + processNames = /* @__PURE__ */ new Map(); + topLevelRendererIds = /* @__PURE__ */ new Set(); + __name(makeNewTraceBounds, "makeNewTraceBounds"); + traceBounds = makeNewTraceBounds(); + navigationsByFrameId = /* @__PURE__ */ new Map(); + navigationsByNavigationId = /* @__PURE__ */ new Map(); + finalDisplayUrlByNavigationId = /* @__PURE__ */ new Map(); + mainFrameNavigations = []; + threadsInProcess = /* @__PURE__ */ new Map(); + traceStartedTimeFromTracingStartedEvent = Timing_exports.Micro(-1); + eventPhasesOfInterestForTraceBounds = /* @__PURE__ */ new Set([ + TraceEvents_exports.Phase.BEGIN, + TraceEvents_exports.Phase.END, + TraceEvents_exports.Phase.COMPLETE, + TraceEvents_exports.Phase.INSTANT + ]); + traceIsGeneric = true; + CHROME_WEB_TRACE_EVENTS = /* @__PURE__ */ new Set([ + TraceEvents_exports.Name.TRACING_STARTED_IN_PAGE, + TraceEvents_exports.Name.TRACING_SESSION_ID_FOR_WORKER, + TraceEvents_exports.Name.TRACING_STARTED_IN_BROWSER, + TraceEvents_exports.Name.CPU_PROFILE + ]); + __name(reset5, "reset"); + __name(updateRendererProcessByFrame, "updateRendererProcessByFrame"); + __name(handleEvent5, "handleEvent"); + __name(finalize5, "finalize"); + __name(data5, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/NetworkRequestsHandler.js +var NetworkRequestsHandler_exports = {}; +__export(NetworkRequestsHandler_exports, { + data: () => data6, + deps: () => deps2, + finalize: () => finalize6, + handleEvent: () => handleEvent6, + reset: () => reset6 +}); +function storeTraceEventWithRequestId(requestId, key, value) { + if (!requestMap.has(requestId)) { + requestMap.set(requestId, {}); + } + const traceEvents = requestMap.get(requestId); + if (!traceEvents) { + throw new Error(`Unable to locate trace events for request ID ${requestId}`); + } + if (Array.isArray(traceEvents[key])) { + const target = traceEvents[key]; + const values = value; + target.push(...values); + } else { + traceEvents[key] = value; + } +} +function firstPositiveValueInList(entries) { + for (const entry of entries) { + if (entry && entry > 0) { + return entry; + } + } + return 0; +} +function reset6() { + requestsById = /* @__PURE__ */ new Map(); + requestMap = /* @__PURE__ */ new Map(); + requestsByTime = []; + networkRequestEventByInitiatorUrl = /* @__PURE__ */ new Map(); + eventToInitiatorMap = /* @__PURE__ */ new Map(); + webSocketData = /* @__PURE__ */ new Map(); + entityMappings = { + eventsByEntity: /* @__PURE__ */ new Map(), + entityByEvent: /* @__PURE__ */ new Map(), + createdEntityCache: /* @__PURE__ */ new Map(), + entityByUrlCache: /* @__PURE__ */ new Map() + }; + linkPreconnectEvents = []; +} +function handleEvent6(event) { + if (TraceEvents_exports.isResourceChangePriority(event)) { + storeTraceEventWithRequestId(event.args.data.requestId, "changePriority", event); + return; + } + if (TraceEvents_exports.isResourceWillSendRequest(event)) { + storeTraceEventWithRequestId(event.args.data.requestId, "willSendRequests", [event]); + return; + } + if (TraceEvents_exports.isResourceSendRequest(event)) { + storeTraceEventWithRequestId(event.args.data.requestId, "sendRequests", [event]); + return; + } + if (TraceEvents_exports.isResourceReceiveResponse(event)) { + storeTraceEventWithRequestId(event.args.data.requestId, "receiveResponse", event); + return; + } + if (TraceEvents_exports.isResourceReceivedData(event)) { + storeTraceEventWithRequestId(event.args.data.requestId, "receivedData", [event]); + return; + } + if (TraceEvents_exports.isResourceFinish(event)) { + storeTraceEventWithRequestId(event.args.data.requestId, "resourceFinish", event); + return; + } + if (TraceEvents_exports.isResourceMarkAsCached(event)) { + storeTraceEventWithRequestId(event.args.data.requestId, "resourceMarkAsCached", event); + return; + } + if (TraceEvents_exports.isWebSocketCreate(event) || TraceEvents_exports.isWebSocketInfo(event) || TraceEvents_exports.isWebSocketTransfer(event)) { + const identifier = event.args.data.identifier; + if (!webSocketData.has(identifier)) { + if (event.args.data.frame) { + webSocketData.set(identifier, { + frame: event.args.data.frame, + webSocketIdentifier: identifier, + events: [], + syntheticConnection: null + }); + } else if (event.args.data.workerId) { + webSocketData.set(identifier, { + workerId: event.args.data.workerId, + webSocketIdentifier: identifier, + events: [], + syntheticConnection: null + }); + } + } + webSocketData.get(identifier)?.events.push(event); + } + if (TraceEvents_exports.isLinkPreconnect(event)) { + linkPreconnectEvents.push(event); + return; + } +} +async function finalize6() { + const { rendererProcessesByFrame } = data5(); + for (const [requestId, request] of requestMap.entries()) { + if (!request.sendRequests) { + continue; + } + const redirects = []; + for (let i = 0; i < request.sendRequests.length - 1; i++) { + const sendRequest = request.sendRequests[i]; + const nextSendRequest = request.sendRequests[i + 1]; + let ts = sendRequest.ts; + let dur = Timing_exports.Micro(nextSendRequest.ts - sendRequest.ts); + if (request.willSendRequests?.[i] && request.willSendRequests[i + 1]) { + const willSendRequest = request.willSendRequests[i]; + const nextWillSendRequest = request.willSendRequests[i + 1]; + ts = willSendRequest.ts; + dur = Timing_exports.Micro(nextWillSendRequest.ts - willSendRequest.ts); + } + redirects.push({ + url: sendRequest.args.data.url, + priority: sendRequest.args.data.priority, + requestMethod: sendRequest.args.data.requestMethod, + ts, + dur + }); + } + const firstSendRequest = request.sendRequests[0]; + const finalSendRequest = request.sendRequests[request.sendRequests.length - 1]; + if (finalSendRequest.args.data.url.startsWith("data:")) { + continue; + } + const isLightrider = globalThis.isLightrider; + if (isLightrider && request.resourceFinish && request.receiveResponse?.args.data.headers) { + const lrSizeHeader = request.receiveResponse.args.data.headers.find((h) => h.name === "X-TotalFetchedSize"); + if (lrSizeHeader) { + const size = parseFloat(lrSizeHeader.value); + if (!isNaN(size)) { + request.resourceFinish.args.data.encodedDataLength = size; + } + } + } + const isPushedResource = request.resourceFinish?.args.data.encodedDataLength !== 0; + const isDiskCached = !!request.receiveResponse && request.receiveResponse.args.data.fromCache && !request.receiveResponse.args.data.fromServiceWorker && !isPushedResource; + const isMemoryCached = request.resourceMarkAsCached !== void 0; + let timing = isMemoryCached ? void 0 : request.receiveResponse?.args.data.timing; + let lrServerResponseTime; + if (isLightrider && request.receiveResponse?.args.data.headers) { + timing = { + requestTime: Timing_exports3.microToSeconds(request.sendRequests.at(0)?.ts ?? 0), + connectEnd: 0, + connectStart: 0, + dnsEnd: 0, + dnsStart: 0, + proxyEnd: 0, + proxyStart: 0, + pushEnd: 0, + pushStart: 0, + receiveHeadersEnd: 0, + receiveHeadersStart: 0, + sendEnd: 0, + sendStart: 0, + sslEnd: 0, + sslStart: 0, + workerReady: 0, + workerStart: 0, + ...timing + }; + const TCPMsHeader = request.receiveResponse.args.data.headers.find((h) => h.name === "X-TCPMs"); + const TCPMs = TCPMsHeader ? Math.max(0, parseInt(TCPMsHeader.value, 10)) : 0; + if (request.receiveResponse.args.data.protocol.startsWith("h3")) { + timing.connectStart = 0; + timing.connectEnd = TCPMs; + } else { + timing.connectStart = 0; + timing.sslStart = TCPMs / 2; + timing.connectEnd = TCPMs; + timing.sslEnd = TCPMs; + } + const ResponseMsHeader = request.receiveResponse.args.data.headers.find((h) => h.name === "X-ResponseMs"); + if (ResponseMsHeader) { + lrServerResponseTime = Math.max(0, parseInt(ResponseMsHeader.value, 10)); + } + } + const allowedProtocols2 = [ + "blob:", + "file:", + "filesystem:", + "http:", + "https:" + ]; + if (!allowedProtocols2.some((p) => firstSendRequest.args.data.url.startsWith(p))) { + continue; + } + const initialPriority = finalSendRequest.args.data.priority; + let finalPriority = initialPriority; + if (request.changePriority) { + finalPriority = request.changePriority.args.data.priority; + } + const startTime = request.willSendRequests?.length ? Timing_exports.Micro(request.willSendRequests[0].ts) : Timing_exports.Micro(firstSendRequest.ts); + const endRedirectTime = request.willSendRequests?.length ? Timing_exports.Micro(request.willSendRequests[request.willSendRequests.length - 1].ts) : Timing_exports.Micro(finalSendRequest.ts); + const endTime = request.resourceFinish ? request.resourceFinish.ts : endRedirectTime; + const finishTime = request.resourceFinish?.args.data.finishTime ? Timing_exports.Micro(request.resourceFinish.args.data.finishTime * SECONDS_TO_MICROSECONDS) : Timing_exports.Micro(endTime); + const networkDuration = Timing_exports.Micro(timing ? (finishTime || endRedirectTime) - endRedirectTime : 0); + const processingDuration = Timing_exports.Micro(endTime - (finishTime || endTime)); + const redirectionDuration = Timing_exports.Micro(endRedirectTime - startTime); + const queueingFromTraceData = timing ? timing.requestTime * SECONDS_TO_MICROSECONDS - endRedirectTime : 0; + const queueing = Timing_exports.Micro(NumberUtilities_exports.clamp(queueingFromTraceData, 0, Number.MAX_VALUE)); + const stalled = timing ? Timing_exports.Micro(firstPositiveValueInList([ + timing.dnsStart * MILLISECONDS_TO_MICROSECONDS, + timing.connectStart * MILLISECONDS_TO_MICROSECONDS, + timing.sendStart * MILLISECONDS_TO_MICROSECONDS, + request.receiveResponse ? request.receiveResponse.ts - endRedirectTime : null + ])) : request.receiveResponse ? Timing_exports.Micro(request.receiveResponse.ts - startTime) : Timing_exports.Micro(0); + const sendStartTime = timing ? Timing_exports.Micro(timing.requestTime * SECONDS_TO_MICROSECONDS + timing.sendStart * MILLISECONDS_TO_MICROSECONDS) : startTime; + const waiting = timing ? Timing_exports.Micro((timing.receiveHeadersEnd - timing.sendEnd) * MILLISECONDS_TO_MICROSECONDS) : Timing_exports.Micro(0); + const serverResponseTime = timing ? Timing_exports.Micro(((timing.receiveHeadersStart ?? timing.receiveHeadersEnd) - timing.sendEnd) * MILLISECONDS_TO_MICROSECONDS) : Timing_exports.Micro(0); + const downloadStart = timing ? Timing_exports.Micro(timing.requestTime * SECONDS_TO_MICROSECONDS + timing.receiveHeadersEnd * MILLISECONDS_TO_MICROSECONDS) : startTime; + const download = timing ? Timing_exports.Micro((finishTime || downloadStart) - downloadStart) : request.receiveResponse ? Timing_exports.Micro(endTime - request.receiveResponse.ts) : Timing_exports.Micro(0); + const totalTime = Timing_exports.Micro(networkDuration + processingDuration); + const dnsLookup = timing ? Timing_exports.Micro((timing.dnsEnd - timing.dnsStart) * MILLISECONDS_TO_MICROSECONDS) : Timing_exports.Micro(0); + const ssl = timing ? Timing_exports.Micro((timing.sslEnd - timing.sslStart) * MILLISECONDS_TO_MICROSECONDS) : Timing_exports.Micro(0); + const proxyNegotiation = timing ? Timing_exports.Micro((timing.proxyEnd - timing.proxyStart) * MILLISECONDS_TO_MICROSECONDS) : Timing_exports.Micro(0); + const requestSent = timing ? Timing_exports.Micro((timing.sendEnd - timing.sendStart) * MILLISECONDS_TO_MICROSECONDS) : Timing_exports.Micro(0); + const initialConnection = timing ? Timing_exports.Micro((timing.connectEnd - timing.connectStart) * MILLISECONDS_TO_MICROSECONDS) : Timing_exports.Micro(0); + const { frame, url, renderBlocking } = finalSendRequest.args.data; + const { encodedDataLength, decodedBodyLength } = request.resourceFinish ? request.resourceFinish.args.data : { encodedDataLength: 0, decodedBodyLength: 0 }; + const parsedUrl = new URL(url); + const isHttps = parsedUrl.protocol === "https:"; + const requestingFrameUrl = Trace_exports.activeURLForFrameAtTime(frame, finalSendRequest.ts, rendererProcessesByFrame) || ""; + const networkEvent = SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent({ + rawSourceEvent: finalSendRequest, + args: { + data: { + // All data we create from trace events should be added to |syntheticData|. + syntheticData: { + dnsLookup, + download, + downloadStart, + finishTime, + initialConnection, + isDiskCached, + isHttps, + isMemoryCached, + isPushedResource, + networkDuration, + processingDuration, + proxyNegotiation, + queueing, + redirectionDuration, + requestSent, + sendStartTime, + ssl, + stalled, + totalTime, + waiting, + serverResponseTime + }, + // All fields below are from TraceEventsForNetworkRequest. + decodedBodyLength, + encodedDataLength, + frame, + fromServiceWorker: request.receiveResponse?.args.data.fromServiceWorker, + isLinkPreload: finalSendRequest.args.data.isLinkPreload || false, + mimeType: request.receiveResponse?.args.data.mimeType ?? "", + priority: finalPriority, + initialPriority, + protocol: request.receiveResponse?.args.data.protocol ?? "unknown", + redirects, + // In the event the property isn't set, assume non-blocking. + renderBlocking: renderBlocking ?? "non_blocking", + requestId, + requestingFrameUrl, + requestMethod: finalSendRequest.args.data.requestMethod, + resourceType: finalSendRequest.args.data.resourceType ?? "Other", + statusCode: request.receiveResponse?.args.data.statusCode ?? 0, + responseHeaders: request.receiveResponse?.args.data.headers ?? null, + fetchPriorityHint: finalSendRequest.args.data.fetchPriorityHint ?? "auto", + initiator: finalSendRequest.args.data.initiator, + stackTrace: finalSendRequest.args.data.stackTrace, + timing, + lrServerResponseTime, + url, + failed: request.resourceFinish?.args.data.didFail ?? false, + finished: Boolean(request.resourceFinish), + hasResponse: Boolean(request.receiveResponse), + connectionId: request.receiveResponse?.args.data.connectionId, + connectionReused: request.receiveResponse?.args.data.connectionReused + } + }, + cat: "loading", + name: TraceEvents_exports.Name.SYNTHETIC_NETWORK_REQUEST, + ph: TraceEvents_exports.Phase.COMPLETE, + dur: Timing_exports.Micro(endTime - startTime), + tdur: Timing_exports.Micro(endTime - startTime), + ts: Timing_exports.Micro(startTime), + tts: Timing_exports.Micro(startTime), + pid: finalSendRequest.pid, + tid: finalSendRequest.tid + }); + requestsByTime.push(networkEvent); + requestsById.set(networkEvent.args.data.requestId, networkEvent); + addNetworkRequestToEntityMapping(networkEvent, entityMappings, request); + const initiatorUrl = networkEvent.args.data.initiator?.url || Trace_exports.getStackTraceTopCallFrameInEventPayload(networkEvent)?.url; + if (initiatorUrl) { + const events = networkRequestEventByInitiatorUrl.get(initiatorUrl) ?? []; + events.push(networkEvent); + networkRequestEventByInitiatorUrl.set(initiatorUrl, events); + } + } + for (const request of requestsByTime) { + const initiatedEvents = networkRequestEventByInitiatorUrl.get(request.args.data.url); + if (initiatedEvents) { + for (const initiatedEvent of initiatedEvents) { + eventToInitiatorMap.set(initiatedEvent, request); + } + } + } + finalizeWebSocketData(); +} +function data6() { + return { + byId: requestsById, + byTime: requestsByTime, + eventToInitiator: eventToInitiatorMap, + webSocket: [...webSocketData.values()], + entityMappings: { + entityByEvent: entityMappings.entityByEvent, + eventsByEntity: entityMappings.eventsByEntity, + createdEntityCache: entityMappings.createdEntityCache, + entityByUrlCache: entityMappings.entityByUrlCache + }, + linkPreconnectEvents + }; +} +function deps2() { + return ["Meta"]; +} +function finalizeWebSocketData() { + webSocketData.forEach((data31) => { + let startEvent = null; + let endEvent = null; + for (const event of data31.events) { + if (TraceEvents_exports.isWebSocketCreate(event)) { + startEvent = event; + } + if (TraceEvents_exports.isWebSocketDestroy(event)) { + endEvent = event; + } + } + data31.syntheticConnection = createSyntheticWebSocketConnection(startEvent, endEvent, data31.events[0]); + }); +} +function createSyntheticWebSocketConnection(startEvent, endEvent, firstRecordedEvent) { + const { traceBounds: traceBounds2 } = data5(); + const startTs = startEvent ? startEvent.ts : traceBounds2.min; + const endTs = endEvent ? endEvent.ts : traceBounds2.max; + const duration = endTs - startTs; + const mainEvent = startEvent || endEvent || firstRecordedEvent; + return { + name: "SyntheticWebSocketConnection", + cat: mainEvent.cat, + ph: TraceEvents_exports.Phase.COMPLETE, + ts: startTs, + dur: duration, + pid: mainEvent.pid, + tid: mainEvent.tid, + s: mainEvent.s, + rawSourceEvent: mainEvent, + _tag: "SyntheticEntryTag", + args: { + data: { + identifier: mainEvent.args.data.identifier, + priority: "Low", + url: mainEvent.args.data.url || "" + } + } + }; +} +var MILLISECONDS_TO_MICROSECONDS, SECONDS_TO_MICROSECONDS, webSocketData, linkPreconnectEvents, requestMap, requestsById, requestsByTime, networkRequestEventByInitiatorUrl, eventToInitiatorMap, entityMappings; +var init_NetworkRequestsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/NetworkRequestsHandler.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + init_helpers(); + init_MetaHandler(); + MILLISECONDS_TO_MICROSECONDS = 1e3; + SECONDS_TO_MICROSECONDS = 1e6; + webSocketData = /* @__PURE__ */ new Map(); + linkPreconnectEvents = []; + requestMap = /* @__PURE__ */ new Map(); + requestsById = /* @__PURE__ */ new Map(); + requestsByTime = []; + networkRequestEventByInitiatorUrl = /* @__PURE__ */ new Map(); + eventToInitiatorMap = /* @__PURE__ */ new Map(); + entityMappings = { + eventsByEntity: /* @__PURE__ */ new Map(), + entityByEvent: /* @__PURE__ */ new Map(), + createdEntityCache: /* @__PURE__ */ new Map(), + entityByUrlCache: /* @__PURE__ */ new Map() + }; + __name(storeTraceEventWithRequestId, "storeTraceEventWithRequestId"); + __name(firstPositiveValueInList, "firstPositiveValueInList"); + __name(reset6, "reset"); + __name(handleEvent6, "handleEvent"); + __name(finalize6, "finalize"); + __name(data6, "data"); + __name(deps2, "deps"); + __name(finalizeWebSocketData, "finalizeWebSocketData"); + __name(createSyntheticWebSocketConnection, "createSyntheticWebSocketConnection"); + } +}); + +// node_modules/@paulirish/trace_engine/models/cpu_profile/ProfileTreeModel.js +var ProfileNode, ProfileTreeModel; +var init_ProfileTreeModel = __esm({ + "node_modules/@paulirish/trace_engine/models/cpu_profile/ProfileTreeModel.js"() { + init_process_global(); + ProfileNode = class { + static { + __name(this, "ProfileNode"); + } + callFrame; + callUID; + self; + total; + id; + parent; + children; + functionName; + depth; + deoptReason; + constructor(callFrame) { + this.callFrame = callFrame; + this.callUID = `${callFrame.functionName}@${callFrame.scriptId}:${callFrame.lineNumber}:${callFrame.columnNumber}`; + this.self = 0; + this.total = 0; + this.id = 0; + this.functionName = callFrame.functionName; + this.parent = null; + this.children = []; + } + get scriptId() { + return String(this.callFrame.scriptId); + } + get url() { + return this.callFrame.url; + } + get lineNumber() { + return this.callFrame.lineNumber; + } + get columnNumber() { + return this.callFrame.columnNumber; + } + setFunctionName(name) { + if (name === null) { + return; + } + this.functionName = name; + } + }; + ProfileTreeModel = class { + static { + __name(this, "ProfileTreeModel"); + } + root; + total; + maxDepth; + initialize(root2) { + this.root = root2; + this.assignDepthsAndParents(); + this.total = this.calculateTotals(this.root); + } + assignDepthsAndParents() { + const root2 = this.root; + root2.depth = -1; + root2.parent = null; + this.maxDepth = 0; + const nodesToTraverse = [root2]; + while (nodesToTraverse.length) { + const parent = nodesToTraverse.pop(); + const depth = parent.depth + 1; + if (depth > this.maxDepth) { + this.maxDepth = depth; + } + const children = parent.children; + for (const child of children) { + child.depth = depth; + child.parent = parent; + nodesToTraverse.push(child); + } + } + } + calculateTotals(root2) { + const nodesToTraverse = [root2]; + const dfsList = []; + while (nodesToTraverse.length) { + const node = nodesToTraverse.pop(); + node.total = node.self; + dfsList.push(node); + nodesToTraverse.push(...node.children); + } + while (dfsList.length > 1) { + const node = dfsList.pop(); + if (node.parent) { + node.parent.total += node.total; + } + } + return root2.total; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/cpu_profile/CPUProfileDataModel.js +var CPUProfileDataModel_exports = {}; +__export(CPUProfileDataModel_exports, { + CPUProfileDataModel: () => CPUProfileDataModel, + CPUProfileNode: () => CPUProfileNode +}); +var CPUProfileNode, CPUProfileDataModel; +var init_CPUProfileDataModel = __esm({ + "node_modules/@paulirish/trace_engine/models/cpu_profile/CPUProfileDataModel.js"() { + init_process_global(); + init_platform(); + init_ProfileTreeModel(); + CPUProfileNode = class extends ProfileNode { + static { + __name(this, "CPUProfileNode"); + } + id; + self; + // Position ticks are available in profile nodes coming from CDP + // profiles and not in those coming from tracing. They are used to + // calculate the line level execution time shown in the Sources panel + // after recording a profile. For trace CPU profiles we use the + // `lines` array instead. + positionTicks; + deoptReason; + constructor(node, samplingInterval) { + const callFrame = node.callFrame || { + // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration + // @ts-expect-error + functionName: node["functionName"], + // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration + // @ts-expect-error + scriptId: node["scriptId"], + // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration + // @ts-expect-error + url: node["url"], + // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration + // @ts-expect-error + lineNumber: node["lineNumber"] - 1, + // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration + // @ts-expect-error + columnNumber: node["columnNumber"] - 1 + }; + super(callFrame); + this.id = node.id; + this.self = (node.hitCount || 0) * samplingInterval; + this.positionTicks = node.positionTicks; + this.deoptReason = node.deoptReason && node.deoptReason !== "no reason" ? node.deoptReason : null; + } + }; + CPUProfileDataModel = class extends ProfileTreeModel { + static { + __name(this, "CPUProfileDataModel"); + } + profileStartTime; + profileEndTime; + timestamps; + samples; + /** + * Contains trace ids assigned to samples, if any. Trace ids are + * keyed by the sample index in the profile. These are only created + * for CPU profiles coming from traces. + */ + traceIds; + lines; + totalHitCount; + profileHead; + /** + * A cache for the nodes we have parsed. + * Note: "Parsed" nodes are different from the "Protocol" nodes, the + * latter being the raw data we receive from the backend. + */ + #idToParsedNode; + gcNode; + programNode; + idleNode; + #stackStartTimes; + #stackChildrenDuration; + constructor(profile) { + super(); + const isLegacyFormat = Boolean(profile["head"]); + if (isLegacyFormat) { + this.profileStartTime = profile.startTime * 1e3; + this.profileEndTime = profile.endTime * 1e3; + this.timestamps = profile.timestamps; + this.compatibilityConversionHeadToNodes(profile); + } else { + this.profileStartTime = profile.startTime / 1e3; + this.profileEndTime = profile.endTime / 1e3; + this.timestamps = this.convertTimeDeltas(profile); + } + this.traceIds = profile.traceIds; + this.samples = profile.samples; + this.lines = profile.lines; + this.totalHitCount = 0; + this.profileHead = this.translateProfileTree(profile.nodes); + this.initialize(this.profileHead); + this.extractMetaNodes(); + if (this.samples?.length) { + this.sortSamples(); + this.normalizeTimestamps(); + this.fixMissingSamples(); + } + } + compatibilityConversionHeadToNodes(profile) { + if (!profile.head || profile.nodes) { + return; + } + const nodes = []; + convertNodesTree(profile.head); + profile.nodes = nodes; + delete profile.head; + function convertNodesTree(node) { + nodes.push(node); + node.children = node.children.map(convertNodesTree); + return node.id; + } + __name(convertNodesTree, "convertNodesTree"); + } + /** + * Calculate timestamps using timeDeltas. Some CPU profile formats, + * like the ones contained in traces have timeDeltas instead of + * timestamps. + */ + convertTimeDeltas(profile) { + if (!profile.timeDeltas) { + return []; + } + let lastTimeMicroSec = profile.startTime; + const timestamps = new Array(profile.timeDeltas.length); + for (let i = 0; i < profile.timeDeltas.length; ++i) { + lastTimeMicroSec += profile.timeDeltas[i]; + timestamps[i] = lastTimeMicroSec; + } + return timestamps; + } + /** + * Creates a Tree of CPUProfileNodes using the Protocol.Profiler.ProfileNodes. + * As the tree is built, samples of native code (prefixed with "native ") are + * filtered out. Samples of filtered nodes are replaced with the parent of the + * node being filtered. + * + * This function supports legacy and new definitions of the CDP Profiler.Profile + * type. + */ + translateProfileTree(nodes) { + function buildChildrenFromParents(nodes2) { + if (nodes2[0].children) { + return; + } + nodes2[0].children = []; + for (let i = 1; i < nodes2.length; ++i) { + const node = nodes2[i]; + const parentNode = protocolNodeById.get(node.parent); + if (!parentNode) { + continue; + } + if (parentNode.children) { + parentNode.children.push(node.id); + } else { + parentNode.children = [node.id]; + } + } + } + __name(buildChildrenFromParents, "buildChildrenFromParents"); + function buildHitCountFromSamples(nodes2, samples) { + if (typeof nodes2[0].hitCount === "number") { + return; + } + if (!samples) { + throw new Error("Error: Neither hitCount nor samples are present in profile."); + } + for (let i = 0; i < nodes2.length; ++i) { + nodes2[i].hitCount = 0; + } + for (let i = 0; i < samples.length; ++i) { + const node = protocolNodeById.get(samples[i]); + if (node?.hitCount === void 0) { + continue; + } + node.hitCount++; + } + } + __name(buildHitCountFromSamples, "buildHitCountFromSamples"); + const protocolNodeById = /* @__PURE__ */ new Map(); + for (let i = 0; i < nodes.length; ++i) { + const node = nodes[i]; + protocolNodeById.set(node.id, node); + } + buildHitCountFromSamples(nodes, this.samples); + buildChildrenFromParents(nodes); + this.totalHitCount = nodes.reduce((acc, node) => acc + (node.hitCount || 0), 0); + const sampleTime = (this.profileEndTime - this.profileStartTime) / this.totalHitCount; + const root2 = nodes[0]; + const idToUseForRemovedNode = /* @__PURE__ */ new Map([[root2.id, root2.id]]); + this.#idToParsedNode = /* @__PURE__ */ new Map(); + const resultRoot = new CPUProfileNode(root2, sampleTime); + this.#idToParsedNode.set(root2.id, resultRoot); + if (!root2.children) { + throw new Error("Missing children for root"); + } + const parentNodeStack = root2.children.map(() => resultRoot); + const sourceNodeStack = root2.children.map((id) => protocolNodeById.get(id)); + while (sourceNodeStack.length) { + let parentNode = parentNodeStack.pop(); + const sourceNode = sourceNodeStack.pop(); + if (!sourceNode || !parentNode) { + continue; + } + if (!sourceNode.children) { + sourceNode.children = []; + } + const targetNode = new CPUProfileNode(sourceNode, sampleTime); + parentNode.children.push(targetNode); + parentNode = targetNode; + idToUseForRemovedNode.set(sourceNode.id, parentNode.id); + parentNodeStack.push.apply(parentNodeStack, sourceNode.children.map(() => parentNode)); + sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children.map((id) => protocolNodeById.get(id))); + this.#idToParsedNode.set(sourceNode.id, targetNode); + } + if (this.samples) { + this.samples = this.samples.map((id) => idToUseForRemovedNode.get(id)); + } + return resultRoot; + } + /** + * Sorts the samples array using the timestamps array (there is a one + * to one matching by index between the two). + */ + sortSamples() { + if (!this.timestamps || !this.samples) { + return; + } + const timestamps = this.timestamps; + const samples = this.samples; + const orderedIndices = timestamps.map((_x, index) => index); + orderedIndices.sort((a, b) => timestamps[a] - timestamps[b]); + this.timestamps = []; + this.samples = []; + for (let i = 0; i < orderedIndices.length; i++) { + const orderedIndex = orderedIndices[i]; + this.timestamps.push(timestamps[orderedIndex]); + this.samples.push(samples[orderedIndex]); + } + } + /** + * Fills in timestamps and/or time deltas from legacy profiles where + * they could be missing. + */ + normalizeTimestamps() { + if (!this.samples) { + return; + } + let timestamps = this.timestamps; + if (!timestamps) { + const profileStartTime = this.profileStartTime; + const interval = (this.profileEndTime - profileStartTime) / this.samples.length; + timestamps = new Array(this.samples.length + 1); + for (let i = 0; i < timestamps.length; ++i) { + timestamps[i] = profileStartTime + i * interval; + } + this.timestamps = timestamps; + return; + } + for (let i = 0; i < timestamps.length; ++i) { + timestamps[i] /= 1e3; + } + if (this.samples.length === timestamps.length) { + const lastTimestamp = timestamps.at(-1) || 0; + const averageIntervalTime = (lastTimestamp - timestamps[0]) / (timestamps.length - 1); + this.timestamps.push(lastTimestamp + averageIntervalTime); + } + this.profileStartTime = timestamps.at(0) || this.profileStartTime; + this.profileEndTime = timestamps.at(-1) || this.profileEndTime; + } + /** + * Some nodes do not refer to JS samples but to V8 system tasks, AKA + * "meta" nodes. This function extracts those nodes from the profile. + */ + extractMetaNodes() { + const topLevelNodes = this.profileHead.children; + for (let i = 0; i < topLevelNodes.length && !(this.gcNode && this.programNode && this.idleNode); i++) { + const node = topLevelNodes[i]; + if (node.functionName === "(garbage collector)") { + this.gcNode = node; + } else if (node.functionName === "(program)") { + this.programNode = node; + } else if (node.functionName === "(idle)") { + this.idleNode = node; + } + } + } + fixMissingSamples() { + const samples = this.samples; + if (!samples) { + return; + } + const samplesCount = samples.length; + if (!this.programNode || samplesCount < 3) { + return; + } + const idToNode = this.#idToParsedNode; + const programNodeId = this.programNode.id; + const gcNodeId = this.gcNode ? this.gcNode.id : -1; + const idleNodeId = this.idleNode ? this.idleNode.id : -1; + let prevNodeId = samples[0]; + let nodeId = samples[1]; + for (let sampleIndex = 1; sampleIndex < samplesCount - 1; sampleIndex++) { + const nextNodeId = samples[sampleIndex + 1]; + const prevNode = idToNode.get(prevNodeId); + const nextNode = idToNode.get(nextNodeId); + if (prevNodeId === void 0 || nextNodeId === void 0 || !prevNode || !nextNode) { + console.error(`Unexpectedly found undefined nodes: ${prevNodeId} ${nextNodeId}`); + continue; + } + if (nodeId === programNodeId && !isSystemNode(prevNodeId) && !isSystemNode(nextNodeId) && bottomNode(prevNode) === bottomNode(nextNode)) { + samples[sampleIndex] = prevNodeId; + } + prevNodeId = nodeId; + nodeId = nextNodeId; + } + function bottomNode(node) { + while (node.parent?.parent) { + node = node.parent; + } + return node; + } + __name(bottomNode, "bottomNode"); + function isSystemNode(nodeId2) { + return nodeId2 === programNodeId || nodeId2 === gcNodeId || nodeId2 === idleNodeId; + } + __name(isSystemNode, "isSystemNode"); + } + /** + * Traverses the call tree derived from the samples calling back when a call is opened + * and when it's closed + */ + forEachFrame(openFrameCallback, closeFrameCallback, startTime, stopTime) { + if (!this.profileHead || !this.samples) { + return; + } + startTime = startTime || 0; + stopTime = stopTime || Infinity; + const samples = this.samples; + const timestamps = this.timestamps; + const idToNode = this.#idToParsedNode; + const gcNode = this.gcNode; + const samplesCount = samples.length; + const startIndex = ArrayUtilities_exports.lowerBound(timestamps, startTime, ArrayUtilities_exports.DEFAULT_COMPARATOR); + let stackTop = 0; + const stackNodes = []; + let prevId = this.profileHead.id; + let sampleTime; + let gcParentNode = null; + const stackDepth = this.maxDepth + 3; + if (!this.#stackStartTimes) { + this.#stackStartTimes = new Array(stackDepth); + } + const stackStartTimes = this.#stackStartTimes; + if (!this.#stackChildrenDuration) { + this.#stackChildrenDuration = new Array(stackDepth); + } + const stackChildrenDuration = this.#stackChildrenDuration; + let node; + let sampleIndex; + for (sampleIndex = startIndex; sampleIndex < samplesCount; sampleIndex++) { + sampleTime = timestamps[sampleIndex]; + if (sampleTime >= stopTime) { + break; + } + const id = samples[sampleIndex]; + if (id === prevId) { + continue; + } + node = idToNode.get(id); + let prevNode = idToNode.get(prevId) || null; + if (!prevNode) { + continue; + } + if (gcNode && node === gcNode) { + gcParentNode = prevNode; + openFrameCallback(gcParentNode.depth + 1, gcNode, sampleIndex, sampleTime); + stackStartTimes[++stackTop] = sampleTime; + stackChildrenDuration[stackTop] = 0; + prevId = id; + continue; + } + if (gcNode && prevNode === gcNode && gcParentNode) { + const start = stackStartTimes[stackTop]; + const duration = sampleTime - start; + stackChildrenDuration[stackTop - 1] += duration; + closeFrameCallback(gcParentNode.depth + 1, gcNode, sampleIndex, start, duration, duration - stackChildrenDuration[stackTop]); + --stackTop; + prevNode = gcParentNode; + prevId = prevNode.id; + gcParentNode = null; + } + while (node && node.depth > prevNode.depth) { + stackNodes.push(node); + node = node.parent; + } + while (prevNode && prevNode !== node) { + const start = stackStartTimes[stackTop]; + const duration = sampleTime - start; + stackChildrenDuration[stackTop - 1] += duration; + closeFrameCallback(prevNode.depth, prevNode, sampleIndex, start, duration, duration - stackChildrenDuration[stackTop]); + --stackTop; + if (node && node.depth === prevNode.depth) { + stackNodes.push(node); + node = node.parent; + } + prevNode = prevNode.parent; + } + while (stackNodes.length) { + const currentNode = stackNodes.pop(); + if (!currentNode) { + break; + } + node = currentNode; + openFrameCallback(currentNode.depth, currentNode, sampleIndex, sampleTime); + stackStartTimes[++stackTop] = sampleTime; + stackChildrenDuration[stackTop] = 0; + } + prevId = id; + } + sampleTime = timestamps[sampleIndex] || this.profileEndTime; + if (node && gcParentNode && idToNode.get(prevId) === gcNode) { + const start = stackStartTimes[stackTop]; + const duration = sampleTime - start; + stackChildrenDuration[stackTop - 1] += duration; + closeFrameCallback(gcParentNode.depth + 1, node, sampleIndex, start, duration, duration - stackChildrenDuration[stackTop]); + --stackTop; + prevId = gcParentNode.id; + } + for (let node2 = idToNode.get(prevId); node2?.parent; node2 = node2.parent) { + const start = stackStartTimes[stackTop]; + const duration = sampleTime - start; + stackChildrenDuration[stackTop - 1] += duration; + closeFrameCallback(node2.depth, node2, sampleIndex, start, duration, duration - stackChildrenDuration[stackTop]); + --stackTop; + } + } + /** + * Returns the node that corresponds to a given index of a sample. + */ + nodeByIndex(index) { + return this.samples && this.#idToParsedNode.get(this.samples[index]) || null; + } + /** + * Returns the node that corresponds to a given node id. + */ + nodeById(nodeId) { + return this.#idToParsedNode.get(nodeId) || null; + } + nodes() { + if (!this.#idToParsedNode) { + return null; + } + return [...this.#idToParsedNode.values()]; + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/cpu_profile/cpu_profile.js +var init_cpu_profile = __esm({ + "node_modules/@paulirish/trace_engine/models/cpu_profile/cpu_profile.js"() { + init_process_global(); + init_CPUProfileDataModel(); + init_ProfileTreeModel(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/SamplesHandler.js +var SamplesHandler_exports = {}; +__export(SamplesHandler_exports, { + data: () => data7, + finalize: () => finalize7, + getProfileCallFunctionName: () => getProfileCallFunctionName, + handleEvent: () => handleEvent7, + reset: () => reset7 +}); +function parseCPUProfileData(parseOptions) { + for (const [processId, profiles] of preprocessedData) { + for (const [profileId, preProcessedData] of profiles) { + let buildProfileCallsForCPUProfile = function() { + profileModel.forEachFrame(openFrameCallback, closeFrameCallback); + function openFrameCallback(depth, node, sampleIndex, timeStampMilliseconds) { + if (threadId === void 0) { + return; + } + const ts = Timing_exports3.milliToMicro(Timing_exports.Milli(timeStampMilliseconds)); + const nodeId = node.id; + const profileCall = Trace_exports.makeProfileCall(node, profileId, sampleIndex, ts, processId, threadId); + finalizedData.profileCalls.push(profileCall); + indexStack.push(finalizedData.profileCalls.length - 1); + const traceEntryNode = TreeHelpers_exports.makeEmptyTraceEntryNode(profileCall, nodeId); + entryToNode.set(profileCall, traceEntryNode); + traceEntryNode.depth = depth; + if (indexStack.length === 1) { + finalizedData.profileTree?.roots.add(traceEntryNode); + } + } + __name(openFrameCallback, "openFrameCallback"); + function closeFrameCallback(_depth, _node, _sampleIndex, _timeStampMillis, durMs, selfTimeMs) { + const profileCallIndex = indexStack.pop(); + const profileCall = profileCallIndex !== void 0 && finalizedData.profileCalls[profileCallIndex]; + if (!profileCall) { + return; + } + const { callFrame, ts, pid, tid } = profileCall; + const traceEntryNode = entryToNode.get(profileCall); + if (callFrame === void 0 || ts === void 0 || pid === void 0 || profileId === void 0 || tid === void 0 || traceEntryNode === void 0) { + return; + } + const dur = Timing_exports3.milliToMicro(Timing_exports.Milli(durMs)); + const selfTime = Timing_exports3.milliToMicro(Timing_exports.Milli(selfTimeMs)); + profileCall.dur = dur; + traceEntryNode.selfTime = selfTime; + const parentIndex = indexStack.at(-1); + const parent = parentIndex !== void 0 && finalizedData.profileCalls.at(parentIndex); + const parentNode = parent && entryToNode.get(parent); + if (!parentNode) { + return; + } + traceEntryNode.parent = parentNode; + parentNode.children.push(traceEntryNode); + } + __name(closeFrameCallback, "closeFrameCallback"); + }; + __name(buildProfileCallsForCPUProfile, "buildProfileCallsForCPUProfile"); + const threadId = preProcessedData.threadId; + if (!preProcessedData.rawProfile.nodes.length || threadId === void 0) { + continue; + } + const indexStack = []; + const profileModel = new CPUProfileDataModel_exports.CPUProfileDataModel(preProcessedData.rawProfile); + const profileTree = TreeHelpers_exports.makeEmptyTraceEntryTree(); + profileTree.maxDepth = profileModel.maxDepth; + const finalizedData = { + rawProfile: preProcessedData.rawProfile, + parsedProfile: profileModel, + profileCalls: [], + profileTree, + profileId + }; + const dataByThread = MapUtilities_exports.getWithDefault(profilesInProcess, processId, () => /* @__PURE__ */ new Map()); + dataByThread.set(threadId, finalizedData); + if (parseOptions.isCPUProfile) { + buildProfileCallsForCPUProfile(); + } + } + } +} +function reset7() { + preprocessedData = /* @__PURE__ */ new Map(); + profilesInProcess = /* @__PURE__ */ new Map(); + entryToNode = /* @__PURE__ */ new Map(); +} +function handleEvent7(event) { + if (TraceEvents_exports.isSyntheticCpuProfile(event)) { + const profileData = getOrCreatePreProcessedData(event.pid, event.id); + profileData.rawProfile = event.args.data.cpuProfile; + profileData.threadId = event.tid; + return; + } + if (TraceEvents_exports.isProfile(event)) { + const profileData = getOrCreatePreProcessedData(event.pid, event.id); + profileData.rawProfile.startTime = event.ts; + profileData.threadId = event.tid; + return; + } + if (TraceEvents_exports.isProfileChunk(event)) { + const profileData = getOrCreatePreProcessedData(event.pid, event.id); + const cdpProfile = profileData.rawProfile; + const nodesAndSamples = event.args?.data?.cpuProfile || { samples: [] }; + const samples = nodesAndSamples?.samples || []; + const traceIds = event.args?.data?.cpuProfile?.trace_ids; + for (const n of nodesAndSamples?.nodes || []) { + const lineNumber = typeof n.callFrame.lineNumber === "undefined" ? -1 : n.callFrame.lineNumber; + const columnNumber = typeof n.callFrame.columnNumber === "undefined" ? -1 : n.callFrame.columnNumber; + const scriptId = String(n.callFrame.scriptId); + const url = n.callFrame.url || ""; + const node = { + ...n, + callFrame: { + ...n.callFrame, + url, + lineNumber, + columnNumber, + scriptId + } + }; + cdpProfile.nodes.push(node); + } + const timeDeltas = event.args.data?.timeDeltas || []; + const lines = event.args.data?.lines || Array(samples.length).fill(0); + cdpProfile.samples?.push(...samples); + cdpProfile.timeDeltas?.push(...timeDeltas); + cdpProfile.lines?.push(...lines); + if (traceIds) { + cdpProfile.traceIds ??= {}; + for (const key in traceIds) { + cdpProfile.traceIds[key] = traceIds[key]; + } + } + if (cdpProfile.samples && cdpProfile.timeDeltas && cdpProfile.samples.length !== cdpProfile.timeDeltas.length) { + console.error("Failed to parse CPU profile."); + return; + } + if (!cdpProfile.endTime && cdpProfile.timeDeltas) { + const timeDeltas2 = cdpProfile.timeDeltas; + cdpProfile.endTime = timeDeltas2.reduce((x, y) => x + y, cdpProfile.startTime); + } + return; + } +} +async function finalize7(parseOptions = {}) { + parseCPUProfileData(parseOptions); +} +function data7() { + return { + profilesInProcess, + entryToNode + }; +} +function getOrCreatePreProcessedData(processId, profileId) { + const profileById = MapUtilities_exports.getWithDefault(preprocessedData, processId, () => /* @__PURE__ */ new Map()); + return MapUtilities_exports.getWithDefault(profileById, profileId, () => ({ + rawProfile: { + startTime: 0, + endTime: 0, + nodes: [], + samples: [], + timeDeltas: [], + lines: [] + }, + profileId + })); +} +function getProfileCallFunctionName(data31, entry) { + const profile = data31.profilesInProcess.get(entry.pid)?.get(entry.tid); + const node = profile?.parsedProfile.nodeById(entry.nodeId); + if (node?.functionName) { + return node.functionName; + } + return entry.callFrame.functionName; +} +var profilesInProcess, entryToNode, preprocessedData; +var init_SamplesHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/SamplesHandler.js"() { + init_process_global(); + init_platform(); + init_cpu_profile(); + init_helpers2(); + init_types2(); + profilesInProcess = /* @__PURE__ */ new Map(); + entryToNode = /* @__PURE__ */ new Map(); + preprocessedData = /* @__PURE__ */ new Map(); + __name(parseCPUProfileData, "parseCPUProfileData"); + __name(reset7, "reset"); + __name(handleEvent7, "handleEvent"); + __name(finalize7, "finalize"); + __name(data7, "data"); + __name(getOrCreatePreProcessedData, "getOrCreatePreProcessedData"); + __name(getProfileCallFunctionName, "getProfileCallFunctionName"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/RendererHandler.js +var RendererHandler_exports = {}; +__export(RendererHandler_exports, { + assignIsMainFrame: () => assignIsMainFrame, + assignMeta: () => assignMeta, + assignOrigin: () => assignOrigin, + assignThreadName: () => assignThreadName, + buildHierarchy: () => buildHierarchy, + data: () => data8, + deps: () => deps3, + finalize: () => finalize8, + handleEvent: () => handleEvent8, + handleUserConfig: () => handleUserConfig2, + makeCompleteEvent: () => makeCompleteEvent, + reset: () => reset8, + sanitizeProcesses: () => sanitizeProcesses, + sanitizeThreads: () => sanitizeThreads +}); +function handleUserConfig2(userConfig) { + config = userConfig; +} +function reset8() { + processes = /* @__PURE__ */ new Map(); + entryToNode2 = /* @__PURE__ */ new Map(); + entityMappings2 = { + eventsByEntity: /* @__PURE__ */ new Map(), + entityByEvent: /* @__PURE__ */ new Map(), + createdEntityCache: /* @__PURE__ */ new Map(), + entityByUrlCache: /* @__PURE__ */ new Map() + }; + completeEventStack = []; + compositorTileWorkers = []; +} +function handleEvent8(event) { + if (TraceEvents_exports.isThreadName(event) && event.args.name?.startsWith("CompositorTileWorker")) { + compositorTileWorkers.push({ + pid: event.pid, + tid: event.tid + }); + } + if (TraceEvents_exports.isBegin(event) || TraceEvents_exports.isEnd(event)) { + const process5 = getOrCreateRendererProcess(processes, event.pid); + const thread = getOrCreateRendererThread(process5, event.tid); + const completeEvent = makeCompleteEvent(event); + if (!completeEvent) { + return; + } + thread.entries.push(completeEvent); + return; + } + if (TraceEvents_exports.isInstant(event) || TraceEvents_exports.isComplete(event)) { + const process5 = getOrCreateRendererProcess(processes, event.pid); + const thread = getOrCreateRendererThread(process5, event.tid); + thread.entries.push(event); + } + if (TraceEvents_exports.isLayout(event)) { + const process5 = getOrCreateRendererProcess(processes, event.pid); + const thread = getOrCreateRendererThread(process5, event.tid); + thread.layoutEvents.push(event); + } + if (TraceEvents_exports.isRecalcStyle(event)) { + const process5 = getOrCreateRendererProcess(processes, event.pid); + const thread = getOrCreateRendererThread(process5, event.tid); + thread.recalcStyleEvents.push(event); + } +} +async function finalize8() { + const { mainFrameId: mainFrameId2, rendererProcessesByFrame, threadsInProcess: threadsInProcess2 } = data5(); + entityMappings2 = data6().entityMappings; + assignMeta(processes, mainFrameId2, rendererProcessesByFrame, threadsInProcess2); + sanitizeProcesses(processes); + buildHierarchy(processes); + sanitizeThreads(processes); +} +function data8() { + return { + processes, + compositorTileWorkers: gatherCompositorThreads(), + entryToNode: entryToNode2, + entityMappings: { + entityByEvent: entityMappings2.entityByEvent, + eventsByEntity: entityMappings2.eventsByEntity, + createdEntityCache: entityMappings2.createdEntityCache, + entityByUrlCache: entityMappings2.entityByUrlCache + } + }; +} +function gatherCompositorThreads() { + const threadsByProcess = /* @__PURE__ */ new Map(); + for (const worker of compositorTileWorkers) { + const byProcess = threadsByProcess.get(worker.pid) || []; + byProcess.push(worker.tid); + threadsByProcess.set(worker.pid, byProcess); + } + return threadsByProcess; +} +function assignMeta(processes2, mainFrameId2, rendererProcessesByFrame, threadsInProcess2) { + assignOrigin(processes2, rendererProcessesByFrame); + assignIsMainFrame(processes2, mainFrameId2, rendererProcessesByFrame); + assignThreadName(processes2, threadsInProcess2); +} +function assignOrigin(processes2, rendererProcessesByFrame) { + for (const renderProcessesByPid of rendererProcessesByFrame.values()) { + for (const [pid, processWindows] of renderProcessesByPid) { + for (const processInfo of processWindows.flat()) { + const process5 = getOrCreateRendererProcess(processes2, pid); + if (process5.url === null || process5.url === "about:blank") { + try { + new URL(processInfo.frame.url); + process5.url = processInfo.frame.url; + } catch { + process5.url = null; + } + } + } + } + } +} +function assignIsMainFrame(processes2, mainFrameId2, rendererProcessesByFrame) { + for (const [frameId, renderProcessesByPid] of rendererProcessesByFrame) { + for (const [pid] of renderProcessesByPid) { + const process5 = getOrCreateRendererProcess(processes2, pid); + if (frameId === mainFrameId2) { + process5.isOnMainFrame = true; + } + } + } +} +function assignThreadName(processes2, threadsInProcess2) { + for (const [pid, process5] of processes2) { + for (const [tid, threadInfo] of threadsInProcess2.get(pid) ?? []) { + const thread = getOrCreateRendererThread(process5, tid); + thread.name = threadInfo?.args.name ?? `${tid}`; + } + } +} +function sanitizeProcesses(processes2) { + const auctionWorklets = data4().worklets; + const metaData = data5(); + if (metaData.traceIsGeneric) { + return; + } + for (const [pid, process5] of processes2) { + if (process5.url === null) { + const maybeWorklet = auctionWorklets.get(pid); + if (maybeWorklet) { + process5.url = maybeWorklet.host; + } else { + processes2.delete(pid); + } + continue; + } + } +} +function sanitizeThreads(processes2) { + for (const [, process5] of processes2) { + for (const [tid, thread] of process5.threads) { + if (!thread.tree?.roots.size) { + process5.threads.delete(tid); + } + } + } +} +function buildHierarchy(processes2, options) { + const samplesData = data7(); + for (const [pid, process5] of processes2) { + for (const [tid, thread] of process5.threads) { + if (!thread.entries.length) { + thread.tree = TreeHelpers_exports.makeEmptyTraceEntryTree(); + continue; + } + Trace_exports.sortTraceEventsInPlace(thread.entries); + const samplesDataForThread = samplesData.profilesInProcess.get(pid)?.get(tid); + if (samplesDataForThread) { + const cpuProfile = samplesDataForThread.parsedProfile; + const samplesIntegrator = cpuProfile && new SamplesIntegrator_exports.SamplesIntegrator(cpuProfile, samplesDataForThread.profileId, pid, tid, config); + const profileCalls = samplesIntegrator?.buildProfileCalls(thread.entries); + if (samplesIntegrator && profileCalls) { + thread.entries = Trace_exports.mergeEventsInOrder(thread.entries, profileCalls); + thread.profileCalls = profileCalls; + const jsSamples = samplesIntegrator.jsSampleEvents; + if (jsSamples.length) { + thread.entries = Trace_exports.mergeEventsInOrder(thread.entries, jsSamples); + } + } + } + const treeData = TreeHelpers_exports.treify(thread.entries, options); + thread.tree = treeData.tree; + for (const [entry, node] of treeData.entryToNode) { + entryToNode2.set(entry, node); + addEventToEntityMapping(entry, entityMappings2); + } + } + } +} +function makeCompleteEvent(event) { + if (TraceEvents_exports.isEnd(event)) { + const beginEvent = completeEventStack.pop(); + if (!beginEvent) { + return null; + } + if (beginEvent.name !== event.name || beginEvent.cat !== event.cat) { + console.error("Begin/End events mismatch at " + beginEvent.ts + " (" + beginEvent.name + ") vs. " + event.ts + " (" + event.name + ")"); + return null; + } + beginEvent.dur = Timing_exports.Micro(event.ts - beginEvent.ts); + return null; + } + const syntheticComplete = { + ...event, + ph: TraceEvents_exports.Phase.COMPLETE, + dur: Timing_exports.Micro(0) + }; + completeEventStack.push(syntheticComplete); + return syntheticComplete; +} +function deps3() { + return ["Meta", "Samples", "AuctionWorklets", "NetworkRequests"]; +} +var processes, entityMappings2, compositorTileWorkers, entryToNode2, completeEventStack, config, makeRendererProcess, makeRendererThread, getOrCreateRendererProcess, getOrCreateRendererThread; +var init_RendererHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/RendererHandler.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + init_AuctionWorkletsHandler(); + init_helpers(); + init_MetaHandler(); + init_NetworkRequestsHandler(); + init_SamplesHandler(); + processes = /* @__PURE__ */ new Map(); + entityMappings2 = { + eventsByEntity: /* @__PURE__ */ new Map(), + entityByEvent: /* @__PURE__ */ new Map(), + createdEntityCache: /* @__PURE__ */ new Map(), + entityByUrlCache: /* @__PURE__ */ new Map() + }; + compositorTileWorkers = Array(); + entryToNode2 = /* @__PURE__ */ new Map(); + completeEventStack = []; + config = Configuration_exports.defaults(); + makeRendererProcess = /* @__PURE__ */ __name(() => ({ + url: null, + isOnMainFrame: false, + threads: /* @__PURE__ */ new Map() + }), "makeRendererProcess"); + makeRendererThread = /* @__PURE__ */ __name(() => ({ + name: null, + entries: [], + profileCalls: [], + layoutEvents: [], + recalcStyleEvents: [] + }), "makeRendererThread"); + getOrCreateRendererProcess = /* @__PURE__ */ __name((processes2, pid) => { + return MapUtilities_exports.getWithDefault(processes2, pid, makeRendererProcess); + }, "getOrCreateRendererProcess"); + getOrCreateRendererThread = /* @__PURE__ */ __name((process5, tid) => { + return MapUtilities_exports.getWithDefault(process5.threads, tid, makeRendererThread); + }, "getOrCreateRendererThread"); + __name(handleUserConfig2, "handleUserConfig"); + __name(reset8, "reset"); + __name(handleEvent8, "handleEvent"); + __name(finalize8, "finalize"); + __name(data8, "data"); + __name(gatherCompositorThreads, "gatherCompositorThreads"); + __name(assignMeta, "assignMeta"); + __name(assignOrigin, "assignOrigin"); + __name(assignIsMainFrame, "assignIsMainFrame"); + __name(assignThreadName, "assignThreadName"); + __name(sanitizeProcesses, "sanitizeProcesses"); + __name(sanitizeThreads, "sanitizeThreads"); + __name(buildHierarchy, "buildHierarchy"); + __name(makeCompleteEvent, "makeCompleteEvent"); + __name(deps3, "deps"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/AsyncJSCallsHandler.js +var AsyncJSCallsHandler_exports = {}; +__export(AsyncJSCallsHandler_exports, { + data: () => data9, + deps: () => deps4, + finalize: () => finalize9, + handleEvent: () => handleEvent9, + reset: () => reset9 +}); +function reset9() { + schedulerToRunEntryPoints = /* @__PURE__ */ new Map(); + asyncCallToScheduler = /* @__PURE__ */ new Map(); + taskScheduleForTaskRunEvent = /* @__PURE__ */ new Map(); + runEntryPointToScheduler = /* @__PURE__ */ new Map(); +} +function handleEvent9(_) { +} +async function finalize9() { + const { flows: flows2 } = data3(); + const { entryToNode: entryToNode4 } = data8(); + for (const flow of flows2) { + let maybeAsyncTaskScheduled = flow.at(0); + if (!maybeAsyncTaskScheduled) { + continue; + } + if (TraceEvents_exports.isDebuggerAsyncTaskRun(maybeAsyncTaskScheduled)) { + maybeAsyncTaskScheduled = taskScheduleForTaskRunEvent.get(maybeAsyncTaskScheduled); + } + if (!maybeAsyncTaskScheduled || !TraceEvents_exports.isDebuggerAsyncTaskScheduled(maybeAsyncTaskScheduled)) { + continue; + } + const taskName = maybeAsyncTaskScheduled.args.taskName; + const asyncTaskRun = flow.at(1); + if (!asyncTaskRun || !TraceEvents_exports.isDebuggerAsyncTaskRun(asyncTaskRun)) { + continue; + } + taskScheduleForTaskRunEvent.set(asyncTaskRun, maybeAsyncTaskScheduled); + const asyncCaller = findNearestJSAncestor(maybeAsyncTaskScheduled, entryToNode4); + const asyncEntryPoint = findFirstJsInvocationForAsyncTaskRun(asyncTaskRun, entryToNode4); + runEntryPointToScheduler.set(asyncEntryPoint || asyncTaskRun, { taskName, scheduler: asyncCaller || maybeAsyncTaskScheduled }); + if (!asyncCaller || !asyncEntryPoint) { + continue; + } + const entryPoints = MapUtilities_exports.getWithDefault(schedulerToRunEntryPoints, asyncCaller, () => []); + entryPoints.push(asyncEntryPoint); + const scheduledProfileCalls = findFirstJSCallsForAsyncTaskRun(asyncTaskRun, entryToNode4); + for (const call of scheduledProfileCalls) { + asyncCallToScheduler.set(call, { taskName, scheduler: asyncCaller }); + } + } +} +function findNearestJSAncestor(asyncTaskScheduled, entryToNode4) { + let node = entryToNode4.get(asyncTaskScheduled)?.parent; + while (node) { + if (TraceEvents_exports.isProfileCall(node.entry) || acceptJSInvocationsPredicate(node.entry)) { + return node.entry; + } + node = node.parent; + } + return null; +} +function acceptJSInvocationsPredicate(event) { + const eventIsConsoleRunTask = TraceEvents_exports.isConsoleRunTask(event); + const eventIsV8EntryPoint = event.name.startsWith("v8") || event.name.startsWith("V8"); + return TraceEvents_exports.isJSInvocationEvent(event) && (eventIsConsoleRunTask || !eventIsV8EntryPoint); +} +function findFirstJsInvocationForAsyncTaskRun(asyncTaskRun, entryToNode4) { + return findFirstDescendantsOfType(asyncTaskRun, entryToNode4, acceptJSInvocationsPredicate, TraceEvents_exports.isDebuggerAsyncTaskRun).at(0); +} +function findFirstJSCallsForAsyncTaskRun(asyncTaskRun, entryToNode4) { + return findFirstDescendantsOfType(asyncTaskRun, entryToNode4, TraceEvents_exports.isProfileCall, TraceEvents_exports.isDebuggerAsyncTaskRun); +} +function findFirstDescendantsOfType(root2, entryToNode4, predicateAccept, predicateIgnore) { + const node = entryToNode4.get(root2); + if (!node) { + return []; + } + const childrenGroups = [[...node.children]]; + const firstDescendants = []; + for (let i = 0; i < childrenGroups.length; i++) { + const siblings = childrenGroups[i]; + for (let j = 0; j < siblings.length; j++) { + const node2 = siblings[j]; + if (predicateAccept(node2.entry)) { + firstDescendants.push(node2.entry); + } else if (!predicateIgnore(node2.entry)) { + childrenGroups.push([...node2.children]); + } + } + } + return firstDescendants; +} +function data9() { + return { + schedulerToRunEntryPoints, + asyncCallToScheduler, + runEntryPointToScheduler + }; +} +function deps4() { + return ["Renderer", "Flows"]; +} +var schedulerToRunEntryPoints, taskScheduleForTaskRunEvent, asyncCallToScheduler, runEntryPointToScheduler; +var init_AsyncJSCallsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/AsyncJSCallsHandler.js"() { + init_process_global(); + init_platform(); + init_types2(); + init_FlowsHandler(); + init_RendererHandler(); + schedulerToRunEntryPoints = /* @__PURE__ */ new Map(); + taskScheduleForTaskRunEvent = /* @__PURE__ */ new Map(); + asyncCallToScheduler = /* @__PURE__ */ new Map(); + runEntryPointToScheduler = /* @__PURE__ */ new Map(); + __name(reset9, "reset"); + __name(handleEvent9, "handleEvent"); + __name(finalize9, "finalize"); + __name(findNearestJSAncestor, "findNearestJSAncestor"); + __name(acceptJSInvocationsPredicate, "acceptJSInvocationsPredicate"); + __name(findFirstJsInvocationForAsyncTaskRun, "findFirstJsInvocationForAsyncTaskRun"); + __name(findFirstJSCallsForAsyncTaskRun, "findFirstJSCallsForAsyncTaskRun"); + __name(findFirstDescendantsOfType, "findFirstDescendantsOfType"); + __name(data9, "data"); + __name(deps4, "deps"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/DOMStatsHandler.js +var DOMStatsHandler_exports = {}; +__export(DOMStatsHandler_exports, { + data: () => data10, + finalize: () => finalize10, + handleEvent: () => handleEvent10, + reset: () => reset10 +}); +function reset10() { + domStatsByFrameId = /* @__PURE__ */ new Map(); +} +function handleEvent10(event) { + if (!TraceEvents_exports.isDOMStats(event)) { + return; + } + const domStatEvents = MapUtilities_exports.getWithDefault(domStatsByFrameId, event.args.data.frame, () => []); + domStatEvents.push(event); +} +async function finalize10() { +} +function data10() { + return { domStatsByFrameId }; +} +var domStatsByFrameId; +var init_DOMStatsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/DOMStatsHandler.js"() { + init_process_global(); + init_platform(); + init_types2(); + domStatsByFrameId = /* @__PURE__ */ new Map(); + __name(reset10, "reset"); + __name(handleEvent10, "handleEvent"); + __name(finalize10, "finalize"); + __name(data10, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/UserTimingsHandler.js +var UserTimingsHandler_exports = {}; +__export(UserTimingsHandler_exports, { + data: () => data11, + finalize: () => finalize11, + handleEvent: () => handleEvent11, + reset: () => reset11, + userTimingComparator: () => userTimingComparator +}); +function reset11() { + syntheticEvents = []; + performanceMeasureEvents = []; + performanceMarkEvents = []; + consoleTimings = []; + timestampEvents = []; + measureTraceByTraceId = /* @__PURE__ */ new Map(); +} +function getEventTimings(event) { + if ("dur" in event) { + return { start: event.ts, end: Timing_exports.Micro(event.ts + (event.dur ?? 0)) }; + } + if (TraceEvents_exports.isConsoleTimeStamp(event)) { + const { start, end } = event.args.data || {}; + if (typeof start === "number" && typeof end === "number") { + return { start: Timing_exports.Micro(start), end: Timing_exports.Micro(end) }; + } + } + return { start: event.ts, end: event.ts }; +} +function getEventTrack(event) { + if (event.cat === "blink.user_timing") { + const detailString = event.args.data.beginEvent.args?.detail; + if (detailString) { + const details = Trace_exports.parseDevtoolsDetails(detailString, "devtools"); + if (details && "track" in details) { + return details.track; + } + } + } else if (TraceEvents_exports.isConsoleTimeStamp(event)) { + const track = event.args.data?.track; + return typeof track === "string" ? track : void 0; + } + return void 0; +} +function userTimingComparator(a, b, originalArray) { + const { start: aStart, end: aEnd } = getEventTimings(a); + const { start: bStart, end: bEnd } = getEventTimings(b); + const timeDifference = Trace_exports.compareBeginAndEnd(aStart, bStart, aEnd, bEnd); + if (timeDifference) { + return timeDifference; + } + const aTrack = getEventTrack(a); + const bTrack = getEventTrack(b); + if (aTrack !== bTrack) { + return 0; + } + const aIndex = originalArray.indexOf(a); + const bIndex = originalArray.indexOf(b); + return bIndex - aIndex; +} +function handleEvent11(event) { + if (ignoredNames.includes(event.name)) { + return; + } + if (TraceEvents_exports.isUserTimingMeasure(event)) { + measureTraceByTraceId.set(event.args.traceId, event); + } + if (TraceEvents_exports.isPerformanceMeasure(event)) { + performanceMeasureEvents.push(event); + return; + } + if (TraceEvents_exports.isPerformanceMark(event)) { + performanceMarkEvents.push(event); + } + if (TraceEvents_exports.isConsoleTime(event)) { + consoleTimings.push(event); + } + if (TraceEvents_exports.isConsoleTimeStamp(event)) { + timestampEvents.push(event); + } +} +async function finalize11() { + const asyncEvents = [...performanceMeasureEvents, ...consoleTimings]; + syntheticEvents = Trace_exports.createMatchedSortedSyntheticEvents(asyncEvents); + syntheticEvents = syntheticEvents.sort((a, b) => userTimingComparator(a, b, [...syntheticEvents])); + timestampEvents = timestampEvents.sort((a, b) => userTimingComparator(a, b, [...timestampEvents])); +} +function data11() { + return { + consoleTimings: syntheticEvents.filter((e) => e.cat === "blink.console"), + performanceMeasures: syntheticEvents.filter((e) => e.cat === "blink.user_timing"), + performanceMarks: performanceMarkEvents, + timestampEvents, + measureTraceByTraceId + }; +} +var syntheticEvents, measureTraceByTraceId, performanceMeasureEvents, performanceMarkEvents, consoleTimings, timestampEvents, resourceTimingNames, navTimingNames, ignoredNames; +var init_UserTimingsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/UserTimingsHandler.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + syntheticEvents = []; + measureTraceByTraceId = /* @__PURE__ */ new Map(); + performanceMeasureEvents = []; + performanceMarkEvents = []; + consoleTimings = []; + timestampEvents = []; + __name(reset11, "reset"); + resourceTimingNames = [ + "workerStart", + "redirectStart", + "redirectEnd", + "fetchStart", + "domainLookupStart", + "domainLookupEnd", + "connectStart", + "connectEnd", + "secureConnectionStart", + "requestStart", + "responseStart", + "responseEnd" + ]; + navTimingNames = [ + "navigationStart", + "unloadEventStart", + "unloadEventEnd", + "redirectStart", + "redirectEnd", + "fetchStart", + "commitNavigationEnd", + "domainLookupStart", + "domainLookupEnd", + "connectStart", + "connectEnd", + "secureConnectionStart", + "requestStart", + "responseStart", + "responseEnd", + "domLoading", + "domInteractive", + "domContentLoadedEventStart", + "domContentLoadedEventEnd", + "domComplete", + "loadEventStart", + "loadEventEnd" + ]; + ignoredNames = [...resourceTimingNames, ...navTimingNames]; + __name(getEventTimings, "getEventTimings"); + __name(getEventTrack, "getEventTrack"); + __name(userTimingComparator, "userTimingComparator"); + __name(handleEvent11, "handleEvent"); + __name(finalize11, "finalize"); + __name(data11, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/ExtensionTraceDataHandler.js +var ExtensionTraceDataHandler_exports = {}; +__export(ExtensionTraceDataHandler_exports, { + data: () => data12, + deps: () => deps5, + extensionDataInConsoleTimeStamp: () => extensionDataInConsoleTimeStamp, + extensionDataInPerformanceTiming: () => extensionDataInPerformanceTiming, + extractConsoleAPIExtensionEntries: () => extractConsoleAPIExtensionEntries, + extractPerformanceAPIExtensionEntries: () => extractPerformanceAPIExtensionEntries, + finalize: () => finalize12, + handleEvent: () => handleEvent12, + reset: () => reset12 +}); +function handleEvent12(_event) { +} +function reset12() { + extensionTrackEntries = []; + syntheticConsoleEntriesForTimingsTrack = []; + extensionTrackData = []; + extensionMarkers = []; + entryToNode3 = /* @__PURE__ */ new Map(); + timeStampByName = /* @__PURE__ */ new Map(); +} +async function finalize12() { + createExtensionFlameChartEntries(); +} +function createExtensionFlameChartEntries() { + const pairedMeasures = data11().performanceMeasures; + const marks = data11().performanceMarks; + const mergedRawExtensionEvents = Trace_exports.mergeEventsInOrder(pairedMeasures, marks); + extractPerformanceAPIExtensionEntries(mergedRawExtensionEvents); + extractConsoleAPIExtensionEntries(); + Trace_exports.sortTraceEventsInPlace(extensionTrackEntries); + Extensions_exports2.buildTrackDataFromExtensionEntries(extensionTrackEntries, extensionTrackData, entryToNode3); +} +function extractConsoleAPIExtensionEntries() { + const consoleTimeStamps = data11().timestampEvents; + for (const currentTimeStamp of consoleTimeStamps) { + if (!currentTimeStamp.args.data) { + continue; + } + const timeStampName = String(currentTimeStamp.args.data.name ?? currentTimeStamp.args.data.message); + timeStampByName.set(timeStampName, currentTimeStamp); + const { devtoolsObj: extensionData, userDetail } = extensionDataInConsoleTimeStamp(currentTimeStamp); + const start = currentTimeStamp.args.data.start; + const end = currentTimeStamp.args.data.end; + if (!extensionData && !start && !end) { + continue; + } + const startTimeStamp = typeof start === "number" ? Timing_exports.Micro(start) : timeStampByName.get(String(start))?.ts; + const endTimeStamp = typeof end === "number" ? Timing_exports.Micro(end) : timeStampByName.get(String(end))?.ts; + if (endTimeStamp !== void 0 && startTimeStamp === void 0) { + continue; + } + const entryStartTime = startTimeStamp ?? currentTimeStamp.ts; + const entryEndTime = endTimeStamp ?? currentTimeStamp.ts; + if (extensionData) { + const unregisteredExtensionEntry = { + ...currentTimeStamp, + name: timeStampName, + cat: "devtools.extension", + devtoolsObj: extensionData, + userDetail, + rawSourceEvent: currentTimeStamp, + dur: Timing_exports.Micro(entryEndTime - entryStartTime), + ts: entryStartTime, + ph: TraceEvents_exports.Phase.COMPLETE + }; + const extensionEntry = SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent(unregisteredExtensionEntry); + extensionTrackEntries.push(extensionEntry); + continue; + } + const unregisteredSyntheticTimeStamp = { + ...currentTimeStamp, + name: timeStampName, + cat: "disabled-by-default-v8.inspector", + ph: TraceEvents_exports.Phase.COMPLETE, + ts: entryStartTime, + dur: Timing_exports.Micro(entryEndTime - entryStartTime), + rawSourceEvent: currentTimeStamp + }; + const syntheticTimeStamp = SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent(unregisteredSyntheticTimeStamp); + syntheticConsoleEntriesForTimingsTrack.push(syntheticTimeStamp); + } +} +function extractPerformanceAPIExtensionEntries(timings) { + for (const timing of timings) { + const { devtoolsObj, userDetail } = extensionDataInPerformanceTiming(timing); + if (!devtoolsObj) { + continue; + } + const extensionSyntheticEntry = { + name: timing.name, + ph: Extensions_exports.isExtensionPayloadMarker(devtoolsObj) ? TraceEvents_exports.Phase.INSTANT : TraceEvents_exports.Phase.COMPLETE, + pid: timing.pid, + tid: timing.tid, + ts: timing.ts, + dur: timing.dur, + cat: "devtools.extension", + devtoolsObj, + userDetail, + rawSourceEvent: TraceEvents_exports.isSyntheticUserTiming(timing) ? timing.rawSourceEvent : timing + }; + if (Extensions_exports.isExtensionPayloadMarker(devtoolsObj)) { + const extensionMarker = SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent(extensionSyntheticEntry); + extensionMarkers.push(extensionMarker); + continue; + } + if (Extensions_exports.isExtensionEntryObj(extensionSyntheticEntry.devtoolsObj)) { + const extensionTrackEntry = SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent(extensionSyntheticEntry); + extensionTrackEntries.push(extensionTrackEntry); + continue; + } + } +} +function extensionDataInPerformanceTiming(timing) { + const timingDetail = TraceEvents_exports.isPerformanceMark(timing) ? timing.args.data?.detail : timing.args.data.beginEvent.args.detail; + if (!timingDetail) { + return { devtoolsObj: null, userDetail: null }; + } + const devtoolsObj = Trace_exports.parseDevtoolsDetails(timingDetail, "devtools"); + let userDetail = null; + try { + userDetail = JSON.parse(timingDetail); + delete userDetail.devtools; + } catch { + } + return { devtoolsObj, userDetail }; +} +function extensionDataInConsoleTimeStamp(timeStamp) { + if (!timeStamp.args.data || !timeStamp.args.data.track) { + return { devtoolsObj: null, userDetail: null }; + } + let userDetail = null; + try { + userDetail = JSON.parse(timeStamp.args.data?.devtools || '""'); + } catch { + } + const devtoolsObj = { + // the color is defaulted to primary if it's value isn't one from + // the defined palette (see ExtensionUI::extensionEntryColor) so + // we don't need to check the value is valid here. + color: String(timeStamp.args.data.color), + track: String(timeStamp.args.data.track), + dataType: "track-entry", + trackGroup: timeStamp.args.data.trackGroup !== void 0 ? String(timeStamp.args.data.trackGroup) : void 0 + }; + return { devtoolsObj, userDetail }; +} +function data12() { + return { + entryToNode: entryToNode3, + extensionTrackData, + extensionMarkers, + syntheticConsoleEntriesForTimingsTrack + }; +} +function deps5() { + return ["UserTimings"]; +} +var extensionTrackEntries, extensionTrackData, extensionMarkers, entryToNode3, timeStampByName, syntheticConsoleEntriesForTimingsTrack; +var init_ExtensionTraceDataHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/ExtensionTraceDataHandler.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + init_UserTimingsHandler(); + extensionTrackEntries = []; + extensionTrackData = []; + extensionMarkers = []; + entryToNode3 = /* @__PURE__ */ new Map(); + timeStampByName = /* @__PURE__ */ new Map(); + syntheticConsoleEntriesForTimingsTrack = []; + __name(handleEvent12, "handleEvent"); + __name(reset12, "reset"); + __name(finalize12, "finalize"); + __name(createExtensionFlameChartEntries, "createExtensionFlameChartEntries"); + __name(extractConsoleAPIExtensionEntries, "extractConsoleAPIExtensionEntries"); + __name(extractPerformanceAPIExtensionEntries, "extractPerformanceAPIExtensionEntries"); + __name(extensionDataInPerformanceTiming, "extensionDataInPerformanceTiming"); + __name(extensionDataInConsoleTimeStamp, "extensionDataInConsoleTimeStamp"); + __name(data12, "data"); + __name(deps5, "deps"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/LayerTreeHandler.js +var LayerTreeHandler_exports = {}; +__export(LayerTreeHandler_exports, { + data: () => data13, + deps: () => deps6, + finalize: () => finalize13, + handleEvent: () => handleEvent13, + reset: () => reset13 +}); +function reset13() { + paintEvents = []; + snapshotEvents = []; + paintToSnapshotMap = /* @__PURE__ */ new Map(); + lastPaintForLayerId = {}; + currentMainFrameLayerTreeId = null; + updateLayerEvents = []; + relevantEvents = []; +} +function handleEvent13(event) { + if (TraceEvents_exports.isPaint(event) || TraceEvents_exports.isDisplayListItemListSnapshot(event) || TraceEvents_exports.isUpdateLayer(event) || TraceEvents_exports.isSetLayerId(event)) { + relevantEvents.push(event); + } +} +async function finalize13() { + const metaData = data5(); + Trace_exports.sortTraceEventsInPlace(relevantEvents); + for (const event of relevantEvents) { + if (TraceEvents_exports.isSetLayerId(event)) { + if (metaData.mainFrameId !== event.args.data.frame) { + continue; + } + currentMainFrameLayerTreeId = event.args.data.layerTreeId; + } else if (TraceEvents_exports.isUpdateLayer(event)) { + updateLayerEvents.push(event); + } else if (TraceEvents_exports.isPaint(event)) { + if (!event.args.data.layerId) { + continue; + } + paintEvents.push(event); + lastPaintForLayerId[event.args.data.layerId] = event; + continue; + } else if (TraceEvents_exports.isDisplayListItemListSnapshot(event)) { + let lastUpdateLayerEventForThread = null; + for (let i = updateLayerEvents.length - 1; i > -1; i--) { + const updateEvent = updateLayerEvents[i]; + if (updateEvent.pid === event.pid && updateEvent.tid === event.tid) { + lastUpdateLayerEventForThread = updateEvent; + break; + } + } + if (!lastUpdateLayerEventForThread) { + continue; + } + if (lastUpdateLayerEventForThread.args.layerTreeId !== currentMainFrameLayerTreeId) { + continue; + } + const paintEvent = lastPaintForLayerId[lastUpdateLayerEventForThread.args.layerId]; + if (!paintEvent) { + continue; + } + snapshotEvents.push(event); + paintToSnapshotMap.set(paintEvent, event); + } + } +} +function data13() { + return { + paints: paintEvents, + snapshots: snapshotEvents, + paintsToSnapshots: paintToSnapshotMap + }; +} +function deps6() { + return ["Meta"]; +} +var paintEvents, snapshotEvents, paintToSnapshotMap, lastPaintForLayerId, currentMainFrameLayerTreeId, updateLayerEvents, relevantEvents; +var init_LayerTreeHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/LayerTreeHandler.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + init_MetaHandler(); + paintEvents = []; + snapshotEvents = []; + paintToSnapshotMap = /* @__PURE__ */ new Map(); + lastPaintForLayerId = {}; + currentMainFrameLayerTreeId = null; + updateLayerEvents = []; + relevantEvents = []; + __name(reset13, "reset"); + __name(handleEvent13, "handleEvent"); + __name(finalize13, "finalize"); + __name(data13, "data"); + __name(deps6, "deps"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/Threads.js +var Threads_exports = {}; +__export(Threads_exports, { + ThreadType: () => ThreadType, + threadsInRenderer: () => threadsInRenderer, + threadsInTrace: () => threadsInTrace +}); +function getThreadTypeForRendererThread(pid, thread, auctionWorkletsData) { + let threadType = ThreadType.OTHER; + if (thread.name === "CrRendererMain") { + threadType = ThreadType.MAIN_THREAD; + } else if (thread.name === "DedicatedWorker thread") { + threadType = ThreadType.WORKER; + } else if (thread.name?.startsWith("CompositorTileWorker")) { + threadType = ThreadType.RASTERIZER; + } else if (auctionWorkletsData.worklets.has(pid)) { + threadType = ThreadType.AUCTION_WORKLET; + } else if (thread.name?.startsWith("ThreadPool")) { + threadType = ThreadType.THREAD_POOL; + } + return threadType; +} +function threadsInRenderer(rendererData, auctionWorkletsData) { + const foundThreads = []; + if (rendererData.processes.size) { + for (const [pid, process5] of rendererData.processes) { + for (const [tid, thread] of process5.threads) { + if (!thread.tree) { + continue; + } + const threadType = getThreadTypeForRendererThread(pid, thread, auctionWorkletsData); + foundThreads.push({ + name: thread.name, + pid, + tid, + processIsOnMainFrame: process5.isOnMainFrame, + entries: thread.entries, + tree: thread.tree, + type: threadType, + entryToNode: rendererData.entryToNode + }); + } + } + } + return foundThreads; +} +function threadsInTrace(handlerData) { + const cached = threadsInHandlerDataCache.get(handlerData); + if (cached) { + return cached; + } + const threadsFromRenderer = threadsInRenderer(handlerData.Renderer, handlerData.AuctionWorklets); + if (threadsFromRenderer.length) { + threadsInHandlerDataCache.set(handlerData, threadsFromRenderer); + return threadsFromRenderer; + } + const foundThreads = []; + if (handlerData.Samples.profilesInProcess.size) { + for (const [pid, process5] of handlerData.Samples.profilesInProcess) { + for (const [tid, thread] of process5) { + if (!thread.profileTree) { + continue; + } + foundThreads.push({ + pid, + tid, + // CPU Profile threads do not have a name. + name: null, + entries: thread.profileCalls, + // There is no concept of a "Main Frame" in a CPU profile. + processIsOnMainFrame: false, + tree: thread.profileTree, + type: ThreadType.CPU_PROFILE, + entryToNode: handlerData.Samples.entryToNode + }); + } + } + } + threadsInHandlerDataCache.set(handlerData, foundThreads); + return foundThreads; +} +var ThreadType, threadsInHandlerDataCache; +var init_Threads = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/Threads.js"() { + init_process_global(); + (function(ThreadType2) { + ThreadType2["MAIN_THREAD"] = "MAIN_THREAD"; + ThreadType2["WORKER"] = "WORKER"; + ThreadType2["RASTERIZER"] = "RASTERIZER"; + ThreadType2["AUCTION_WORKLET"] = "AUCTION_WORKLET"; + ThreadType2["OTHER"] = "OTHER"; + ThreadType2["CPU_PROFILE"] = "CPU_PROFILE"; + ThreadType2["THREAD_POOL"] = "THREAD_POOL"; + })(ThreadType || (ThreadType = {})); + __name(getThreadTypeForRendererThread, "getThreadTypeForRendererThread"); + __name(threadsInRenderer, "threadsInRenderer"); + threadsInHandlerDataCache = /* @__PURE__ */ new WeakMap(); + __name(threadsInTrace, "threadsInTrace"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/FramesHandler.js +var FramesHandler_exports = {}; +__export(FramesHandler_exports, { + LayerPaintEvent: () => LayerPaintEvent, + PendingFrame: () => PendingFrame, + TimelineFrameBeginFrameQueue: () => TimelineFrameBeginFrameQueue, + TimelineFrameModel: () => TimelineFrameModel, + data: () => data14, + deps: () => deps7, + finalize: () => finalize14, + framesWithinWindow: () => framesWithinWindow, + handleEvent: () => handleEvent14, + reset: () => reset14 +}); +function isFrameEvent(event) { + return TraceEvents_exports.isSetLayerId(event) || TraceEvents_exports.isBeginFrame(event) || TraceEvents_exports.isDroppedFrame(event) || TraceEvents_exports.isRequestMainThreadFrame(event) || TraceEvents_exports.isBeginMainThreadFrame(event) || TraceEvents_exports.isNeedsBeginFrameChanged(event) || // Note that "Commit" is the replacement for "CompositeLayers" so in a trace + // we wouldn't expect to see a combination of these. All "new" trace + // recordings use "Commit", but we can easily support "CompositeLayers" too + // to not break older traces being imported. + TraceEvents_exports.isCommit(event) || TraceEvents_exports.isCompositeLayers(event) || TraceEvents_exports.isActivateLayerTree(event) || TraceEvents_exports.isDrawFrame(event); +} +function entryIsTopLevel(entry) { + const devtoolsTimelineCategory = "disabled-by-default-devtools.timeline"; + return entry.name === TraceEvents_exports.Name.RUN_TASK && entry.cat.includes(devtoolsTimelineCategory); +} +function reset14() { + model = null; + relevantFrameEvents = []; +} +function handleEvent14(event) { + if (isFrameEvent(event) || TraceEvents_exports.isLayerTreeHostImplSnapshot(event) || entryIsTopLevel(event) || MAIN_FRAME_MARKERS.has(event.name) || TraceEvents_exports.isPaint(event)) { + relevantFrameEvents.push(event); + } +} +async function finalize14() { + Trace_exports.sortTraceEventsInPlace(relevantFrameEvents); + const modelForTrace = new TimelineFrameModel(relevantFrameEvents, data8(), data4(), data5(), data13()); + model = modelForTrace; +} +function data14() { + return { + frames: model?.frames() ?? [], + framesById: model?.framesById() ?? {} + }; +} +function deps7() { + return ["Meta", "Renderer", "AuctionWorklets", "LayerTree"]; +} +function framesWithinWindow(frames2, startTime, endTime) { + const firstFrame = ArrayUtilities_exports.lowerBound(frames2, startTime || 0, (time, frame) => time - frame.endTime); + const lastFrame = ArrayUtilities_exports.lowerBound(frames2, endTime || Infinity, (time, frame) => time - frame.startTime); + return frames2.slice(firstFrame, lastFrame); +} +var model, relevantFrameEvents, MAIN_FRAME_MARKERS, TimelineFrameModel, TimelineFrame, LayerPaintEvent, PendingFrame, BeginFrameInfo, TimelineFrameBeginFrameQueue; +var init_FramesHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/FramesHandler.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + init_AuctionWorkletsHandler(); + init_LayerTreeHandler(); + init_MetaHandler(); + init_RendererHandler(); + init_Threads(); + model = null; + relevantFrameEvents = []; + __name(isFrameEvent, "isFrameEvent"); + __name(entryIsTopLevel, "entryIsTopLevel"); + MAIN_FRAME_MARKERS = /* @__PURE__ */ new Set([ + TraceEvents_exports.Name.SCHEDULE_STYLE_RECALCULATION, + TraceEvents_exports.Name.INVALIDATE_LAYOUT, + TraceEvents_exports.Name.BEGIN_MAIN_THREAD_FRAME, + TraceEvents_exports.Name.SCROLL_LAYER + ]); + __name(reset14, "reset"); + __name(handleEvent14, "handleEvent"); + __name(finalize14, "finalize"); + __name(data14, "data"); + __name(deps7, "deps"); + TimelineFrameModel = class { + static { + __name(this, "TimelineFrameModel"); + } + #frames = []; + #frameById = {}; + #beginFrameQueue = new TimelineFrameBeginFrameQueue(); + #lastFrame = null; + #mainFrameCommitted = false; + #mainFrameRequested = false; + #lastLayerTree = null; + #framePendingActivation = null; + #framePendingCommit = null; + #lastBeginFrame = null; + #lastNeedsBeginFrame = null; + #lastTaskBeginTime = null; + #layerTreeId = null; + #activeProcessId = null; + #activeThreadId = null; + #layerTreeData; + constructor(allEvents, rendererData, auctionWorkletsData, metaData, layerTreeData) { + const mainThreads = threadsInRenderer(rendererData, auctionWorkletsData).filter((thread) => { + return thread.type === ThreadType.MAIN_THREAD && thread.processIsOnMainFrame; + }); + const threadData = mainThreads.map((thread) => { + return { + tid: thread.tid, + pid: thread.pid, + startTime: thread.entries[0].ts + }; + }); + this.#layerTreeData = layerTreeData; + this.#addTraceEvents(allEvents, threadData, metaData.mainFrameId); + } + framesById() { + return this.#frameById; + } + frames() { + return this.#frames; + } + #handleBeginFrame(startTime, seqId) { + if (!this.#lastFrame) { + this.#startFrame(startTime, seqId); + } + this.#lastBeginFrame = startTime; + this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, false, false); + } + #handleDroppedFrame(startTime, seqId, isPartial) { + if (!this.#lastFrame) { + this.#startFrame(startTime, seqId); + } + this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, true, isPartial); + this.#beginFrameQueue.setDropped(seqId, true); + this.#beginFrameQueue.setPartial(seqId, isPartial); + } + #handleDrawFrame(startTime, seqId) { + if (!this.#lastFrame) { + this.#startFrame(startTime, seqId); + return; + } + if (this.#mainFrameCommitted || !this.#mainFrameRequested) { + if (this.#lastNeedsBeginFrame) { + const idleTimeEnd = this.#framePendingActivation ? this.#framePendingActivation.triggerTime : this.#lastBeginFrame || this.#lastNeedsBeginFrame; + if (idleTimeEnd > this.#lastFrame.startTime) { + this.#lastFrame.idle = true; + this.#lastBeginFrame = null; + } + this.#lastNeedsBeginFrame = null; + } + const framesToVisualize = this.#beginFrameQueue.processPendingBeginFramesOnDrawFrame(seqId); + for (const frame of framesToVisualize) { + const isLastFrameIdle = this.#lastFrame.idle; + this.#startFrame(frame.startTime, seqId); + if (isLastFrameIdle && this.#framePendingActivation) { + this.#commitPendingFrame(); + } + if (frame.isDropped) { + this.#lastFrame.dropped = true; + } + if (frame.isPartial) { + this.#lastFrame.isPartial = true; + } + } + } + this.#mainFrameCommitted = false; + } + #handleActivateLayerTree() { + if (!this.#lastFrame) { + return; + } + if (this.#framePendingActivation && !this.#lastNeedsBeginFrame) { + this.#commitPendingFrame(); + } + } + #handleRequestMainThreadFrame() { + if (!this.#lastFrame) { + return; + } + this.#mainFrameRequested = true; + } + #handleCommit() { + if (!this.#framePendingCommit) { + return; + } + this.#framePendingActivation = this.#framePendingCommit; + this.#framePendingCommit = null; + this.#mainFrameRequested = false; + this.#mainFrameCommitted = true; + } + #handleLayerTreeSnapshot(layerTree) { + this.#lastLayerTree = layerTree; + } + #handleNeedFrameChanged(startTime, needsBeginFrame) { + if (needsBeginFrame) { + this.#lastNeedsBeginFrame = startTime; + } + } + #startFrame(startTime, seqId) { + if (this.#lastFrame) { + this.#flushFrame(this.#lastFrame, startTime); + } + this.#lastFrame = new TimelineFrame(seqId, startTime, Timing_exports.Micro(startTime - data5().traceBounds.min)); + } + #flushFrame(frame, endTime) { + frame.setLayerTree(this.#lastLayerTree); + frame.setEndTime(endTime); + if (this.#lastLayerTree) { + this.#lastLayerTree.paints = frame.paints; + } + const lastFrame = this.#frames[this.#frames.length - 1]; + if (this.#frames.length && lastFrame && (frame.startTime !== lastFrame.endTime || frame.startTime > frame.endTime)) { + console.assert(false, `Inconsistent frame time for frame ${this.#frames.length} (${frame.startTime} - ${frame.endTime})`); + } + const newFramesLength = this.#frames.push(frame); + frame.setIndex(newFramesLength - 1); + if (typeof frame.mainFrameId === "number") { + this.#frameById[frame.mainFrameId] = frame; + } + } + #commitPendingFrame() { + if (!this.#framePendingActivation || !this.#lastFrame) { + return; + } + this.#lastFrame.paints = this.#framePendingActivation.paints; + this.#lastFrame.mainFrameId = this.#framePendingActivation.mainFrameId; + this.#framePendingActivation = null; + } + #addTraceEvents(events, threadData, mainFrameId2) { + let j = 0; + this.#activeThreadId = threadData.length && threadData[0].tid || null; + this.#activeProcessId = threadData.length && threadData[0].pid || null; + for (let i = 0; i < events.length; ++i) { + while (j + 1 < threadData.length && threadData[j + 1].startTime <= events[i].ts) { + this.#activeThreadId = threadData[++j].tid; + this.#activeProcessId = threadData[j].pid; + } + this.#addTraceEvent(events[i], mainFrameId2); + } + this.#activeThreadId = null; + this.#activeProcessId = null; + } + #addTraceEvent(event, mainFrameId2) { + if (TraceEvents_exports.isSetLayerId(event) && event.args.data.frame === mainFrameId2) { + this.#layerTreeId = event.args.data.layerTreeId; + } else if (TraceEvents_exports.isLayerTreeHostImplSnapshot(event) && Number(event.id) === this.#layerTreeId) { + this.#handleLayerTreeSnapshot({ + entry: event, + paints: [] + }); + } else { + if (isFrameEvent(event)) { + this.#processCompositorEvents(event); + } + if (event.tid === this.#activeThreadId && event.pid === this.#activeProcessId) { + this.#addMainThreadTraceEvent(event); + } + } + } + #processCompositorEvents(entry) { + if (entry.args["layerTreeId"] !== this.#layerTreeId) { + return; + } + if (TraceEvents_exports.isBeginFrame(entry)) { + this.#handleBeginFrame(entry.ts, entry.args["frameSeqId"]); + } else if (TraceEvents_exports.isDrawFrame(entry)) { + this.#handleDrawFrame(entry.ts, entry.args["frameSeqId"]); + } else if (TraceEvents_exports.isActivateLayerTree(entry)) { + this.#handleActivateLayerTree(); + } else if (TraceEvents_exports.isRequestMainThreadFrame(entry)) { + this.#handleRequestMainThreadFrame(); + } else if (TraceEvents_exports.isNeedsBeginFrameChanged(entry)) { + this.#handleNeedFrameChanged(entry.ts, entry.args["data"] && Boolean(entry.args["data"]["needsBeginFrame"])); + } else if (TraceEvents_exports.isDroppedFrame(entry)) { + this.#handleDroppedFrame(entry.ts, entry.args["frameSeqId"], Boolean(entry.args["hasPartialUpdate"])); + } + } + #addMainThreadTraceEvent(entry) { + if (entryIsTopLevel(entry)) { + this.#lastTaskBeginTime = entry.ts; + } + if (!this.#framePendingCommit && MAIN_FRAME_MARKERS.has(entry.name)) { + this.#framePendingCommit = new PendingFrame(this.#lastTaskBeginTime || entry.ts); + } + if (!this.#framePendingCommit) { + return; + } + if (TraceEvents_exports.isBeginMainThreadFrame(entry) && entry.args.data.frameId) { + this.#framePendingCommit.mainFrameId = entry.args.data.frameId; + } + if (TraceEvents_exports.isPaint(entry)) { + const snapshot2 = this.#layerTreeData.paintsToSnapshots.get(entry); + if (snapshot2) { + this.#framePendingCommit.paints.push(new LayerPaintEvent(entry, snapshot2)); + } + } + if ((TraceEvents_exports.isCompositeLayers(entry) || TraceEvents_exports.isCommit(entry)) && entry.args["layerTreeId"] === this.#layerTreeId) { + this.#handleCommit(); + } + } + }; + TimelineFrame = class { + static { + __name(this, "TimelineFrame"); + } + // These fields exist to satisfy the base Event type which all + // "trace events" must implement. They aren't used, but doing this means we + // can pass `TimelineFrame` instances into places that expect + // Types.Events.Event. + cat = "devtools.legacy_frame"; + name = "frame"; + ph = TraceEvents_exports.Phase.COMPLETE; + ts; + pid = TraceEvents_exports.ProcessID(-1); + tid = TraceEvents_exports.ThreadID(-1); + index = -1; + startTime; + startTimeOffset; + endTime; + duration; + idle; + dropped; + isPartial; + layerTree; + paints; + mainFrameId; + seqId; + constructor(seqId, startTime, startTimeOffset) { + this.seqId = seqId; + this.startTime = startTime; + this.ts = startTime; + this.startTimeOffset = startTimeOffset; + this.endTime = this.startTime; + this.duration = Timing_exports.Micro(0); + this.idle = false; + this.dropped = false; + this.isPartial = false; + this.layerTree = null; + this.paints = []; + this.mainFrameId = void 0; + } + setIndex(i) { + this.index = i; + } + setEndTime(endTime) { + this.endTime = endTime; + this.duration = Timing_exports.Micro(this.endTime - this.startTime); + } + setLayerTree(layerTree) { + this.layerTree = layerTree; + } + /** + * Fake the `dur` field to meet the expected value given that we pretend + * these TimelineFrame classes are trace events across the codebase. + */ + get dur() { + return this.duration; + } + }; + LayerPaintEvent = class { + static { + __name(this, "LayerPaintEvent"); + } + #event; + #snapshot; + constructor(event, snapshot2) { + this.#event = event; + this.#snapshot = snapshot2; + } + layerId() { + return this.#event.args.data.layerId; + } + event() { + return this.#event; + } + picture() { + const rect = this.#snapshot.args.snapshot.params?.layer_rect; + const pictureData = this.#snapshot.args.snapshot.skp64; + return rect && pictureData ? { rect, serializedPicture: pictureData } : null; + } + }; + PendingFrame = class { + static { + __name(this, "PendingFrame"); + } + paints; + mainFrameId; + triggerTime; + constructor(triggerTime) { + this.paints = []; + this.mainFrameId = void 0; + this.triggerTime = triggerTime; + } + }; + BeginFrameInfo = class { + static { + __name(this, "BeginFrameInfo"); + } + seqId; + startTime; + isDropped; + isPartial; + constructor(seqId, startTime, isDropped, isPartial) { + this.seqId = seqId; + this.startTime = startTime; + this.isDropped = isDropped; + this.isPartial = isPartial; + } + }; + TimelineFrameBeginFrameQueue = class { + static { + __name(this, "TimelineFrameBeginFrameQueue"); + } + queueFrames = []; + // Maps frameSeqId to BeginFrameInfo. + mapFrames = {}; + // Add a BeginFrame to the queue, if it does not already exit. + addFrameIfNotExists(seqId, startTime, isDropped, isPartial) { + if (!(seqId in this.mapFrames)) { + this.mapFrames[seqId] = new BeginFrameInfo(seqId, startTime, isDropped, isPartial); + this.queueFrames.push(seqId); + } + } + // Set a BeginFrame in queue as dropped. + setDropped(seqId, isDropped) { + if (seqId in this.mapFrames) { + this.mapFrames[seqId].isDropped = isDropped; + } + } + setPartial(seqId, isPartial) { + if (seqId in this.mapFrames) { + this.mapFrames[seqId].isPartial = isPartial; + } + } + processPendingBeginFramesOnDrawFrame(seqId) { + const framesToVisualize = []; + if (seqId in this.mapFrames) { + while (this.queueFrames[0] !== seqId) { + const currentSeqId = this.queueFrames[0]; + if (this.mapFrames[currentSeqId].isDropped) { + framesToVisualize.push(this.mapFrames[currentSeqId]); + } + delete this.mapFrames[currentSeqId]; + this.queueFrames.shift(); + } + framesToVisualize.push(this.mapFrames[seqId]); + delete this.mapFrames[seqId]; + this.queueFrames.shift(); + } + return framesToVisualize; + } + }; + __name(framesWithinWindow, "framesWithinWindow"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/GPUHandler.js +var GPUHandler_exports = {}; +__export(GPUHandler_exports, { + data: () => data15, + deps: () => deps8, + finalize: () => finalize15, + handleEvent: () => handleEvent15, + reset: () => reset15 +}); +function reset15() { + eventsInProcessThread = /* @__PURE__ */ new Map(); + mainGPUThreadTasks = []; +} +function handleEvent15(event) { + if (!TraceEvents_exports.isGPUTask(event)) { + return; + } + Trace_exports.addEventToProcessThread(event, eventsInProcessThread); +} +async function finalize15() { + const { gpuProcessId: gpuProcessId2, gpuThreadId: gpuThreadId2 } = data5(); + const gpuThreadsForProcess = eventsInProcessThread.get(gpuProcessId2); + if (gpuThreadsForProcess && gpuThreadId2) { + mainGPUThreadTasks = gpuThreadsForProcess.get(gpuThreadId2) || []; + } +} +function data15() { + return { + mainGPUThreadTasks + }; +} +function deps8() { + return ["Meta"]; +} +var eventsInProcessThread, mainGPUThreadTasks; +var init_GPUHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/GPUHandler.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + init_MetaHandler(); + eventsInProcessThread = /* @__PURE__ */ new Map(); + mainGPUThreadTasks = []; + __name(reset15, "reset"); + __name(handleEvent15, "handleEvent"); + __name(finalize15, "finalize"); + __name(data15, "data"); + __name(deps8, "deps"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/ImagePaintingHandler.js +var ImagePaintingHandler_exports = {}; +__export(ImagePaintingHandler_exports, { + data: () => data16, + finalize: () => finalize16, + handleEvent: () => handleEvent16, + reset: () => reset16 +}); +function reset16() { + paintImageEvents = /* @__PURE__ */ new Map(); + decodeLazyPixelRefEvents = /* @__PURE__ */ new Map(); + paintImageByLazyPixelRef = /* @__PURE__ */ new Map(); + eventToPaintImage = /* @__PURE__ */ new Map(); + urlToPaintImage = /* @__PURE__ */ new Map(); + paintEventToCorrectedDisplaySize = /* @__PURE__ */ new Map(); + didCorrectForHostDpr = false; +} +function handleEvent16(event) { + if (TraceEvents_exports.isPaintImage(event)) { + const forProcess = paintImageEvents.get(event.pid) || /* @__PURE__ */ new Map(); + const forThread = forProcess.get(event.tid) || []; + forThread.push(event); + forProcess.set(event.tid, forThread); + paintImageEvents.set(event.pid, forProcess); + if (event.args.data.url) { + const paintsForUrl = MapUtilities_exports.getWithDefault(urlToPaintImage, event.args.data.url, () => []); + paintsForUrl.push(event); + } + return; + } + if (TraceEvents_exports.isDecodeLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== "undefined") { + const forProcess = decodeLazyPixelRefEvents.get(event.pid) || /* @__PURE__ */ new Map(); + const forThread = forProcess.get(event.tid) || []; + forThread.push(event); + forProcess.set(event.tid, forThread); + decodeLazyPixelRefEvents.set(event.pid, forProcess); + } + if (TraceEvents_exports.isDrawLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== "undefined") { + const lastPaintEvent = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1); + if (!lastPaintEvent) { + return; + } + paintImageByLazyPixelRef.set(event.args.LazyPixelRef, lastPaintEvent); + return; + } + if (TraceEvents_exports.isDecodeImage(event)) { + const lastPaintImageEventOnThread = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1); + if (lastPaintImageEventOnThread) { + eventToPaintImage.set(event, lastPaintImageEventOnThread); + return; + } + const lastDecodeLazyPixelRef = decodeLazyPixelRefEvents.get(event.pid)?.get(event.tid)?.at(-1); + if (typeof lastDecodeLazyPixelRef?.args?.LazyPixelRef === "undefined") { + return; + } + const paintEvent = paintImageByLazyPixelRef.get(lastDecodeLazyPixelRef.args.LazyPixelRef); + if (!paintEvent) { + return; + } + eventToPaintImage.set(event, paintEvent); + } +} +async function finalize16(options) { + if (!options.metadata?.hostDPR) { + return; + } + const { devicePixelRatio: emulatedDpr } = data5(); + if (!emulatedDpr) { + return; + } + for (const byThread of paintImageEvents.values()) { + for (const paintEvents2 of byThread.values()) { + for (const paintEvent of paintEvents2) { + const cssPixelsWidth = paintEvent.args.data.width / options.metadata.hostDPR; + const cssPixelsHeight = paintEvent.args.data.height / options.metadata.hostDPR; + const width = cssPixelsWidth * emulatedDpr; + const height = cssPixelsHeight * emulatedDpr; + paintEventToCorrectedDisplaySize.set(paintEvent, { width, height }); + } + } + } + didCorrectForHostDpr = true; +} +function data16() { + return { + paintImageByDrawLazyPixelRef: paintImageByLazyPixelRef, + paintImageForEvent: eventToPaintImage, + paintImageEventForUrl: urlToPaintImage, + paintEventToCorrectedDisplaySize, + didCorrectForHostDpr + }; +} +var paintImageEvents, decodeLazyPixelRefEvents, paintImageByLazyPixelRef, eventToPaintImage, urlToPaintImage, paintEventToCorrectedDisplaySize, didCorrectForHostDpr; +var init_ImagePaintingHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/ImagePaintingHandler.js"() { + init_process_global(); + init_platform(); + init_types2(); + init_MetaHandler(); + paintImageEvents = /* @__PURE__ */ new Map(); + decodeLazyPixelRefEvents = /* @__PURE__ */ new Map(); + paintImageByLazyPixelRef = /* @__PURE__ */ new Map(); + eventToPaintImage = /* @__PURE__ */ new Map(); + urlToPaintImage = /* @__PURE__ */ new Map(); + paintEventToCorrectedDisplaySize = /* @__PURE__ */ new Map(); + didCorrectForHostDpr = false; + __name(reset16, "reset"); + __name(handleEvent16, "handleEvent"); + __name(finalize16, "finalize"); + __name(data16, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/InitiatorsHandler.js +var InitiatorsHandler_exports = {}; +__export(InitiatorsHandler_exports, { + data: () => data17, + deps: () => deps9, + finalize: () => finalize17, + handleEvent: () => handleEvent17, + reset: () => reset17 +}); +function reset17() { + lastScheduleStyleRecalcByFrame = /* @__PURE__ */ new Map(); + lastInvalidationEventForFrame = /* @__PURE__ */ new Map(); + lastRecalcByFrame = /* @__PURE__ */ new Map(); + timerInstallEventsById = /* @__PURE__ */ new Map(); + eventToInitiatorMap2 = /* @__PURE__ */ new Map(); + initiatorToEventsMap = /* @__PURE__ */ new Map(); + requestIdleCallbackEventsById = /* @__PURE__ */ new Map(); + webSocketCreateEventsById = /* @__PURE__ */ new Map(); + schedulePostTaskCallbackEventsById = /* @__PURE__ */ new Map(); +} +function storeInitiator(data31) { + eventToInitiatorMap2.set(data31.event, data31.initiator); + const eventsForInitiator = initiatorToEventsMap.get(data31.initiator) || []; + eventsForInitiator.push(data31.event); + initiatorToEventsMap.set(data31.initiator, eventsForInitiator); +} +function handleEvent17(event) { + if (TraceEvents_exports.isScheduleStyleRecalculation(event)) { + lastScheduleStyleRecalcByFrame.set(event.args.data.frame, event); + } else if (TraceEvents_exports.isRecalcStyle(event)) { + if (event.args.beginData) { + lastRecalcByFrame.set(event.args.beginData.frame, event); + const scheduledStyleForFrame = lastScheduleStyleRecalcByFrame.get(event.args.beginData.frame); + if (scheduledStyleForFrame) { + storeInitiator({ + event, + initiator: scheduledStyleForFrame + }); + } + } + } else if (TraceEvents_exports.isInvalidateLayout(event)) { + let invalidationInitiator = event; + if (!lastInvalidationEventForFrame.has(event.args.data.frame)) { + const lastRecalcStyleForFrame = lastRecalcByFrame.get(event.args.data.frame); + if (lastRecalcStyleForFrame) { + const { endTime } = Timing_exports3.eventTimingsMicroSeconds(lastRecalcStyleForFrame); + const initiatorOfRecalcStyle = eventToInitiatorMap2.get(lastRecalcStyleForFrame); + if (initiatorOfRecalcStyle && endTime && endTime > event.ts) { + invalidationInitiator = initiatorOfRecalcStyle; + } + } + } + lastInvalidationEventForFrame.set(event.args.data.frame, invalidationInitiator); + } else if (TraceEvents_exports.isLayout(event)) { + const lastInvalidation = lastInvalidationEventForFrame.get(event.args.beginData.frame); + if (lastInvalidation) { + storeInitiator({ + event, + initiator: lastInvalidation + }); + } + lastInvalidationEventForFrame.delete(event.args.beginData.frame); + } else if (TraceEvents_exports.isTimerInstall(event)) { + timerInstallEventsById.set(event.args.data.timerId, event); + } else if (TraceEvents_exports.isTimerFire(event)) { + const matchingInstall = timerInstallEventsById.get(event.args.data.timerId); + if (matchingInstall) { + storeInitiator({ event, initiator: matchingInstall }); + } + } else if (TraceEvents_exports.isRequestIdleCallback(event)) { + requestIdleCallbackEventsById.set(event.args.data.id, event); + } else if (TraceEvents_exports.isFireIdleCallback(event)) { + const matchingRequestEvent = requestIdleCallbackEventsById.get(event.args.data.id); + if (matchingRequestEvent) { + storeInitiator({ + event, + initiator: matchingRequestEvent + }); + } + } else if (TraceEvents_exports.isWebSocketCreate(event)) { + webSocketCreateEventsById.set(event.args.data.identifier, event); + } else if (TraceEvents_exports.isWebSocketInfo(event) || TraceEvents_exports.isWebSocketTransfer(event)) { + const matchingCreateEvent = webSocketCreateEventsById.get(event.args.data.identifier); + if (matchingCreateEvent) { + storeInitiator({ + event, + initiator: matchingCreateEvent + }); + } + } else if (TraceEvents_exports.isSchedulePostTaskCallback(event)) { + schedulePostTaskCallbackEventsById.set(event.args.data.taskId, event); + } else if (TraceEvents_exports.isRunPostTaskCallback(event) || TraceEvents_exports.isAbortPostTaskCallback(event)) { + const matchingSchedule = schedulePostTaskCallbackEventsById.get(event.args.data.taskId); + if (matchingSchedule) { + storeInitiator({ event, initiator: matchingSchedule }); + } + } +} +function createRelationshipsFromFlows() { + const flows2 = data3().flows; + for (let i = 0; i < flows2.length; i++) { + const flow = flows2[i]; + for (let j = 0; j < flow.length - 1; j++) { + storeInitiator({ event: flow[j + 1], initiator: flow[j] }); + } + } +} +function createRelationshipsFromAsyncJSCalls() { + const asyncCallEntries = data9().schedulerToRunEntryPoints.entries(); + for (const [asyncCaller, asyncCallees] of asyncCallEntries) { + for (const asyncCallee of asyncCallees) { + storeInitiator({ event: asyncCallee, initiator: asyncCaller }); + } + } +} +async function finalize17() { + createRelationshipsFromFlows(); + createRelationshipsFromAsyncJSCalls(); +} +function data17() { + return { + eventToInitiator: eventToInitiatorMap2, + initiatorToEvents: initiatorToEventsMap + }; +} +function deps9() { + return ["Flows", "AsyncJSCalls"]; +} +var lastScheduleStyleRecalcByFrame, lastInvalidationEventForFrame, lastRecalcByFrame, eventToInitiatorMap2, initiatorToEventsMap, timerInstallEventsById, requestIdleCallbackEventsById, webSocketCreateEventsById, schedulePostTaskCallbackEventsById; +var init_InitiatorsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/InitiatorsHandler.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + init_AsyncJSCallsHandler(); + init_FlowsHandler(); + lastScheduleStyleRecalcByFrame = /* @__PURE__ */ new Map(); + lastInvalidationEventForFrame = /* @__PURE__ */ new Map(); + lastRecalcByFrame = /* @__PURE__ */ new Map(); + eventToInitiatorMap2 = /* @__PURE__ */ new Map(); + initiatorToEventsMap = /* @__PURE__ */ new Map(); + timerInstallEventsById = /* @__PURE__ */ new Map(); + requestIdleCallbackEventsById = /* @__PURE__ */ new Map(); + webSocketCreateEventsById = /* @__PURE__ */ new Map(); + schedulePostTaskCallbackEventsById = /* @__PURE__ */ new Map(); + __name(reset17, "reset"); + __name(storeInitiator, "storeInitiator"); + __name(handleEvent17, "handleEvent"); + __name(createRelationshipsFromFlows, "createRelationshipsFromFlows"); + __name(createRelationshipsFromAsyncJSCalls, "createRelationshipsFromAsyncJSCalls"); + __name(finalize17, "finalize"); + __name(data17, "data"); + __name(deps9, "deps"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/InvalidationsHandler.js +var InvalidationsHandler_exports = {}; +__export(InvalidationsHandler_exports, { + data: () => data18, + finalize: () => finalize18, + handleEvent: () => handleEvent18, + handleUserConfig: () => handleUserConfig3, + reset: () => reset18 +}); +function reset18() { + frameStateByFrame.clear(); + maxInvalidationsPerEvent = null; +} +function handleUserConfig3(userConfig) { + maxInvalidationsPerEvent = userConfig.maxInvalidationEventsPerEvent; +} +function getState(frameId) { + let frameState = frameStateByFrame.get(frameId); + if (!frameState) { + frameState = { + invalidationsForEvent: /* @__PURE__ */ new Map(), + invalidationCountForEvent: /* @__PURE__ */ new Map(), + lastRecalcStyleEvent: null, + pendingInvalidations: [], + hasPainted: false + }; + frameStateByFrame.set(frameId, frameState); + } + return frameState; +} +function getFrameId(event) { + if (TraceEvents_exports.isRecalcStyle(event) || TraceEvents_exports.isLayout(event)) { + return event.args.beginData?.frame ?? null; + } + return event.args?.data?.frame ?? null; +} +function addInvalidationToEvent(frameState, event, invalidation) { + const existingInvalidations = frameState.invalidationsForEvent.get(event) || []; + existingInvalidations.push(invalidation); + if (maxInvalidationsPerEvent !== null && existingInvalidations.length > maxInvalidationsPerEvent) { + existingInvalidations.shift(); + } + frameState.invalidationsForEvent.set(event, existingInvalidations); + const count = frameState.invalidationCountForEvent.get(event) ?? 0; + frameState.invalidationCountForEvent.set(event, count + 1); +} +function handleEvent18(event) { + if (maxInvalidationsPerEvent === 0) { + return; + } + const frameId = getFrameId(event); + if (!frameId) { + return; + } + const thisFrame = getState(frameId); + if (TraceEvents_exports.isRecalcStyle(event)) { + thisFrame.lastRecalcStyleEvent = event; + for (const invalidation of thisFrame.pendingInvalidations) { + if (TraceEvents_exports.isLayoutInvalidationTracking(invalidation)) { + continue; + } + addInvalidationToEvent(thisFrame, event, invalidation); + } + return; + } + if (TraceEvents_exports.isInvalidationTracking(event)) { + if (thisFrame.hasPainted) { + thisFrame.pendingInvalidations.length = 0; + thisFrame.lastRecalcStyleEvent = null; + thisFrame.hasPainted = false; + } + if (thisFrame.lastRecalcStyleEvent && (TraceEvents_exports.isScheduleStyleInvalidationTracking(event) || TraceEvents_exports.isStyleRecalcInvalidationTracking(event) || TraceEvents_exports.isStyleInvalidatorInvalidationTracking(event))) { + const recalcLastRecalc = thisFrame.lastRecalcStyleEvent; + const recalcEndTime = recalcLastRecalc.ts + (recalcLastRecalc.dur || 0); + if (event.ts >= recalcLastRecalc.ts && event.ts <= recalcEndTime) { + addInvalidationToEvent(thisFrame, recalcLastRecalc, event); + } + } + thisFrame.pendingInvalidations.push(event); + return; + } + if (TraceEvents_exports.isPaint(event)) { + thisFrame.hasPainted = true; + return; + } + if (TraceEvents_exports.isLayout(event)) { + for (const invalidation of thisFrame.pendingInvalidations) { + if (!TraceEvents_exports.isLayoutInvalidationTracking(invalidation)) { + continue; + } + addInvalidationToEvent(thisFrame, event, invalidation); + } + } +} +async function finalize18() { +} +function data18() { + const invalidationsForEvent = /* @__PURE__ */ new Map(); + const invalidationCountForEvent = /* @__PURE__ */ new Map(); + for (const frame of frameStateByFrame.values()) { + for (const [event, invalidations] of frame.invalidationsForEvent.entries()) { + invalidationsForEvent.set(event, invalidations); + } + for (const [event, count] of frame.invalidationCountForEvent.entries()) { + invalidationCountForEvent.set(event, count); + } + } + return { + invalidationsForEvent, + invalidationCountForEvent + }; +} +var frameStateByFrame, maxInvalidationsPerEvent; +var init_InvalidationsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/InvalidationsHandler.js"() { + init_process_global(); + init_types2(); + frameStateByFrame = /* @__PURE__ */ new Map(); + maxInvalidationsPerEvent = null; + __name(reset18, "reset"); + __name(handleUserConfig3, "handleUserConfig"); + __name(getState, "getState"); + __name(getFrameId, "getFrameId"); + __name(addInvalidationToEvent, "addInvalidationToEvent"); + __name(handleEvent18, "handleEvent"); + __name(finalize18, "finalize"); + __name(data18, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/PageLoadMetricsHandler.js +var PageLoadMetricsHandler_exports = {}; +__export(PageLoadMetricsHandler_exports, { + MetricName: () => MetricName, + ScoreClassification: () => ScoreClassification, + data: () => data19, + deps: () => deps10, + finalize: () => finalize19, + getFrameIdForPageLoadEvent: () => getFrameIdForPageLoadEvent, + handleEvent: () => handleEvent19, + metricIsLCP: () => metricIsLCP, + reset: () => reset19, + scoreClassificationForDOMContentLoaded: () => scoreClassificationForDOMContentLoaded, + scoreClassificationForFirstContentfulPaint: () => scoreClassificationForFirstContentfulPaint, + scoreClassificationForLargestContentfulPaint: () => scoreClassificationForLargestContentfulPaint, + scoreClassificationForTimeToInteractive: () => scoreClassificationForTimeToInteractive, + scoreClassificationForTotalBlockingTime: () => scoreClassificationForTotalBlockingTime +}); +function reset19() { + metricScoresByFrameId = /* @__PURE__ */ new Map(); + pageLoadEventsArray = []; + allMarkerEvents = []; + selectedLCPCandidateEvents = /* @__PURE__ */ new Set(); +} +function handleEvent19(event) { + if (!TraceEvents_exports.eventIsPageLoadEvent(event)) { + return; + } + pageLoadEventsArray.push(event); +} +function storePageLoadMetricAgainstNavigationId(navigation2, event) { + const navigationId = navigation2.args.data?.navigationId; + if (!navigationId) { + throw new Error("Navigation event unexpectedly had no navigation ID."); + } + const frameId = getFrameIdForPageLoadEvent(event); + const { rendererProcessesByFrame } = data5(); + const rendererProcessesInFrame = rendererProcessesByFrame.get(frameId); + if (!rendererProcessesInFrame) { + return; + } + const processData = rendererProcessesInFrame.get(event.pid); + if (!processData) { + return; + } + if (TraceEvents_exports.isNavigationStart(event)) { + return; + } + if (TraceEvents_exports.isFirstContentfulPaint(event)) { + const fcpTime = Timing_exports.Micro(event.ts - navigation2.ts); + const classification = scoreClassificationForFirstContentfulPaint(fcpTime); + const metricScore = { event, metricName: MetricName.FCP, classification, navigation: navigation2, timing: fcpTime }; + storeMetricScore(frameId, navigationId, metricScore); + return; + } + if (TraceEvents_exports.isFirstPaint(event)) { + const paintTime = Timing_exports.Micro(event.ts - navigation2.ts); + const classification = ScoreClassification.UNCLASSIFIED; + const metricScore = { event, metricName: MetricName.FP, classification, navigation: navigation2, timing: paintTime }; + storeMetricScore(frameId, navigationId, metricScore); + return; + } + if (TraceEvents_exports.isMarkDOMContent(event)) { + const dclTime = Timing_exports.Micro(event.ts - navigation2.ts); + const metricScore = { + event, + metricName: MetricName.DCL, + classification: scoreClassificationForDOMContentLoaded(dclTime), + navigation: navigation2, + timing: dclTime + }; + storeMetricScore(frameId, navigationId, metricScore); + return; + } + if (TraceEvents_exports.isInteractiveTime(event)) { + const ttiValue = Timing_exports.Micro(event.ts - navigation2.ts); + const tti = { + event, + metricName: MetricName.TTI, + classification: scoreClassificationForTimeToInteractive(ttiValue), + navigation: navigation2, + timing: ttiValue + }; + storeMetricScore(frameId, navigationId, tti); + const tbtValue = Timing_exports3.milliToMicro(Timing_exports.Milli(event.args.args.total_blocking_time_ms)); + const tbt = { + event, + metricName: MetricName.TBT, + classification: scoreClassificationForTotalBlockingTime(tbtValue), + navigation: navigation2, + timing: tbtValue + }; + storeMetricScore(frameId, navigationId, tbt); + return; + } + if (TraceEvents_exports.isMarkLoad(event)) { + const loadTime = Timing_exports.Micro(event.ts - navigation2.ts); + const metricScore = { + event, + metricName: MetricName.L, + classification: ScoreClassification.UNCLASSIFIED, + navigation: navigation2, + timing: loadTime + }; + storeMetricScore(frameId, navigationId, metricScore); + return; + } + if (TraceEvents_exports.isLargestContentfulPaintCandidate(event)) { + const candidateIndex = event.args.data?.candidateIndex; + if (!candidateIndex) { + throw new Error("Largest Contentful Paint unexpectedly had no candidateIndex."); + } + const lcpTime = Timing_exports.Micro(event.ts - navigation2.ts); + const lcp = { + event, + metricName: MetricName.LCP, + classification: scoreClassificationForLargestContentfulPaint(lcpTime), + navigation: navigation2, + timing: lcpTime + }; + const metricsByNavigation = MapUtilities_exports.getWithDefault(metricScoresByFrameId, frameId, () => /* @__PURE__ */ new Map()); + const metrics = MapUtilities_exports.getWithDefault(metricsByNavigation, navigationId, () => /* @__PURE__ */ new Map()); + const lastLCPCandidate = metrics.get(MetricName.LCP); + if (lastLCPCandidate === void 0) { + selectedLCPCandidateEvents.add(lcp.event); + storeMetricScore(frameId, navigationId, lcp); + return; + } + const lastLCPCandidateEvent = lastLCPCandidate.event; + if (!TraceEvents_exports.isLargestContentfulPaintCandidate(lastLCPCandidateEvent)) { + return; + } + const lastCandidateIndex = lastLCPCandidateEvent.args.data?.candidateIndex; + if (!lastCandidateIndex) { + return; + } + if (lastCandidateIndex < candidateIndex) { + selectedLCPCandidateEvents.delete(lastLCPCandidateEvent); + selectedLCPCandidateEvents.add(lcp.event); + storeMetricScore(frameId, navigationId, lcp); + } + return; + } + if (TraceEvents_exports.isLayoutShift(event)) { + return; + } + return assertNever(event, `Unexpected event type: ${event}`); +} +function storeMetricScore(frameId, navigationId, metricScore) { + const metricsByNavigation = MapUtilities_exports.getWithDefault(metricScoresByFrameId, frameId, () => /* @__PURE__ */ new Map()); + const metrics = MapUtilities_exports.getWithDefault(metricsByNavigation, navigationId, () => /* @__PURE__ */ new Map()); + metrics.delete(metricScore.metricName); + metrics.set(metricScore.metricName, metricScore); +} +function getFrameIdForPageLoadEvent(event) { + if (TraceEvents_exports.isFirstContentfulPaint(event) || TraceEvents_exports.isInteractiveTime(event) || TraceEvents_exports.isLargestContentfulPaintCandidate(event) || TraceEvents_exports.isNavigationStart(event) || TraceEvents_exports.isLayoutShift(event) || TraceEvents_exports.isFirstPaint(event)) { + return event.args.frame; + } + if (TraceEvents_exports.isMarkDOMContent(event) || TraceEvents_exports.isMarkLoad(event)) { + const frameId = event.args.data?.frame; + if (!frameId) { + throw new Error("MarkDOMContent unexpectedly had no frame ID."); + } + return frameId; + } + assertNever(event, `Unexpected event type: ${event}`); +} +function getNavigationForPageLoadEvent(event) { + if (TraceEvents_exports.isFirstContentfulPaint(event) || TraceEvents_exports.isLargestContentfulPaintCandidate(event) || TraceEvents_exports.isFirstPaint(event)) { + const navigationId = event.args.data?.navigationId; + if (!navigationId) { + throw new Error("Trace event unexpectedly had no navigation ID."); + } + const { navigationsByNavigationId: navigationsByNavigationId2 } = data5(); + const navigation2 = navigationsByNavigationId2.get(navigationId); + if (!navigation2) { + return null; + } + return navigation2; + } + if (TraceEvents_exports.isMarkDOMContent(event) || TraceEvents_exports.isInteractiveTime(event) || TraceEvents_exports.isLayoutShift(event) || TraceEvents_exports.isMarkLoad(event)) { + const frameId = getFrameIdForPageLoadEvent(event); + const { navigationsByFrameId: navigationsByFrameId2 } = data5(); + return Trace_exports.getNavigationForTraceEvent(event, frameId, navigationsByFrameId2); + } + if (TraceEvents_exports.isNavigationStart(event)) { + return null; + } + return assertNever(event, `Unexpected event type: ${event}`); +} +function scoreClassificationForFirstContentfulPaint(fcpScoreInMicroseconds) { + const FCP_GOOD_TIMING = Timing_exports3.secondsToMicro(Timing_exports.Seconds(1.8)); + const FCP_MEDIUM_TIMING = Timing_exports3.secondsToMicro(Timing_exports.Seconds(3)); + let scoreClassification = ScoreClassification.BAD; + if (fcpScoreInMicroseconds <= FCP_MEDIUM_TIMING) { + scoreClassification = ScoreClassification.OK; + } + if (fcpScoreInMicroseconds <= FCP_GOOD_TIMING) { + scoreClassification = ScoreClassification.GOOD; + } + return scoreClassification; +} +function scoreClassificationForTimeToInteractive(ttiTimeInMicroseconds) { + const TTI_GOOD_TIMING = Timing_exports3.secondsToMicro(Timing_exports.Seconds(3.8)); + const TTI_MEDIUM_TIMING = Timing_exports3.secondsToMicro(Timing_exports.Seconds(7.3)); + let scoreClassification = ScoreClassification.BAD; + if (ttiTimeInMicroseconds <= TTI_MEDIUM_TIMING) { + scoreClassification = ScoreClassification.OK; + } + if (ttiTimeInMicroseconds <= TTI_GOOD_TIMING) { + scoreClassification = ScoreClassification.GOOD; + } + return scoreClassification; +} +function scoreClassificationForLargestContentfulPaint(lcpTimeInMicroseconds) { + const LCP_GOOD_TIMING = Timing_exports3.secondsToMicro(Timing_exports.Seconds(2.5)); + const LCP_MEDIUM_TIMING = Timing_exports3.secondsToMicro(Timing_exports.Seconds(4)); + let scoreClassification = ScoreClassification.BAD; + if (lcpTimeInMicroseconds <= LCP_MEDIUM_TIMING) { + scoreClassification = ScoreClassification.OK; + } + if (lcpTimeInMicroseconds <= LCP_GOOD_TIMING) { + scoreClassification = ScoreClassification.GOOD; + } + return scoreClassification; +} +function scoreClassificationForDOMContentLoaded(_dclTimeInMicroseconds) { + return ScoreClassification.UNCLASSIFIED; +} +function scoreClassificationForTotalBlockingTime(tbtTimeInMicroseconds) { + const TBT_GOOD_TIMING = Timing_exports3.milliToMicro(Timing_exports.Milli(200)); + const TBT_MEDIUM_TIMING = Timing_exports3.milliToMicro(Timing_exports.Milli(600)); + let scoreClassification = ScoreClassification.BAD; + if (tbtTimeInMicroseconds <= TBT_MEDIUM_TIMING) { + scoreClassification = ScoreClassification.OK; + } + if (tbtTimeInMicroseconds <= TBT_GOOD_TIMING) { + scoreClassification = ScoreClassification.GOOD; + } + return scoreClassification; +} +function gatherFinalLCPEvents() { + const allFinalLCPEvents = []; + const dataForAllFrames = [...metricScoresByFrameId.values()]; + const dataForAllNavigations = dataForAllFrames.flatMap((frameData) => [...frameData.values()]); + for (let i = 0; i < dataForAllNavigations.length; i++) { + const navigationData = dataForAllNavigations[i]; + const lcpInNavigation = navigationData.get(MetricName.LCP); + if (!lcpInNavigation?.event) { + continue; + } + allFinalLCPEvents.push(lcpInNavigation.event); + } + return allFinalLCPEvents; +} +async function finalize19() { + pageLoadEventsArray.sort((a, b) => a.ts - b.ts); + for (const pageLoadEvent of pageLoadEventsArray) { + const navigation2 = getNavigationForPageLoadEvent(pageLoadEvent); + if (navigation2) { + storePageLoadMetricAgainstNavigationId(navigation2, pageLoadEvent); + } + } + const allFinalLCPEvents = gatherFinalLCPEvents(); + const mainFrame = data5().mainFrameId; + const allEventsButLCP = pageLoadEventsArray.filter((event) => !TraceEvents_exports.isLargestContentfulPaintCandidate(event)); + const markerEvents = [...allFinalLCPEvents, ...allEventsButLCP].filter(TraceEvents_exports.isMarkerEvent); + allMarkerEvents = markerEvents.filter((event) => getFrameIdForPageLoadEvent(event) === mainFrame).sort((a, b) => a.ts - b.ts); +} +function data19() { + return { + metricScoresByFrameId, + allMarkerEvents + }; +} +function deps10() { + return ["Meta"]; +} +function metricIsLCP(metric) { + return metric.metricName === MetricName.LCP; +} +var metricScoresByFrameId, allMarkerEvents, pageLoadEventsArray, selectedLCPCandidateEvents, ScoreClassification, MetricName; +var init_PageLoadMetricsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/PageLoadMetricsHandler.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + init_MetaHandler(); + metricScoresByFrameId = /* @__PURE__ */ new Map(); + allMarkerEvents = []; + __name(reset19, "reset"); + pageLoadEventsArray = []; + selectedLCPCandidateEvents = /* @__PURE__ */ new Set(); + __name(handleEvent19, "handleEvent"); + __name(storePageLoadMetricAgainstNavigationId, "storePageLoadMetricAgainstNavigationId"); + __name(storeMetricScore, "storeMetricScore"); + __name(getFrameIdForPageLoadEvent, "getFrameIdForPageLoadEvent"); + __name(getNavigationForPageLoadEvent, "getNavigationForPageLoadEvent"); + __name(scoreClassificationForFirstContentfulPaint, "scoreClassificationForFirstContentfulPaint"); + __name(scoreClassificationForTimeToInteractive, "scoreClassificationForTimeToInteractive"); + __name(scoreClassificationForLargestContentfulPaint, "scoreClassificationForLargestContentfulPaint"); + __name(scoreClassificationForDOMContentLoaded, "scoreClassificationForDOMContentLoaded"); + __name(scoreClassificationForTotalBlockingTime, "scoreClassificationForTotalBlockingTime"); + __name(gatherFinalLCPEvents, "gatherFinalLCPEvents"); + __name(finalize19, "finalize"); + __name(data19, "data"); + __name(deps10, "deps"); + (function(ScoreClassification2) { + ScoreClassification2["GOOD"] = "good"; + ScoreClassification2["OK"] = "ok"; + ScoreClassification2["BAD"] = "bad"; + ScoreClassification2["UNCLASSIFIED"] = "unclassified"; + })(ScoreClassification || (ScoreClassification = {})); + (function(MetricName2) { + MetricName2["FCP"] = "FCP"; + MetricName2["FP"] = "FP"; + MetricName2["L"] = "L"; + MetricName2["LCP"] = "LCP"; + MetricName2["DCL"] = "DCL"; + MetricName2["TTI"] = "TTI"; + MetricName2["TBT"] = "TBT"; + MetricName2["CLS"] = "CLS"; + MetricName2["NAV"] = "Nav"; + })(MetricName || (MetricName = {})); + __name(metricIsLCP, "metricIsLCP"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/LargestImagePaintHandler.js +var LargestImagePaintHandler_exports = {}; +__export(LargestImagePaintHandler_exports, { + data: () => data20, + deps: () => deps11, + finalize: () => finalize20, + handleEvent: () => handleEvent20, + reset: () => reset20 +}); +function reset20() { + imagePaintsByNodeIdAndProcess = /* @__PURE__ */ new Map(); + lcpRequestByNavigationId = /* @__PURE__ */ new Map(); +} +function handleEvent20(event) { + if (!TraceEvents_exports.isLargestImagePaintCandidate(event) || !event.args.data) { + return; + } + const imagePaintsByNodeId = MapUtilities_exports.getWithDefault(imagePaintsByNodeIdAndProcess, event.pid, () => /* @__PURE__ */ new Map()); + imagePaintsByNodeId.set(event.args.data.DOMNodeId, event); +} +async function finalize20() { + const requests = data6().byTime; + const { traceBounds: traceBounds2, navigationsByNavigationId: navigationsByNavigationId2 } = data5(); + const metricScoresByFrameId2 = data19().metricScoresByFrameId; + for (const [navigationId, navigation2] of navigationsByNavigationId2) { + const lcpMetric = metricScoresByFrameId2.get(navigation2.args.frame)?.get(navigationId)?.get(MetricName.LCP); + const lcpEvent = lcpMetric?.event; + if (!lcpEvent || !TraceEvents_exports.isLargestContentfulPaintCandidate(lcpEvent)) { + continue; + } + const nodeId = lcpEvent.args.data?.nodeId; + if (!nodeId) { + continue; + } + const lcpImagePaintEvent = imagePaintsByNodeIdAndProcess.get(lcpEvent.pid)?.get(nodeId); + const lcpUrl = lcpImagePaintEvent?.args.data?.imageUrl; + if (!lcpUrl) { + continue; + } + const startTime = navigation2?.ts ?? traceBounds2.min; + const endTime = lcpImagePaintEvent.ts; + let lcpRequest; + for (const request of requests) { + if (request.ts < startTime) { + continue; + } + if (request.ts >= endTime) { + break; + } + if (request.args.data.url === lcpUrl || request.args.data.redirects.some((r) => r.url === lcpUrl)) { + lcpRequest = request; + break; + } + } + if (lcpRequest) { + lcpRequestByNavigationId.set(navigationId, lcpRequest); + } + } +} +function data20() { + return { lcpRequestByNavigationId }; +} +function deps11() { + return ["Meta", "NetworkRequests", "PageLoadMetrics"]; +} +var imagePaintsByNodeIdAndProcess, lcpRequestByNavigationId; +var init_LargestImagePaintHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/LargestImagePaintHandler.js"() { + init_process_global(); + init_platform(); + init_types2(); + init_MetaHandler(); + init_NetworkRequestsHandler(); + init_PageLoadMetricsHandler(); + imagePaintsByNodeIdAndProcess = /* @__PURE__ */ new Map(); + lcpRequestByNavigationId = /* @__PURE__ */ new Map(); + __name(reset20, "reset"); + __name(handleEvent20, "handleEvent"); + __name(finalize20, "finalize"); + __name(data20, "data"); + __name(deps11, "deps"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/LargestTextPaintHandler.js +var LargestTextPaintHandler_exports = {}; +__export(LargestTextPaintHandler_exports, { + data: () => data21, + finalize: () => finalize21, + handleEvent: () => handleEvent21, + reset: () => reset21 +}); +function reset21() { + textPaintByDOMNodeId = /* @__PURE__ */ new Map(); +} +function handleEvent21(event) { + if (!TraceEvents_exports.isLargestTextPaintCandidate(event)) { + return; + } + if (!event.args.data) { + return; + } + textPaintByDOMNodeId.set(event.args.data.DOMNodeId, event); +} +async function finalize21() { +} +function data21() { + return textPaintByDOMNodeId; +} +var textPaintByDOMNodeId; +var init_LargestTextPaintHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/LargestTextPaintHandler.js"() { + init_process_global(); + init_types2(); + textPaintByDOMNodeId = /* @__PURE__ */ new Map(); + __name(reset21, "reset"); + __name(handleEvent21, "handleEvent"); + __name(finalize21, "finalize"); + __name(data21, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/ScreenshotsHandler.js +var ScreenshotsHandler_exports = {}; +__export(ScreenshotsHandler_exports, { + data: () => data22, + deps: () => deps12, + finalize: () => finalize22, + handleEvent: () => handleEvent22, + reset: () => reset22, + screenshotImageDataUri: () => screenshotImageDataUri +}); +function reset22() { + unpairedAsyncEvents = []; + legacyScreenshotEvents = []; + syntheticScreenshots = []; + modernScreenshotEvents = []; + frameSequenceToTs = {}; +} +function handleEvent22(event) { + if (TraceEvents_exports.isLegacyScreenshot(event)) { + legacyScreenshotEvents.push(event); + } else if (TraceEvents_exports.isScreenshot(event)) { + modernScreenshotEvents.push(event); + } else if (TraceEvents_exports.isPipelineReporter(event)) { + unpairedAsyncEvents.push(event); + } +} +async function finalize22() { + const pipelineReporterEvents = Trace_exports.createMatchedSortedSyntheticEvents(unpairedAsyncEvents); + frameSequenceToTs = Object.fromEntries(pipelineReporterEvents.map((evt) => { + const args = evt.args.data.beginEvent.args; + const frameReporter = "frame_reporter" in args ? args.frame_reporter : args.chrome_frame_reporter; + const frameSequenceId = frameReporter.frame_sequence; + const presentationTs = Timing_exports.Micro(evt.ts + evt.dur); + return [frameSequenceId, presentationTs]; + })); + for (const snapshotEvent of legacyScreenshotEvents) { + const { cat, name, ph, pid, tid } = snapshotEvent; + const syntheticEvent = SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent({ + rawSourceEvent: snapshotEvent, + cat, + name, + ph, + pid, + tid, + // TODO(paulirish, crbug.com/41363012): investigate why getPresentationTimestamp(snapshotEvent) seems less accurate. Resolve screenshot timing inaccuracy. + // `getPresentationTimestamp(snapshotEvent) - snapshotEvent.ts` is how many microsec the screenshot should be adjusted to the right/later + ts: snapshotEvent.ts, + args: { + dataUri: `data:image/jpg;base64,${snapshotEvent.args.snapshot}` + } + }); + syntheticScreenshots.push(syntheticEvent); + } +} +function screenshotImageDataUri(event) { + if (TraceEvents_exports.isLegacySyntheticScreenshot(event)) { + return event.args.dataUri; + } + return `data:image/jpg;base64,${event.args.snapshot}`; +} +function data22() { + return { + legacySyntheticScreenshots: syntheticScreenshots.length ? syntheticScreenshots : null, + screenshots: modernScreenshotEvents.length ? modernScreenshotEvents : null + }; +} +function deps12() { + return ["Meta"]; +} +var unpairedAsyncEvents, legacyScreenshotEvents, modernScreenshotEvents, syntheticScreenshots, frameSequenceToTs; +var init_ScreenshotsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/ScreenshotsHandler.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + unpairedAsyncEvents = []; + legacyScreenshotEvents = []; + modernScreenshotEvents = []; + syntheticScreenshots = []; + frameSequenceToTs = {}; + __name(reset22, "reset"); + __name(handleEvent22, "handleEvent"); + __name(finalize22, "finalize"); + __name(screenshotImageDataUri, "screenshotImageDataUri"); + __name(data22, "data"); + __name(deps12, "deps"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/LayoutShiftsHandler.js +var LayoutShiftsHandler_exports = {}; +__export(LayoutShiftsHandler_exports, { + LayoutShiftsThreshold: () => LayoutShiftsThreshold, + MAX_CLUSTER_DURATION: () => MAX_CLUSTER_DURATION, + MAX_SHIFT_TIME_DELTA: () => MAX_SHIFT_TIME_DELTA, + data: () => data23, + deps: () => deps13, + finalize: () => finalize23, + handleEvent: () => handleEvent23, + reset: () => reset23, + scoreClassificationForLayoutShift: () => scoreClassificationForLayoutShift +}); +function reset23() { + layoutShiftEvents = []; + layoutInvalidationEvents = []; + scheduleStyleInvalidationEvents = []; + styleRecalcInvalidationEvents = []; + prePaintEvents = []; + paintImageEvents2 = []; + renderFrameImplCreateChildFrameEvents = []; + layoutImageUnsizedEvents = []; + domLoadingEvents = []; + remoteFonts = []; + backendNodeIds = /* @__PURE__ */ new Set(); + clusters = []; + sessionMaxScore = 0; + scoreRecords = []; + clsWindowID = -1; + clustersByNavigationId = /* @__PURE__ */ new Map(); +} +function handleEvent23(event) { + if (TraceEvents_exports.isLayoutShift(event) && !event.args.data?.had_recent_input) { + layoutShiftEvents.push(event); + return; + } + if (TraceEvents_exports.isLayoutInvalidationTracking(event)) { + layoutInvalidationEvents.push(event); + return; + } + if (TraceEvents_exports.isScheduleStyleInvalidationTracking(event)) { + scheduleStyleInvalidationEvents.push(event); + } + if (TraceEvents_exports.isStyleRecalcInvalidationTracking(event)) { + styleRecalcInvalidationEvents.push(event); + } + if (TraceEvents_exports.isPrePaint(event)) { + prePaintEvents.push(event); + return; + } + if (TraceEvents_exports.isRenderFrameImplCreateChildFrame(event)) { + renderFrameImplCreateChildFrameEvents.push(event); + } + if (TraceEvents_exports.isDomLoading(event)) { + domLoadingEvents.push(event); + } + if (TraceEvents_exports.isLayoutImageUnsized(event)) { + layoutImageUnsizedEvents.push(event); + } + if (TraceEvents_exports.isBeginRemoteFontLoad(event)) { + remoteFonts.push({ + display: event.args.display, + url: event.args.url, + beginRemoteFontLoadEvent: event + }); + } + if (TraceEvents_exports.isRemoteFontLoaded(event)) { + for (const remoteFont of remoteFonts) { + if (remoteFont.url === event.args.url) { + remoteFont.name = event.args.name; + } + } + } + if (TraceEvents_exports.isPaintImage(event)) { + paintImageEvents2.push(event); + } +} +function traceWindowFromTime(time) { + return { + min: time, + max: time, + range: Timing_exports.Micro(0) + }; +} +function updateTraceWindowMax(traceWindow, newMax) { + traceWindow.max = newMax; + traceWindow.range = Timing_exports.Micro(traceWindow.max - traceWindow.min); +} +function findScreenshots(timestamp) { + const data31 = data22(); + if (data31.screenshots) { + const before = Trace_exports.findPreviousEventBeforeTimestamp(data31.screenshots, timestamp); + const after = before ? data31.screenshots[data31.screenshots.indexOf(before) + 1] : null; + return { before, after }; + } + if (data31.legacySyntheticScreenshots) { + const before = Trace_exports.findPreviousEventBeforeTimestamp(data31.legacySyntheticScreenshots, timestamp); + const after = before ? data31.legacySyntheticScreenshots[data31.legacySyntheticScreenshots.indexOf(before) + 1] : null; + return { before, after }; + } + return { before: null, after: null }; +} +function buildScoreRecords() { + const { traceBounds: traceBounds2 } = data5(); + scoreRecords.push({ ts: traceBounds2.min, score: 0 }); + for (const cluster of clusters) { + let clusterScore = 0; + if (cluster.events[0].args.data) { + scoreRecords.push({ ts: cluster.clusterWindow.min, score: cluster.events[0].args.data.weighted_score_delta }); + } + for (let i = 0; i < cluster.events.length; i++) { + const event = cluster.events[i]; + if (!event.args.data) { + continue; + } + clusterScore += event.args.data.weighted_score_delta; + scoreRecords.push({ ts: event.ts, score: clusterScore }); + } + scoreRecords.push({ ts: cluster.clusterWindow.max, score: 0 }); + } +} +function collectNodes() { + backendNodeIds.clear(); + for (const layoutShift of layoutShiftEvents) { + if (!layoutShift.args.data?.impacted_nodes) { + continue; + } + for (const node of layoutShift.args.data.impacted_nodes) { + backendNodeIds.add(node.node_id); + } + } + for (const layoutInvalidation of layoutInvalidationEvents) { + if (!layoutInvalidation.args.data?.nodeId) { + continue; + } + backendNodeIds.add(layoutInvalidation.args.data.nodeId); + } + for (const scheduleStyleInvalidation of scheduleStyleInvalidationEvents) { + if (!scheduleStyleInvalidation.args.data?.nodeId) { + continue; + } + backendNodeIds.add(scheduleStyleInvalidation.args.data.nodeId); + } +} +async function finalize23() { + layoutShiftEvents.sort((a, b) => a.ts - b.ts); + prePaintEvents.sort((a, b) => a.ts - b.ts); + layoutInvalidationEvents.sort((a, b) => a.ts - b.ts); + renderFrameImplCreateChildFrameEvents.sort((a, b) => a.ts - b.ts); + domLoadingEvents.sort((a, b) => a.ts - b.ts); + layoutImageUnsizedEvents.sort((a, b) => a.ts - b.ts); + remoteFonts.sort((a, b) => a.beginRemoteFontLoadEvent.ts - b.beginRemoteFontLoadEvent.ts); + paintImageEvents2.sort((a, b) => a.ts - b.ts); + await buildLayoutShiftsClusters(); + buildScoreRecords(); + collectNodes(); +} +async function buildLayoutShiftsClusters() { + const { navigationsByFrameId: navigationsByFrameId2, mainFrameId: mainFrameId2, traceBounds: traceBounds2 } = data5(); + const navigations = navigationsByFrameId2.get(mainFrameId2) || []; + if (layoutShiftEvents.length === 0) { + return; + } + let firstShiftTime = layoutShiftEvents[0].ts; + let lastShiftTime = layoutShiftEvents[0].ts; + let lastShiftNavigation = null; + for (const event of layoutShiftEvents) { + const clusterDurationExceeded = event.ts - firstShiftTime > MAX_CLUSTER_DURATION; + const maxTimeDeltaSinceLastShiftExceeded = event.ts - lastShiftTime > MAX_SHIFT_TIME_DELTA; + const currentShiftNavigation = ArrayUtilities_exports.nearestIndexFromEnd(navigations, (nav) => nav.ts < event.ts); + const hasNavigated = lastShiftNavigation !== currentShiftNavigation && currentShiftNavigation !== null; + if (clusterDurationExceeded || maxTimeDeltaSinceLastShiftExceeded || hasNavigated || !clusters.length) { + const clusterStartTime = event.ts; + const endTimeByMaxSessionDuration = clusterDurationExceeded ? firstShiftTime + MAX_CLUSTER_DURATION : Infinity; + const endTimeByMaxShiftGap = maxTimeDeltaSinceLastShiftExceeded ? lastShiftTime + MAX_SHIFT_TIME_DELTA : Infinity; + const endTimeByNavigation = hasNavigated ? navigations[currentShiftNavigation].ts : Infinity; + const previousClusterEndTime = Math.min(endTimeByMaxSessionDuration, endTimeByMaxShiftGap, endTimeByNavigation); + if (clusters.length > 0) { + const currentCluster2 = clusters[clusters.length - 1]; + updateTraceWindowMax(currentCluster2.clusterWindow, Timing_exports.Micro(previousClusterEndTime)); + } + const navigationId = currentShiftNavigation === null ? TraceEvents_exports.NO_NAVIGATION : navigations[currentShiftNavigation].args.data?.navigationId; + clusters.push(SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent({ + name: "SyntheticLayoutShiftCluster", + // Will be replaced by the worst layout shift in the next for loop. + rawSourceEvent: event, + events: [], + clusterWindow: traceWindowFromTime(clusterStartTime), + clusterCumulativeScore: 0, + scoreWindows: { + good: traceWindowFromTime(clusterStartTime) + }, + navigationId, + // Set default Event so that this event is treated accordingly for the track appender. + ts: event.ts, + pid: event.pid, + tid: event.tid, + ph: TraceEvents_exports.Phase.COMPLETE, + cat: "", + dur: Timing_exports.Micro(-1) + // This `cluster.dur` is updated below. + })); + firstShiftTime = clusterStartTime; + } + const currentCluster = clusters[clusters.length - 1]; + const timeFromNavigation = currentShiftNavigation !== null ? Timing_exports.Micro(event.ts - navigations[currentShiftNavigation].ts) : void 0; + currentCluster.clusterCumulativeScore += event.args.data ? event.args.data.weighted_score_delta : 0; + if (!event.args.data) { + continue; + } + const shift = SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent({ + rawSourceEvent: event, + ...event, + name: TraceEvents_exports.Name.SYNTHETIC_LAYOUT_SHIFT, + args: { + frame: event.args.frame, + data: { + ...event.args.data, + rawEvent: event, + navigationId: currentCluster.navigationId ?? void 0 + } + }, + parsedData: { + timeFromNavigation, + screenshots: findScreenshots(event.ts), + cumulativeWeightedScoreInWindow: currentCluster.clusterCumulativeScore, + // The score of the session window is temporarily set to 0 just + // to initialize it. Since we need to get the score of all shifts + // in the session window to determine its value, its definite + // value is set when stepping through the built clusters. + sessionWindowData: { cumulativeWindowScore: 0, id: clusters.length } + } + }); + currentCluster.events.push(shift); + updateTraceWindowMax(currentCluster.clusterWindow, event.ts); + lastShiftTime = event.ts; + lastShiftNavigation = currentShiftNavigation; + } + for (const cluster of clusters) { + let weightedScore = 0; + let windowID = -1; + if (cluster === clusters[clusters.length - 1]) { + const clusterEndByMaxDuration = MAX_CLUSTER_DURATION + cluster.clusterWindow.min; + const clusterEndByMaxGap = cluster.clusterWindow.max + MAX_SHIFT_TIME_DELTA; + const nextNavigationIndex = ArrayUtilities_exports.nearestIndexFromBeginning(navigations, (nav) => nav.ts > cluster.clusterWindow.max); + const nextNavigationTime = nextNavigationIndex ? navigations[nextNavigationIndex].ts : Infinity; + const clusterEnd = Math.min(clusterEndByMaxDuration, clusterEndByMaxGap, traceBounds2.max, nextNavigationTime); + updateTraceWindowMax(cluster.clusterWindow, Timing_exports.Micro(clusterEnd)); + } + let largestScore = 0; + let worstShiftEvent = null; + for (const shift of cluster.events) { + weightedScore += shift.args.data ? shift.args.data.weighted_score_delta : 0; + windowID = shift.parsedData.sessionWindowData.id; + const ts = shift.ts; + shift.parsedData.sessionWindowData.cumulativeWindowScore = cluster.clusterCumulativeScore; + if (weightedScore < LayoutShiftsThreshold.NEEDS_IMPROVEMENT) { + updateTraceWindowMax(cluster.scoreWindows.good, ts); + } else if (weightedScore >= LayoutShiftsThreshold.NEEDS_IMPROVEMENT && weightedScore < LayoutShiftsThreshold.BAD) { + if (!cluster.scoreWindows.needsImprovement) { + updateTraceWindowMax(cluster.scoreWindows.good, Timing_exports.Micro(ts - 1)); + cluster.scoreWindows.needsImprovement = traceWindowFromTime(ts); + } + updateTraceWindowMax(cluster.scoreWindows.needsImprovement, ts); + } else if (weightedScore >= LayoutShiftsThreshold.BAD) { + if (!cluster.scoreWindows.bad) { + if (cluster.scoreWindows.needsImprovement) { + updateTraceWindowMax(cluster.scoreWindows.needsImprovement, Timing_exports.Micro(ts - 1)); + } else { + updateTraceWindowMax(cluster.scoreWindows.good, Timing_exports.Micro(ts - 1)); + } + cluster.scoreWindows.bad = traceWindowFromTime(shift.ts); + } + updateTraceWindowMax(cluster.scoreWindows.bad, ts); + } + if (cluster.scoreWindows.bad) { + updateTraceWindowMax(cluster.scoreWindows.bad, cluster.clusterWindow.max); + } else if (cluster.scoreWindows.needsImprovement) { + updateTraceWindowMax(cluster.scoreWindows.needsImprovement, cluster.clusterWindow.max); + } else { + updateTraceWindowMax(cluster.scoreWindows.good, cluster.clusterWindow.max); + } + const score = shift.args.data?.weighted_score_delta; + if (score !== void 0 && score > largestScore) { + largestScore = score; + worstShiftEvent = shift; + } + } + if (worstShiftEvent) { + cluster.worstShiftEvent = worstShiftEvent; + cluster.rawSourceEvent = worstShiftEvent; + } + cluster.ts = cluster.events[0].ts; + const lastShiftTimings = Timing_exports3.eventTimingsMicroSeconds(cluster.events[cluster.events.length - 1]); + cluster.dur = Timing_exports.Micro(lastShiftTimings.endTime - cluster.events[0].ts + MAX_SHIFT_TIME_DELTA); + if (weightedScore > sessionMaxScore) { + clsWindowID = windowID; + sessionMaxScore = weightedScore; + } + if (cluster.navigationId) { + const clustersForId = MapUtilities_exports.getWithDefault(clustersByNavigationId, cluster.navigationId, () => { + return []; + }); + clustersForId.push(cluster); + } + } +} +function data23() { + return { + clusters, + sessionMaxScore, + clsWindowID, + prePaintEvents, + layoutInvalidationEvents, + scheduleStyleInvalidationEvents, + styleRecalcInvalidationEvents, + renderFrameImplCreateChildFrameEvents, + domLoadingEvents, + layoutImageUnsizedEvents, + remoteFonts, + scoreRecords, + backendNodeIds, + clustersByNavigationId, + paintImageEvents: paintImageEvents2 + }; +} +function deps13() { + return ["Screenshots", "Meta"]; +} +function scoreClassificationForLayoutShift(score) { + let state = ScoreClassification.GOOD; + if (score >= LayoutShiftsThreshold.NEEDS_IMPROVEMENT) { + state = ScoreClassification.OK; + } + if (score >= LayoutShiftsThreshold.BAD) { + state = ScoreClassification.BAD; + } + return state; +} +var MAX_CLUSTER_DURATION, MAX_SHIFT_TIME_DELTA, layoutShiftEvents, layoutInvalidationEvents, scheduleStyleInvalidationEvents, styleRecalcInvalidationEvents, renderFrameImplCreateChildFrameEvents, domLoadingEvents, layoutImageUnsizedEvents, remoteFonts, backendNodeIds, prePaintEvents, paintImageEvents2, sessionMaxScore, clsWindowID, clusters, clustersByNavigationId, scoreRecords, LayoutShiftsThreshold; +var init_LayoutShiftsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/LayoutShiftsHandler.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + init_MetaHandler(); + init_PageLoadMetricsHandler(); + init_ScreenshotsHandler(); + MAX_CLUSTER_DURATION = Timing_exports3.milliToMicro(Timing_exports.Milli(5e3)); + MAX_SHIFT_TIME_DELTA = Timing_exports3.milliToMicro(Timing_exports.Milli(1e3)); + layoutShiftEvents = []; + layoutInvalidationEvents = []; + scheduleStyleInvalidationEvents = []; + styleRecalcInvalidationEvents = []; + renderFrameImplCreateChildFrameEvents = []; + domLoadingEvents = []; + layoutImageUnsizedEvents = []; + remoteFonts = []; + backendNodeIds = /* @__PURE__ */ new Set(); + prePaintEvents = []; + paintImageEvents2 = []; + sessionMaxScore = 0; + clsWindowID = -1; + clusters = []; + clustersByNavigationId = /* @__PURE__ */ new Map(); + scoreRecords = []; + __name(reset23, "reset"); + __name(handleEvent23, "handleEvent"); + __name(traceWindowFromTime, "traceWindowFromTime"); + __name(updateTraceWindowMax, "updateTraceWindowMax"); + __name(findScreenshots, "findScreenshots"); + __name(buildScoreRecords, "buildScoreRecords"); + __name(collectNodes, "collectNodes"); + __name(finalize23, "finalize"); + __name(buildLayoutShiftsClusters, "buildLayoutShiftsClusters"); + __name(data23, "data"); + __name(deps13, "deps"); + __name(scoreClassificationForLayoutShift, "scoreClassificationForLayoutShift"); + (function(LayoutShiftsThreshold2) { + LayoutShiftsThreshold2[LayoutShiftsThreshold2["GOOD"] = 0] = "GOOD"; + LayoutShiftsThreshold2[LayoutShiftsThreshold2["NEEDS_IMPROVEMENT"] = 0.1] = "NEEDS_IMPROVEMENT"; + LayoutShiftsThreshold2[LayoutShiftsThreshold2["BAD"] = 0.25] = "BAD"; + })(LayoutShiftsThreshold || (LayoutShiftsThreshold = {})); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/MemoryHandler.js +var MemoryHandler_exports = {}; +__export(MemoryHandler_exports, { + data: () => data24, + finalize: () => finalize24, + handleEvent: () => handleEvent24, + reset: () => reset24 +}); +function reset24() { + updateCountersByProcess = /* @__PURE__ */ new Map(); +} +function handleEvent24(event) { + if (TraceEvents_exports.isUpdateCounters(event)) { + const countersForProcess = MapUtilities_exports.getWithDefault(updateCountersByProcess, event.pid, () => []); + countersForProcess.push(event); + updateCountersByProcess.set(event.pid, countersForProcess); + } +} +async function finalize24() { +} +function data24() { + return { updateCountersByProcess }; +} +var updateCountersByProcess; +var init_MemoryHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/MemoryHandler.js"() { + init_process_global(); + init_platform(); + init_types2(); + updateCountersByProcess = /* @__PURE__ */ new Map(); + __name(reset24, "reset"); + __name(handleEvent24, "handleEvent"); + __name(finalize24, "finalize"); + __name(data24, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/PageFramesHandler.js +var PageFramesHandler_exports = {}; +__export(PageFramesHandler_exports, { + data: () => data25, + finalize: () => finalize25, + handleEvent: () => handleEvent25, + reset: () => reset25 +}); +function reset25() { + frames = /* @__PURE__ */ new Map(); +} +function handleEvent25(event) { + if (TraceEvents_exports.isTracingStartedInBrowser(event)) { + for (const frame of event.args.data?.frames ?? []) { + frames.set(frame.frame, frame); + } + return; + } + if (TraceEvents_exports.isCommitLoad(event)) { + const frameData = event.args.data; + if (!frameData) { + return; + } + const frame = frames.get(frameData.frame); + if (!frame) { + return; + } + frames.set(frameData.frame, { + ...frame, + url: frameData.url || frame.url, + name: frameData.name || frameData.name + }); + } +} +async function finalize25() { +} +function data25() { + return { + frames + }; +} +var frames; +var init_PageFramesHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/PageFramesHandler.js"() { + init_process_global(); + init_types2(); + frames = /* @__PURE__ */ new Map(); + __name(reset25, "reset"); + __name(handleEvent25, "handleEvent"); + __name(finalize25, "finalize"); + __name(data25, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/ScriptsHandler.js +var ScriptsHandler_exports = {}; +__export(ScriptsHandler_exports, { + data: () => data26, + deps: () => deps14, + finalize: () => finalize26, + getScriptGeneratedSizes: () => getScriptGeneratedSizes, + handleEvent: () => handleEvent26, + reset: () => reset26 +}); +function completeURL(base, url) { + if (url.startsWith("data:") || url.startsWith("blob:") || url.startsWith("javascript:") || url.startsWith("mailto:")) { + return url; + } + try { + return new URL(url, base).href; + } catch { + } + return null; +} +function deps14() { + return ["Meta", "NetworkRequests"]; +} +function reset26() { + scriptById = /* @__PURE__ */ new Map(); +} +function handleEvent26(event) { + const getOrMakeScript = /* @__PURE__ */ __name((isolate, scriptIdAsNumber) => { + const scriptId = String(scriptIdAsNumber); + const key = `${isolate}.${scriptId}`; + return MapUtilities_exports.getWithDefault(scriptById, key, () => ({ isolate, scriptId, frame: "", ts: event.ts })); + }, "getOrMakeScript"); + if (TraceEvents_exports.isRundownScriptCompiled(event) && event.args.data) { + const { isolate, scriptId, frame } = event.args.data; + const script = getOrMakeScript(isolate, scriptId); + script.frame = frame; + script.ts = event.ts; + return; + } + if (TraceEvents_exports.isRundownScript(event)) { + const { isolate, scriptId, url, sourceUrl, sourceMapUrl, sourceMapUrlElided } = event.args.data; + const script = getOrMakeScript(isolate, scriptId); + script.url = url; + script.ts = event.ts; + if (sourceUrl) { + script.sourceUrl = sourceUrl; + } + if (sourceMapUrlElided) { + script.sourceMapUrlElided = true; + } else if (sourceMapUrl) { + script.sourceMapUrl = sourceMapUrl; + } + return; + } + if (TraceEvents_exports.isRundownScriptSource(event)) { + const { isolate, scriptId, sourceText } = event.args.data; + const script = getOrMakeScript(isolate, scriptId); + script.content = sourceText; + return; + } + if (TraceEvents_exports.isRundownScriptSourceLarge(event)) { + const { isolate, scriptId, sourceText } = event.args.data; + const script = getOrMakeScript(isolate, scriptId); + script.content = (script.content ?? "") + sourceText; + return; + } +} +function findFrame(meta, frameId) { + for (const frames2 of meta.frameByProcessId?.values()) { + const frame = frames2.get(frameId); + if (frame) { + return frame; + } + } + return null; +} +function findNetworkRequest(networkRequests, script) { + if (!script.url) { + return null; + } + return networkRequests.find((request) => request.args.data.url === script.url) ?? null; +} +function computeMappingEndColumns(map) { + const result = /* @__PURE__ */ new Map(); + const mappings = map.mappings(); + for (let i = 0; i < mappings.length - 1; i++) { + const mapping = mappings[i]; + const nextMapping = mappings[i + 1]; + if (mapping.lineNumber === nextMapping.lineNumber) { + result.set(mapping, nextMapping.columnNumber); + } + } + return result; +} +function computeGeneratedFileSizes(script) { + if (!script.sourceMap) { + throw new Error("expected source map"); + } + const map = script.sourceMap; + const content = script.content ?? ""; + const contentLength = content.length; + const lines = content.split("\n"); + const files = {}; + const totalBytes = contentLength; + let unmappedBytes = totalBytes; + const mappingEndCols = computeMappingEndColumns(script.sourceMap); + for (const mapping of map.mappings()) { + const source = mapping.sourceURL; + const lineNum = mapping.lineNumber; + const colNum = mapping.columnNumber; + const lastColNum = mappingEndCols.get(mapping); + if (!source) { + continue; + } + const line = lines[lineNum]; + if (line === null || line === void 0) { + const errorMessage = `${map.url()} mapping for line out of bounds: ${lineNum + 1}`; + return { errorMessage }; + } + if (colNum > line.length) { + const errorMessage = `${map.url()} mapping for column out of bounds: ${lineNum + 1}:${colNum}`; + return { errorMessage }; + } + let mappingLength = 0; + if (lastColNum !== void 0) { + if (lastColNum > line.length) { + const errorMessage = `${map.url()} mapping for last column out of bounds: ${lineNum + 1}:${lastColNum}`; + return { errorMessage }; + } + mappingLength = lastColNum - colNum; + } else { + mappingLength = line.length - colNum + 1; + } + files[source] = (files[source] || 0) + mappingLength; + unmappedBytes -= mappingLength; + } + return { + files, + unmappedBytes, + totalBytes + }; +} +function getScriptGeneratedSizes(script) { + if (script.sourceMap && !script.sizes) { + script.sizes = computeGeneratedFileSizes(script); + } + return script.sizes ?? null; +} +function findCachedRawSourceMap(script, options) { + if (options.isFreshRecording || !options.metadata?.sourceMaps) { + return; + } + if (script.sourceMapUrlElided) { + if (!script.url) { + return; + } + const cachedSourceMap = options.metadata.sourceMaps.find((m) => m.url === script.url); + if (cachedSourceMap) { + return cachedSourceMap.sourceMap; + } + return; + } + if (!script.sourceMapUrl) { + return; + } + const isDataUrl = script.sourceMapUrl.startsWith("data:"); + if (!isDataUrl) { + const cachedSourceMap = options.metadata.sourceMaps.find((m) => m.sourceMapUrl === script.sourceMapUrl); + if (cachedSourceMap) { + return cachedSourceMap.sourceMap; + } + } + return; +} +async function finalize26(options) { + const meta = data5(); + const networkRequests = [...data6().byId.values()]; + const documentUrls = /* @__PURE__ */ new Set(); + for (const frames2 of meta.frameByProcessId.values()) { + for (const frame of frames2.values()) { + documentUrls.add(frame.url); + } + } + for (const script of scriptById.values()) { + script.request = findNetworkRequest(networkRequests, script) ?? void 0; + script.inline = !!script.url && documentUrls.has(script.url); + } + if (!options.resolveSourceMap) { + return; + } + const promises = []; + for (const script of scriptById.values()) { + if (!script.frame || !script.url || !script.sourceMapUrl && !script.sourceMapUrlElided) { + continue; + } + const frameUrl = findFrame(meta, script.frame)?.url; + if (!frameUrl) { + continue; + } + let sourceUrl = script.url; + if (script.sourceUrl) { + sourceUrl = completeURL(frameUrl, script.sourceUrl) ?? script.sourceUrl; + } + let sourceMapUrl; + if (script.sourceMapUrl) { + sourceMapUrl = completeURL(sourceUrl, script.sourceMapUrl); + if (!sourceMapUrl) { + continue; + } + script.sourceMapUrl = sourceMapUrl; + } + const params = { + scriptId: script.scriptId, + scriptUrl: script.url, + sourceUrl, + sourceMapUrl: sourceMapUrl ?? "", + frame: script.frame, + cachedRawSourceMap: findCachedRawSourceMap(script, options) + }; + const promise = options.resolveSourceMap(params).then((sourceMap) => { + if (sourceMap) { + script.sourceMap = sourceMap; + } + }); + promises.push(promise.catch((e) => { + console.error("Uncaught error when resolving source map", params, e); + })); + } + await Promise.all(promises); +} +function data26() { + return { + scripts: [...scriptById.values()] + }; +} +var scriptById; +var init_ScriptsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/ScriptsHandler.js"() { + init_process_global(); + init_platform(); + init_types2(); + init_MetaHandler(); + init_NetworkRequestsHandler(); + __name(completeURL, "completeURL"); + scriptById = /* @__PURE__ */ new Map(); + __name(deps14, "deps"); + __name(reset26, "reset"); + __name(handleEvent26, "handleEvent"); + __name(findFrame, "findFrame"); + __name(findNetworkRequest, "findNetworkRequest"); + __name(computeMappingEndColumns, "computeMappingEndColumns"); + __name(computeGeneratedFileSizes, "computeGeneratedFileSizes"); + __name(getScriptGeneratedSizes, "getScriptGeneratedSizes"); + __name(findCachedRawSourceMap, "findCachedRawSourceMap"); + __name(finalize26, "finalize"); + __name(data26, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/SelectorStatsHandler.js +var SelectorStatsHandler_exports = {}; +__export(SelectorStatsHandler_exports, { + data: () => data27, + finalize: () => finalize27, + handleEvent: () => handleEvent27, + reset: () => reset27 +}); +function reset27() { + lastRecalcStyleEvent = null; + lastInvalidatedNode = null; + selectorDataForRecalcStyle = /* @__PURE__ */ new Map(); + invalidatedNodeList = []; +} +function handleEvent27(event) { + if (TraceEvents_exports.isStyleRecalcInvalidationTracking(event)) { + if (event.args.data.subtree && event.args.data.reason === TraceEvents_exports.StyleRecalcInvalidationReason.RELATED_STYLE_RULE && lastInvalidatedNode && event.args.data.nodeId === lastInvalidatedNode.backendNodeId) { + lastInvalidatedNode.subtree = true; + return; + } + } + if (TraceEvents_exports.isSelectorStats(event) && lastRecalcStyleEvent && event.args.selector_stats) { + selectorDataForRecalcStyle.set(lastRecalcStyleEvent, { + timings: event.args.selector_stats.selector_timings + }); + return; + } + if (TraceEvents_exports.isStyleInvalidatorInvalidationTracking(event)) { + const selectorList = new Array(); + event.args.data.selectors?.forEach((selector) => { + selectorList.push({ + selector: selector.selector, + styleSheetId: selector.style_sheet_id + }); + }); + if (selectorList.length > 0) { + lastInvalidatedNode = { + frame: event.args.data.frame, + backendNodeId: event.args.data.nodeId, + type: TraceEvents_exports.InvalidationEventType.StyleInvalidatorInvalidationTracking, + selectorList, + ts: event.ts, + tts: event.tts, + subtree: false, + lastRecalcStyleEventTs: lastRecalcStyleEvent ? lastRecalcStyleEvent.ts : Timing_exports.Micro(0) + }; + invalidatedNodeList.push(lastInvalidatedNode); + } + } + if (TraceEvents_exports.isRecalcStyle(event)) { + lastRecalcStyleEvent = event; + return; + } +} +async function finalize27() { +} +function data27() { + return { + dataForRecalcStyleEvent: selectorDataForRecalcStyle, + invalidatedNodeList + }; +} +var lastRecalcStyleEvent, lastInvalidatedNode, selectorDataForRecalcStyle, invalidatedNodeList; +var init_SelectorStatsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/SelectorStatsHandler.js"() { + init_process_global(); + init_types2(); + lastRecalcStyleEvent = null; + lastInvalidatedNode = null; + selectorDataForRecalcStyle = /* @__PURE__ */ new Map(); + invalidatedNodeList = new Array(); + __name(reset27, "reset"); + __name(handleEvent27, "handleEvent"); + __name(finalize27, "finalize"); + __name(data27, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/UserInteractionsHandler.js +var UserInteractionsHandler_exports = {}; +__export(UserInteractionsHandler_exports, { + LONG_INTERACTION_THRESHOLD: () => LONG_INTERACTION_THRESHOLD, + categoryOfInteraction: () => categoryOfInteraction, + data: () => data28, + deps: () => deps15, + finalize: () => finalize28, + handleEvent: () => handleEvent28, + removeNestedInteractionsAndSetProcessingTime: () => removeNestedInteractionsAndSetProcessingTime, + reset: () => reset28, + scoreClassificationForInteractionToNextPaint: () => scoreClassificationForInteractionToNextPaint +}); +function reset28() { + beginCommitCompositorFrameEvents = []; + parseMetaViewportEvents = []; + interactionEvents = []; + eventTimingStartEventsForInteractions = []; + eventTimingEndEventsForInteractions = []; + interactionEventsWithNoNesting = []; + longestInteractionEvent = null; +} +function handleEvent28(event) { + if (TraceEvents_exports.isBeginCommitCompositorFrame(event)) { + beginCommitCompositorFrameEvents.push(event); + return; + } + if (TraceEvents_exports.isParseMetaViewport(event)) { + parseMetaViewportEvents.push(event); + return; + } + if (!TraceEvents_exports.isEventTiming(event)) { + return; + } + if (TraceEvents_exports.isEventTimingEnd(event)) { + eventTimingEndEventsForInteractions.push(event); + } + if (!event.args.data || !TraceEvents_exports.isEventTimingStart(event)) { + return; + } + const { duration, interactionId } = event.args.data; + if (duration < 1 || interactionId === void 0 || interactionId === 0) { + return; + } + eventTimingStartEventsForInteractions.push(event); +} +function categoryOfInteraction(interaction) { + if (pointerEventTypes.has(interaction.type)) { + return "POINTER"; + } + if (keyboardEventTypes.has(interaction.type)) { + return "KEYBOARD"; + } + return "OTHER"; +} +function removeNestedInteractionsAndSetProcessingTime(interactions) { + const earliestEventForEndTimePerCategory = { + POINTER: /* @__PURE__ */ new Map(), + KEYBOARD: /* @__PURE__ */ new Map(), + OTHER: /* @__PURE__ */ new Map() + }; + function storeEventIfEarliestForCategoryAndEndTime(interaction) { + const category = categoryOfInteraction(interaction); + const earliestEventForEndTime = earliestEventForEndTimePerCategory[category]; + const endTime = Timing_exports.Micro(interaction.ts + interaction.dur); + const earliestCurrentEvent = earliestEventForEndTime.get(endTime); + if (!earliestCurrentEvent) { + earliestEventForEndTime.set(endTime, interaction); + return; + } + if (interaction.ts < earliestCurrentEvent.ts) { + earliestEventForEndTime.set(endTime, interaction); + } else if (interaction.ts === earliestCurrentEvent.ts && interaction.interactionId === earliestCurrentEvent.interactionId) { + const currentProcessingDuration = earliestCurrentEvent.processingEnd - earliestCurrentEvent.processingStart; + const newProcessingDuration = interaction.processingEnd - interaction.processingStart; + if (newProcessingDuration > currentProcessingDuration) { + earliestEventForEndTime.set(endTime, interaction); + } + } + if (interaction.processingStart < earliestCurrentEvent.processingStart) { + earliestCurrentEvent.processingStart = interaction.processingStart; + writeSyntheticTimespans(earliestCurrentEvent); + } + if (interaction.processingEnd > earliestCurrentEvent.processingEnd) { + earliestCurrentEvent.processingEnd = interaction.processingEnd; + writeSyntheticTimespans(earliestCurrentEvent); + } + } + __name(storeEventIfEarliestForCategoryAndEndTime, "storeEventIfEarliestForCategoryAndEndTime"); + for (const interaction of interactions) { + storeEventIfEarliestForCategoryAndEndTime(interaction); + } + const keptEvents = Object.values(earliestEventForEndTimePerCategory).flatMap((eventsByEndTime) => Array.from(eventsByEndTime.values())); + keptEvents.sort((eventA, eventB) => { + return eventA.ts - eventB.ts; + }); + return keptEvents; +} +function writeSyntheticTimespans(event) { + const startEvent = event.args.data.beginEvent; + const endEvent = event.args.data.endEvent; + event.inputDelay = Timing_exports.Micro(event.processingStart - startEvent.ts); + event.mainThreadHandling = Timing_exports.Micro(event.processingEnd - event.processingStart); + event.presentationDelay = Timing_exports.Micro(endEvent.ts - event.processingEnd); +} +async function finalize28() { + const { navigationsByFrameId: navigationsByFrameId2 } = data5(); + const beginAndEndEvents = ArrayUtilities_exports.mergeOrdered(eventTimingStartEventsForInteractions, eventTimingEndEventsForInteractions, Trace_exports.eventTimeComparator); + const beginEventById = /* @__PURE__ */ new Map(); + for (const event of beginAndEndEvents) { + if (TraceEvents_exports.isEventTimingStart(event)) { + const forId = beginEventById.get(event.id) ?? []; + forId.push(event); + beginEventById.set(event.id, forId); + } else if (TraceEvents_exports.isEventTimingEnd(event)) { + const beginEvents = beginEventById.get(event.id) ?? []; + const beginEvent = beginEvents.pop(); + if (!beginEvent) { + continue; + } + const { type, interactionId, timeStamp, processingStart, processingEnd } = beginEvent.args.data; + if (!type || !interactionId || !timeStamp || !processingStart || !processingEnd) { + continue; + } + const processingStartRelativeToTraceTime = Timing_exports.Micro(Timing_exports3.milliToMicro(processingStart) - Timing_exports3.milliToMicro(timeStamp) + beginEvent.ts); + const processingEndRelativeToTraceTime = Timing_exports.Micro(Timing_exports3.milliToMicro(processingEnd) - Timing_exports3.milliToMicro(timeStamp) + beginEvent.ts); + const frameId = beginEvent.args.frame ?? beginEvent.args.data.frame ?? ""; + const navigation2 = Trace_exports.getNavigationForTraceEvent(beginEvent, frameId, navigationsByFrameId2); + const navigationId = navigation2?.args.data?.navigationId; + const interactionEvent = SyntheticEvents_exports.SyntheticEventsManager.registerSyntheticEvent({ + // Use the start event to define the common fields. + rawSourceEvent: beginEvent, + cat: beginEvent.cat, + name: beginEvent.name, + pid: beginEvent.pid, + tid: beginEvent.tid, + ph: beginEvent.ph, + processingStart: processingStartRelativeToTraceTime, + processingEnd: processingEndRelativeToTraceTime, + // These will be set in writeSyntheticTimespans() + inputDelay: Timing_exports.Micro(-1), + mainThreadHandling: Timing_exports.Micro(-1), + presentationDelay: Timing_exports.Micro(-1), + args: { + data: { + beginEvent, + endEvent: event, + frame: frameId, + navigationId + } + }, + ts: beginEvent.ts, + dur: Timing_exports.Micro(event.ts - beginEvent.ts), + type: beginEvent.args.data.type, + interactionId: beginEvent.args.data.interactionId + }); + writeSyntheticTimespans(interactionEvent); + interactionEvents.push(interactionEvent); + } + } + Trace_exports.sortTraceEventsInPlace(interactionEvents); + interactionEventsWithNoNesting.push(...removeNestedInteractionsAndSetProcessingTime(interactionEvents)); + for (const interactionEvent of interactionEventsWithNoNesting) { + if (!longestInteractionEvent || longestInteractionEvent.dur < interactionEvent.dur) { + longestInteractionEvent = interactionEvent; + } + } +} +function data28() { + return { + beginCommitCompositorFrameEvents, + parseMetaViewportEvents, + interactionEvents, + interactionEventsWithNoNesting, + longestInteractionEvent, + interactionsOverThreshold: new Set(interactionEvents.filter((event) => { + return event.dur > LONG_INTERACTION_THRESHOLD; + })) + }; +} +function deps15() { + return ["Meta"]; +} +function scoreClassificationForInteractionToNextPaint(timing) { + if (timing <= INP_GOOD_TIMING) { + return ScoreClassification.GOOD; + } + if (timing <= INP_MEDIUM_TIMING) { + return ScoreClassification.OK; + } + return ScoreClassification.BAD; +} +var beginCommitCompositorFrameEvents, parseMetaViewportEvents, LONG_INTERACTION_THRESHOLD, INP_GOOD_TIMING, INP_MEDIUM_TIMING, longestInteractionEvent, interactionEvents, interactionEventsWithNoNesting, eventTimingStartEventsForInteractions, eventTimingEndEventsForInteractions, pointerEventTypes, keyboardEventTypes; +var init_UserInteractionsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/UserInteractionsHandler.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + init_MetaHandler(); + init_PageLoadMetricsHandler(); + beginCommitCompositorFrameEvents = []; + parseMetaViewportEvents = []; + LONG_INTERACTION_THRESHOLD = Timing_exports3.milliToMicro(Timing_exports.Milli(200)); + INP_GOOD_TIMING = LONG_INTERACTION_THRESHOLD; + INP_MEDIUM_TIMING = Timing_exports3.milliToMicro(Timing_exports.Milli(500)); + longestInteractionEvent = null; + interactionEvents = []; + interactionEventsWithNoNesting = []; + eventTimingStartEventsForInteractions = []; + eventTimingEndEventsForInteractions = []; + __name(reset28, "reset"); + __name(handleEvent28, "handleEvent"); + pointerEventTypes = /* @__PURE__ */ new Set([ + "pointerdown", + "touchstart", + "pointerup", + "touchend", + "mousedown", + "mouseup", + "click" + ]); + keyboardEventTypes = /* @__PURE__ */ new Set([ + "keydown", + "keypress", + "keyup" + ]); + __name(categoryOfInteraction, "categoryOfInteraction"); + __name(removeNestedInteractionsAndSetProcessingTime, "removeNestedInteractionsAndSetProcessingTime"); + __name(writeSyntheticTimespans, "writeSyntheticTimespans"); + __name(finalize28, "finalize"); + __name(data28, "data"); + __name(deps15, "deps"); + __name(scoreClassificationForInteractionToNextPaint, "scoreClassificationForInteractionToNextPaint"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/WorkersHandler.js +var WorkersHandler_exports = {}; +__export(WorkersHandler_exports, { + data: () => data29, + finalize: () => finalize29, + handleEvent: () => handleEvent29, + reset: () => reset29 +}); +function reset29() { + sessionIdEvents = []; + workerIdByThread = /* @__PURE__ */ new Map(); + workerURLById = /* @__PURE__ */ new Map(); +} +function handleEvent29(event) { + if (TraceEvents_exports.isTracingSessionIdForWorker(event)) { + sessionIdEvents.push(event); + } +} +async function finalize29() { + for (const sessionIdEvent of sessionIdEvents) { + if (!sessionIdEvent.args.data) { + continue; + } + workerIdByThread.set(sessionIdEvent.args.data.workerThreadId, sessionIdEvent.args.data.workerId); + workerURLById.set(sessionIdEvent.args.data.workerId, sessionIdEvent.args.data.url); + } +} +function data29() { + return { + workerSessionIdEvents: sessionIdEvents, + workerIdByThread, + workerURLById + }; +} +var sessionIdEvents, workerIdByThread, workerURLById; +var init_WorkersHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/WorkersHandler.js"() { + init_process_global(); + init_types2(); + sessionIdEvents = []; + workerIdByThread = /* @__PURE__ */ new Map(); + workerURLById = /* @__PURE__ */ new Map(); + __name(reset29, "reset"); + __name(handleEvent29, "handleEvent"); + __name(finalize29, "finalize"); + __name(data29, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/WarningsHandler.js +var WarningsHandler_exports = {}; +__export(WarningsHandler_exports, { + FORCED_REFLOW_THRESHOLD: () => FORCED_REFLOW_THRESHOLD, + LONG_MAIN_THREAD_TASK_THRESHOLD: () => LONG_MAIN_THREAD_TASK_THRESHOLD, + data: () => data30, + deps: () => deps16, + finalize: () => finalize30, + handleEvent: () => handleEvent30, + reset: () => reset30 +}); +function reset30() { + warningsPerEvent = /* @__PURE__ */ new Map(); + eventsPerWarning = /* @__PURE__ */ new Map(); + allEventsStack = []; + jsInvokeStack = []; + taskReflowEvents = []; + longTaskEvents = []; +} +function storeWarning(event, warning) { + const existingWarnings = MapUtilities_exports.getWithDefault(warningsPerEvent, event, () => []); + existingWarnings.push(warning); + warningsPerEvent.set(event, existingWarnings); + const existingEvents = MapUtilities_exports.getWithDefault(eventsPerWarning, warning, () => []); + existingEvents.push(event); + eventsPerWarning.set(warning, existingEvents); +} +function handleEvent30(event) { + processForcedReflowWarning(event); + if (event.name === TraceEvents_exports.Name.RUN_TASK) { + const { duration } = Timing_exports3.eventTimingsMicroSeconds(event); + if (duration > LONG_MAIN_THREAD_TASK_THRESHOLD) { + longTaskEvents.push(event); + } + return; + } + if (TraceEvents_exports.isFireIdleCallback(event)) { + const { duration } = Timing_exports3.eventTimingsMilliSeconds(event); + if (duration > event.args.data.allottedMilliseconds) { + storeWarning(event, "IDLE_CALLBACK_OVER_TIME"); + } + return; + } +} +function processForcedReflowWarning(event) { + accomodateEventInStack(event, allEventsStack); + accomodateEventInStack( + event, + jsInvokeStack, + /* pushEventToStack */ + TraceEvents_exports.isJSInvocationEvent(event) + ); + if (jsInvokeStack.length) { + if (event.name === TraceEvents_exports.Name.LAYOUT || event.name === TraceEvents_exports.Name.RECALC_STYLE) { + taskReflowEvents.push(event); + return; + } + } + if (allEventsStack.length === 1) { + const totalTime = taskReflowEvents.reduce((time, event2) => time + (event2.dur || 0), 0); + if (totalTime >= FORCED_REFLOW_THRESHOLD) { + taskReflowEvents.forEach((reflowEvent) => storeWarning(reflowEvent, "FORCED_REFLOW")); + } + taskReflowEvents.length = 0; + } +} +function accomodateEventInStack(event, stack, pushEventToStack = true) { + let nextItem = stack.at(-1); + while (nextItem && event.ts > nextItem.ts + (nextItem.dur || 0)) { + stack.pop(); + nextItem = stack.at(-1); + } + if (!pushEventToStack) { + return; + } + stack.push(event); +} +function deps16() { + return ["UserInteractions", "Workers"]; +} +async function finalize30() { + const longInteractions = data28().interactionsOverThreshold; + for (const interaction of longInteractions) { + storeWarning(interaction, "LONG_INTERACTION"); + } + for (const event of longTaskEvents) { + if (!(event.tid, data29().workerIdByThread.has(event.tid))) { + storeWarning(event, "LONG_TASK"); + } + } + longTaskEvents.length = 0; +} +function data30() { + return { + perEvent: warningsPerEvent, + perWarning: eventsPerWarning + }; +} +var warningsPerEvent, eventsPerWarning, allEventsStack, jsInvokeStack, taskReflowEvents, longTaskEvents, FORCED_REFLOW_THRESHOLD, LONG_MAIN_THREAD_TASK_THRESHOLD; +var init_WarningsHandler = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/WarningsHandler.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + init_UserInteractionsHandler(); + init_WorkersHandler(); + warningsPerEvent = /* @__PURE__ */ new Map(); + eventsPerWarning = /* @__PURE__ */ new Map(); + allEventsStack = []; + jsInvokeStack = []; + taskReflowEvents = []; + longTaskEvents = []; + FORCED_REFLOW_THRESHOLD = Timing_exports3.milliToMicro(Timing_exports.Milli(30)); + LONG_MAIN_THREAD_TASK_THRESHOLD = Timing_exports3.milliToMicro(Timing_exports.Milli(50)); + __name(reset30, "reset"); + __name(storeWarning, "storeWarning"); + __name(handleEvent30, "handleEvent"); + __name(processForcedReflowWarning, "processForcedReflowWarning"); + __name(accomodateEventInStack, "accomodateEventInStack"); + __name(deps16, "deps"); + __name(finalize30, "finalize"); + __name(data30, "data"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/ModelHandlers.js +var ModelHandlers_exports = {}; +__export(ModelHandlers_exports, { + AnimationFrames: () => AnimationFramesHandler_exports, + Animations: () => AnimationHandler_exports, + AsyncJSCalls: () => AsyncJSCallsHandler_exports, + AuctionWorklets: () => AuctionWorkletsHandler_exports, + DOMStats: () => DOMStatsHandler_exports, + ExtensionTraceData: () => ExtensionTraceDataHandler_exports, + Flows: () => FlowsHandler_exports, + Frames: () => FramesHandler_exports, + GPU: () => GPUHandler_exports, + ImagePainting: () => ImagePaintingHandler_exports, + Initiators: () => InitiatorsHandler_exports, + Invalidations: () => InvalidationsHandler_exports, + LargestImagePaint: () => LargestImagePaintHandler_exports, + LargestTextPaint: () => LargestTextPaintHandler_exports, + LayerTree: () => LayerTreeHandler_exports, + LayoutShifts: () => LayoutShiftsHandler_exports, + Memory: () => MemoryHandler_exports, + Meta: () => MetaHandler_exports, + NetworkRequests: () => NetworkRequestsHandler_exports, + PageFrames: () => PageFramesHandler_exports, + PageLoadMetrics: () => PageLoadMetricsHandler_exports, + Renderer: () => RendererHandler_exports, + Samples: () => SamplesHandler_exports, + Screenshots: () => ScreenshotsHandler_exports, + Scripts: () => ScriptsHandler_exports, + SelectorStats: () => SelectorStatsHandler_exports, + UserInteractions: () => UserInteractionsHandler_exports, + UserTimings: () => UserTimingsHandler_exports, + Warnings: () => WarningsHandler_exports, + Workers: () => WorkersHandler_exports +}); +var init_ModelHandlers = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/ModelHandlers.js"() { + init_process_global(); + init_AnimationFramesHandler(); + init_AnimationHandler(); + init_AsyncJSCallsHandler(); + init_AuctionWorkletsHandler(); + init_DOMStatsHandler(); + init_ExtensionTraceDataHandler(); + init_FlowsHandler(); + init_FramesHandler(); + init_GPUHandler(); + init_ImagePaintingHandler(); + init_InitiatorsHandler(); + init_InvalidationsHandler(); + init_LargestImagePaintHandler(); + init_LargestTextPaintHandler(); + init_LayerTreeHandler(); + init_LayoutShiftsHandler(); + init_MemoryHandler(); + init_MetaHandler(); + init_NetworkRequestsHandler(); + init_PageFramesHandler(); + init_PageLoadMetricsHandler(); + init_RendererHandler(); + init_SamplesHandler(); + init_ScreenshotsHandler(); + init_ScriptsHandler(); + init_SelectorStatsHandler(); + init_UserInteractionsHandler(); + init_UserTimingsHandler(); + init_WarningsHandler(); + init_WorkersHandler(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/types.js +var init_types3 = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/types.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/handlers/handlers.js +var init_handlers = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/handlers/handlers.js"() { + init_process_global(); + init_helpers(); + init_ModelHandlers(); + init_Threads(); + init_types3(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/EntityMapper.js +var init_EntityMapper = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/EntityMapper.js"() { + init_process_global(); + init_handlers(); + init_helpers2(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/EventsSerializer.js +var init_EventsSerializer = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/EventsSerializer.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/extras/ScriptDuplication.js +var ScriptDuplication_exports = {}; +__export(ScriptDuplication_exports, { + computeScriptDuplication: () => computeScriptDuplication, + getNodeModuleName: () => getNodeModuleName, + normalizeDuplication: () => normalizeDuplication, + normalizeSource: () => normalizeSource +}); +function normalizeSource(source) { + source = source.replace(/\?$/, ""); + const lastNodeModulesIndex = source.lastIndexOf("node_modules"); + if (lastNodeModulesIndex !== -1) { + source = source.substring(lastNodeModulesIndex); + } + return source; +} +function shouldIgnoreSource(source) { + if (source.includes("webpack/bootstrap")) { + return true; + } + if (source.includes("(webpack)/buildin")) { + return true; + } + if (source.includes("external ")) { + return true; + } + return false; +} +function normalizeDuplication(duplication) { + for (const [key, data31] of duplication) { + data31.duplicates.sort((a, b) => b.attributedSize - a.attributedSize); + if (data31.duplicates.length > 1) { + const largestResourceSize = data31.duplicates[0].attributedSize; + data31.duplicates = data31.duplicates.filter((duplicate) => { + const percentSize = duplicate.attributedSize / largestResourceSize; + return percentSize >= RELATIVE_SIZE_THRESHOLD; + }); + } + data31.duplicates = data31.duplicates.filter((duplicate) => duplicate.attributedSize >= ABSOLUTE_SIZE_THRESHOLD_BYTES); + if (data31.duplicates.length <= 1) { + duplication.delete(key); + continue; + } + data31.estimatedDuplicateBytes = data31.duplicates.slice(1).reduce((acc, cur) => acc + cur.attributedSize, 0); + } +} +function indexOfOrLength(haystack, needle, startPosition = 0) { + const index = haystack.indexOf(needle, startPosition); + return index === -1 ? haystack.length : index; +} +function getNodeModuleName(source) { + const sourceSplit = source.split("node_modules/"); + source = sourceSplit[sourceSplit.length - 1]; + const indexFirstSlash = indexOfOrLength(source, "/"); + if (source[0] === "@") { + return source.slice(0, indexOfOrLength(source, "/", indexFirstSlash + 1)); + } + return source.slice(0, indexFirstSlash); +} +function groupByNodeModules(duplication) { + const groupedDuplication = /* @__PURE__ */ new Map(); + for (const [source, data31] of duplication) { + if (!source.includes("node_modules")) { + groupedDuplication.set(source, data31); + continue; + } + const nodeModuleKey = "node_modules/" + getNodeModuleName(source); + const aggregatedData = groupedDuplication.get(nodeModuleKey) ?? { + duplicates: [], + // This is calculated in normalizeDuplication. + estimatedDuplicateBytes: 0 + }; + groupedDuplication.set(nodeModuleKey, aggregatedData); + for (const { script, attributedSize } of data31.duplicates) { + let duplicate = aggregatedData.duplicates.find((d) => d.script === script); + if (!duplicate) { + duplicate = { script, attributedSize: 0 }; + aggregatedData.duplicates.push(duplicate); + } + duplicate.attributedSize += attributedSize; + } + } + return groupedDuplication; +} +function sorted(duplication) { + return new Map([...duplication].sort((a, b) => b[1].estimatedDuplicateBytes - a[1].estimatedDuplicateBytes)); +} +function computeScriptDuplication(scriptsData, compressionRatios) { + const sourceDatasMap = /* @__PURE__ */ new Map(); + for (const script of scriptsData.scripts) { + if (!script.content || !script.sourceMap) { + continue; + } + const sizes = ModelHandlers_exports.Scripts.getScriptGeneratedSizes(script); + if (!sizes) { + continue; + } + if ("errorMessage" in sizes) { + console.error(sizes.errorMessage); + continue; + } + const sourceDataArray = []; + sourceDatasMap.set(script, sourceDataArray); + const sources = script.sourceMap.sourceURLs(); + for (let i = 0; i < sources.length; i++) { + if (shouldIgnoreSource(sources[i])) { + continue; + } + const sourceSize = sizes.files[sources[i]]; + sourceDataArray.push({ + source: normalizeSource(sources[i]), + resourceSize: sourceSize + }); + } + } + const duplication = /* @__PURE__ */ new Map(); + for (const [script, sourceDataArray] of sourceDatasMap) { + for (const sourceData of sourceDataArray) { + let data31 = duplication.get(sourceData.source); + if (!data31) { + data31 = { estimatedDuplicateBytes: 0, duplicates: [] }; + duplication.set(sourceData.source, data31); + } + const compressionRatio = script.request ? compressionRatios.get(script.request?.args.data.requestId) ?? 1 : 1; + const transferSize = Math.round(sourceData.resourceSize * compressionRatio); + data31.duplicates.push({ + script, + attributedSize: transferSize + }); + } + } + const duplicationGroupedByNodeModules = groupByNodeModules(duplication); + normalizeDuplication(duplication); + normalizeDuplication(duplicationGroupedByNodeModules); + return { + duplication: sorted(duplication), + duplicationGroupedByNodeModules: sorted(duplicationGroupedByNodeModules) + }; +} +var ABSOLUTE_SIZE_THRESHOLD_BYTES, RELATIVE_SIZE_THRESHOLD; +var init_ScriptDuplication = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/extras/ScriptDuplication.js"() { + init_process_global(); + init_handlers(); + ABSOLUTE_SIZE_THRESHOLD_BYTES = 1024 * 0.5; + RELATIVE_SIZE_THRESHOLD = 0.1; + __name(normalizeSource, "normalizeSource"); + __name(shouldIgnoreSource, "shouldIgnoreSource"); + __name(normalizeDuplication, "normalizeDuplication"); + __name(indexOfOrLength, "indexOfOrLength"); + __name(getNodeModuleName, "getNodeModuleName"); + __name(groupByNodeModules, "groupByNodeModules"); + __name(sorted, "sorted"); + __name(computeScriptDuplication, "computeScriptDuplication"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/extras/StackTraceForEvent.js +var StackTraceForEvent_exports = {}; +__export(StackTraceForEvent_exports, { + clearCacheForTrace: () => clearCacheForTrace, + get: () => get, + stackTraceForEventInTrace: () => stackTraceForEventInTrace +}); +function clearCacheForTrace(data31) { + stackTraceForEventInTrace.delete(data31); +} +function get(event, data31) { + let cacheForTrace = stackTraceForEventInTrace.get(data31); + if (!cacheForTrace) { + cacheForTrace = /* @__PURE__ */ new Map(); + stackTraceForEventInTrace.set(data31, cacheForTrace); + } + const resultFromCache = cacheForTrace.get(event); + if (resultFromCache) { + return resultFromCache; + } + let result = null; + if (Extensions_exports.isSyntheticExtensionEntry(event)) { + result = getForExtensionEntry(event, data31); + } else if (TraceEvents_exports.isPerformanceMeasureBegin(event)) { + result = getForPerformanceMeasure(event, data31); + } else { + result = getForEvent(event, data31); + const payloadCallFrames = getTraceEventPayloadStackAsProtocolCallFrame(event).filter((callFrame) => !isNativeJSFunction(callFrame)); + if (!result.callFrames.length) { + result.callFrames = payloadCallFrames; + } else { + for (let i = 0; i < payloadCallFrames.length && i < result.callFrames.length; i++) { + result.callFrames[i] = payloadCallFrames[i]; + } + } + } + if (result) { + cacheForTrace.set(event, result); + } + return result; +} +function getForEvent(event, data31) { + const entryToNode4 = data31.Renderer.entryToNode.size > 0 ? data31.Renderer.entryToNode : data31.Samples.entryToNode; + const topStackTrace = { callFrames: [] }; + let stackTrace = topStackTrace; + let currentEntry; + let node = entryToNode4.get(event); + const traceCache = stackTraceForEventInTrace.get(data31) || /* @__PURE__ */ new Map(); + stackTraceForEventInTrace.set(data31, traceCache); + while (node) { + if (!TraceEvents_exports.isProfileCall(node.entry)) { + const maybeAsyncParent = data31.AsyncJSCalls.runEntryPointToScheduler.get(node.entry); + if (!maybeAsyncParent) { + node = node.parent; + continue; + } + const maybeAsyncParentNode2 = maybeAsyncParent && entryToNode4.get(maybeAsyncParent.scheduler); + if (maybeAsyncParentNode2) { + stackTrace = addAsyncParentToStack(stackTrace, maybeAsyncParent.taskName); + node = maybeAsyncParentNode2; + } + continue; + } + currentEntry = node.entry; + const stackTraceFromCache = traceCache.get(node.entry); + if (stackTraceFromCache) { + stackTrace.callFrames.push(...stackTraceFromCache.callFrames.filter((callFrame) => !isNativeJSFunction(callFrame))); + stackTrace.parent = stackTraceFromCache.parent; + stackTrace.description = stackTrace.description || stackTraceFromCache.description; + break; + } + if (!isNativeJSFunction(currentEntry.callFrame)) { + stackTrace.callFrames.push(currentEntry.callFrame); + } + const maybeAsyncParentEvent = data31.AsyncJSCalls.asyncCallToScheduler.get(currentEntry); + const maybeAsyncParentNode = maybeAsyncParentEvent && entryToNode4.get(maybeAsyncParentEvent.scheduler); + if (maybeAsyncParentNode) { + stackTrace = addAsyncParentToStack(stackTrace, maybeAsyncParentEvent.taskName); + node = maybeAsyncParentNode; + continue; + } + node = node.parent; + } + return topStackTrace; +} +function addAsyncParentToStack(stackTrace, taskName) { + const parent = { callFrames: [] }; + stackTrace.parent = parent; + parent.description = taskName; + return parent; +} +function getForExtensionEntry(event, data31) { + const rawEvent = event.rawSourceEvent; + if (TraceEvents_exports.isPerformanceMeasureBegin(rawEvent)) { + return getForPerformanceMeasure(rawEvent, data31); + } + if (!rawEvent) { + return null; + } + return get(rawEvent, data31); +} +function getForPerformanceMeasure(event, data31) { + let rawEvent = event; + if (event.args.traceId === void 0) { + return null; + } + rawEvent = data31.UserTimings.measureTraceByTraceId.get(event.args.traceId); + if (!rawEvent) { + return null; + } + return get(rawEvent, data31); +} +function isNativeJSFunction({ columnNumber, lineNumber, url, scriptId }) { + return lineNumber === -1 && columnNumber === -1 && url === "" && scriptId === "0"; +} +function getTraceEventPayloadStackAsProtocolCallFrame(event) { + const payloadCallStack = Trace_exports.getZeroIndexedStackTraceInEventPayload(event) || []; + const callFrames = []; + for (const frame of payloadCallStack) { + callFrames.push({ ...frame, scriptId: String(frame.scriptId) }); + } + return callFrames; +} +var stackTraceForEventInTrace; +var init_StackTraceForEvent = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/extras/StackTraceForEvent.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + stackTraceForEventInTrace = /* @__PURE__ */ new Map(); + __name(clearCacheForTrace, "clearCacheForTrace"); + __name(get, "get"); + __name(getForEvent, "getForEvent"); + __name(addAsyncParentToStack, "addAsyncParentToStack"); + __name(getForExtensionEntry, "getForExtensionEntry"); + __name(getForPerformanceMeasure, "getForPerformanceMeasure"); + __name(isNativeJSFunction, "isNativeJSFunction"); + __name(getTraceEventPayloadStackAsProtocolCallFrame, "getTraceEventPayloadStackAsProtocolCallFrame"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/extras/TraceFilter.js +var TraceFilter, VisibleEventsFilter, ExclusiveNameFilter; +var init_TraceFilter = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/extras/TraceFilter.js"() { + init_process_global(); + init_types2(); + TraceFilter = class { + static { + __name(this, "TraceFilter"); + } + }; + VisibleEventsFilter = class _VisibleEventsFilter extends TraceFilter { + static { + __name(this, "VisibleEventsFilter"); + } + visibleTypes; + constructor(visibleTypes) { + super(); + this.visibleTypes = new Set(visibleTypes); + } + accept(event) { + if (Extensions_exports.isSyntheticExtensionEntry(event)) { + return true; + } + return this.visibleTypes.has(_VisibleEventsFilter.eventType(event)); + } + static eventType(event) { + if (event.cat.includes("blink.console")) { + return TraceEvents_exports.Name.CONSOLE_TIME; + } + if (event.cat.includes("blink.user_timing")) { + return TraceEvents_exports.Name.USER_TIMING; + } + return event.name; + } + }; + ExclusiveNameFilter = class extends TraceFilter { + static { + __name(this, "ExclusiveNameFilter"); + } + #excludeNames; + constructor(excludeNames) { + super(); + this.#excludeNames = new Set(excludeNames); + } + accept(event) { + return !this.#excludeNames.has(event.name); + } + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/extras/TraceTree.js +function generateEventID(event) { + if (TraceEvents_exports.isProfileCall(event)) { + const name = SamplesIntegrator.isNativeRuntimeFrame(event.callFrame) ? SamplesIntegrator.nativeGroup(event.callFrame.functionName) : event.callFrame.functionName; + const location = event.callFrame.scriptId || event.callFrame.url || ""; + return `f:${name}@${location}`; + } + if (TraceEvents_exports.isConsoleTimeStamp(event) && event.args.data) { + return `${event.name}:${event.args.data.name}`; + } + if (TraceEvents_exports.isSyntheticNetworkRequest(event) || TraceEvents_exports.isReceivedDataEvent(event)) { + return `req:${event.args.data.requestId}`; + } + return event.name; +} +var Node2, BottomUpRootNode, GroupNode, BottomUpNode; +var init_TraceTree = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/extras/TraceTree.js"() { + init_process_global(); + init_helpers2(); + init_SamplesIntegrator(); + init_types2(); + Node2 = class { + static { + __name(this, "Node"); + } + /** ms */ + totalTime; + /** ms */ + selfTime; + transferSize; + id; + /** The first trace event encountered that necessitated the creation of this tree node. */ + event; + /** + * All of the trace events associated with this aggregate node. + * Minor: In the case of Event Log (EventsTimelineTreeView), the node is not aggregate and this will only hold 1 event, the same that's in this.event + */ + events; + parent; + groupId; + isGroupNodeInternal; + depth; + constructor(id, event) { + this.totalTime = 0; + this.selfTime = 0; + this.transferSize = 0; + this.id = id; + this.event = event; + this.events = [event]; + this.groupId = ""; + this.isGroupNodeInternal = false; + this.depth = 0; + } + isGroupNode() { + return this.isGroupNodeInternal; + } + hasChildren() { + throw new Error("Not implemented"); + } + setHasChildren(_value) { + throw new Error("Not implemented"); + } + /** + * Returns the direct descendants of this node. + * @returns a map with ordered tuples. + */ + children() { + throw new Error("Not implemented"); + } + searchTree(matchFunction, results) { + results = results || []; + if (this.event && matchFunction(this.event)) { + results.push(this); + } + for (const child of this.children().values()) { + child.searchTree(matchFunction, results); + } + return results; + } + }; + BottomUpRootNode = class extends Node2 { + static { + __name(this, "BottomUpRootNode"); + } + childrenInternal; + textFilter; + filter; + startTime; + endTime; + totalTime; + eventGroupIdCallback; + calculateTransferSize; + forceGroupIdCallback; + constructor(events, { textFilter, filters, startTime, endTime, eventGroupIdCallback, calculateTransferSize, forceGroupIdCallback }) { + super("", events[0]); + this.childrenInternal = null; + this.events = events; + this.textFilter = textFilter; + this.filter = (e) => filters.every((f) => f.accept(e)); + this.startTime = startTime; + this.endTime = endTime; + this.eventGroupIdCallback = eventGroupIdCallback; + this.totalTime = endTime - startTime; + this.calculateTransferSize = calculateTransferSize; + this.forceGroupIdCallback = forceGroupIdCallback; + } + hasChildren() { + return true; + } + filterChildren(children) { + for (const [id, child] of children) { + if (child.event && child.depth <= 1 && !this.textFilter.accept(child.event)) { + children.delete(id); + } + } + return children; + } + children() { + if (!this.childrenInternal) { + this.childrenInternal = this.filterChildren(this.grouppedTopNodes()); + } + return this.childrenInternal; + } + // If no grouping is applied, the nodes returned here are what's initially shown in the bottom-up view. + // "No grouping" == no grouping in UI dropdown == no groupingFunction… + // … HOWEVER, nodes are still aggregated via `generateEventID`, which is ~= the event name. + ungroupedTopNodes() { + const root2 = this; + const startTime = this.startTime; + const endTime = this.endTime; + const nodeById = /* @__PURE__ */ new Map(); + const selfTimeStack = [endTime - startTime]; + const firstNodeStack = []; + const totalTimeById = /* @__PURE__ */ new Map(); + const eventGroupIdCallback = this.eventGroupIdCallback; + const forceGroupIdCallback = this.forceGroupIdCallback; + const sumTransferSizeOfInstantEvent = /* @__PURE__ */ __name((e) => { + if (TraceEvents_exports.isReceivedDataEvent(e)) { + let id = generateEventID(e); + if (this.forceGroupIdCallback && this.eventGroupIdCallback) { + id = `${id}-${this.eventGroupIdCallback(e)}`; + } + let node = nodeById.get(id); + if (!node) { + node = new BottomUpNode(root2, id, e, false, root2); + nodeById.set(id, node); + } else { + node.events.push(e); + } + if (e.name === "ResourceReceivedData") { + node.transferSize += e.args.data.encodedDataLength; + } else if (e.args.data.encodedDataLength > 0) { + node.transferSize = e.args.data.encodedDataLength; + } + } + }, "sumTransferSizeOfInstantEvent"); + Trace_exports.forEachEvent(this.events, { + onStartEvent, + onEndEvent, + onInstantEvent: this.calculateTransferSize ? sumTransferSizeOfInstantEvent : void 0, + startTime: Timing_exports3.milliToMicro(this.startTime), + endTime: Timing_exports3.milliToMicro(this.endTime), + eventFilter: this.filter, + ignoreAsyncEvents: false + }); + function onStartEvent(e) { + const { startTime: currentStartTime, endTime: currentEndTime } = Timing_exports3.eventTimingsMilliSeconds(e); + const actualEndTime = currentEndTime !== void 0 ? Math.min(currentEndTime, endTime) : endTime; + const duration = actualEndTime - Math.max(currentStartTime, startTime); + selfTimeStack[selfTimeStack.length - 1] -= duration; + selfTimeStack.push(duration); + let id = generateEventID(e); + if (forceGroupIdCallback && eventGroupIdCallback) { + id = `${id}-${eventGroupIdCallback(e)}`; + } + const noNodeOnStack = !totalTimeById.has(id); + if (noNodeOnStack) { + totalTimeById.set(id, duration); + } + firstNodeStack.push(noNodeOnStack); + } + __name(onStartEvent, "onStartEvent"); + function onEndEvent(event) { + let id = generateEventID(event); + if (forceGroupIdCallback && eventGroupIdCallback) { + id = `${id}-${eventGroupIdCallback(event)}`; + } + let node = nodeById.get(id); + if (!node) { + node = new BottomUpNode(root2, id, event, false, root2); + nodeById.set(id, node); + } else { + node.events.push(event); + } + node.selfTime += selfTimeStack.pop() || 0; + if (firstNodeStack.pop()) { + node.totalTime += totalTimeById.get(id) || 0; + totalTimeById.delete(id); + } + if (firstNodeStack.length) { + node.setHasChildren(true); + } + } + __name(onEndEvent, "onEndEvent"); + this.selfTime = selfTimeStack.pop() || 0; + for (const pair of nodeById) { + if (pair[1].selfTime <= 0 && (!this.calculateTransferSize || pair[1].transferSize <= 0)) { + nodeById.delete(pair[0]); + } + } + return nodeById; + } + grouppedTopNodes() { + const flatNodes = this.ungroupedTopNodes(); + if (!this.eventGroupIdCallback) { + return flatNodes; + } + const groupNodes = /* @__PURE__ */ new Map(); + for (const node of flatNodes.values()) { + const groupId = this.eventGroupIdCallback(node.event); + let groupNode = groupNodes.get(groupId); + if (!groupNode) { + groupNode = new GroupNode(groupId, this, node.events); + groupNodes.set(groupId, groupNode); + } else { + for (const e of node.events) { + groupNode.events.push(e); + } + } + groupNode.addChild(node, node.selfTime, node.selfTime, node.transferSize); + } + return groupNodes; + } + }; + GroupNode = class extends Node2 { + static { + __name(this, "GroupNode"); + } + childrenInternal; + isGroupNodeInternal; + events; + constructor(id, parent, events) { + super(id, events[0]); + this.events = events; + this.childrenInternal = /* @__PURE__ */ new Map(); + this.parent = parent; + this.isGroupNodeInternal = true; + } + addChild(child, selfTime, totalTime, transferSize) { + this.childrenInternal.set(child.id, child); + this.selfTime += selfTime; + this.totalTime += totalTime; + this.transferSize += transferSize; + child.parent = this; + } + hasChildren() { + return true; + } + children() { + return this.childrenInternal; + } + }; + BottomUpNode = class _BottomUpNode extends Node2 { + static { + __name(this, "BottomUpNode"); + } + parent; + root; + depth; + cachedChildren; + hasChildrenInternal; + constructor(root2, id, event, hasChildren, parent) { + super(id, event); + this.parent = parent; + this.root = root2; + this.depth = (parent.depth || 0) + 1; + this.cachedChildren = null; + this.hasChildrenInternal = hasChildren; + } + hasChildren() { + return this.hasChildrenInternal; + } + setHasChildren(value) { + this.hasChildrenInternal = value; + } + children() { + if (this.cachedChildren) { + return this.cachedChildren; + } + const selfTimeStack = [0]; + const eventIdStack = []; + const eventStack = []; + const nodeById = /* @__PURE__ */ new Map(); + const startTime = this.root.startTime; + const endTime = this.root.endTime; + let lastTimeMarker = startTime; + const self2 = this; + Trace_exports.forEachEvent(this.root.events, { + onStartEvent, + onEndEvent, + startTime: Timing_exports3.milliToMicro(startTime), + endTime: Timing_exports3.milliToMicro(endTime), + eventFilter: this.root.filter, + ignoreAsyncEvents: false + }); + function onStartEvent(e) { + const { startTime: currentStartTime, endTime: currentEndTime } = Timing_exports3.eventTimingsMilliSeconds(e); + const actualEndTime = currentEndTime !== void 0 ? Math.min(currentEndTime, endTime) : endTime; + const duration = actualEndTime - Math.max(currentStartTime, startTime); + if (duration < 0) { + console.assert(false, "Negative duration of an event"); + } + selfTimeStack[selfTimeStack.length - 1] -= duration; + selfTimeStack.push(duration); + const id = generateEventID(e); + eventIdStack.push(id); + eventStack.push(e); + } + __name(onStartEvent, "onStartEvent"); + function onEndEvent(e) { + const { startTime: currentStartTime, endTime: currentEndTime } = Timing_exports3.eventTimingsMilliSeconds(e); + const selfTime = selfTimeStack.pop(); + const id = eventIdStack.pop(); + eventStack.pop(); + let node; + for (node = self2; node.depth > 1; node = node.parent) { + if (node.id !== eventIdStack[eventIdStack.length + 1 - node.depth]) { + return; + } + } + if (node.id !== id || eventIdStack.length < self2.depth) { + return; + } + const childId = eventIdStack[eventIdStack.length - self2.depth]; + node = nodeById.get(childId); + if (!node) { + const event = eventStack[eventStack.length - self2.depth]; + const hasChildren = eventStack.length > self2.depth; + node = new _BottomUpNode(self2.root, childId, event, hasChildren, self2); + nodeById.set(childId, node); + } else { + node.events.push(e); + } + const actualEndTime = currentEndTime !== void 0 ? Math.min(currentEndTime, endTime) : endTime; + const totalTime = actualEndTime - Math.max(currentStartTime, lastTimeMarker); + node.selfTime += selfTime || 0; + node.totalTime += totalTime; + lastTimeMarker = actualEndTime; + } + __name(onEndEvent, "onEndEvent"); + this.cachedChildren = this.root.filterChildren(nodeById); + return this.cachedChildren; + } + searchTree(matchFunction, results) { + results = results || []; + if (this.event && matchFunction(this.event)) { + results.push(this); + } + return results; + } + }; + __name(generateEventID, "generateEventID"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/extras/ThirdParties.js +var ThirdParties_exports = {}; +__export(ThirdParties_exports, { + summarizeByThirdParty: () => summarizeByThirdParty, + summarizeByURL: () => summarizeByURL +}); +function collectMainThreadActivity(data31) { + const mainFrameMainThread = data31.Renderer.processes.values().find((p) => { + const url = p.url ?? ""; + return p.isOnMainFrame && !url.startsWith("about:") && !url.startsWith("chrome:"); + })?.threads.values().find((t) => t.name === "CrRendererMain"); + if (!mainFrameMainThread) { + return []; + } + return mainFrameMainThread.entries; +} +function summarizeByThirdParty(data31, traceBounds2) { + const mainThreadEvents = collectMainThreadActivity(data31).sort(Trace_exports.eventTimeComparator); + const groupingFunction = /* @__PURE__ */ __name((event) => { + const entity = data31.Renderer.entityMappings.entityByEvent.get(event); + return entity?.name ?? ""; + }, "groupingFunction"); + const node = getBottomUpTree(mainThreadEvents, traceBounds2, groupingFunction); + const summaries = summarizeBottomUpByEntity(node, data31); + return summaries; +} +function summarizeByURL(data31, traceBounds2) { + const mainThreadEvents = collectMainThreadActivity(data31).sort(Trace_exports.eventTimeComparator); + const groupingFunction = /* @__PURE__ */ __name((event) => { + return helpers_exports.getNonResolvedURL(event, data31) ?? ""; + }, "groupingFunction"); + const node = getBottomUpTree(mainThreadEvents, traceBounds2, groupingFunction); + const summaries = summarizeBottomUpByURL(node, data31); + return summaries; +} +function summarizeBottomUpByEntity(root2, data31) { + const summaries = []; + const topNodes = [...root2.children().values()].flat(); + for (const node of topNodes) { + if (node.id === "") { + continue; + } + const entity = data31.Renderer.entityMappings.entityByEvent.get(node.event); + if (!entity) { + continue; + } + const summary = { + transferSize: node.transferSize, + mainThreadTime: Timing_exports.Milli(node.selfTime), + entity, + relatedEvents: data31.Renderer.entityMappings.eventsByEntity.get(entity) ?? [] + }; + summaries.push(summary); + } + return summaries; +} +function summarizeBottomUpByURL(root2, data31) { + const summaries = []; + const allRequests = data31.NetworkRequests.byTime; + const topNodes = [...root2.children().values()].flat(); + for (const node of topNodes) { + if (node.id === "" || typeof node.id !== "string") { + continue; + } + const entity = data31.Renderer.entityMappings.entityByEvent.get(node.event); + if (!entity) { + continue; + } + const url = node.id; + const request = allRequests.find((r) => r.args.data.url === url); + const summary = { + request, + url, + entity, + transferSize: node.transferSize, + mainThreadTime: Timing_exports.Milli(node.selfTime) + }; + summaries.push(summary); + } + return summaries; +} +function getBottomUpTree(mainThreadEvents, tracebounds, groupingFunction) { + const visibleEvents = Trace_exports.VISIBLE_TRACE_EVENT_TYPES.values().toArray(); + const filter = new VisibleEventsFilter(visibleEvents.concat([TraceEvents_exports.Name.SYNTHETIC_NETWORK_REQUEST])); + const startTime = Timing_exports3.microToMilli(tracebounds.min); + const endTime = Timing_exports3.microToMilli(tracebounds.max); + return new BottomUpRootNode(mainThreadEvents, { + textFilter: new ExclusiveNameFilter([]), + filters: [filter], + startTime, + endTime, + eventGroupIdCallback: groupingFunction, + calculateTransferSize: true, + // Ensure we group by 3P alongside eventID for correct 3P grouping. + forceGroupIdCallback: true + }); +} +var init_ThirdParties = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/extras/ThirdParties.js"() { + init_process_global(); + init_handlers(); + init_helpers2(); + init_types2(); + init_TraceFilter(); + init_TraceTree(); + __name(collectMainThreadActivity, "collectMainThreadActivity"); + __name(summarizeByThirdParty, "summarizeByThirdParty"); + __name(summarizeByURL, "summarizeByURL"); + __name(summarizeBottomUpByEntity, "summarizeBottomUpByEntity"); + __name(summarizeBottomUpByURL, "summarizeBottomUpByURL"); + __name(getBottomUpTree, "getBottomUpTree"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/extras/extras.js +var init_extras = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/extras/extras.js"() { + init_process_global(); + init_ScriptDuplication(); + init_StackTraceForEvent(); + init_ThirdParties(); + init_TraceFilter(); + init_TraceTree(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/Statistics.js +function erf2(x) { + const sign = Math.sign(x); + x = Math.abs(x); + const a1 = 0.254829592; + const a2 = -0.284496736; + const a3 = 1.421413741; + const a4 = -1.453152027; + const a5 = 1.061405429; + const p = 0.3275911; + const t = 1 / (1 + p * x); + const y = t * (a1 + t * (a2 + t * (a3 + t * (a4 + t * a5)))); + return sign * (1 - y * Math.exp(-x * x)); +} +function getLogNormalScore2({ median, p10 }, value) { + if (median <= 0) { + throw new Error("median must be greater than zero"); + } + if (p10 <= 0) { + throw new Error("p10 must be greater than zero"); + } + if (p10 >= median) { + throw new Error("p10 must be less than the median"); + } + if (value <= 0) { + return 1; + } + const INVERSE_ERFC_ONE_FIFTH = 0.9061938024368232; + const xRatio = Math.max(Number.MIN_VALUE, value / median); + const xLogRatio = Math.log(xRatio); + const p10Ratio = Math.max(Number.MIN_VALUE, p10 / median); + const p10LogRatio = -Math.log(p10Ratio); + const standardizedX = xLogRatio * INVERSE_ERFC_ONE_FIFTH / p10LogRatio; + const complementaryPercentile = (1 - erf2(standardizedX)) / 2; + let score; + if (value <= p10) { + score = Math.max(MIN_PASSING_SCORE2, Math.min(1, complementaryPercentile)); + } else if (value <= median) { + score = Math.max(MIN_AVERAGE_SCORE2, Math.min(MAX_AVERAGE_SCORE2, complementaryPercentile)); + } else { + score = Math.max(0, Math.min(MAX_FAILING_SCORE2, complementaryPercentile)); + } + return score; +} +function linearInterpolation(x0, y0, x1, y1, x) { + const slope = (y1 - y0) / (x1 - x0); + return y0 + (x - x0) * slope; +} +var MIN_PASSING_SCORE2, MAX_AVERAGE_SCORE2, MIN_AVERAGE_SCORE2, MAX_FAILING_SCORE2; +var init_Statistics = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/Statistics.js"() { + init_process_global(); + /** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + MIN_PASSING_SCORE2 = 0.9; + MAX_AVERAGE_SCORE2 = 0.8999999999999999; + MIN_AVERAGE_SCORE2 = 0.5; + MAX_FAILING_SCORE2 = 0.49999999999999994; + __name(erf2, "erf"); + __name(getLogNormalScore2, "getLogNormalScore"); + __name(linearInterpolation, "linearInterpolation"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/types.js +var InsightWarning, InsightCategory, InsightKeys; +var init_types4 = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/types.js"() { + init_process_global(); + (function(InsightWarning2) { + InsightWarning2["NO_FP"] = "NO_FP"; + InsightWarning2["NO_LCP"] = "NO_LCP"; + InsightWarning2["NO_DOCUMENT_REQUEST"] = "NO_DOCUMENT_REQUEST"; + InsightWarning2["NO_LAYOUT"] = "NO_LAYOUT"; + })(InsightWarning || (InsightWarning = {})); + (function(InsightCategory2) { + InsightCategory2["ALL"] = "All"; + InsightCategory2["INP"] = "INP"; + InsightCategory2["LCP"] = "LCP"; + InsightCategory2["CLS"] = "CLS"; + })(InsightCategory || (InsightCategory = {})); + (function(InsightKeys2) { + InsightKeys2["LCP_BREAKDOWN"] = "LCPBreakdown"; + InsightKeys2["INP_BREAKDOWN"] = "INPBreakdown"; + InsightKeys2["CLS_CULPRITS"] = "CLSCulprits"; + InsightKeys2["THIRD_PARTIES"] = "ThirdParties"; + InsightKeys2["DOCUMENT_LATENCY"] = "DocumentLatency"; + InsightKeys2["DOM_SIZE"] = "DOMSize"; + InsightKeys2["DUPLICATE_JAVASCRIPT"] = "DuplicatedJavaScript"; + InsightKeys2["FONT_DISPLAY"] = "FontDisplay"; + InsightKeys2["FORCED_REFLOW"] = "ForcedReflow"; + InsightKeys2["IMAGE_DELIVERY"] = "ImageDelivery"; + InsightKeys2["LCP_DISCOVERY"] = "LCPDiscovery"; + InsightKeys2["LEGACY_JAVASCRIPT"] = "LegacyJavaScript"; + InsightKeys2["NETWORK_DEPENDENCY_TREE"] = "NetworkDependencyTree"; + InsightKeys2["RENDER_BLOCKING"] = "RenderBlocking"; + InsightKeys2["SLOW_CSS_SELECTOR"] = "SlowCSSSelector"; + InsightKeys2["VIEWPORT"] = "Viewport"; + InsightKeys2["MODERN_HTTP"] = "ModernHTTP"; + InsightKeys2["CACHE"] = "Cache"; + })(InsightKeys || (InsightKeys = {})); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/Common.js +var Common_exports = {}; +__export(Common_exports, { + calculateDocFirstByteTs: () => calculateDocFirstByteTs, + calculateMetricWeightsForSorting: () => calculateMetricWeightsForSorting, + estimateCompressedContentSize: () => estimateCompressedContentSize, + estimateCompressionRatioForScript: () => estimateCompressionRatioForScript, + evaluateCLSMetricScore: () => evaluateCLSMetricScore, + evaluateINPMetricScore: () => evaluateINPMetricScore, + evaluateLCPMetricScore: () => evaluateLCPMetricScore, + getCLS: () => getCLS, + getFieldMetricsForInsightSet: () => getFieldMetricsForInsightSet, + getINP: () => getINP, + getInsight: () => getInsight, + getLCP: () => getLCP, + insightBounds: () => insightBounds, + isRequestCompressed: () => isRequestCompressed, + isRequestServedFromBrowserCache: () => isRequestServedFromBrowserCache, + metricSavingsForWastedBytes: () => metricSavingsForWastedBytes +}); +function getInsight(insightName, insightSet) { + const insight = insightSet.model[insightName]; + if (insight instanceof Error) { + return null; + } + return insight; +} +function getLCP(insightSet) { + const insight = getInsight(InsightKeys.LCP_BREAKDOWN, insightSet); + if (!insight || !insight.lcpMs || !insight.lcpEvent) { + return null; + } + const value = Timing_exports3.milliToMicro(insight.lcpMs); + return { value, event: insight.lcpEvent }; +} +function getINP(insightSet) { + const insight = getInsight(InsightKeys.INP_BREAKDOWN, insightSet); + if (!insight?.longestInteractionEvent?.dur) { + return null; + } + const value = insight.longestInteractionEvent.dur; + return { value, event: insight.longestInteractionEvent }; +} +function getCLS(insightSet) { + const insight = getInsight(InsightKeys.CLS_CULPRITS, insightSet); + if (!insight) { + return { value: 0, worstClusterEvent: null }; + } + let maxScore = 0; + let worstCluster; + for (const cluster of insight.clusters) { + if (cluster.clusterCumulativeScore > maxScore) { + maxScore = cluster.clusterCumulativeScore; + worstCluster = cluster; + } + } + return { value: maxScore, worstClusterEvent: worstCluster ?? null }; +} +function evaluateLCPMetricScore(value) { + return getLogNormalScore2({ p10: 2500, median: 4e3 }, value); +} +function evaluateINPMetricScore(value) { + return getLogNormalScore2({ p10: 200, median: 500 }, value); +} +function evaluateCLSMetricScore(value) { + return getLogNormalScore2({ p10: 0.1, median: 0.25 }, value); +} +function getPageResult(cruxFieldData, url, origin, scope = null) { + return cruxFieldData.find((result) => { + const key = scope ? result[`${scope.pageScope}-${scope.deviceScope}`]?.record.key : (result["url-ALL"] || result["origin-ALL"])?.record.key; + return key?.url && key.url === url || key?.origin && key.origin === origin; + }); +} +function getMetricResult(pageResult, name, scope = null) { + const scopes = []; + if (scope) { + scopes.push(scope); + } else { + scopes.push({ pageScope: "url", deviceScope: "ALL" }); + scopes.push({ pageScope: "origin", deviceScope: "ALL" }); + } + for (const scope2 of scopes) { + const key = `${scope2.pageScope}-${scope2.deviceScope}`; + let value = pageResult[key]?.record.metrics[name]?.percentiles?.p75; + if (typeof value === "string") { + value = Number(value); + } + if (typeof value === "number" && Number.isFinite(value)) { + return { value, pageScope: scope2.pageScope }; + } + } + return null; +} +function getMetricTimingResult(pageResult, name, scope = null) { + const result = getMetricResult(pageResult, name, scope); + if (result) { + const valueMs = result.value; + return { value: Timing_exports3.milliToMicro(valueMs), pageScope: result.pageScope }; + } + return null; +} +function getFieldMetricsForInsightSet(insightSet, metadata, scope = null) { + const cruxFieldData = metadata?.cruxFieldData; + if (!cruxFieldData) { + return null; + } + const pageResult = getPageResult(cruxFieldData, insightSet.url.href, insightSet.url.origin, scope); + if (!pageResult) { + return null; + } + return { + fcp: getMetricTimingResult(pageResult, "first_contentful_paint", scope), + lcp: getMetricTimingResult(pageResult, "largest_contentful_paint", scope), + inp: getMetricTimingResult(pageResult, "interaction_to_next_paint", scope), + cls: getMetricResult(pageResult, "cumulative_layout_shift", scope), + lcpBreakdown: { + ttfb: getMetricTimingResult(pageResult, "largest_contentful_paint_image_time_to_first_byte", scope), + loadDelay: getMetricTimingResult(pageResult, "largest_contentful_paint_image_resource_load_delay", scope), + loadDuration: getMetricTimingResult(pageResult, "largest_contentful_paint_image_resource_load_duration", scope), + renderDelay: getMetricTimingResult(pageResult, "largest_contentful_paint_image_element_render_delay", scope) + } + }; +} +function calculateMetricWeightsForSorting(insightSet, metadata) { + const weights = { + lcp: 1 / 3, + inp: 1 / 3, + cls: 1 / 3 + }; + const cruxFieldData = metadata?.cruxFieldData; + if (!cruxFieldData) { + return weights; + } + const fieldMetrics = getFieldMetricsForInsightSet(insightSet, metadata); + if (!fieldMetrics) { + return weights; + } + const fieldLcp = fieldMetrics.lcp?.value ?? null; + const fieldInp = fieldMetrics.inp?.value ?? null; + const fieldCls = fieldMetrics.cls?.value ?? null; + const fieldLcpScore = fieldLcp !== null ? evaluateLCPMetricScore(Timing_exports3.microToMilli(fieldLcp)) : 0; + const fieldInpScore = fieldInp !== null ? evaluateINPMetricScore(Timing_exports3.microToMilli(fieldInp)) : 0; + const fieldClsScore = fieldCls !== null ? evaluateCLSMetricScore(fieldCls) : 0; + const fieldLcpScoreInverted = 1 - fieldLcpScore; + const fieldInpScoreInverted = 1 - fieldInpScore; + const fieldClsScoreInverted = 1 - fieldClsScore; + const invertedSum = fieldLcpScoreInverted + fieldInpScoreInverted + fieldClsScoreInverted; + if (!invertedSum) { + return weights; + } + weights.lcp = fieldLcpScoreInverted / invertedSum; + weights.inp = fieldInpScoreInverted / invertedSum; + weights.cls = fieldClsScoreInverted / invertedSum; + return weights; +} +function estimateSavingsWithGraphs(wastedBytesByRequestId, simulator, graph2) { + const simulationBeforeChanges = simulator.simulate(graph2); + const originalTransferSizes = /* @__PURE__ */ new Map(); + graph2.traverse((node) => { + if (node.type !== "network") { + return; + } + const wastedBytes = wastedBytesByRequestId.get(node.request.requestId); + if (!wastedBytes) { + return; + } + const original = node.request.transferSize; + originalTransferSizes.set(node.request.requestId, original); + node.request.transferSize = Math.max(original - wastedBytes, 0); + }); + const simulationAfterChanges = simulator.simulate(graph2); + graph2.traverse((node) => { + if (node.type !== "network") { + return; + } + const originalTransferSize = originalTransferSizes.get(node.request.requestId); + if (originalTransferSize === void 0) { + return; + } + node.request.transferSize = originalTransferSize; + }); + let savings = simulationBeforeChanges.timeInMs - simulationAfterChanges.timeInMs; + savings = Math.round(savings / GRAPH_SAVINGS_PRECISION) * GRAPH_SAVINGS_PRECISION; + return Timing_exports.Milli(savings); +} +function metricSavingsForWastedBytes(wastedBytesByRequestId, context) { + if (!context.navigation || !context.lantern) { + return; + } + if (!wastedBytesByRequestId.size) { + return { FCP: Timing_exports.Milli(0), LCP: Timing_exports.Milli(0) }; + } + const simulator = context.lantern.simulator; + const fcpGraph = context.lantern.metrics.firstContentfulPaint.optimisticGraph; + const lcpGraph = context.lantern.metrics.largestContentfulPaint.optimisticGraph; + return { + FCP: estimateSavingsWithGraphs(wastedBytesByRequestId, simulator, fcpGraph), + LCP: estimateSavingsWithGraphs(wastedBytesByRequestId, simulator, lcpGraph) + }; +} +function isRequestCompressed(request) { + if (!request.args.data.responseHeaders) { + return false; + } + const patterns = [ + /^content-encoding$/i, + /^x-content-encoding-over-network$/i, + /^x-original-content-encoding$/i + // Lightrider. + ]; + const compressionTypes = ["gzip", "br", "deflate", "zstd"]; + return request.args.data.responseHeaders.some((header) => patterns.some((p) => header.name.match(p)) && compressionTypes.includes(header.value)); +} +function isRequestServedFromBrowserCache(request) { + if (!request.args.data.responseHeaders || request.args.data.failed) { + return false; + } + if (request.args.data.statusCode === 304) { + return true; + } + const { transferSize, resourceSize } = getRequestSizes(request); + const ratio = resourceSize ? transferSize / resourceSize : 0; + if (ratio < 0.01) { + return true; + } + return false; +} +function getRequestSizes(request) { + const resourceSize = request.args.data.decodedBodyLength; + const transferSize = request.args.data.encodedDataLength; + return { resourceSize, transferSize }; +} +function estimateCompressedContentSize(request, totalBytes, resourceType) { + if (!request || isRequestServedFromBrowserCache(request)) { + switch (resourceType) { + case "Stylesheet": + return Math.round(totalBytes * 0.2); + case "Script": + case "Document": + return Math.round(totalBytes * 0.33); + default: + return Math.round(totalBytes * 0.5); + } + } + const { transferSize, resourceSize } = getRequestSizes(request); + let contentTransferSize = transferSize; + if (!isRequestCompressed(request)) { + contentTransferSize = resourceSize; + } + if (request.args.data.resourceType === resourceType) { + return contentTransferSize; + } + const compressionRatio = Number.isFinite(resourceSize) && resourceSize > 0 ? contentTransferSize / resourceSize : 1; + return Math.round(totalBytes * compressionRatio); +} +function estimateCompressionRatioForScript(script) { + if (!script.request) { + return 1; + } + const request = script.request; + const contentLength = request.args.data.decodedBodyLength ?? script.content?.length ?? 0; + const compressedSize = estimateCompressedContentSize( + request, + contentLength, + "Script" + /* Protocol.Network.ResourceType.Script */ + ); + if (contentLength === 0 || compressedSize === 0) { + return 1; + } + const compressionRatio = compressedSize / contentLength; + return compressionRatio; +} +function calculateDocFirstByteTs(docRequest) { + if (docRequest.args.data.protocol === "file") { + return docRequest.ts; + } + const timing = docRequest.args.data.timing; + if (!timing) { + return null; + } + return Timing_exports.Micro(Timing_exports3.secondsToMicro(timing.requestTime) + Timing_exports3.milliToMicro(timing.receiveHeadersStart ?? timing.receiveHeadersEnd)); +} +function insightBounds(insight, insightSetBounds) { + const overlays = insight.createOverlays?.() ?? []; + const windows = overlays.map(Timing_exports3.traceWindowFromOverlay).filter((bounds) => !!bounds); + const overlaysBounds = Timing_exports3.combineTraceWindowsMicro(windows); + if (overlaysBounds) { + return overlaysBounds; + } + return insightSetBounds; +} +var GRAPH_SAVINGS_PRECISION; +var init_Common = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/Common.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + init_Statistics(); + init_types4(); + GRAPH_SAVINGS_PRECISION = 50; + __name(getInsight, "getInsight"); + __name(getLCP, "getLCP"); + __name(getINP, "getINP"); + __name(getCLS, "getCLS"); + __name(evaluateLCPMetricScore, "evaluateLCPMetricScore"); + __name(evaluateINPMetricScore, "evaluateINPMetricScore"); + __name(evaluateCLSMetricScore, "evaluateCLSMetricScore"); + __name(getPageResult, "getPageResult"); + __name(getMetricResult, "getMetricResult"); + __name(getMetricTimingResult, "getMetricTimingResult"); + __name(getFieldMetricsForInsightSet, "getFieldMetricsForInsightSet"); + __name(calculateMetricWeightsForSorting, "calculateMetricWeightsForSorting"); + __name(estimateSavingsWithGraphs, "estimateSavingsWithGraphs"); + __name(metricSavingsForWastedBytes, "metricSavingsForWastedBytes"); + __name(isRequestCompressed, "isRequestCompressed"); + __name(isRequestServedFromBrowserCache, "isRequestServedFromBrowserCache"); + __name(getRequestSizes, "getRequestSizes"); + __name(estimateCompressedContentSize, "estimateCompressedContentSize"); + __name(estimateCompressionRatioForScript, "estimateCompressionRatioForScript"); + __name(calculateDocFirstByteTs, "calculateDocFirstByteTs"); + __name(insightBounds, "insightBounds"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/Cache.js +var Cache_exports = {}; +__export(Cache_exports, { + UIStrings: () => UIStrings2, + cachingDisabled: () => cachingDisabled, + computeCacheLifetimeInSeconds: () => computeCacheLifetimeInSeconds, + createOverlayForRequest: () => createOverlayForRequest, + createOverlays: () => createOverlays, + generateInsight: () => generateInsight, + getCombinedHeaders: () => getCombinedHeaders, + i18nString: () => i18nString, + isCacheInsight: () => isCacheInsight, + isCacheable: () => isCacheable +}); +function finalize31(partialModel) { + return { + insightKey: InsightKeys.CACHE, + strings: UIStrings2, + title: i18nString(UIStrings2.title), + description: i18nString(UIStrings2.description), + docs: "https://developer.chrome.com/docs/performance/insights/cache", + category: InsightCategory.ALL, + state: partialModel.requests.length > 0 ? "fail" : "pass", + ...partialModel + }; +} +function isCacheable(request) { + if (Network_exports.NON_NETWORK_SCHEMES.includes(request.args.data.protocol)) { + return false; + } + return Boolean(Network_exports.CACHEABLE_STATUS_CODES.has(request.args.data.statusCode) && Network_exports.STATIC_RESOURCE_TYPES.has( + request.args.data.resourceType || "Other" + /* Protocol.Network.ResourceType.Other */ + )); +} +function computeCacheLifetimeInSeconds(headers, cacheControl) { + if (cacheControl?.["max-age"] !== void 0) { + return cacheControl["max-age"]; + } + const expiresHeaders = headers.find((h) => h.name === "expires")?.value ?? null; + if (expiresHeaders) { + const expires = new Date(expiresHeaders).getTime(); + if (!expires) { + return 0; + } + return Math.ceil((expires - Date.now()) / 1e3); + } + return null; +} +function getCacheHitProbability(maxAgeInSeconds) { + const RESOURCE_AGE_IN_HOURS_DECILES = [0, 0.2, 1, 3, 8, 12, 24, 48, 72, 168, 8760, Infinity]; + const maxAgeInHours = maxAgeInSeconds / 3600; + const upperDecileIndex = RESOURCE_AGE_IN_HOURS_DECILES.findIndex((decile) => decile >= maxAgeInHours); + if (upperDecileIndex === RESOURCE_AGE_IN_HOURS_DECILES.length - 1) { + return 1; + } + if (upperDecileIndex === 0) { + return 0; + } + const upperDecileValue = RESOURCE_AGE_IN_HOURS_DECILES[upperDecileIndex]; + const lowerDecileValue = RESOURCE_AGE_IN_HOURS_DECILES[upperDecileIndex - 1]; + const upperDecile = upperDecileIndex / 10; + const lowerDecile = (upperDecileIndex - 1) / 10; + return linearInterpolation(lowerDecileValue, lowerDecile, upperDecileValue, upperDecile, maxAgeInHours); +} +function getCombinedHeaders(responseHeaders) { + const headers = /* @__PURE__ */ new Map(); + for (const header of responseHeaders) { + const name = header.name.toLowerCase(); + if (headers.get(name)) { + headers.set(name, `${headers.get(name)}, ${header.value}`); + } else { + headers.set(name, header.value); + } + } + return headers; +} +function cachingDisabled(headers, parsedCacheControl) { + const cacheControl = headers?.get("cache-control") ?? null; + const pragma = headers?.get("pragma") ?? null; + if (!cacheControl && pragma?.includes("no-cache")) { + return true; + } + if (parsedCacheControl && (parsedCacheControl["must-revalidate"] || parsedCacheControl["no-cache"] || parsedCacheControl["no-store"] || parsedCacheControl["private"])) { + return true; + } + return false; +} +function isCacheInsight(model2) { + return model2.insightKey === InsightKeys.CACHE; +} +function generateInsight(data31, context) { + const isWithinContext = /* @__PURE__ */ __name((event) => Timing_exports3.eventIsInBounds(event, context.bounds), "isWithinContext"); + const contextRequests = data31.NetworkRequests.byTime.filter(isWithinContext); + const results = []; + let totalWastedBytes = 0; + const wastedBytesByRequestId = /* @__PURE__ */ new Map(); + for (const req of contextRequests) { + if (!req.args.data.responseHeaders || !isCacheable(req)) { + continue; + } + const headers = getCombinedHeaders(req.args.data.responseHeaders); + const cacheControl = headers.get("cache-control") ?? null; + const parsedDirectives = Network_exports.parseCacheControl(cacheControl); + if (cachingDisabled(headers, parsedDirectives)) { + continue; + } + let ttl = computeCacheLifetimeInSeconds(req.args.data.responseHeaders, parsedDirectives); + if (ttl !== null && (!Number.isFinite(ttl) || ttl <= 0)) { + continue; + } + ttl = ttl || 0; + const ttlDays = ttl / 86400; + if (ttlDays >= 30) { + continue; + } + const cacheHitProbability = getCacheHitProbability(ttl); + if (cacheHitProbability > IGNORE_THRESHOLD_IN_PERCENT) { + continue; + } + const transferSize = req.args.data.encodedDataLength || 0; + const wastedBytes = (1 - cacheHitProbability) * transferSize; + wastedBytesByRequestId.set(req.args.data.requestId, wastedBytes); + totalWastedBytes += wastedBytes; + results.push({ request: req, ttl, wastedBytes }); + } + results.sort((a, b) => { + return b.request.args.data.decodedBodyLength - a.request.args.data.decodedBodyLength || a.ttl - b.ttl; + }); + return finalize31({ + relatedEvents: results.map((r) => r.request), + requests: results, + metricSavings: metricSavingsForWastedBytes(wastedBytesByRequestId, context), + wastedBytes: totalWastedBytes + }); +} +function createOverlayForRequest(request) { + return { + type: "ENTRY_OUTLINE", + entry: request, + outlineReason: "ERROR" + }; +} +function createOverlays(model2) { + return model2.requests.map((req) => createOverlayForRequest(req.request)); +} +var UIStrings2, i18nString, IGNORE_THRESHOLD_IN_PERCENT; +var init_Cache = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/Cache.js"() { + init_process_global(); + init_helpers2(); + init_Common(); + init_Statistics(); + init_types4(); + UIStrings2 = { + /** + * @description Title of an insight that provides information and suggestions of resources that could improve their caching. + */ + title: "Use efficient cache lifetimes", + /** + * @description Text to tell the user about how caching can help improve performance. + */ + description: "A long cache lifetime can speed up repeat visits to your page. [Learn more about caching](https://developer.chrome.com/docs/performance/insights/cache).", + /** + * @description Column for a font loaded by the page to render text. + */ + requestColumn: "Request", + /** + * @description Column for a resource cache's Time To Live. + */ + cacheTTL: "Cache TTL", + /** + * @description Text describing that there were no requests found that need caching. + */ + noRequestsToCache: "No requests with inefficient cache policies", + /** + * @description Table row value representing the remaining items not shown in the table due to size constraints. This row will always represent at least 2 items. + * @example {5} PH1 + */ + others: "{PH1} others" + }; + i18nString = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + IGNORE_THRESHOLD_IN_PERCENT = 0.925; + __name(finalize31, "finalize"); + __name(isCacheable, "isCacheable"); + __name(computeCacheLifetimeInSeconds, "computeCacheLifetimeInSeconds"); + __name(getCacheHitProbability, "getCacheHitProbability"); + __name(getCombinedHeaders, "getCombinedHeaders"); + __name(cachingDisabled, "cachingDisabled"); + __name(isCacheInsight, "isCacheInsight"); + __name(generateInsight, "generateInsight"); + __name(createOverlayForRequest, "createOverlayForRequest"); + __name(createOverlays, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/CLSCulprits.js +var CLSCulprits_exports = {}; +__export(CLSCulprits_exports, { + AnimationFailureReasons: () => AnimationFailureReasons, + LayoutShiftType: () => LayoutShiftType, + UIStrings: () => UIStrings3, + createOverlays: () => createOverlays2, + generateInsight: () => generateInsight2, + getNonCompositedFailure: () => getNonCompositedFailure, + i18nString: () => i18nString2, + isCLSCulpritsInsight: () => isCLSCulpritsInsight +}); +function isInRootCauseWindow(event, targetEvent) { + const eventEnd = event.dur ? event.ts + event.dur : event.ts; + return eventEnd < targetEvent.ts && eventEnd >= targetEvent.ts - ROOT_CAUSE_WINDOW; +} +function getNonCompositedFailure(animationEvent) { + const failures = []; + const beginEvent = animationEvent.args.data.beginEvent; + const instantEvents = animationEvent.args.data.instantEvents || []; + for (const event of instantEvents) { + const failureMask = event.args.data.compositeFailed; + const unsupportedProperties = event.args.data.unsupportedProperties; + if (!failureMask) { + continue; + } + const failureReasons = ACTIONABLE_FAILURE_REASONS.filter((reason) => failureMask & reason.flag).map((reason) => reason.failure); + const failure = { + name: beginEvent.args.data.displayName, + failureReasons, + unsupportedProperties, + animation: animationEvent + }; + failures.push(failure); + } + return failures; +} +function getNonCompositedFailureRootCauses(animationEvents, prePaintEvents2, shiftsByPrePaint, rootCausesByShift) { + const allAnimationFailures = []; + for (const animation of animationEvents) { + const failures = getNonCompositedFailure(animation); + if (!failures) { + continue; + } + allAnimationFailures.push(...failures); + const nextPrePaint = getNextEvent(prePaintEvents2, animation); + if (!nextPrePaint) { + continue; + } + if (!isInRootCauseWindow(animation, nextPrePaint)) { + continue; + } + const shifts = shiftsByPrePaint.get(nextPrePaint); + if (!shifts) { + continue; + } + for (const shift of shifts) { + const rootCausesForShift = rootCausesByShift.get(shift); + if (!rootCausesForShift) { + throw new Error("Unaccounted shift"); + } + rootCausesForShift.nonCompositedAnimations.push(...failures); + } + } + return allAnimationFailures; +} +function getShiftsByPrePaintEvents(layoutShifts, prePaintEvents2) { + const shiftsByPrePaint = /* @__PURE__ */ new Map(); + for (const prePaintEvent of prePaintEvents2) { + const firstShiftIndex = ArrayUtilities_exports.nearestIndexFromBeginning(layoutShifts, (shift) => shift.ts >= prePaintEvent.ts); + if (firstShiftIndex === null) { + continue; + } + for (let i = firstShiftIndex; i < layoutShifts.length; i++) { + const shift = layoutShifts[i]; + if (shift.ts >= prePaintEvent.ts && shift.ts <= prePaintEvent.ts + prePaintEvent.dur) { + const shiftsInPrePaint = MapUtilities_exports.getWithDefault(shiftsByPrePaint, prePaintEvent, () => []); + shiftsInPrePaint.push(shift); + } + if (shift.ts > prePaintEvent.ts + prePaintEvent.dur) { + break; + } + } + } + return shiftsByPrePaint; +} +function getNextEvent(sourceEvents, targetEvent) { + const index = ArrayUtilities_exports.nearestIndexFromBeginning(sourceEvents, (source) => source.ts > targetEvent.ts + (targetEvent.dur || 0)); + if (index === null) { + return void 0; + } + return sourceEvents[index]; +} +function getIframeRootCauses(data31, iframeCreatedEvents, prePaintEvents2, shiftsByPrePaint, rootCausesByShift, domLoadingEvents2) { + for (const iframeEvent of iframeCreatedEvents) { + const nextPrePaint = getNextEvent(prePaintEvents2, iframeEvent); + if (!nextPrePaint) { + continue; + } + const shifts = shiftsByPrePaint.get(nextPrePaint); + if (!shifts) { + continue; + } + for (const shift of shifts) { + const rootCausesForShift = rootCausesByShift.get(shift); + if (!rootCausesForShift) { + throw new Error("Unaccounted shift"); + } + const domEvent = domLoadingEvents2.find((e) => { + const maxIframe = Timing_exports.Micro(iframeEvent.ts + (iframeEvent.dur ?? 0)); + return e.ts >= iframeEvent.ts && e.ts <= maxIframe; + }); + if (domEvent?.args.frame) { + const frame = domEvent.args.frame; + let url; + const processes2 = data31.Meta.rendererProcessesByFrame.get(frame); + if (processes2 && processes2.size > 0) { + url = [...processes2.values()][0]?.[0].frame.url; + } + rootCausesForShift.iframes.push({ frame, url }); + } + } + } + return rootCausesByShift; +} +function getUnsizedImageRootCauses(unsizedImageEvents, paintImageEvents3, shiftsByPrePaint, rootCausesByShift) { + shiftsByPrePaint.forEach((shifts, prePaint) => { + const paintImage = getNextEvent(paintImageEvents3, prePaint); + if (!paintImage) { + return; + } + const matchingNode = unsizedImageEvents.find((unsizedImage) => unsizedImage.args.data.nodeId === paintImage.args.data.nodeId); + if (!matchingNode) { + return; + } + for (const shift of shifts) { + const rootCausesForShift = rootCausesByShift.get(shift); + if (!rootCausesForShift) { + throw new Error("Unaccounted shift"); + } + rootCausesForShift.unsizedImages.push({ + backendNodeId: matchingNode.args.data.nodeId, + paintImageEvent: paintImage + }); + } + }); + return rootCausesByShift; +} +function isCLSCulpritsInsight(insight) { + return insight.insightKey === InsightKeys.CLS_CULPRITS; +} +function getFontRootCauses(networkRequests, prePaintEvents2, shiftsByPrePaint, rootCausesByShift) { + const fontRequests = networkRequests.filter((req) => req.args.data.resourceType === "Font" && req.args.data.mimeType.startsWith("font")); + for (const req of fontRequests) { + const nextPrePaint = getNextEvent(prePaintEvents2, req); + if (!nextPrePaint) { + continue; + } + if (!isInRootCauseWindow(req, nextPrePaint)) { + continue; + } + const shifts = shiftsByPrePaint.get(nextPrePaint); + if (!shifts) { + continue; + } + for (const shift of shifts) { + const rootCausesForShift = rootCausesByShift.get(shift); + if (!rootCausesForShift) { + throw new Error("Unaccounted shift"); + } + rootCausesForShift.webFonts.push(req); + } + } + return rootCausesByShift; +} +function getTopCulprits(cluster, culpritsByShift) { + const MAX_TOP_CULPRITS = 3; + const causes = []; + const shifts = cluster.events; + for (const shift of shifts) { + const culprits = culpritsByShift.get(shift); + if (!culprits) { + continue; + } + const fontReq = culprits.webFonts; + const iframes = culprits.iframes; + const animations2 = culprits.nonCompositedAnimations; + const unsizedImages = culprits.unsizedImages; + for (let i = 0; i < fontReq.length && causes.length < MAX_TOP_CULPRITS; i++) { + causes.push({ type: LayoutShiftType.WEB_FONT, description: i18nString2(UIStrings3.webFont) }); + } + for (let i = 0; i < iframes.length && causes.length < MAX_TOP_CULPRITS; i++) { + causes.push({ type: LayoutShiftType.IFRAMES, description: i18nString2(UIStrings3.injectedIframe) }); + } + for (let i = 0; i < animations2.length && causes.length < MAX_TOP_CULPRITS; i++) { + causes.push({ type: LayoutShiftType.ANIMATIONS, description: i18nString2(UIStrings3.animation) }); + } + for (let i = 0; i < unsizedImages.length && causes.length < MAX_TOP_CULPRITS; i++) { + causes.push({ + type: LayoutShiftType.UNSIZED_IMAGE, + description: i18nString2(UIStrings3.unsizedImage), + url: unsizedImages[i].paintImageEvent.args.data.url || "", + backendNodeId: unsizedImages[i].backendNodeId, + frame: unsizedImages[i].paintImageEvent.args.data.frame || "" + }); + } + if (causes.length >= MAX_TOP_CULPRITS) { + break; + } + } + return causes.slice(0, MAX_TOP_CULPRITS); +} +function finalize32(partialModel) { + let state = "pass"; + if (partialModel.worstCluster) { + const classification = ModelHandlers_exports.LayoutShifts.scoreClassificationForLayoutShift(partialModel.worstCluster.clusterCumulativeScore); + if (classification === ModelHandlers_exports.PageLoadMetrics.ScoreClassification.GOOD) { + state = "informative"; + } else { + state = "fail"; + } + } + return { + insightKey: InsightKeys.CLS_CULPRITS, + strings: UIStrings3, + title: i18nString2(UIStrings3.title), + description: i18nString2(UIStrings3.description), + docs: "https://developer.chrome.com/docs/performance/insights/cls-culprit", + category: InsightCategory.CLS, + state, + ...partialModel + }; +} +function generateInsight2(data31, context) { + const isWithinContext = /* @__PURE__ */ __name((event) => Timing_exports3.eventIsInBounds(event, context.bounds), "isWithinContext"); + const compositeAnimationEvents = data31.Animations.animations.filter(isWithinContext); + const iframeEvents = data31.LayoutShifts.renderFrameImplCreateChildFrameEvents.filter(isWithinContext); + const networkRequests = data31.NetworkRequests.byTime.filter(isWithinContext); + const domLoadingEvents2 = data31.LayoutShifts.domLoadingEvents.filter(isWithinContext); + const unsizedImageEvents = data31.LayoutShifts.layoutImageUnsizedEvents.filter(isWithinContext); + const clusterKey = context.navigation ? context.navigationId : TraceEvents_exports.NO_NAVIGATION; + const clusters2 = data31.LayoutShifts.clustersByNavigationId.get(clusterKey) ?? []; + const clustersByScore = [...clusters2].sort((a, b) => b.clusterCumulativeScore - a.clusterCumulativeScore); + const worstCluster = clustersByScore.at(0); + const layoutShifts = clusters2.flatMap((cluster) => cluster.events); + const prePaintEvents2 = data31.LayoutShifts.prePaintEvents.filter(isWithinContext); + const paintImageEvents3 = data31.LayoutShifts.paintImageEvents.filter(isWithinContext); + const rootCausesByShift = /* @__PURE__ */ new Map(); + const shiftsByPrePaint = getShiftsByPrePaintEvents(layoutShifts, prePaintEvents2); + for (const shift of layoutShifts) { + rootCausesByShift.set(shift, { iframes: [], webFonts: [], nonCompositedAnimations: [], unsizedImages: [] }); + } + getIframeRootCauses(data31, iframeEvents, prePaintEvents2, shiftsByPrePaint, rootCausesByShift, domLoadingEvents2); + getFontRootCauses(networkRequests, prePaintEvents2, shiftsByPrePaint, rootCausesByShift); + getUnsizedImageRootCauses(unsizedImageEvents, paintImageEvents3, shiftsByPrePaint, rootCausesByShift); + const animationFailures = getNonCompositedFailureRootCauses(compositeAnimationEvents, prePaintEvents2, shiftsByPrePaint, rootCausesByShift); + const relatedEvents = [...layoutShifts]; + if (worstCluster) { + relatedEvents.push(worstCluster); + } + const topCulpritsByCluster = /* @__PURE__ */ new Map(); + for (const cluster of clusters2) { + topCulpritsByCluster.set(cluster, getTopCulprits(cluster, rootCausesByShift)); + } + return finalize32({ + relatedEvents, + animationFailures, + shifts: rootCausesByShift, + clusters: clusters2, + worstCluster, + topCulpritsByCluster + }); +} +function createOverlays2(model2) { + const clustersByScore = model2.clusters.toSorted((a, b) => b.clusterCumulativeScore - a.clusterCumulativeScore) ?? []; + const worstCluster = clustersByScore[0]; + if (!worstCluster) { + return []; + } + const range = Timing_exports.Micro(worstCluster.dur ?? 0); + const max = Timing_exports.Micro(worstCluster.ts + range); + return [{ + type: "TIMESPAN_BREAKDOWN", + sections: [ + { + bounds: { min: worstCluster.ts, range, max }, + label: i18nString2(UIStrings3.worstLayoutShiftCluster), + showDuration: false + } + ], + // This allows for the overlay to sit over the layout shift. + entry: worstCluster.events[0], + renderLocation: "ABOVE_EVENT" + }]; +} +var UIStrings3, i18nString2, AnimationFailureReasons, LayoutShiftType, ACTIONABLE_FAILURE_REASONS, ROOT_CAUSE_WINDOW; +var init_CLSCulprits = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/CLSCulprits.js"() { + init_process_global(); + init_platform(); + init_handlers(); + init_helpers2(); + init_types2(); + init_types4(); + UIStrings3 = { + /** Title of an insight that provides details about why elements shift/move on the page. The causes for these shifts are referred to as culprits ("reasons"). */ + title: "Layout shift culprits", + /** + * @description Description of a DevTools insight that identifies the reasons that elements shift on the page. + * This is displayed after a user expands the section to see more. No character length limits. + */ + description: "Layout shifts occur when elements move absent any user interaction. [Investigate the causes of layout shifts](https://developer.chrome.com/docs/performance/insights/cls-culprit), such as elements being added, removed, or their fonts changing as the page loads.", + /** + * @description Text indicating the worst layout shift cluster. + */ + worstLayoutShiftCluster: "Worst layout shift cluster", + /** + * @description Text indicating the worst layout shift cluster. + */ + worstCluster: "Worst cluster", + /** + * @description Text indicating a layout shift cluster and its start time. + * @example {32 ms} PH1 + */ + layoutShiftCluster: "Layout shift cluster @ {PH1}", + /** + * @description Text indicating the biggest reasons for the layout shifts. + */ + topCulprits: "Top layout shift culprits", + /** + * @description Text for a culprit type of Injected iframe. + */ + injectedIframe: "Injected iframe", + /** + * @description Text for a culprit type of web font request. + */ + webFont: "Web font", + /** + * @description Text for a culprit type of Animation. + */ + animation: "Animation", + /** + * @description Text for a culprit type of Unsized image. + */ + unsizedImage: "Unsized image element", + /** + * @description Text status when there were no layout shifts detected. + */ + noLayoutShifts: "No layout shifts", + /** + * @description Text status when there no layout shifts culprits/root causes were found. + */ + noCulprits: "Could not detect any layout shift culprits" + }; + i18nString2 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + (function(AnimationFailureReasons2) { + AnimationFailureReasons2["ACCELERATED_ANIMATIONS_DISABLED"] = "ACCELERATED_ANIMATIONS_DISABLED"; + AnimationFailureReasons2["EFFECT_SUPPRESSED_BY_DEVTOOLS"] = "EFFECT_SUPPRESSED_BY_DEVTOOLS"; + AnimationFailureReasons2["INVALID_ANIMATION_OR_EFFECT"] = "INVALID_ANIMATION_OR_EFFECT"; + AnimationFailureReasons2["EFFECT_HAS_UNSUPPORTED_TIMING_PARAMS"] = "EFFECT_HAS_UNSUPPORTED_TIMING_PARAMS"; + AnimationFailureReasons2["EFFECT_HAS_NON_REPLACE_COMPOSITE_MODE"] = "EFFECT_HAS_NON_REPLACE_COMPOSITE_MODE"; + AnimationFailureReasons2["TARGET_HAS_INVALID_COMPOSITING_STATE"] = "TARGET_HAS_INVALID_COMPOSITING_STATE"; + AnimationFailureReasons2["TARGET_HAS_INCOMPATIBLE_ANIMATIONS"] = "TARGET_HAS_INCOMPATIBLE_ANIMATIONS"; + AnimationFailureReasons2["TARGET_HAS_CSS_OFFSET"] = "TARGET_HAS_CSS_OFFSET"; + AnimationFailureReasons2["ANIMATION_AFFECTS_NON_CSS_PROPERTIES"] = "ANIMATION_AFFECTS_NON_CSS_PROPERTIES"; + AnimationFailureReasons2["TRANSFORM_RELATED_PROPERTY_CANNOT_BE_ACCELERATED_ON_TARGET"] = "TRANSFORM_RELATED_PROPERTY_CANNOT_BE_ACCELERATED_ON_TARGET"; + AnimationFailureReasons2["TRANSFROM_BOX_SIZE_DEPENDENT"] = "TRANSFROM_BOX_SIZE_DEPENDENT"; + AnimationFailureReasons2["FILTER_RELATED_PROPERTY_MAY_MOVE_PIXELS"] = "FILTER_RELATED_PROPERTY_MAY_MOVE_PIXELS"; + AnimationFailureReasons2["UNSUPPORTED_CSS_PROPERTY"] = "UNSUPPORTED_CSS_PROPERTY"; + AnimationFailureReasons2["MIXED_KEYFRAME_VALUE_TYPES"] = "MIXED_KEYFRAME_VALUE_TYPES"; + AnimationFailureReasons2["TIMELINE_SOURCE_HAS_INVALID_COMPOSITING_STATE"] = "TIMELINE_SOURCE_HAS_INVALID_COMPOSITING_STATE"; + AnimationFailureReasons2["ANIMATION_HAS_NO_VISIBLE_CHANGE"] = "ANIMATION_HAS_NO_VISIBLE_CHANGE"; + AnimationFailureReasons2["AFFECTS_IMPORTANT_PROPERTY"] = "AFFECTS_IMPORTANT_PROPERTY"; + AnimationFailureReasons2["SVG_TARGET_HAS_INDEPENDENT_TRANSFORM_PROPERTY"] = "SVG_TARGET_HAS_INDEPENDENT_TRANSFORM_PROPERTY"; + })(AnimationFailureReasons || (AnimationFailureReasons = {})); + (function(LayoutShiftType2) { + LayoutShiftType2[LayoutShiftType2["WEB_FONT"] = 0] = "WEB_FONT"; + LayoutShiftType2[LayoutShiftType2["IFRAMES"] = 1] = "IFRAMES"; + LayoutShiftType2[LayoutShiftType2["ANIMATIONS"] = 2] = "ANIMATIONS"; + LayoutShiftType2[LayoutShiftType2["UNSIZED_IMAGE"] = 3] = "UNSIZED_IMAGE"; + })(LayoutShiftType || (LayoutShiftType = {})); + ACTIONABLE_FAILURE_REASONS = [ + { + flag: 1 << 0, + failure: AnimationFailureReasons.ACCELERATED_ANIMATIONS_DISABLED + }, + { + flag: 1 << 1, + failure: AnimationFailureReasons.EFFECT_SUPPRESSED_BY_DEVTOOLS + }, + { + flag: 1 << 2, + failure: AnimationFailureReasons.INVALID_ANIMATION_OR_EFFECT + }, + { + flag: 1 << 3, + failure: AnimationFailureReasons.EFFECT_HAS_UNSUPPORTED_TIMING_PARAMS + }, + { + flag: 1 << 4, + failure: AnimationFailureReasons.EFFECT_HAS_NON_REPLACE_COMPOSITE_MODE + }, + { + flag: 1 << 5, + failure: AnimationFailureReasons.TARGET_HAS_INVALID_COMPOSITING_STATE + }, + { + flag: 1 << 6, + failure: AnimationFailureReasons.TARGET_HAS_INCOMPATIBLE_ANIMATIONS + }, + { + flag: 1 << 7, + failure: AnimationFailureReasons.TARGET_HAS_CSS_OFFSET + }, + // The failure 1 << 8 is marked as obsolete in Blink + { + flag: 1 << 9, + failure: AnimationFailureReasons.ANIMATION_AFFECTS_NON_CSS_PROPERTIES + }, + { + flag: 1 << 10, + failure: AnimationFailureReasons.TRANSFORM_RELATED_PROPERTY_CANNOT_BE_ACCELERATED_ON_TARGET + }, + { + flag: 1 << 11, + failure: AnimationFailureReasons.TRANSFROM_BOX_SIZE_DEPENDENT + }, + { + flag: 1 << 12, + failure: AnimationFailureReasons.FILTER_RELATED_PROPERTY_MAY_MOVE_PIXELS + }, + { + flag: 1 << 13, + failure: AnimationFailureReasons.UNSUPPORTED_CSS_PROPERTY + }, + // The failure 1 << 14 is marked as obsolete in Blink + { + flag: 1 << 15, + failure: AnimationFailureReasons.MIXED_KEYFRAME_VALUE_TYPES + }, + { + flag: 1 << 16, + failure: AnimationFailureReasons.TIMELINE_SOURCE_HAS_INVALID_COMPOSITING_STATE + }, + { + flag: 1 << 17, + failure: AnimationFailureReasons.ANIMATION_HAS_NO_VISIBLE_CHANGE + }, + { + flag: 1 << 18, + failure: AnimationFailureReasons.AFFECTS_IMPORTANT_PROPERTY + }, + { + flag: 1 << 19, + failure: AnimationFailureReasons.SVG_TARGET_HAS_INDEPENDENT_TRANSFORM_PROPERTY + } + ]; + ROOT_CAUSE_WINDOW = Timing_exports3.secondsToMicro(Timing_exports.Seconds(0.5)); + __name(isInRootCauseWindow, "isInRootCauseWindow"); + __name(getNonCompositedFailure, "getNonCompositedFailure"); + __name(getNonCompositedFailureRootCauses, "getNonCompositedFailureRootCauses"); + __name(getShiftsByPrePaintEvents, "getShiftsByPrePaintEvents"); + __name(getNextEvent, "getNextEvent"); + __name(getIframeRootCauses, "getIframeRootCauses"); + __name(getUnsizedImageRootCauses, "getUnsizedImageRootCauses"); + __name(isCLSCulpritsInsight, "isCLSCulpritsInsight"); + __name(getFontRootCauses, "getFontRootCauses"); + __name(getTopCulprits, "getTopCulprits"); + __name(finalize32, "finalize"); + __name(generateInsight2, "generateInsight"); + __name(createOverlays2, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/DocumentLatency.js +var DocumentLatency_exports = {}; +__export(DocumentLatency_exports, { + UIStrings: () => UIStrings4, + createOverlays: () => createOverlays3, + generateInsight: () => generateInsight3, + i18nString: () => i18nString3, + isDocumentLatencyInsight: () => isDocumentLatencyInsight +}); +function isDocumentLatencyInsight(x) { + return x.insightKey === "DocumentLatency"; +} +function getServerResponseTime(request) { + const isLightrider = globalThis.isLightrider; + if (isLightrider) { + return request.args.data.lrServerResponseTime ?? null; + } + const timing = request.args.data.timing; + if (!timing) { + return null; + } + const ms = Timing_exports3.microToMilli(request.args.data.syntheticData.serverResponseTime); + return Math.round(ms); +} +function getCompressionSavings(request) { + const isCompressed = isRequestCompressed(request); + if (isCompressed) { + return 0; + } + const originalSize = request.args.data.decodedBodyLength; + let estimatedSavings = 0; + switch (request.args.data.mimeType) { + case "text/css": + estimatedSavings = Math.round(originalSize * 0.8); + break; + case "text/html": + case "text/javascript": + estimatedSavings = Math.round(originalSize * 0.67); + break; + case "text/plain": + case "text/xml": + case "text/x-component": + case "application/javascript": + case "application/json": + case "application/manifest+json": + case "application/vnd.api+json": + case "application/xml": + case "application/xhtml+xml": + case "application/rss+xml": + case "application/atom+xml": + case "application/vnd.ms-fontobject": + case "application/x-font-ttf": + case "application/x-font-opentype": + case "application/x-font-truetype": + case "image/svg+xml": + case "image/x-icon": + case "image/vnd.microsoft.icon": + case "font/ttf": + case "font/eot": + case "font/otf": + case "font/opentype": + estimatedSavings = Math.round(originalSize * 0.5); + break; + default: + } + return estimatedSavings < IGNORE_THRESHOLD_IN_BYTES ? 0 : estimatedSavings; +} +function finalize33(partialModel) { + let hasFailure = false; + if (partialModel.data) { + hasFailure = !partialModel.data.checklist.usesCompression.value || !partialModel.data.checklist.serverResponseIsFast.value || !partialModel.data.checklist.noRedirects.value; + } + return { + insightKey: InsightKeys.DOCUMENT_LATENCY, + strings: UIStrings4, + title: i18nString3(UIStrings4.title), + description: i18nString3(UIStrings4.description), + docs: "https://developer.chrome.com/docs/performance/insights/document-latency", + category: InsightCategory.ALL, + state: hasFailure ? "fail" : "pass", + ...partialModel + }; +} +function generateInsight3(data31, context) { + if (!context.navigation) { + return finalize33({}); + } + const millisToString = context.options.insightTimeFormatters?.milli ?? ((bytes) => ({ __i18nMillis: bytes })); + const documentRequest = data31.NetworkRequests.byId.get(context.navigationId); + if (!documentRequest) { + return finalize33({ warnings: [InsightWarning.NO_DOCUMENT_REQUEST] }); + } + const serverResponseTime = getServerResponseTime(documentRequest); + if (serverResponseTime === null) { + throw new Error("missing document request timing"); + } + const serverResponseTooSlow = serverResponseTime > TOO_SLOW_THRESHOLD_MS; + let overallSavingsMs = 0; + if (serverResponseTime > TOO_SLOW_THRESHOLD_MS) { + overallSavingsMs = Math.max(serverResponseTime - TARGET_MS, 0); + } + const redirectDuration = Math.round(documentRequest.args.data.syntheticData.redirectionDuration / 1e3); + overallSavingsMs += redirectDuration; + const metricSavings = { + FCP: overallSavingsMs, + LCP: overallSavingsMs + }; + const uncompressedResponseBytes = getCompressionSavings(documentRequest); + const noRedirects = redirectDuration === 0; + const serverResponseIsFast = !serverResponseTooSlow; + const usesCompression = uncompressedResponseBytes === 0; + return finalize33({ + relatedEvents: [documentRequest], + data: { + serverResponseTime, + redirectDuration: Timing_exports.Milli(redirectDuration), + uncompressedResponseBytes, + documentRequest, + checklist: { + noRedirects: { + label: noRedirects ? i18nString3(UIStrings4.passingRedirects) : i18nString3(UIStrings4.failedRedirects, { + PH1: documentRequest.args.data.redirects.length, + PH2: millisToString(redirectDuration) + }), + value: noRedirects + }, + serverResponseIsFast: { + label: serverResponseIsFast ? i18nString3(UIStrings4.passingServerResponseTime, { PH1: millisToString(serverResponseTime) }) : i18nString3(UIStrings4.failedServerResponseTime, { PH1: millisToString(serverResponseTime) }), + value: serverResponseIsFast + }, + usesCompression: { + label: usesCompression ? i18nString3(UIStrings4.passingTextCompression) : i18nString3(UIStrings4.failedTextCompression), + value: usesCompression + } + } + }, + metricSavings, + wastedBytes: uncompressedResponseBytes + }); +} +function createOverlays3(model2) { + if (!model2.data?.documentRequest) { + return []; + } + const overlays = []; + const event = model2.data.documentRequest; + const redirectDurationMicro = Timing_exports3.milliToMicro(model2.data.redirectDuration); + const sections = []; + if (model2.data.redirectDuration) { + const bounds = Timing_exports3.traceWindowFromMicroSeconds(event.ts, event.ts + redirectDurationMicro); + sections.push({ bounds, label: i18nString3(UIStrings4.redirectsLabel), showDuration: true }); + overlays.push({ type: "CANDY_STRIPED_TIME_RANGE", bounds, entry: event }); + } + if (!model2.data.checklist.serverResponseIsFast.value) { + const serverResponseTimeMicro = Timing_exports3.milliToMicro(model2.data.serverResponseTime); + const sendEnd = event.args.data.timing?.sendEnd ?? Timing_exports.Milli(0); + const sendEndMicro = Timing_exports3.milliToMicro(sendEnd); + const bounds = Timing_exports3.traceWindowFromMicroSeconds(sendEndMicro, sendEndMicro + serverResponseTimeMicro); + sections.push({ bounds, label: i18nString3(UIStrings4.serverResponseTimeLabel), showDuration: true }); + } + if (model2.data.uncompressedResponseBytes) { + const bounds = Timing_exports3.traceWindowFromMicroSeconds(event.args.data.syntheticData.downloadStart, event.args.data.syntheticData.downloadStart + event.args.data.syntheticData.download); + sections.push({ bounds, label: i18nString3(UIStrings4.uncompressedDownload), showDuration: true }); + overlays.push({ type: "CANDY_STRIPED_TIME_RANGE", bounds, entry: event }); + } + if (sections.length) { + overlays.push({ + type: "TIMESPAN_BREAKDOWN", + sections, + entry: model2.data.documentRequest, + // Always render below because the document request is guaranteed to be + // the first request in the network track. + renderLocation: "BELOW_EVENT" + }); + } + overlays.push({ + type: "ENTRY_SELECTED", + entry: model2.data.documentRequest + }); + return overlays; +} +var UIStrings4, i18nString3, TOO_SLOW_THRESHOLD_MS, TARGET_MS, IGNORE_THRESHOLD_IN_BYTES; +var init_DocumentLatency = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/DocumentLatency.js"() { + init_process_global(); + init_helpers2(); + init_types2(); + init_Common(); + init_types4(); + UIStrings4 = { + /** + * @description Title of an insight that provides a breakdown for how long it took to download the main document. + */ + title: "Document request latency", + /** + * @description Description of an insight that provides a breakdown for how long it took to download the main document. + */ + description: "Your first network request is the most important. [Reduce its latency](https://developer.chrome.com/docs/performance/insights/document-latency) by avoiding redirects, ensuring a fast server response, and enabling text compression.", + /** + * @description Text to tell the user that the document request does not have redirects. + */ + passingRedirects: "Avoids redirects", + /** + * @description Text to tell the user that the document request had redirects. + * @example {3} PH1 + * @example {1000 ms} PH2 + */ + failedRedirects: "Had redirects ({PH1} redirects, +{PH2})", + /** + * @description Text to tell the user that the time starting the document request to when the server started responding is acceptable. + * @example {600 ms} PH1 + */ + passingServerResponseTime: "Server responds quickly (observed {PH1})", + /** + * @description Text to tell the user that the time starting the document request to when the server started responding is not acceptable. + * @example {601 ms} PH1 + */ + failedServerResponseTime: "Server responded slowly (observed {PH1})", + /** + * @description Text to tell the user that text compression (like gzip) was applied. + */ + passingTextCompression: "Applies text compression", + /** + * @description Text to tell the user that text compression (like gzip) was not applied. + */ + failedTextCompression: "No compression applied", + /** + * @description Text for a label describing a network request event as having redirects. + */ + redirectsLabel: "Redirects", + /** + * @description Text for a label describing a network request event as taking too long to start delivery by the server. + */ + serverResponseTimeLabel: "Server response time", + /** + * @description Text for a label describing a network request event as taking longer to download because it wasn't compressed. + */ + uncompressedDownload: "Uncompressed download" + }; + i18nString3 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + TOO_SLOW_THRESHOLD_MS = 600; + TARGET_MS = 100; + IGNORE_THRESHOLD_IN_BYTES = 1400; + __name(isDocumentLatencyInsight, "isDocumentLatencyInsight"); + __name(getServerResponseTime, "getServerResponseTime"); + __name(getCompressionSavings, "getCompressionSavings"); + __name(finalize33, "finalize"); + __name(generateInsight3, "generateInsight"); + __name(createOverlays3, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js +var DOMSize_exports = {}; +__export(DOMSize_exports, { + UIStrings: () => UIStrings5, + createOverlays: () => createOverlays4, + generateInsight: () => generateInsight4, + i18nString: () => i18nString4, + isDomSizeInsight: () => isDomSizeInsight +}); +function finalize34(partialModel) { + const relatedEvents = [...partialModel.largeLayoutUpdates, ...partialModel.largeStyleRecalcs]; + return { + insightKey: InsightKeys.DOM_SIZE, + strings: UIStrings5, + title: i18nString4(UIStrings5.title), + description: i18nString4(UIStrings5.description), + docs: "https://developer.chrome.com/docs/performance/insights/dom-size", + category: InsightCategory.INP, + state: relatedEvents.length > 0 ? "informative" : "pass", + ...partialModel, + relatedEvents + }; +} +function isDomSizeInsight(model2) { + return model2.insightKey === InsightKeys.DOM_SIZE; +} +function generateInsight4(data31, context) { + const isWithinContext = /* @__PURE__ */ __name((event) => Timing_exports3.eventIsInBounds(event, context.bounds), "isWithinContext"); + const mainTid = context.navigation?.tid; + const largeLayoutUpdates = []; + const largeStyleRecalcs = []; + const threads = Threads_exports.threadsInRenderer(data31.Renderer, data31.AuctionWorklets); + for (const thread of threads) { + if (thread.type !== Threads_exports.ThreadType.MAIN_THREAD) { + continue; + } + if (mainTid === void 0) { + if (!thread.processIsOnMainFrame) { + continue; + } + } else if (thread.tid !== mainTid) { + continue; + } + const rendererThread = data31.Renderer.processes.get(thread.pid)?.threads.get(thread.tid); + if (!rendererThread) { + continue; + } + const { entries, layoutEvents, recalcStyleEvents } = rendererThread; + if (!entries.length) { + continue; + } + const first = entries[0]; + const last = entries[entries.length - 1]; + const timeRange = Timing_exports3.traceWindowFromMicroSeconds(first.ts, Timing_exports.Micro(last.ts + (last.dur ?? 0))); + if (!Timing_exports3.boundsIncludeTimeRange({ timeRange, bounds: context.bounds })) { + continue; + } + for (const event of layoutEvents) { + if (event.dur < DOM_SIZE_DURATION_THRESHOLD || !isWithinContext(event)) { + continue; + } + const { dirtyObjects } = event.args.beginData; + if (dirtyObjects > LAYOUT_OBJECTS_THRESHOLD) { + largeLayoutUpdates.push(event); + } + } + for (const event of recalcStyleEvents) { + if (event.dur < DOM_SIZE_DURATION_THRESHOLD || !isWithinContext(event)) { + continue; + } + const { elementCount } = event.args; + if (elementCount > STYLE_RECALC_ELEMENTS_THRESHOLD) { + largeStyleRecalcs.push(event); + } + } + } + const largeUpdates = [ + ...largeLayoutUpdates.map((event) => { + const duration = event.dur / 1e3; + const size = event.args.beginData.dirtyObjects; + const label = i18nString4(UIStrings5.largeLayout, { PH1: size }); + return { label, duration, size, event }; + }), + ...largeStyleRecalcs.map((event) => { + const duration = event.dur / 1e3; + const size = event.args.elementCount; + const label = i18nString4(UIStrings5.largeStyleRecalc, { PH1: size }); + return { label, duration, size, event }; + }) + ].sort((a, b) => b.duration - a.duration).slice(0, 5); + const domStatsEvents = data31.DOMStats.domStatsByFrameId.get(context.frameId)?.filter(isWithinContext) ?? []; + let maxDOMStats; + for (const domStats of domStatsEvents) { + const navigationPid = context.navigation?.pid; + if (navigationPid && domStats.pid !== navigationPid) { + continue; + } + if (!maxDOMStats || domStats.args.data.totalElements > maxDOMStats.args.data.totalElements) { + maxDOMStats = domStats; + } + } + return finalize34({ + largeLayoutUpdates, + largeStyleRecalcs, + largeUpdates, + maxDOMStats + }); +} +function createOverlays4(model2) { + const entries = [...model2.largeStyleRecalcs, ...model2.largeLayoutUpdates]; + return entries.map((entry) => ({ + type: "ENTRY_OUTLINE", + entry, + outlineReason: "ERROR" + })); +} +var UIStrings5, i18nString4, DOM_SIZE_DURATION_THRESHOLD, LAYOUT_OBJECTS_THRESHOLD, STYLE_RECALC_ELEMENTS_THRESHOLD; +var init_DOMSize = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js"() { + init_process_global(); + init_handlers(); + init_helpers2(); + init_types2(); + init_types4(); + UIStrings5 = { + /** + * @description Title of an insight that recommends reducing the size of the DOM tree as a means to improve page responsiveness. "DOM" is an acronym and should not be translated. + */ + title: "Optimize DOM size", + /** + * @description Description of an insight that recommends reducing the size of the DOM tree as a means to improve page responsiveness. "DOM" is an acronym and should not be translated. "layout reflows" are when the browser will recompute the layout of content on the page. + */ + description: "A large DOM can increase the duration of style calculations and layout reflows, impacting page responsiveness. A large DOM will also increase memory usage. [Learn how to avoid an excessive DOM size](https://developer.chrome.com/docs/performance/insights/dom-size).", + /** + * @description Header for a column containing the names of statistics as opposed to the actual statistic values. + */ + statistic: "Statistic", + /** + * @description Header for a column containing the value of a statistic. + */ + value: "Value", + /** + * @description Header for a column containing the page element related to a statistic. + */ + element: "Element", + /** + * @description Label for a value representing the total number of elements on the page. + */ + totalElements: "Total elements", + /** + * @description Label for a value representing the maximum depth of the Document Object Model (DOM). "DOM" is a acronym and should not be translated. + */ + maxDOMDepth: "DOM depth", + /** + * @description Label for a value representing the maximum number of child elements of any parent element on the page. + */ + maxChildren: "Most children", + /** + * @description Text for a section. + */ + topUpdatesDescription: "These are the largest layout and style recalculation events. Their performance impact may be reduced by making the DOM simpler.", + /** + * @description Label used for a time duration. + */ + duration: "Duration", + /** + * @description Message displayed in a table detailing how big a layout (rendering) is. + * @example {134} PH1 + */ + largeLayout: "Layout ({PH1} objects)", + /** + * @description Message displayed in a table detailing how big a style recalculation (rendering) is. + * @example {134} PH1 + */ + largeStyleRecalc: "Style recalculation ({PH1} elements)" + }; + i18nString4 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + DOM_SIZE_DURATION_THRESHOLD = Timing_exports3.milliToMicro(Timing_exports.Milli(40)); + LAYOUT_OBJECTS_THRESHOLD = 100; + STYLE_RECALC_ELEMENTS_THRESHOLD = 300; + __name(finalize34, "finalize"); + __name(isDomSizeInsight, "isDomSizeInsight"); + __name(generateInsight4, "generateInsight"); + __name(createOverlays4, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/DuplicatedJavaScript.js +var DuplicatedJavaScript_exports = {}; +__export(DuplicatedJavaScript_exports, { + UIStrings: () => UIStrings6, + createOverlays: () => createOverlays5, + generateInsight: () => generateInsight5, + i18nString: () => i18nString5, + isDuplicatedJavaScriptInsight: () => isDuplicatedJavaScriptInsight +}); +function finalize35(partialModel) { + const requests = partialModel.scriptsWithDuplication.map((script) => script.request).filter((e) => !!e); + return { + insightKey: InsightKeys.DUPLICATE_JAVASCRIPT, + strings: UIStrings6, + title: i18nString5(UIStrings6.title), + description: i18nString5(UIStrings6.description), + docs: "https://developer.chrome.com/docs/performance/insights/duplicated-javascript", + category: InsightCategory.LCP, + state: Boolean(partialModel.duplication.values().next().value) ? "fail" : "pass", + relatedEvents: [...new Set(requests)], + ...partialModel + }; +} +function isDuplicatedJavaScriptInsight(model2) { + return model2.insightKey === InsightKeys.DUPLICATE_JAVASCRIPT; +} +function generateInsight5(data31, context) { + const scripts = data31.Scripts.scripts.filter((script) => { + if (script.frame !== context.frameId) { + return false; + } + if (script.url?.startsWith("chrome-extension://")) { + return false; + } + return Timing_exports3.timestampIsInBounds(context.bounds, script.ts); + }); + const compressionRatios = /* @__PURE__ */ new Map(); + for (const script of scripts) { + if (script.request) { + compressionRatios.set(script.request.args.data.requestId, estimateCompressionRatioForScript(script)); + } + } + const { duplication, duplicationGroupedByNodeModules } = ScriptDuplication_exports.computeScriptDuplication({ scripts }, compressionRatios); + const scriptsWithDuplication = [...duplication.values().flatMap((data32) => data32.duplicates.map((d) => d.script))]; + const wastedBytesByRequestId = /* @__PURE__ */ new Map(); + for (const { duplicates } of duplication.values()) { + for (let i = 1; i < duplicates.length; i++) { + const sourceData = duplicates[i]; + if (!sourceData.script.request) { + continue; + } + const transferSize = sourceData.attributedSize; + const requestId = sourceData.script.request.args.data.requestId; + wastedBytesByRequestId.set(requestId, (wastedBytesByRequestId.get(requestId) || 0) + transferSize); + } + } + return finalize35({ + duplication, + duplicationGroupedByNodeModules, + scriptsWithDuplication: [...new Set(scriptsWithDuplication)], + scripts, + mainDocumentUrl: context.navigation?.args.data?.url ?? data31.Meta.mainFrameURL, + metricSavings: metricSavingsForWastedBytes(wastedBytesByRequestId, context), + wastedBytes: wastedBytesByRequestId.values().reduce((acc, cur) => acc + cur, 0) + }); +} +function createOverlays5(model2) { + return model2.scriptsWithDuplication.map((script) => script.request).filter((e) => !!e).map((request) => { + return { + type: "ENTRY_OUTLINE", + entry: request, + outlineReason: "ERROR" + }; + }); +} +var UIStrings6, i18nString5; +var init_DuplicatedJavaScript = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/DuplicatedJavaScript.js"() { + init_process_global(); + init_extras(); + init_helpers2(); + init_Common(); + init_types4(); + UIStrings6 = { + /** + * @description Title of an insight that identifies multiple copies of the same JavaScript sources, and recommends removing the duplication. + */ + title: "Duplicated JavaScript", + /** + * @description Description of an insight that identifies multiple copies of the same JavaScript sources, and recommends removing the duplication. + */ + description: "Remove large, [duplicate JavaScript modules](https://developer.chrome.com/docs/performance/insights/duplicated-javascript) from bundles to reduce unnecessary bytes consumed by network activity.", + /** Label for a column in a data table; entries will be the locations of JavaScript or CSS code, e.g. the name of a Javascript package or module. */ + columnSource: "Source", + /** Label for a column in a data table; entries will be the number of wasted bytes due to duplication of a web resource. */ + columnDuplicatedBytes: "Duplicated bytes" + }; + i18nString5 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(finalize35, "finalize"); + __name(isDuplicatedJavaScriptInsight, "isDuplicatedJavaScriptInsight"); + __name(generateInsight5, "generateInsight"); + __name(createOverlays5, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/FontDisplay.js +var FontDisplay_exports = {}; +__export(FontDisplay_exports, { + UIStrings: () => UIStrings7, + createOverlays: () => createOverlays6, + generateInsight: () => generateInsight6, + i18nString: () => i18nString6, + isFontDisplayInsight: () => isFontDisplayInsight +}); +function finalize36(partialModel) { + return { + insightKey: InsightKeys.FONT_DISPLAY, + strings: UIStrings7, + title: i18nString6(UIStrings7.title), + description: i18nString6(UIStrings7.description), + docs: "https://developer.chrome.com/docs/performance/insights/font-display", + category: InsightCategory.INP, + state: partialModel.fonts.find((font) => font.wastedTime > 0) ? "fail" : "pass", + ...partialModel + }; +} +function isFontDisplayInsight(model2) { + return model2.insightKey === InsightKeys.FONT_DISPLAY; +} +function generateInsight6(data31, context) { + const fonts = []; + for (const remoteFont of data31.LayoutShifts.remoteFonts) { + const event = remoteFont.beginRemoteFontLoadEvent; + if (!Timing_exports3.eventIsInBounds(event, context.bounds)) { + continue; + } + const requestId = `${event.pid}.${event.args.id}`; + const request = data31.NetworkRequests.byId.get(requestId); + if (!request) { + continue; + } + if (!/^(block|fallback|auto)$/.test(remoteFont.display)) { + continue; + } + const wastedTimeMicro = Timing_exports.Micro(request.args.data.syntheticData.finishTime - request.args.data.syntheticData.sendStartTime); + let wastedTime = NumberUtilities_exports.floor(Timing_exports3.microToMilli(wastedTimeMicro), 1 / 5); + if (wastedTime === 0) { + continue; + } + wastedTime = Math.min(wastedTime, 3e3); + fonts.push({ + name: remoteFont.name, + request, + display: remoteFont.display, + wastedTime + }); + } + fonts.sort((a, b) => b.wastedTime - a.wastedTime); + const savings = Math.max(...fonts.map((f) => f.wastedTime)); + return finalize36({ + relatedEvents: fonts.map((f) => f.request), + fonts, + metricSavings: { FCP: savings } + }); +} +function createOverlays6(model2) { + return model2.fonts.map((font) => ({ + type: "ENTRY_OUTLINE", + entry: font.request, + outlineReason: font.wastedTime ? "ERROR" : "INFO" + })); +} +var UIStrings7, i18nString6; +var init_FontDisplay = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/FontDisplay.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + init_types4(); + UIStrings7 = { + /** Title of an insight that provides details about the fonts used on the page, and the value of their `font-display` properties. */ + title: "Font display", + /** + * @description Text to tell the user about the font-display CSS feature to help improve a the UX of a page. + */ + description: "Consider setting [`font-display`](https://developer.chrome.com/docs/performance/insights/font-display) to `swap` or `optional` to ensure text is consistently visible. `swap` can be further optimized to mitigate layout shifts with [font metric overrides](https://developer.chrome.com/blog/font-fallbacks).", + /** Column for a font loaded by the page to render text. */ + fontColumn: "Font", + /** Column for the amount of time wasted. */ + wastedTimeColumn: "Wasted time" + }; + i18nString6 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(finalize36, "finalize"); + __name(isFontDisplayInsight, "isFontDisplayInsight"); + __name(generateInsight6, "generateInsight"); + __name(createOverlays6, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/ForcedReflow.js +var ForcedReflow_exports = {}; +__export(ForcedReflow_exports, { + UIStrings: () => UIStrings8, + createOverlayForEvents: () => createOverlayForEvents, + createOverlays: () => createOverlays7, + generateInsight: () => generateInsight7, + i18nString: () => i18nString7, + isForcedReflowInsight: () => isForcedReflowInsight +}); +function getCallFrameId(callFrame) { + return callFrame.scriptId + ":" + callFrame.lineNumber + ":" + callFrame.columnNumber; +} +function getLargestTopLevelFunctionData(forcedReflowEvents, traceParsedData) { + const entryToNodeMap = traceParsedData.Renderer.entryToNode; + const dataByTopLevelFunction = /* @__PURE__ */ new Map(); + if (forcedReflowEvents.length === 0) { + return; + } + for (const event of forcedReflowEvents) { + const traceNode = entryToNodeMap.get(event); + if (!traceNode) { + continue; + } + let node = traceNode.parent; + let topLevelFunctionCall; + let topLevelFunctionCallEvent; + while (node) { + const eventData = node.entry; + if (TraceEvents_exports.isProfileCall(eventData)) { + topLevelFunctionCall = eventData.callFrame; + topLevelFunctionCallEvent = eventData; + } else { + if (TraceEvents_exports.isFunctionCall(eventData) && eventData.args.data && TraceEvents_exports.objectIsCallFrame(eventData.args.data)) { + topLevelFunctionCall = eventData.args.data; + topLevelFunctionCallEvent = eventData; + } + break; + } + node = node.parent; + } + if (!topLevelFunctionCall || !topLevelFunctionCallEvent) { + continue; + } + const aggregatedDataId = getCallFrameId(topLevelFunctionCall); + const aggregatedData = MapUtilities_exports.getWithDefault(dataByTopLevelFunction, aggregatedDataId, () => ({ + topLevelFunctionCall, + totalReflowTime: 0, + topLevelFunctionCallEvents: [] + })); + aggregatedData.totalReflowTime += event.dur ?? 0; + aggregatedData.topLevelFunctionCallEvents.push(topLevelFunctionCallEvent); + } + let topTimeConsumingData = void 0; + dataByTopLevelFunction.forEach((data31) => { + if (!topTimeConsumingData || data31.totalReflowTime > topTimeConsumingData.totalReflowTime) { + topTimeConsumingData = data31; + } + }); + return topTimeConsumingData; +} +function finalize37(partialModel) { + return { + insightKey: InsightKeys.FORCED_REFLOW, + strings: UIStrings8, + title: i18nString7(UIStrings8.title), + description: i18nString7(UIStrings8.description), + docs: "https://developer.chrome.com/docs/performance/insights/forced-reflow", + category: InsightCategory.ALL, + state: partialModel.aggregatedBottomUpData.length !== 0 ? "fail" : "pass", + ...partialModel + }; +} +function getBottomCallFrameForEvent(event, traceParsedData) { + const profileStackTrace = StackTraceForEvent_exports.get(event, traceParsedData); + const eventTopCallFrame = Trace_exports.getStackTraceTopCallFrameInEventPayload(event); + return profileStackTrace?.callFrames[0] ?? eventTopCallFrame ?? null; +} +function isForcedReflowInsight(model2) { + return model2.insightKey === InsightKeys.FORCED_REFLOW; +} +function generateInsight7(traceParsedData, context) { + const isWithinContext = /* @__PURE__ */ __name((event) => { + const frameId = Trace_exports.frameIDForEvent(event); + if (frameId !== context.frameId) { + return false; + } + return Timing_exports3.eventIsInBounds(event, context.bounds); + }, "isWithinContext"); + const bottomUpDataMap = /* @__PURE__ */ new Map(); + const events = traceParsedData.Warnings.perWarning.get("FORCED_REFLOW")?.filter(isWithinContext) ?? []; + for (const event of events) { + const bottomCallFrame = getBottomCallFrameForEvent(event, traceParsedData); + const bottomCallId = bottomCallFrame ? getCallFrameId(bottomCallFrame) : "UNATTRIBUTED"; + const bottomUpData = MapUtilities_exports.getWithDefault(bottomUpDataMap, bottomCallId, () => ({ + bottomUpData: bottomCallFrame, + totalTime: 0, + relatedEvents: [] + })); + bottomUpData.totalTime += event.dur ?? 0; + bottomUpData.relatedEvents.push(event); + } + const topLevelFunctionCallData = getLargestTopLevelFunctionData(events, traceParsedData); + return finalize37({ + relatedEvents: events, + topLevelFunctionCallData, + aggregatedBottomUpData: [...bottomUpDataMap.values()] + }); +} +function createOverlays7(model2) { + if (!model2.topLevelFunctionCallData) { + return []; + } + const allBottomUpEvents = [...model2.aggregatedBottomUpData.values().flatMap((data31) => data31.relatedEvents)]; + return [ + ...createOverlayForEvents(model2.topLevelFunctionCallData.topLevelFunctionCallEvents, "INFO"), + ...createOverlayForEvents(allBottomUpEvents) + ]; +} +function createOverlayForEvents(events, outlineReason = "ERROR") { + return events.map((e) => ({ + type: "ENTRY_OUTLINE", + entry: e, + outlineReason + })); +} +var UIStrings8, i18nString7; +var init_ForcedReflow = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/ForcedReflow.js"() { + init_process_global(); + init_platform(); + init_extras(); + init_helpers2(); + init_types2(); + init_types4(); + UIStrings8 = { + /** + * @description Title of an insight that provides details about Forced reflow. + */ + title: "Forced reflow", + /** + * @description Text to describe the forced reflow. + */ + description: "A forced reflow occurs when JavaScript queries geometric properties (such as `offsetWidth`) after styles have been invalidated by a change to the DOM state. This can result in poor performance. Learn more about [forced reflows](https://developer.chrome.com/docs/performance/insights/forced-reflow) and possible mitigations.", + /** + * @description Title of a list to provide related stack trace data + */ + relatedStackTrace: "Stack trace", + /** + * @description Text to describe the top time-consuming function call + */ + topTimeConsumingFunctionCall: "Top function call", + /** + * @description Text to describe the total reflow time + */ + totalReflowTime: "Total reflow time", + /** + * @description Text to describe CPU processor tasks that could not be attributed to any specific source code. + */ + unattributed: "[unattributed]", + /** + * @description Text for the name of anonymous functions + */ + anonymous: "(anonymous)" + }; + i18nString7 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(getCallFrameId, "getCallFrameId"); + __name(getLargestTopLevelFunctionData, "getLargestTopLevelFunctionData"); + __name(finalize37, "finalize"); + __name(getBottomCallFrameForEvent, "getBottomCallFrameForEvent"); + __name(isForcedReflowInsight, "isForcedReflowInsight"); + __name(generateInsight7, "generateInsight"); + __name(createOverlays7, "createOverlays"); + __name(createOverlayForEvents, "createOverlayForEvents"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/ImageDelivery.js +var ImageDelivery_exports = {}; +__export(ImageDelivery_exports, { + ImageOptimizationType: () => ImageOptimizationType, + UIStrings: () => UIStrings9, + createOverlayForRequest: () => createOverlayForRequest2, + createOverlays: () => createOverlays8, + generateInsight: () => generateInsight8, + getOptimizationMessage: () => getOptimizationMessage, + getOptimizationMessageWithBytes: () => getOptimizationMessageWithBytes, + i18nString: () => i18nString8, + isImageDeliveryInsight: () => isImageDeliveryInsight +}); +function isImageDeliveryInsight(model2) { + return model2.insightKey === "ImageDelivery"; +} +function getOptimizationMessage(optimization) { + switch (optimization.type) { + case ImageOptimizationType.ADJUST_COMPRESSION: + return i18nString8(UIStrings9.useCompression); + case ImageOptimizationType.MODERN_FORMAT_OR_COMPRESSION: + return i18nString8(UIStrings9.useModernFormat); + case ImageOptimizationType.VIDEO_FORMAT: + return i18nString8(UIStrings9.useVideoFormat); + case ImageOptimizationType.RESPONSIVE_SIZE: + return i18nString8(UIStrings9.useResponsiveSize, { + PH1: `${optimization.fileDimensions.width}x${optimization.fileDimensions.height}`, + PH2: `${optimization.displayDimensions.width}x${optimization.displayDimensions.height}` + }); + } +} +function getOptimizationMessageWithBytes(optimization) { + const byteSavingsText = /* @__PURE__ */ ((bytes) => ({ __i18nBytes: bytes }))(optimization.byteSavings); + const optimizationMessage = getOptimizationMessage(optimization); + return i18nString8(UIStrings9.estimatedSavings, { PH1: optimizationMessage, PH2: byteSavingsText }); +} +function finalize38(partialModel) { + return { + insightKey: InsightKeys.IMAGE_DELIVERY, + strings: UIStrings9, + title: i18nString8(UIStrings9.title), + description: i18nString8(UIStrings9.description), + docs: "https://developer.chrome.com/docs/performance/insights/image-delivery", + category: InsightCategory.LCP, + state: partialModel.optimizableImages.length > 0 ? "fail" : "pass", + ...partialModel, + relatedEvents: new Map(partialModel.optimizableImages.map((image) => [image.request, image.optimizations.map(getOptimizationMessageWithBytes)])) + }; +} +function estimateGIFPercentSavings(request) { + return Math.round(29.1 * Math.log10(request.args.data.decodedBodyLength) - 100.7) / 100; +} +function getDisplayedSize(data31, paintImage) { + return data31.ImagePainting.paintEventToCorrectedDisplaySize.get(paintImage) ?? { + width: paintImage.args.data.width, + height: paintImage.args.data.height + }; +} +function getPixelCounts(data31, paintImage) { + const { width, height } = getDisplayedSize(data31, paintImage); + return { + filePixels: paintImage.args.data.srcWidth * paintImage.args.data.srcHeight, + displayedPixels: width * height + }; +} +function generateInsight8(data31, context) { + const isWithinContext = /* @__PURE__ */ __name((event) => Timing_exports3.eventIsInBounds(event, context.bounds), "isWithinContext"); + const contextRequests = data31.NetworkRequests.byTime.filter(isWithinContext); + const optimizableImages = []; + for (const request of contextRequests) { + if (request.args.data.resourceType !== "Image") { + continue; + } + if (request.args.data.mimeType === "image/svg+xml") { + continue; + } + const url = request.args.data.redirects[0]?.url ?? request.args.data.url; + const imagePaints = data31.ImagePainting.paintImageEventForUrl.get(url)?.filter(isWithinContext); + if (!imagePaints?.length) { + continue; + } + const largestImagePaint = imagePaints.reduce((prev, curr) => { + const prevPixels = getPixelCounts(data31, prev).displayedPixels; + const currPixels = getPixelCounts(data31, curr).displayedPixels; + return prevPixels > currPixels ? prev : curr; + }); + const { filePixels: imageFilePixels, displayedPixels: largestImageDisplayPixels } = getPixelCounts(data31, largestImagePaint); + const imageBytes = Math.min(request.args.data.decodedBodyLength, request.args.data.encodedDataLength); + const bytesPerPixel = imageBytes / imageFilePixels; + let optimizations = []; + if (request.args.data.mimeType === "image/gif") { + if (imageBytes > GIF_SIZE_THRESHOLD) { + const percentSavings = estimateGIFPercentSavings(request); + const byteSavings = Math.round(imageBytes * percentSavings); + optimizations.push({ type: ImageOptimizationType.VIDEO_FORMAT, byteSavings }); + } + } else if (bytesPerPixel > TARGET_BYTES_PER_PIXEL_AVIF) { + const idealAvifImageSize = Math.round(TARGET_BYTES_PER_PIXEL_AVIF * imageFilePixels); + const byteSavings = imageBytes - idealAvifImageSize; + if (request.args.data.mimeType !== "image/webp" && request.args.data.mimeType !== "image/avif") { + optimizations.push({ type: ImageOptimizationType.MODERN_FORMAT_OR_COMPRESSION, byteSavings }); + } else { + optimizations.push({ type: ImageOptimizationType.ADJUST_COMPRESSION, byteSavings }); + } + } + const imageByteSavingsFromFormat = Math.max(0, ...optimizations.map((o) => o.byteSavings)); + let imageByteSavings = imageByteSavingsFromFormat; + const wastedPixelRatio = 1 - largestImageDisplayPixels / imageFilePixels; + if (wastedPixelRatio > 0 && !largestImagePaint.args.data.isCSS) { + const byteSavings = Math.round(wastedPixelRatio * imageBytes); + const hadBreakpoints = largestImagePaint.args.data.isPicture || largestImagePaint.args.data.srcsetAttribute; + if (!hadBreakpoints || byteSavings > BYTE_SAVINGS_THRESHOLD_RESPONSIVE_BREAKPOINTS) { + imageByteSavings += Math.round(wastedPixelRatio * (imageBytes - imageByteSavingsFromFormat)); + const { width, height } = getDisplayedSize(data31, largestImagePaint); + optimizations.push({ + type: ImageOptimizationType.RESPONSIVE_SIZE, + byteSavings, + fileDimensions: { + width: Math.round(largestImagePaint.args.data.srcWidth), + height: Math.round(largestImagePaint.args.data.srcHeight) + }, + displayDimensions: { + width: Math.round(width), + height: Math.round(height) + } + }); + } + } + optimizations = optimizations.filter((optimization) => optimization.byteSavings > BYTE_SAVINGS_THRESHOLD); + if (optimizations.length > 0) { + optimizableImages.push({ + request, + largestImagePaint, + optimizations, + byteSavings: imageByteSavings + }); + } + } + const wastedBytesByRequestId = /* @__PURE__ */ new Map(); + for (const image of optimizableImages) { + wastedBytesByRequestId.set(image.request.args.data.requestId, image.byteSavings); + } + optimizableImages.sort((a, b) => { + if (b.byteSavings !== a.byteSavings) { + return b.byteSavings - a.byteSavings; + } + return b.request.args.data.decodedBodyLength - a.request.args.data.decodedBodyLength; + }); + return finalize38({ + optimizableImages, + metricSavings: metricSavingsForWastedBytes(wastedBytesByRequestId, context), + wastedBytes: optimizableImages.reduce((total, img) => total + img.byteSavings, 0) + }); +} +function createOverlayForRequest2(request) { + return { + type: "ENTRY_OUTLINE", + entry: request, + outlineReason: "ERROR" + }; +} +function createOverlays8(model2) { + return model2.optimizableImages.map((image) => createOverlayForRequest2(image.request)); +} +var UIStrings9, i18nString8, TARGET_BYTES_PER_PIXEL_AVIF, GIF_SIZE_THRESHOLD, BYTE_SAVINGS_THRESHOLD, BYTE_SAVINGS_THRESHOLD_RESPONSIVE_BREAKPOINTS, ImageOptimizationType; +var init_ImageDelivery = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/ImageDelivery.js"() { + init_process_global(); + init_helpers2(); + init_Common(); + init_types4(); + UIStrings9 = { + /** + * @description Title of an insight that recommends ways to reduce the size of images downloaded and used on the page. + */ + title: "Improve image delivery", + /** + * @description Description of an insight that recommends ways to reduce the size of images downloaded and used on the page. + */ + description: "Reducing the download time of images can improve the perceived load time of the page and LCP. [Learn more about optimizing image size](https://developer.chrome.com/docs/performance/insights/image-delivery)", + /** + * @description Message displayed in a chip explaining that an image file size is large for the # of pixels it has and recommends possible adjustments to improve the image size. + */ + useCompression: "Increasing the image compression factor could improve this image's download size.", + /** + * @description Message displayed in a chip explaining that an image file size is large for the # of pixels it has and recommends possible adjustments to improve the image size. + */ + useModernFormat: "Using a modern image format (WebP, AVIF) or increasing the image compression could improve this image's download size.", + /** + * @description Message displayed in a chip advising the user to use video formats instead of GIFs because videos generally have smaller file sizes. + */ + useVideoFormat: "Using video formats instead of GIFs can improve the download size of animated content.", + /** + * @description Message displayed in a chip explaining that an image was displayed on the page with dimensions much smaller than the image file dimensions. + * @example {1000x500} PH1 + * @example {100x50} PH2 + */ + useResponsiveSize: "This image file is larger than it needs to be ({PH1}) for its displayed dimensions ({PH2}). Use responsive images to reduce the image download size.", + /** + * @description Column header for a table column containing network requests for images which can improve their file size (e.g. use a different format, increase compression, etc). + */ + optimizeFile: "Optimize file size", + /** + * @description Table row value representing the remaining items not shown in the table due to size constraints. This row will always represent at least 2 items. + * @example {5} PH1 + */ + others: "{PH1} others", + /** + * @description Text status indicating that no potential optimizations were found for any image file + */ + noOptimizableImages: "No optimizable images", + /** + * @description Text describing the estimated number of bytes that an image file optimization can save. This text is appended to another block of text describing the image optimization in more detail. "Est" means "Estimated". + * @example {Use the correct image dimensions to reduce the image file size.} PH1 + * @example {50 MB} PH2 + */ + estimatedSavings: "{PH1} (Est {PH2})" + }; + i18nString8 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + TARGET_BYTES_PER_PIXEL_AVIF = 2 * 1 / 12; + GIF_SIZE_THRESHOLD = 100 * 1024; + BYTE_SAVINGS_THRESHOLD = 4096; + BYTE_SAVINGS_THRESHOLD_RESPONSIVE_BREAKPOINTS = 12288; + (function(ImageOptimizationType2) { + ImageOptimizationType2["ADJUST_COMPRESSION"] = "ADJUST_COMPRESSION"; + ImageOptimizationType2["MODERN_FORMAT_OR_COMPRESSION"] = "MODERN_FORMAT_OR_COMPRESSION"; + ImageOptimizationType2["VIDEO_FORMAT"] = "VIDEO_FORMAT"; + ImageOptimizationType2["RESPONSIVE_SIZE"] = "RESPONSIVE_SIZE"; + })(ImageOptimizationType || (ImageOptimizationType = {})); + __name(isImageDeliveryInsight, "isImageDeliveryInsight"); + __name(getOptimizationMessage, "getOptimizationMessage"); + __name(getOptimizationMessageWithBytes, "getOptimizationMessageWithBytes"); + __name(finalize38, "finalize"); + __name(estimateGIFPercentSavings, "estimateGIFPercentSavings"); + __name(getDisplayedSize, "getDisplayedSize"); + __name(getPixelCounts, "getPixelCounts"); + __name(generateInsight8, "generateInsight"); + __name(createOverlayForRequest2, "createOverlayForRequest"); + __name(createOverlays8, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/INPBreakdown.js +var INPBreakdown_exports = {}; +__export(INPBreakdown_exports, { + UIStrings: () => UIStrings10, + createOverlays: () => createOverlays9, + createOverlaysForSubpart: () => createOverlaysForSubpart, + generateInsight: () => generateInsight9, + i18nString: () => i18nString9, + isINPBreakdownInsight: () => isINPBreakdownInsight +}); +function isINPBreakdownInsight(insight) { + return insight.insightKey === InsightKeys.INP_BREAKDOWN; +} +function finalize39(partialModel) { + let state = "pass"; + if (partialModel.longestInteractionEvent) { + const classification = ModelHandlers_exports.UserInteractions.scoreClassificationForInteractionToNextPaint(partialModel.longestInteractionEvent.dur); + if (classification === ModelHandlers_exports.PageLoadMetrics.ScoreClassification.GOOD) { + state = "informative"; + } else { + state = "fail"; + } + } + return { + insightKey: InsightKeys.INP_BREAKDOWN, + strings: UIStrings10, + title: i18nString9(UIStrings10.title), + description: i18nString9(UIStrings10.description), + docs: "https://developer.chrome.com/docs/performance/insights/inp-breakdown", + category: InsightCategory.INP, + state, + ...partialModel + }; +} +function generateInsight9(data31, context) { + const interactionEvents2 = data31.UserInteractions.interactionEventsWithNoNesting.filter((event) => { + return Timing_exports3.eventIsInBounds(event, context.bounds); + }); + if (!interactionEvents2.length) { + return finalize39({}); + } + const longestByInteractionId = /* @__PURE__ */ new Map(); + for (const event of interactionEvents2) { + const key = event.interactionId; + const longest = longestByInteractionId.get(key); + if (!longest || event.dur > longest.dur) { + longestByInteractionId.set(key, event); + } + } + const normalizedInteractionEvents = [...longestByInteractionId.values()]; + normalizedInteractionEvents.sort((a, b) => b.dur - a.dur); + const highPercentileIndex = Math.min(9, Math.floor(normalizedInteractionEvents.length / 50)); + return finalize39({ + relatedEvents: [normalizedInteractionEvents[0]], + longestInteractionEvent: normalizedInteractionEvents[0], + highPercentileInteractionEvent: normalizedInteractionEvents[highPercentileIndex] + }); +} +function createOverlaysForSubpart(event, subpartIndex = -1) { + const p1 = Timing_exports3.traceWindowFromMicroSeconds(event.ts, event.ts + event.inputDelay); + const p2 = Timing_exports3.traceWindowFromMicroSeconds(p1.max, p1.max + event.mainThreadHandling); + const p3 = Timing_exports3.traceWindowFromMicroSeconds(p2.max, p2.max + event.presentationDelay); + let sections = [ + { bounds: p1, label: i18nString9(UIStrings10.inputDelay), showDuration: true }, + { bounds: p2, label: i18nString9(UIStrings10.processingDuration), showDuration: true }, + { bounds: p3, label: i18nString9(UIStrings10.presentationDelay), showDuration: true } + ]; + if (subpartIndex !== -1) { + sections = [sections[subpartIndex]]; + } + return [ + { + type: "TIMESPAN_BREAKDOWN", + sections, + renderLocation: "BELOW_EVENT", + entry: event + } + ]; +} +function createOverlays9(model2) { + const event = model2.longestInteractionEvent; + if (!event) { + return []; + } + return createOverlaysForSubpart(event); +} +var UIStrings10, i18nString9; +var init_INPBreakdown = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/INPBreakdown.js"() { + init_process_global(); + init_handlers(); + init_helpers2(); + init_types4(); + UIStrings10 = { + /** + * @description Text to tell the user about the longest user interaction. + */ + description: "Start investigating [how to improve INP](https://developer.chrome.com/docs/performance/insights/inp-breakdown) by looking at the longest subpart.", + /** + * @description Title for the performance insight "INP breakdown", which shows a breakdown of INP by subparts / sections. + */ + title: "INP breakdown", + /** + * @description Label used for the subpart/component/stage/section of a larger duration. + */ + subpart: "Subpart", + /** + * @description Label used for a time duration. + */ + duration: "Duration", + // TODO: these are repeated in InteractionBreakdown. Add a place for common strings? + /** + * @description Text shown next to the interaction event's input delay time in the detail view. + */ + inputDelay: "Input delay", + /** + * @description Text shown next to the interaction event's thread processing duration in the detail view. + */ + processingDuration: "Processing duration", + /** + * @description Text shown next to the interaction event's presentation delay time in the detail view. + */ + presentationDelay: "Presentation delay", + /** + * @description Text status indicating that no user interactions were detected. + */ + noInteractions: "No interactions detected" + }; + i18nString9 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(isINPBreakdownInsight, "isINPBreakdownInsight"); + __name(finalize39, "finalize"); + __name(generateInsight9, "generateInsight"); + __name(createOverlaysForSubpart, "createOverlaysForSubpart"); + __name(createOverlays9, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js +var LCPBreakdown_exports = {}; +__export(LCPBreakdown_exports, { + UIStrings: () => UIStrings11, + createOverlays: () => createOverlays10, + generateInsight: () => generateInsight10, + i18nString: () => i18nString10, + isLCPBreakdownInsight: () => isLCPBreakdownInsight +}); +function isLCPBreakdownInsight(model2) { + return model2.insightKey === "LCPBreakdown"; +} +function anyValuesNaN(...values) { + return values.some((v) => Number.isNaN(v)); +} +function determineSubparts(nav, docRequest, lcpEvent, lcpRequest) { + const firstDocByteTs = calculateDocFirstByteTs(docRequest); + if (firstDocByteTs === null) { + return null; + } + const ttfb = Timing_exports3.traceWindowFromMicroSeconds(nav.ts, firstDocByteTs); + ttfb.label = i18nString10(UIStrings11.timeToFirstByte); + let renderDelay = Timing_exports3.traceWindowFromMicroSeconds(ttfb.max, lcpEvent.ts); + renderDelay.label = i18nString10(UIStrings11.elementRenderDelay); + if (!lcpRequest) { + if (anyValuesNaN(ttfb.range, renderDelay.range)) { + return null; + } + return { ttfb, renderDelay }; + } + const lcpStartTs = lcpRequest.ts; + const lcpReqEndTs = lcpRequest.args.data.syntheticData.finishTime; + const loadDelay = Timing_exports3.traceWindowFromMicroSeconds(ttfb.max, lcpStartTs); + const loadDuration = Timing_exports3.traceWindowFromMicroSeconds(lcpStartTs, lcpReqEndTs); + renderDelay = Timing_exports3.traceWindowFromMicroSeconds(lcpReqEndTs, lcpEvent.ts); + loadDelay.label = i18nString10(UIStrings11.resourceLoadDelay); + loadDuration.label = i18nString10(UIStrings11.resourceLoadDuration); + renderDelay.label = i18nString10(UIStrings11.elementRenderDelay); + if (anyValuesNaN(ttfb.range, loadDelay.range, loadDuration.range, renderDelay.range)) { + return null; + } + return { + ttfb, + loadDelay, + loadDuration, + renderDelay + }; +} +function finalize40(partialModel) { + const relatedEvents = []; + if (partialModel.lcpEvent) { + relatedEvents.push(partialModel.lcpEvent); + } + if (partialModel.lcpRequest) { + relatedEvents.push(partialModel.lcpRequest); + } + let state = "pass"; + if (partialModel.lcpMs !== void 0) { + const classification = ModelHandlers_exports.PageLoadMetrics.scoreClassificationForLargestContentfulPaint(Timing_exports3.milliToMicro(partialModel.lcpMs)); + if (classification === ModelHandlers_exports.PageLoadMetrics.ScoreClassification.GOOD) { + state = "informative"; + } else { + state = "fail"; + } + } + return { + insightKey: InsightKeys.LCP_BREAKDOWN, + strings: UIStrings11, + title: i18nString10(UIStrings11.title), + description: i18nString10(UIStrings11.description), + docs: "https://developer.chrome.com/docs/performance/insights/lcp-breakdown", + category: InsightCategory.LCP, + state, + ...partialModel, + relatedEvents + }; +} +function generateInsight10(data31, context) { + if (!context.navigation) { + return finalize40({}); + } + const networkRequests = data31.NetworkRequests; + const frameMetrics = data31.PageLoadMetrics.metricScoresByFrameId.get(context.frameId); + if (!frameMetrics) { + throw new Error("no frame metrics"); + } + const navMetrics = frameMetrics.get(context.navigationId); + if (!navMetrics) { + throw new Error("no navigation metrics"); + } + const metricScore = navMetrics.get(ModelHandlers_exports.PageLoadMetrics.MetricName.LCP); + const lcpEvent = metricScore?.event; + if (!lcpEvent || !TraceEvents_exports.isLargestContentfulPaintCandidate(lcpEvent)) { + return finalize40({ warnings: [InsightWarning.NO_LCP] }); + } + const lcpMs = Timing_exports3.microToMilli(metricScore.timing); + const lcpTs = metricScore.event?.ts ? Timing_exports3.microToMilli(metricScore.event?.ts) : void 0; + const lcpRequest = data31.LargestImagePaint.lcpRequestByNavigationId.get(context.navigationId); + const docRequest = networkRequests.byId.get(context.navigationId); + if (!docRequest) { + return finalize40({ lcpMs, lcpTs, lcpEvent, lcpRequest, warnings: [InsightWarning.NO_DOCUMENT_REQUEST] }); + } + return finalize40({ + lcpMs, + lcpTs, + lcpEvent, + lcpRequest, + subparts: determineSubparts(context.navigation, docRequest, lcpEvent, lcpRequest) ?? void 0 + }); +} +function createOverlays10(model2) { + if (!model2.subparts || !model2.lcpTs) { + return []; + } + const overlays = [ + { + type: "TIMESPAN_BREAKDOWN", + sections: Object.values(model2.subparts).map((subpart) => ({ bounds: subpart, label: subpart.label, showDuration: true })) + } + ]; + if (model2.lcpRequest) { + overlays.push({ type: "ENTRY_OUTLINE", entry: model2.lcpRequest, outlineReason: "INFO" }); + } + return overlays; +} +var UIStrings11, i18nString10; +var init_LCPBreakdown = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js"() { + init_process_global(); + init_handlers(); + init_helpers2(); + init_types2(); + init_Common(); + init_types4(); + UIStrings11 = { + /** + * @description Title of an insight that provides details about the LCP metric, broken down by parts. + */ + title: "LCP breakdown", + /** + * @description Description of a DevTools insight that presents a breakdown for the LCP metric by subparts. + * This is displayed after a user expands the section to see more. No character length limits. + */ + description: "Each [subpart has specific improvement strategies](https://developer.chrome.com/docs/performance/insights/lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.", + /** + * @description Time to first byte title for the Largest Contentful Paint's subparts timespan breakdown. + */ + timeToFirstByte: "Time to first byte", + /** + * @description Resource load delay title for the Largest Contentful Paint subparts timespan breakdown. + */ + resourceLoadDelay: "Resource load delay", + /** + * @description Resource load duration title for the Largest Contentful Paint subparts timespan breakdown. + */ + resourceLoadDuration: "Resource load duration", + /** + * @description Element render delay title for the Largest Contentful Paint subparts timespan breakdown. + */ + elementRenderDelay: "Element render delay", + /** + * @description Label used for the subpart (section) of a larger duration. + */ + subpart: "Subpart", + /** + * @description Label used for the duration a single subpart (section) takes up of a larger duration. + */ + duration: "Duration", + /** + * @description Label used for the duration a single subpart (section) takes up of a larger duration. The value will be the 75th percentile of aggregate data. "Field" means that the data was collected from real users in the field as opposed to the developers local environment. "Field" is synonymous with "Real user data". + */ + fieldDuration: "Field p75", + /** + * @description Text status indicating that the the Largest Contentful Paint (LCP) metric timing was not found. "LCP" is an acronym and should not be translated. + */ + noLcp: "No LCP detected" + }; + i18nString10 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(isLCPBreakdownInsight, "isLCPBreakdownInsight"); + __name(anyValuesNaN, "anyValuesNaN"); + __name(determineSubparts, "determineSubparts"); + __name(finalize40, "finalize"); + __name(generateInsight10, "generateInsight"); + __name(createOverlays10, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js +var LCPDiscovery_exports = {}; +__export(LCPDiscovery_exports, { + UIStrings: () => UIStrings12, + createOverlays: () => createOverlays11, + generateInsight: () => generateInsight11, + getImageData: () => getImageData, + i18nString: () => i18nString11, + isLCPDiscoveryInsight: () => isLCPDiscoveryInsight +}); +function isLCPDiscoveryInsight(model2) { + return model2.insightKey === "LCPDiscovery"; +} +function finalize41(partialModel) { + const relatedEvents = partialModel.lcpEvent && partialModel.lcpRequest ? ( + // TODO: add entire request initiator chain? + [partialModel.lcpEvent, partialModel.lcpRequest] + ) : []; + return { + insightKey: InsightKeys.LCP_DISCOVERY, + strings: UIStrings12, + title: i18nString11(UIStrings12.title), + description: i18nString11(UIStrings12.description), + docs: "https://developer.chrome.com/docs/performance/insights/lcp-discovery", + category: InsightCategory.LCP, + state: partialModel.lcpRequest && partialModel.checklist && (!partialModel.checklist.eagerlyLoaded.value || !partialModel.checklist.requestDiscoverable.value || !partialModel.checklist.priorityHinted.value) ? "fail" : "pass", + ...partialModel, + relatedEvents + }; +} +function generateInsight11(data31, context) { + if (!context.navigation) { + return finalize41({}); + } + const networkRequests = data31.NetworkRequests; + const frameMetrics = data31.PageLoadMetrics.metricScoresByFrameId.get(context.frameId); + if (!frameMetrics) { + throw new Error("no frame metrics"); + } + const navMetrics = frameMetrics.get(context.navigationId); + if (!navMetrics) { + throw new Error("no navigation metrics"); + } + const metricScore = navMetrics.get(ModelHandlers_exports.PageLoadMetrics.MetricName.LCP); + const lcpEvent = metricScore?.event; + if (!lcpEvent || !TraceEvents_exports.isLargestContentfulPaintCandidate(lcpEvent)) { + return finalize41({ warnings: [InsightWarning.NO_LCP] }); + } + const docRequest = networkRequests.byId.get(context.navigationId); + if (!docRequest) { + return finalize41({ warnings: [InsightWarning.NO_DOCUMENT_REQUEST] }); + } + const lcpRequest = data31.LargestImagePaint.lcpRequestByNavigationId.get(context.navigationId); + if (!lcpRequest) { + return finalize41({ lcpEvent }); + } + const initiatorUrl = lcpRequest.args.data.initiator?.url; + const initiatedByMainDoc = lcpRequest?.args.data.initiator?.type === "parser" && docRequest.args.data.url === initiatorUrl; + const imgPreloadedOrFoundInHTML = lcpRequest?.args.data.isLinkPreload || initiatedByMainDoc; + const imageLoadingAttr = lcpEvent.args.data?.loadingAttr; + const imageFetchPriorityHint = lcpRequest?.args.data.fetchPriorityHint; + const earliestDiscoveryTime = calculateDocFirstByteTs(docRequest); + const priorityHintFound = imageFetchPriorityHint === "high"; + return finalize41({ + lcpEvent, + lcpRequest, + earliestDiscoveryTimeTs: earliestDiscoveryTime ? Timing_exports.Micro(earliestDiscoveryTime) : void 0, + checklist: { + priorityHinted: { + label: priorityHintFound ? i18nString11(UIStrings12.fetchPriorityApplied) : i18nString11(UIStrings12.fetchPriorityShouldBeApplied), + value: priorityHintFound + }, + requestDiscoverable: { label: i18nString11(UIStrings12.requestDiscoverable), value: imgPreloadedOrFoundInHTML }, + eagerlyLoaded: { label: i18nString11(UIStrings12.lazyLoadNotApplied), value: imageLoadingAttr !== "lazy" } + } + }); +} +function getImageData(model2) { + if (!model2.lcpRequest || !model2.checklist) { + return null; + } + const shouldIncreasePriorityHint = !model2.checklist.priorityHinted.value; + const shouldPreloadImage = !model2.checklist.requestDiscoverable.value; + const shouldRemoveLazyLoading = !model2.checklist.eagerlyLoaded.value; + const imageLCP = shouldIncreasePriorityHint !== void 0 && shouldPreloadImage !== void 0 && shouldRemoveLazyLoading !== void 0; + if (!imageLCP) { + return null; + } + const data31 = { + checklist: model2.checklist, + request: model2.lcpRequest, + discoveryDelay: null, + estimatedSavings: model2.metricSavings?.LCP ?? null + }; + if (model2.earliestDiscoveryTimeTs && model2.lcpRequest) { + const discoveryDelay = model2.lcpRequest.ts - model2.earliestDiscoveryTimeTs; + data31.discoveryDelay = Timing_exports.Micro(discoveryDelay); + } + return data31; +} +function createOverlays11(model2) { + const imageResults = getImageData(model2); + if (!imageResults?.discoveryDelay) { + return []; + } + const delay = Timing_exports3.traceWindowFromMicroSeconds(Timing_exports.Micro(imageResults.request.ts - imageResults.discoveryDelay), imageResults.request.ts); + return [ + { + type: "ENTRY_OUTLINE", + entry: imageResults.request, + outlineReason: "ERROR" + }, + { + type: "CANDY_STRIPED_TIME_RANGE", + bounds: delay, + entry: imageResults.request + }, + { + type: "TIMESPAN_BREAKDOWN", + sections: [{ + bounds: delay, + // This is overridden in the component. + label: `${imageResults.discoveryDelay} microseconds`, + showDuration: false + }], + entry: imageResults.request, + renderLocation: "ABOVE_EVENT" + } + ]; +} +var UIStrings12, i18nString11; +var init_LCPDiscovery = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js"() { + init_process_global(); + init_handlers(); + init_helpers2(); + init_types2(); + init_Common(); + init_types4(); + UIStrings12 = { + /** + * @description Title of an insight that provides details about the LCP metric, and the network requests necessary to load it. Details how the LCP request was discoverable - in other words, the path necessary to load it (ex: network requests, JavaScript) + */ + title: "LCP request discovery", + /** + * @description Description of an insight that provides details about the LCP metric, and the network requests necessary to load it. + */ + description: "[Optimize LCP](https://developer.chrome.com/docs/performance/insights/lcp-discovery) by making the LCP image discoverable from the HTML immediately, and avoiding lazy-loading", + /** + * @description Text to tell the user how long after the earliest discovery time their LCP element loaded. + * @example {401ms} PH1 + */ + lcpLoadDelay: "LCP image loaded {PH1} after earliest start point.", + /** + * @description Text to tell the user that a fetchpriority property value of "high" is applied to the LCP request. + */ + fetchPriorityApplied: "fetchpriority=high applied", + /** + * @description Text to tell the user that a fetchpriority property value of "high" should be applied to the LCP request. + */ + fetchPriorityShouldBeApplied: "fetchpriority=high should be applied", + /** + * @description Text to tell the user that the LCP request is discoverable in the initial document. + */ + requestDiscoverable: "Request is discoverable in initial document", + /** + * @description Text to tell the user that the LCP request does not have the lazy load property applied. + */ + lazyLoadNotApplied: "lazy load not applied", + /** + * @description Text status indicating that the the Largest Contentful Paint (LCP) metric timing was not found. "LCP" is an acronym and should not be translated. + */ + noLcp: "No LCP detected", + /** + * @description Text status indicating that the Largest Contentful Paint (LCP) metric was text rather than an image. "LCP" is an acronym and should not be translated. + */ + noLcpResource: "No LCP resource detected because the LCP is not an image" + }; + i18nString11 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(isLCPDiscoveryInsight, "isLCPDiscoveryInsight"); + __name(finalize41, "finalize"); + __name(generateInsight11, "generateInsight"); + __name(getImageData, "getImageData"); + __name(createOverlays11, "createOverlays"); + } +}); + +// node_modules/legacy-javascript/legacy-javascript.js +var legacy_javascript_exports = {}; +__export(legacy_javascript_exports, { + detectLegacyJavaScript: () => detectLegacyJavaScript, + getCoreJsPolyfillData: () => getCoreJsPolyfillData, + getTransformPatterns: () => getTransformPatterns +}); +function buildPolyfillExpression(object, property, coreJs3Module) { + const qt = /* @__PURE__ */ __name((token) => `['"]${token}['"]`, "qt"); + let expression = ""; + if (object) { + expression += `${object}\\.${property}\\s?=[^=]`; + } else { + expression += `(?:window\\.|[\\s;]+)${property}\\s?=[^=]`; + } + if (object) { + expression += `|${object}\\[${qt(property)}\\]\\s?=[^=]`; + } + expression += `|defineProperty\\(${object || "window"},\\s?${qt(property)}`; + if (object) { + expression += `|\\(${object},\\s*{${property}:.*},\\s*{${property}`; + } + if (object) { + const objectWithoutPrototype = object.replace(".prototype", ""); + expression += `|{target:${qt(objectWithoutPrototype)}[^;]*},{${property}:`; + } else { + } + expression += `|${coreJs3Module.replaceAll(".", "\\.")}(?:\\.js)?"`; + return expression; +} +function getCoreJsPolyfillData() { + return polyfillModuleData.filter((d) => d.corejs).map((d) => { + return { + name: d.name, + coreJs3Module: d.modules[0] + }; + }); +} +function getPolyfillPatterns() { + const patterns = []; + for (const { name, coreJs3Module } of getCoreJsPolyfillData()) { + const parts = name.split("."); + const object = parts.length > 1 ? parts.slice(0, parts.length - 1).join(".") : null; + const property = parts[parts.length - 1]; + patterns.push({ + name, + expression: buildPolyfillExpression(object, property, coreJs3Module) + }); + } + return patterns; +} +function getTransformPatterns() { + const count = /* @__PURE__ */ __name((content, pattern) => { + if (typeof pattern === "string") { + return content.split(pattern).length - 1; + } + return (content.match(pattern) ?? []).length; + }, "count"); + return [ + // @babel/plugin-transform-classes + // + // input: + // + // class MyTestClass { + // log() { + // console.log(1); + // } + // }; + // + // output: + // + // function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } + // function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } + // function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } + // function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } + // function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } + // let MyTestClass = function () { + // function MyTestClass() { + // _classCallCheck(this, MyTestClass); + // } + // return _createClass(MyTestClass, [{ + // key: "log", + // value: function log() { + // console.log(1); + // } + // }]); + // }(); + { + name: "@babel/plugin-transform-classes", + expression: "Cannot call a class as a function", + estimateBytes: /* @__PURE__ */ __name((content) => { + return 1e3 + (count(content, "_classCallCheck") - 1) * "_classCallCheck()".length; + }, "estimateBytes") + }, + { + name: "@babel/plugin-transform-regenerator", + expression: "Generator is already running|regeneratorRuntime", + // Example of this transform: https://gist.github.com/connorjclark/af8bccfff377ac44efc104a79bc75da2 + // `regeneratorRuntime.awrap` is generated for every usage of `await`, and adds ~80 bytes each. + estimateBytes: /* @__PURE__ */ __name((content) => { + return count(content, /regeneratorRuntime\(?\)?\.a?wrap/g) * 80; + }, "estimateBytes") + }, + { + name: "@babel/plugin-transform-spread", + expression: "Invalid attempt to spread non-iterable instance", + estimateBytes: /* @__PURE__ */ __name((content) => { + const per = "_toConsumableArray()".length; + return 1169 + count(content, /\.apply\(void 0,\s?_toConsumableArray/g) * per; + }, "estimateBytes") + } + ]; +} +function estimateWastedBytes(content, matches) { + const polyfillResults = matches.filter((m) => !m.name.startsWith("@")); + const transformResults = matches.filter((m) => m.name.startsWith("@")); + let estimatedWastedBytesFromPolyfills = 0; + const modulesSeen = /* @__PURE__ */ new Set(); + for (const result of polyfillResults) { + const modules = graph.dependencies[result.name]; + if (!modules) + continue; + for (const module2 of modules) { + modulesSeen.add(module2); + } + } + estimatedWastedBytesFromPolyfills += [...modulesSeen].reduce((acc, moduleIndex) => { + return acc + graph.moduleSizes[moduleIndex]; + }, 0); + estimatedWastedBytesFromPolyfills = Math.min(estimatedWastedBytesFromPolyfills, graph.maxSize); + let estimatedWastedBytesFromTransforms = 0; + for (const result of transformResults) { + const pattern = getTransformPatterns().find((p) => p.name === result.name); + if (!pattern || !pattern.estimateBytes || !content) + continue; + estimatedWastedBytesFromTransforms += pattern.estimateBytes(content); + } + const estimatedWastedBytes = estimatedWastedBytesFromPolyfills + estimatedWastedBytesFromTransforms; + return estimatedWastedBytes; +} +function detectLegacyJavaScript(content, map) { + if (!content) + return { matches: [], estimatedByteSavings: 0 }; + let matches = matcher.match(content); + if (map) { + for (const { name, modules } of polyfillModuleData) { + if (matches.some((m) => m.name === name)) + continue; + const source = map.sourceURLs().find((source2) => modules.some((module2) => { + return source2.endsWith(`/${module2}.js`) || source2.includes(`node_modules/${module2}/`); + })); + if (!source) + continue; + const mapping = map.mappings().find((m) => m.sourceURL === source); + if (mapping) { + matches.push({ name, line: mapping.lineNumber, column: mapping.columnNumber }); + } else { + matches.push({ name, line: 0, column: 0 }); + } + } + } + matches = matches.sort((a, b) => a.name > b.name ? 1 : a.name === b.name ? 0 : -1); + return { + matches, + estimatedByteSavings: estimateWastedBytes(content, matches) + }; +} +var polyfill_module_data_default, polyfill_graph_data_default, polyfillModuleData, graph, CodePatternMatcher, matcher; +var init_legacy_javascript = __esm({ + "node_modules/legacy-javascript/legacy-javascript.js"() { + init_process_global(); + polyfill_module_data_default = [ + { + name: "focus-visible", + modules: [ + "focus-visible" + ] + }, + { + name: "Error.prototype.cause", + modules: [ + "es.error.cause" + ] + }, + { + name: "Array.prototype.at", + modules: [ + "es.array.at", + "esnext.array.at" + ], + corejs: true + }, + { + name: "Array.prototype.concat", + modules: [ + "es.array.concat" + ], + corejs: true + }, + { + name: "Array.prototype.copyWithin", + modules: [ + "es.array.copy-within" + ], + corejs: true + }, + { + name: "Array.prototype.every", + modules: [ + "es.array.every" + ], + corejs: true + }, + { + name: "Array.prototype.fill", + modules: [ + "es.array.fill" + ], + corejs: true + }, + { + name: "Array.prototype.filter", + modules: [ + "es.array.filter" + ], + corejs: true + }, + { + name: "Array.prototype.find", + modules: [ + "es.array.find" + ], + corejs: true + }, + { + name: "Array.prototype.findIndex", + modules: [ + "es.array.find-index" + ], + corejs: true + }, + { + name: "Array.prototype.findLast", + modules: [ + "es.array.find-last", + "esnext.array.find-last" + ], + corejs: true + }, + { + name: "Array.prototype.findLastIndex", + modules: [ + "es.array.find-last-index", + "esnext.array.find-last-index" + ], + corejs: true + }, + { + name: "Array.prototype.flat", + modules: [ + "es.array.flat" + ], + corejs: true + }, + { + name: "Array.prototype.flatMap", + modules: [ + "es.array.flat-map" + ], + corejs: true + }, + { + name: "Array.prototype.forEach", + modules: [ + "es.array.for-each" + ], + corejs: true + }, + { + name: "Array.from", + modules: [ + "es.array.from" + ], + corejs: true + }, + { + name: "Array.prototype.includes", + modules: [ + "es.array.includes" + ], + corejs: true + }, + { + name: "Array.prototype.indexOf", + modules: [ + "es.array.index-of" + ], + corejs: true + }, + { + name: "Array.isArray", + modules: [ + "es.array.is-array" + ], + corejs: true + }, + { + name: "Array.prototype.join", + modules: [ + "es.array.join" + ], + corejs: true + }, + { + name: "Array.prototype.map", + modules: [ + "es.array.map" + ], + corejs: true + }, + { + name: "Array.of", + modules: [ + "es.array.of" + ], + corejs: true + }, + { + name: "Array.prototype.slice", + modules: [ + "es.array.slice" + ], + corejs: true + }, + { + name: "Array.prototype.some", + modules: [ + "es.array.some" + ], + corejs: true + }, + { + name: "Array.prototype.sort", + modules: [ + "es.array.sort" + ], + corejs: true + }, + { + name: "Array.prototype.unshift", + modules: [ + "es.array.unshift" + ], + corejs: true + }, + { + name: "Math.acosh", + modules: [ + "es.math.acosh" + ], + corejs: true + }, + { + name: "Math.asinh", + modules: [ + "es.math.asinh" + ], + corejs: true + }, + { + name: "Math.atanh", + modules: [ + "es.math.atanh" + ], + corejs: true + }, + { + name: "Math.cbrt", + modules: [ + "es.math.cbrt" + ], + corejs: true + }, + { + name: "Math.clz32", + modules: [ + "es.math.clz32" + ], + corejs: true + }, + { + name: "Math.cosh", + modules: [ + "es.math.cosh" + ], + corejs: true + }, + { + name: "Math.expm1", + modules: [ + "es.math.expm1" + ], + corejs: true + }, + { + name: "Math.fround", + modules: [ + "es.math.fround" + ], + corejs: true + }, + { + name: "Math.hypot", + modules: [ + "es.math.hypot" + ], + corejs: true + }, + { + name: "Math.imul", + modules: [ + "es.math.imul" + ], + corejs: true + }, + { + name: "Math.log10", + modules: [ + "es.math.log10" + ], + corejs: true + }, + { + name: "Math.log1p", + modules: [ + "es.math.log1p" + ], + corejs: true + }, + { + name: "Math.log2", + modules: [ + "es.math.log2" + ], + corejs: true + }, + { + name: "Math.sign", + modules: [ + "es.math.sign" + ], + corejs: true + }, + { + name: "Math.sinh", + modules: [ + "es.math.sinh" + ], + corejs: true + }, + { + name: "Math.tanh", + modules: [ + "es.math.tanh" + ], + corejs: true + }, + { + name: "Math.trunc", + modules: [ + "es.math.trunc" + ], + corejs: true + }, + { + name: "Object.assign", + modules: [ + "es.object.assign" + ], + corejs: true + }, + { + name: "Object.create", + modules: [ + "es.object.create" + ], + corejs: true + }, + { + name: "Object.entries", + modules: [ + "es.object.entries" + ], + corejs: true + }, + { + name: "Object.freeze", + modules: [ + "es.object.freeze" + ], + corejs: true + }, + { + name: "Object.fromEntries", + modules: [ + "es.object.from-entries" + ], + corejs: true + }, + { + name: "Object.getOwnPropertyDescriptor", + modules: [ + "es.object.get-own-property-descriptor" + ], + corejs: true + }, + { + name: "Object.getOwnPropertyDescriptors", + modules: [ + "es.object.get-own-property-descriptors" + ], + corejs: true + }, + { + name: "Object.getPrototypeOf", + modules: [ + "es.object.get-prototype-of" + ], + corejs: true + }, + { + name: "Object.hasOwn", + modules: [ + "es.object.has-own", + "esnext.object.has-own" + ], + corejs: true + }, + { + name: "Object.is", + modules: [ + "es.object.is" + ], + corejs: true + }, + { + name: "Object.isExtensible", + modules: [ + "es.object.is-extensible" + ], + corejs: true + }, + { + name: "Object.isFrozen", + modules: [ + "es.object.is-frozen" + ], + corejs: true + }, + { + name: "Object.isSealed", + modules: [ + "es.object.is-sealed" + ], + corejs: true + }, + { + name: "Object.keys", + modules: [ + "es.object.keys" + ], + corejs: true + }, + { + name: "Object.preventExtensions", + modules: [ + "es.object.prevent-extensions" + ], + corejs: true + }, + { + name: "Object.seal", + modules: [ + "es.object.seal" + ], + corejs: true + }, + { + name: "Object.setPrototypeOf", + modules: [ + "es.object.set-prototype-of" + ], + corejs: true + }, + { + name: "Object.values", + modules: [ + "es.object.values" + ], + corejs: true + }, + { + name: "Promise.any", + modules: [ + "es.promise.any", + "esnext.promise.any" + ], + corejs: true + }, + { + name: "Reflect.apply", + modules: [ + "es.reflect.apply" + ], + corejs: true + }, + { + name: "Reflect.construct", + modules: [ + "es.reflect.construct" + ], + corejs: true + }, + { + name: "Reflect.deleteProperty", + modules: [ + "es.reflect.delete-property" + ], + corejs: true + }, + { + name: "Reflect.get", + modules: [ + "es.reflect.get" + ], + corejs: true + }, + { + name: "Reflect.getOwnPropertyDescriptor", + modules: [ + "es.reflect.get-own-property-descriptor" + ], + corejs: true + }, + { + name: "Reflect.getPrototypeOf", + modules: [ + "es.reflect.get-prototype-of" + ], + corejs: true + }, + { + name: "Reflect.has", + modules: [ + "es.reflect.has" + ], + corejs: true + }, + { + name: "Reflect.isExtensible", + modules: [ + "es.reflect.is-extensible" + ], + corejs: true + }, + { + name: "Reflect.ownKeys", + modules: [ + "es.reflect.own-keys" + ], + corejs: true + }, + { + name: "Reflect.preventExtensions", + modules: [ + "es.reflect.prevent-extensions" + ], + corejs: true + }, + { + name: "Reflect.setPrototypeOf", + modules: [ + "es.reflect.set-prototype-of" + ], + corejs: true + }, + { + name: "String.prototype.codePointAt", + modules: [ + "es.string.code-point-at" + ], + corejs: true + }, + { + name: "String.prototype.endsWith", + modules: [ + "es.string.ends-with" + ], + corejs: true + }, + { + name: "String.fromCodePoint", + modules: [ + "es.string.from-code-point" + ], + corejs: true + }, + { + name: "String.prototype.includes", + modules: [ + "es.string.includes" + ], + corejs: true + }, + { + name: "String.prototype.matchAll", + modules: [ + "es.string.match-all", + "esnext.string.match-all" + ], + corejs: true + }, + { + name: "String.raw", + modules: [ + "es.string.raw" + ], + corejs: true + }, + { + name: "String.prototype.repeat", + modules: [ + "es.string.repeat" + ], + corejs: true + }, + { + name: "String.prototype.replaceAll", + modules: [ + "es.string.replace-all", + "esnext.string.replace-all" + ], + corejs: true + }, + { + name: "String.prototype.startsWith", + modules: [ + "es.string.starts-with" + ], + corejs: true + }, + { + name: "String.prototype.substr", + modules: [ + "es.string.substr" + ], + corejs: true + }, + { + name: "String.prototype.trim", + modules: [ + "es.string.trim" + ], + corejs: true + }, + { + name: "String.prototype.trimEnd", + modules: [ + "es.string.trim-end" + ], + corejs: true + }, + { + name: "String.prototype.trimStart", + modules: [ + "es.string.trim-start" + ], + corejs: true + }, + { + name: "String.prototype.link", + modules: [ + "es.string.link" + ], + corejs: true + }, + { + name: "Promise.allSettled", + modules: [ + "esnext.promise.all-settled" + ], + corejs: true + } + ]; + polyfill_graph_data_default = { + moduleSizes: [26070, 498, 282, 294, 281, 467, 161, 236, 229, 765, 546, 339, 1608, 723, 729, 1545, 438, 214, 657, 111, 759, 537, 209, 281, 685, 217, 757, 631, 293, 182, 475, 79, 407, 140, 366, 792, 269, 222, 158, 280, 188, 137, 158, 105, 189, 543, 160, 742, 1436, 88, 904, 146, 314, 375, 183, 1083, 195, 503, 269, 208, 334, 350, 460, 568, 229, 1155, 334, 266, 30, 120, 309, 370, 358, 1952, 1638, 304, 153, 274, 1288, 192, 543, 74, 144, 137, 33, 336, 457, 2122, 535, 711, 1323, 117, 1961, 244, 557, 318, 119, 124, 108, 144, 96, 133, 441, 210, 1627, 1956, 693, 1426, 863, 637, 301, 51, 708, 583, 119, 600, 221, 370, 728, 1085, 552, 629, 125, 1746, 97, 441, 543, 2756, 371, 447, 548, 243, 266, 217, 99, 440, 183, 546, 137, 464, 207, 983, 503, 237, 382, 249, 675, 402, 254, 223, 164, 214, 191, 831, 218, 202, 232, 124, 249, 160, 251, 217, 717, 78, 561, 1627, 256, 386, 225, 432, 499, 394, 364, 445, 634, 667, 177, 346, 470, 663, 142, 588, 414, 617, 1559, 380, 2520, 1040, 417, 289, 238, 220, 214, 303, + 163, 141, 510, 397, 137, 137, 133, 133, 390, 266, 137, 183, 215, 191, 485, 328, 575, 799, 533, 148, 215, 589, 589, 130, 362, 562, 471, 179, 186, 1266, 1456, 521, 1536, 427, 444, 406, 912, 150, 283, 144, 485, 470, 205, 1268, 796, 658, 306, 3751, 814, 146, 2328, 1226, 922, 237, 206, 198, 250, 283, 60, 3e3], + dependencies: { + "Array.prototype.at": [0, 5, 69, 105, 106, 116, 164], + "Array.prototype.concat": [0, 16, 21, 22, 26, 34, 40, 76, 78, 155, 165], + "Array.prototype.copyWithin": [0, 5, 9, 37, 69, 105, 106, 116, 166], + "Array.prototype.every": [0, 15, 17, 21, 22, 26, 53, 59, 76, 78, 155, 167], + "Array.prototype.fill": [0, 5, 10, 69, 105, 106, 116, 168], + "Array.prototype.filter": [0, 15, 16, 21, 22, 26, 53, 59, 76, 78, 155, 169], + "Array.prototype.find": [0, 5, 15, 21, 22, 26, 53, 59, 69, 76, 78, 105, 106, 116, 155, 173], + "Array.prototype.findIndex": [0, 5, 15, 21, 22, 26, 53, 59, 69, 76, 78, 105, 106, 116, 155, 170], + "Array.prototype.findLast": [0, 5, 14, 53, 59, 69, 105, 106, 116, 172], + "Array.prototype.findLastIndex": [0, 5, 14, 53, 59, 69, 105, 106, 116, 171], + "Array.prototype.flat": [0, 21, 22, 26, 40, 50, 53, 59, 76, 78, 155, 175], + "Array.prototype.flatMap": [0, 21, 22, 26, 40, 50, 53, 59, 76, 78, 155, 174], + "Array.prototype.forEach": [0, 11, 15, 17, 21, 22, 26, 53, 59, 76, 78, 155, 176], + "Array.from": [0, 12, 23, 24, 26, 34, 53, 59, 62, 63, 75, 78, 88, 155, 177], + "Array.prototype.includes": [0, 5, 69, 105, 106, 116, 178], + "Array.prototype.indexOf": [0, 17, 59, 179], + "Array.isArray": [0, 76, 180], + "Array.prototype.join": [0, 17, 181], + "Array.prototype.map": [0, 15, 16, 21, 22, 26, 53, 59, 76, 78, 155, 182], + "Array.of": [0, 26, 34, 78, 155, 183], + "Array.prototype.slice": [0, 16, 19, 26, 34, 76, 78, 155, 184], + "Array.prototype.some": [0, 15, 17, 21, 22, 26, 53, 59, 76, 78, 155, 185], + "Array.prototype.sort": [0, 17, 19, 20, 26, 37, 42, 43, 46, 155, 156, 186], + "Array.prototype.unshift": [0, 18, 37, 40, 76, 187], + "Math.acosh": [0, 97, 188], + "Math.asinh": [0, 189], + "Math.atanh": [0, 190], + "Math.cbrt": [0, 100, 191], + "Math.clz32": [0, 192], + "Math.cosh": [0, 93, 193], + "Math.expm1": [0, 93, 194], + "Math.fround": [0, 94, 95, 99, 100, 195], + "Math.hypot": [0, 196], + "Math.imul": [0, 197], + "Math.log10": [0, 96, 198], + "Math.log1p": [0, 97, 199], + "Math.log2": [0, 98, 200], + "Math.sign": [0, 100, 201], + "Math.sinh": [0, 93, 202], + "Math.tanh": [0, 93, 203], + "Math.trunc": [0, 204], + "Object.assign": [0, 104, 116, 205], + "Object.create": [0, 69, 105, 106, 116, 206], + "Object.entries": [0, 29, 112, 116, 119, 207], + "Object.freeze": [0, 8, 19, 51, 73, 109, 113, 208], + "Object.fromEntries": [0, 26, 34, 53, 59, 62, 63, 75, 87, 88, 155, 209], + "Object.getOwnPropertyDescriptor": [0, 210], + "Object.getOwnPropertyDescriptors": [0, 34, 211], + "Object.getPrototypeOf": [0, 29, 112, 212], + "Object.hasOwn": [0, 213], + "Object.is": [0, 134, 217], + "Object.isExtensible": [0, 8, 113, 214], + "Object.isFrozen": [0, 8, 215], + "Object.isSealed": [0, 8, 216], + "Object.keys": [0, 116, 218], + "Object.preventExtensions": [0, 8, 19, 51, 73, 109, 113, 219], + "Object.seal": [0, 8, 19, 51, 73, 109, 113, 220], + "Object.setPrototypeOf": [0, 4, 58, 83, 118, 221], + "Object.values": [0, 29, 112, 116, 119, 222], + "Promise.any": [0, 24, 26, 47, 53, 59, 62, 63, 75, 87, 88, 102, 122, 123, 124, 125, 155, 224], + "Reflect.apply": [0, 52, 225], + "Reflect.construct": [0, 3, 19, 26, 52, 55, 69, 78, 105, 106, 116, 155, 226], + "Reflect.deleteProperty": [0, 227], + "Reflect.get": [0, 29, 79, 112, 230], + "Reflect.getOwnPropertyDescriptor": [0, 228], + "Reflect.getPrototypeOf": [0, 29, 112, 229], + "Reflect.has": [0, 231], + "Reflect.isExtensible": [0, 8, 113, 232], + "Reflect.ownKeys": [0, 233], + "Reflect.preventExtensions": [0, 51, 234], + "Reflect.setPrototypeOf": [0, 4, 58, 83, 118, 235], + "String.prototype.codePointAt": [0, 26, 141, 155, 156, 236], + "String.prototype.endsWith": [0, 26, 28, 59, 85, 103, 155, 156, 237], + "String.fromCodePoint": [0, 238], + "String.prototype.includes": [0, 26, 28, 85, 103, 155, 156, 239], + "String.prototype.matchAll": [0, 3, 6, 26, 29, 31, 59, 69, 78, 85, 89, 90, 105, 106, 112, 116, 126, 127, 128, 129, 130, 131, 132, 135, 139, 141, 155, 156, 241], + "String.raw": [0, 26, 155, 156, 242], + "String.prototype.repeat": [0, 26, 142, 155, 156, 243], + "String.prototype.replaceAll": [0, 26, 65, 85, 128, 129, 155, 156, 244], + "String.prototype.startsWith": [0, 26, 28, 59, 85, 103, 155, 156, 245], + "String.prototype.substr": [0, 26, 155, 156, 246], + "String.prototype.trim": [0, 26, 144, 146, 155, 156, 163, 251], + "String.prototype.trimEnd": [0, 26, 143, 144, 146, 155, 156, 163, 247, 249], + "String.prototype.trimStart": [0, 26, 144, 145, 146, 155, 156, 163, 248, 250], + "String.prototype.link": [0, 26, 30, 140, 155, 156, 240], + "Promise.allSettled": [0, 24, 26, 47, 53, 59, 62, 63, 75, 87, 88, 102, 122, 123, 124, 125, 155, 223, 252], + "focus-visible": [253] + }, + maxSize: 155835 + }; + polyfillModuleData = polyfill_module_data_default; + graph = polyfill_graph_data_default; + CodePatternMatcher = class { + static { + __name(this, "CodePatternMatcher"); + } + /** + * @param {Pattern[]} patterns + */ + constructor(patterns) { + this.patterns = patterns; + } + /** + * @param {string} code + * @return {PatternMatchResult[]} + */ + match(code) { + if (!this.re) { + const patternsExpression = this.patterns.map((pattern) => `(${pattern.expression})`).join("|"); + this.re = new RegExp(`(^\r +|\r| +)|${patternsExpression}`, "g"); + } + this.re.lastIndex = 0; + const seen = /* @__PURE__ */ new Set(); + const matches = []; + let result; + let line = 0; + let lineBeginsAtIndex = 0; + while ((result = this.re.exec(code)) !== null) { + const captureGroups = result.slice(1); + const [isNewline, ...patternExpressionMatches] = captureGroups; + if (isNewline) { + line++; + lineBeginsAtIndex = result.index + 1; + continue; + } + const pattern = this.patterns[patternExpressionMatches.findIndex(Boolean)]; + if (seen.has(pattern)) { + continue; + } + seen.add(pattern); + matches.push({ + name: pattern.name, + line, + column: result.index - lineBeginsAtIndex + }); + } + return matches; + } + }; + __name(buildPolyfillExpression, "buildPolyfillExpression"); + __name(getCoreJsPolyfillData, "getCoreJsPolyfillData"); + __name(getPolyfillPatterns, "getPolyfillPatterns"); + __name(getTransformPatterns, "getTransformPatterns"); + __name(estimateWastedBytes, "estimateWastedBytes"); + matcher = new CodePatternMatcher([ + ...getPolyfillPatterns(), + ...getTransformPatterns() + ]); + __name(detectLegacyJavaScript, "detectLegacyJavaScript"); + /** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + } +}); + +// node_modules/@paulirish/trace_engine/third_party/legacy-javascript/legacy-javascript.js +var init_legacy_javascript2 = __esm({ + "node_modules/@paulirish/trace_engine/third_party/legacy-javascript/legacy-javascript.js"() { + init_process_global(); + init_legacy_javascript(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/LegacyJavaScript.js +var LegacyJavaScript_exports = {}; +__export(LegacyJavaScript_exports, { + UIStrings: () => UIStrings13, + createOverlays: () => createOverlays12, + generateInsight: () => generateInsight12, + i18nString: () => i18nString12, + isLegacyJavaScript: () => isLegacyJavaScript +}); +function finalize42(partialModel) { + const requests = [...partialModel.legacyJavaScriptResults.keys()].map((script) => script.request).filter((e) => !!e); + return { + insightKey: InsightKeys.LEGACY_JAVASCRIPT, + strings: UIStrings13, + title: i18nString12(UIStrings13.title), + description: i18nString12(UIStrings13.description), + docs: "https://developer.chrome.com/docs/performance/insights/legacy-javascript", + category: InsightCategory.ALL, + state: requests.length ? "fail" : "pass", + relatedEvents: [...new Set(requests)], + ...partialModel + }; +} +function isLegacyJavaScript(model2) { + return model2.insightKey === InsightKeys.LEGACY_JAVASCRIPT; +} +function generateInsight12(data31, context) { + const scripts = data31.Scripts.scripts.filter((script) => { + if (script.frame !== context.frameId) { + return false; + } + if (script.url?.startsWith("chrome-extension://")) { + return false; + } + return Timing_exports3.timestampIsInBounds(context.bounds, script.ts) || script.request && Timing_exports3.eventIsInBounds(script.request, context.bounds); + }); + const legacyJavaScriptResults = /* @__PURE__ */ new Map(); + const wastedBytesByRequestId = /* @__PURE__ */ new Map(); + for (const script of scripts) { + if (!script.content || script.content.length < BYTE_THRESHOLD) { + continue; + } + const result = detectLegacyJavaScript2(script.content, script.sourceMap); + if (result.estimatedByteSavings < BYTE_THRESHOLD) { + continue; + } + const compressionRatio = estimateCompressionRatioForScript(script); + const transferSize = Math.round(result.estimatedByteSavings * compressionRatio); + result.estimatedByteSavings = transferSize; + legacyJavaScriptResults.set(script, result); + if (script.request) { + const requestId = script.request.args.data.requestId; + wastedBytesByRequestId.set(requestId, transferSize); + } + } + const sorted2 = new Map([...legacyJavaScriptResults].sort((a, b) => b[1].estimatedByteSavings - a[1].estimatedByteSavings)); + return finalize42({ + legacyJavaScriptResults: sorted2, + metricSavings: metricSavingsForWastedBytes(wastedBytesByRequestId, context), + wastedBytes: wastedBytesByRequestId.values().reduce((acc, cur) => acc + cur, 0) + }); +} +function createOverlays12(model2) { + return [...model2.legacyJavaScriptResults.keys()].map((script) => script.request).filter((e) => !!e).map((request) => { + return { + type: "ENTRY_OUTLINE", + entry: request, + outlineReason: "ERROR" + }; + }); +} +var detectLegacyJavaScript2, UIStrings13, i18nString12, BYTE_THRESHOLD; +var init_LegacyJavaScript = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/LegacyJavaScript.js"() { + init_process_global(); + init_legacy_javascript2(); + init_helpers2(); + init_Common(); + init_types4(); + ({ detectLegacyJavaScript: detectLegacyJavaScript2 } = legacy_javascript_exports); + UIStrings13 = { + /** + * @description Title of an insight that identifies polyfills for modern JavaScript features, and recommends their removal. + */ + title: "Legacy JavaScript", + /** + * @description Description of an insight that identifies polyfills for modern JavaScript features, and recommends their removal. + */ + description: "Polyfills and transforms enable older browsers to use new JavaScript features. However, many aren't necessary for modern browsers. Consider modifying your JavaScript build process to not transpile [Baseline](https://web.dev/articles/baseline-and-polyfills) features, unless you know you must support older browsers. [Learn why most sites can deploy ES6+ code without transpiling](https://developer.chrome.com/docs/performance/insights/legacy-javascript)", + /** Label for a column in a data table; entries will be the individual JavaScript scripts. */ + columnScript: "Script", + /** Label for a column in a data table; entries will be the number of wasted bytes (aka the estimated savings in terms of bytes). */ + columnWastedBytes: "Wasted bytes" + }; + i18nString12 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + BYTE_THRESHOLD = 5e3; + __name(finalize42, "finalize"); + __name(isLegacyJavaScript, "isLegacyJavaScript"); + __name(generateInsight12, "generateInsight"); + __name(createOverlays12, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/ModernHTTP.js +var ModernHTTP_exports = {}; +__export(ModernHTTP_exports, { + UIStrings: () => UIStrings14, + createOverlayForRequest: () => createOverlayForRequest3, + createOverlays: () => createOverlays13, + determineHttp1Requests: () => determineHttp1Requests, + generateInsight: () => generateInsight13, + i18nString: () => i18nString13, + isModernHTTPInsight: () => isModernHTTPInsight +}); +function isModernHTTPInsight(model2) { + return model2.insightKey === InsightKeys.MODERN_HTTP; +} +function isMultiplexableStaticAsset(request, entityMappings3, firstPartyEntity) { + if (!Network_exports.STATIC_RESOURCE_TYPES.has(request.args.data.resourceType)) { + return false; + } + if (request.args.data.decodedBodyLength < 100) { + const entity = entityMappings3.entityByEvent.get(request); + if (entity) { + if (firstPartyEntity?.name === entity.name) { + return true; + } + if (!entity.isUnrecognized) { + return false; + } + } + } + return true; +} +function determineHttp1Requests(requests, entityMappings3, firstPartyEntity) { + const http1Requests = []; + const groupedByOrigin = /* @__PURE__ */ new Map(); + for (const record of requests) { + const url = new URL(record.args.data.url); + if (!isMultiplexableStaticAsset(record, entityMappings3, firstPartyEntity)) { + continue; + } + if (Network_exports.isSyntheticNetworkRequestLocalhost(record)) { + continue; + } + const originRequests = MapUtilities_exports.getWithDefault(groupedByOrigin, url.origin, () => []); + originRequests.push(record); + } + const seenURLs = /* @__PURE__ */ new Set(); + for (const request of requests) { + if (seenURLs.has(request.args.data.url)) { + continue; + } + if (request.args.data.fromServiceWorker) { + continue; + } + const isOldHttp = /HTTP\/[01][.\d]?/i.test(request.args.data.protocol); + if (!isOldHttp) { + continue; + } + const url = new URL(request.args.data.url); + const group = groupedByOrigin.get(url.origin) || []; + if (group.length < 6) { + continue; + } + seenURLs.add(request.args.data.url); + http1Requests.push(request); + } + return http1Requests; +} +function computeWasteWithGraph(urlsToChange, graph2, simulator) { + const simulationBefore = simulator.simulate(graph2); + const originalProtocols = /* @__PURE__ */ new Map(); + graph2.traverse((node) => { + if (node.type !== "network") { + return; + } + if (!urlsToChange.has(node.request.url)) { + return; + } + originalProtocols.set(node.request.requestId, node.request.protocol); + node.request.protocol = "h2"; + }); + const simulationAfter = simulator.simulate(graph2); + graph2.traverse((node) => { + if (node.type !== "network") { + return; + } + const originalProtocol = originalProtocols.get(node.request.requestId); + if (originalProtocol === void 0) { + return; + } + node.request.protocol = originalProtocol; + }); + const savings = simulationBefore.timeInMs - simulationAfter.timeInMs; + return NumberUtilities_exports.floor(savings, 1 / 10); +} +function computeMetricSavings(http1Requests, context) { + if (!context.navigation || !context.lantern) { + return; + } + const urlsToChange = new Set(http1Requests.map((r) => r.args.data.url)); + const fcpGraph = context.lantern.metrics.firstContentfulPaint.optimisticGraph; + const lcpGraph = context.lantern.metrics.largestContentfulPaint.optimisticGraph; + return { + FCP: computeWasteWithGraph(urlsToChange, fcpGraph, context.lantern.simulator), + LCP: computeWasteWithGraph(urlsToChange, lcpGraph, context.lantern.simulator) + }; +} +function finalize43(partialModel) { + return { + insightKey: InsightKeys.MODERN_HTTP, + strings: UIStrings14, + title: i18nString13(UIStrings14.title), + description: i18nString13(UIStrings14.description), + docs: "https://developer.chrome.com/docs/performance/insights/modern-http", + category: InsightCategory.LCP, + state: partialModel.http1Requests.length > 0 ? "fail" : "pass", + ...partialModel, + relatedEvents: partialModel.http1Requests + }; +} +function generateInsight13(data31, context) { + const isWithinContext = /* @__PURE__ */ __name((event) => Timing_exports3.eventIsInBounds(event, context.bounds), "isWithinContext"); + const contextRequests = data31.NetworkRequests.byTime.filter(isWithinContext); + const entityMappings3 = data31.NetworkRequests.entityMappings; + const firstPartyUrl = context.navigation?.args.data?.documentLoaderURL ?? data31.Meta.mainFrameURL; + const firstPartyEntity = helpers_exports.getEntityForUrl(firstPartyUrl, entityMappings3); + const http1Requests = determineHttp1Requests(contextRequests, entityMappings3, firstPartyEntity ?? null); + return finalize43({ + http1Requests, + metricSavings: computeMetricSavings(http1Requests, context) + }); +} +function createOverlayForRequest3(request) { + return { + type: "ENTRY_OUTLINE", + entry: request, + outlineReason: "ERROR" + }; +} +function createOverlays13(model2) { + return model2.http1Requests.map((req) => createOverlayForRequest3(req)) ?? []; +} +var UIStrings14, i18nString13; +var init_ModernHTTP = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/ModernHTTP.js"() { + init_process_global(); + init_platform(); + init_handlers(); + init_helpers2(); + init_types4(); + UIStrings14 = { + /** + * @description Title of an insight that recommends using HTTP/2 over HTTP/1.1 because of the performance benefits. "HTTP" should not be translated. + */ + title: "Modern HTTP", + /** + * @description Description of an insight that recommends recommends using HTTP/2 over HTTP/1.1 because of the performance benefits. "HTTP" should not be translated. + */ + description: "HTTP/2 and HTTP/3 offer many benefits over HTTP/1.1, such as multiplexing. [Learn more about using modern HTTP](https://developer.chrome.com/docs/performance/insights/modern-http).", + /** + * @description Column header for a table where each cell represents a network request. + */ + request: "Request", + /** + * @description Column header for a table where each cell represents the protocol of a network request. + */ + protocol: "Protocol", + /** + * @description Text explaining that there were not requests that were slowed down by using HTTP/1.1. "HTTP/1.1" should not be translated. + */ + noOldProtocolRequests: "No requests used HTTP/1.1, or its current use of HTTP/1.1 does not present a significant optimization opportunity. HTTP/1.1 requests are only flagged if six or more static assets originate from the same origin, and they are not served from a local development environment or a third-party source." + }; + i18nString13 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(isModernHTTPInsight, "isModernHTTPInsight"); + __name(isMultiplexableStaticAsset, "isMultiplexableStaticAsset"); + __name(determineHttp1Requests, "determineHttp1Requests"); + __name(computeWasteWithGraph, "computeWasteWithGraph"); + __name(computeMetricSavings, "computeMetricSavings"); + __name(finalize43, "finalize"); + __name(generateInsight13, "generateInsight"); + __name(createOverlayForRequest3, "createOverlayForRequest"); + __name(createOverlays13, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js +var NetworkDependencyTree_exports = {}; +__export(NetworkDependencyTree_exports, { + ParsedURL: () => ParsedURL, + TOO_MANY_PRECONNECTS_THRESHOLD: () => TOO_MANY_PRECONNECTS_THRESHOLD, + UIStrings: () => UIStrings15, + createOverlays: () => createOverlays14, + generateInsight: () => generateInsight14, + generatePreconnectCandidates: () => generatePreconnectCandidates, + generatePreconnectedOrigins: () => generatePreconnectedOrigins, + handleLinkResponseHeader: () => handleLinkResponseHeader, + i18nString: () => i18nString14, + isNetworkDependencyTreeInsight: () => isNetworkDependencyTreeInsight, + normalizePath: () => normalizePath, + schemeIs: () => schemeIs +}); +function finalize44(partialModel) { + return { + insightKey: InsightKeys.NETWORK_DEPENDENCY_TREE, + strings: UIStrings15, + title: i18nString14(UIStrings15.title), + description: i18nString14(UIStrings15.description), + docs: "https://developer.chrome.com/docs/performance/insights/network-dependency-tree", + category: InsightCategory.LCP, + state: partialModel.fail ? "fail" : "pass", + ...partialModel + }; +} +function isCritical(request, context) { + if (request.args.data.requestId === context.navigationId) { + return true; + } + if (request.args.data.isLinkPreload) { + return false; + } + const isIframe = request.args.data.resourceType === "Document" && request.args.data.frame !== context.frameId; + if (nonCriticalResourceTypes.has(request.args.data.resourceType) || isIframe || // Treat any missed images, primarily favicons, as non-critical resources + request.args.data.mimeType.startsWith("image/")) { + return false; + } + const initiatorUrl = request.args.data.initiator?.url || Trace_exports.getStackTraceTopCallFrameInEventPayload(request)?.url; + if (!initiatorUrl) { + return false; + } + const isBlocking = Network_exports.isSyntheticNetworkRequestEventRenderBlocking(request); + const isHighPriority = Network_exports.isSyntheticNetworkRequestHighPriority(request); + return isHighPriority || isBlocking; +} +function findMaxLeafNode(node) { + if (node.children.length === 0) { + return node; + } + let maxLeaf = node.children[0]; + for (const child of node.children) { + const leaf = findMaxLeafNode(child); + if (leaf.timeFromInitialRequest > maxLeaf.timeFromInitialRequest) { + maxLeaf = leaf; + } + } + return maxLeaf; +} +function sortRecursively(nodes) { + for (const node of nodes) { + if (node.children.length > 0) { + node.children.sort((nodeA, nodeB) => { + const leafA = findMaxLeafNode(nodeA); + const leafB = findMaxLeafNode(nodeB); + return leafB.timeFromInitialRequest - leafA.timeFromInitialRequest; + }); + sortRecursively(node.children); + } + } +} +function generateNetworkDependencyTree(context) { + const rootNodes = []; + const relatedEvents = /* @__PURE__ */ new Map(); + let maxTime = Timing_exports.Micro(0); + let fail = false; + let longestChain = []; + function addChain(path7) { + if (path7.length === 0) { + return; + } + if (path7.length >= 2) { + fail = true; + } + const initialRequest = path7[0]; + const lastRequest = path7[path7.length - 1]; + const totalChainTime = Timing_exports.Micro(lastRequest.ts + lastRequest.dur - initialRequest.ts); + if (totalChainTime > maxTime) { + maxTime = totalChainTime; + longestChain = path7; + } + let currentNodes = rootNodes; + for (let depth = 0; depth < path7.length; ++depth) { + const request = path7[depth]; + let found = currentNodes.find((node) => node.request === request); + if (!found) { + const timeFromInitialRequest = Timing_exports.Micro(request.ts + request.dur - initialRequest.ts); + found = { + request, + timeFromInitialRequest, + children: [], + relatedRequests: /* @__PURE__ */ new Set() + }; + currentNodes.push(found); + } + path7.forEach((request2) => found?.relatedRequests.add(request2)); + relatedEvents.set(request, depth < 2 ? [] : [i18nString14(UIStrings15.warningDescription)]); + currentNodes = found.children; + } + } + __name(addChain, "addChain"); + const seenNodes = /* @__PURE__ */ new Set(); + function getNextNodes(node) { + return node.getDependents().filter((n) => n.getDependencies().every((d) => seenNodes.has(d))); + } + __name(getNextNodes, "getNextNodes"); + context.lantern?.graph.traverse((node, traversalPath) => { + seenNodes.add(node); + if (node.type !== "network") { + return; + } + const networkNode = node; + if (!isCritical(networkNode.rawRequest, context)) { + return; + } + const networkPath = traversalPath.filter((node2) => node2.type === "network").reverse().map((node2) => node2.rawRequest); + if (networkPath.some((request) => !isCritical(request, context))) { + return; + } + if (node.isNonNetworkProtocol) { + return; + } + addChain(networkPath); + }, getNextNodes); + if (longestChain.length > 0) { + let currentNodes = rootNodes; + for (const request of longestChain) { + const found = currentNodes.find((node) => node.request === request); + if (found) { + found.isLongest = true; + currentNodes = found.children; + } else { + console.error("Some request in the longest chain is not found"); + } + } + } + sortRecursively(rootNodes); + return { + rootNodes, + maxTime, + fail, + relatedEvents + }; +} +function getSecurityOrigin(url) { + const parsedURL = new ParsedURL(url); + return parsedURL.securityOrigin(); +} +function handleLinkResponseHeaderPart(trimmedPart) { + if (!trimmedPart) { + return null; + } + const urlStart = trimmedPart.indexOf("<"); + const urlEnd = trimmedPart.indexOf(">"); + if (urlStart !== 0 || urlEnd === -1 || urlEnd <= urlStart) { + return null; + } + const url = trimmedPart.substring(urlStart + 1, urlEnd).trim(); + if (!url) { + return null; + } + const paramsString = trimmedPart.substring(urlEnd + 1).trim(); + if (paramsString) { + const params = paramsString.split(";"); + for (const param of params) { + const trimmedParam = param.trim(); + if (!trimmedParam) { + continue; + } + const eqIndex = trimmedParam.indexOf("="); + if (eqIndex === -1) { + continue; + } + const paramName = trimmedParam.substring(0, eqIndex).trim().toLowerCase(); + let paramValue = trimmedParam.substring(eqIndex + 1).trim(); + if (paramValue.startsWith('"') && paramValue.endsWith('"')) { + paramValue = paramValue.substring(1, paramValue.length - 1); + } + if (paramName === "rel" && paramValue === "preconnect") { + return { url, headerText: trimmedPart }; + } + } + } + return null; +} +function handleLinkResponseHeader(linkHeaderValue) { + if (!linkHeaderValue) { + return []; + } + const preconnectedOrigins = []; + for (let i = 0; i < linkHeaderValue.length; ) { + const firstUrlEnd = linkHeaderValue.indexOf(">", i); + if (firstUrlEnd === -1) { + break; + } + const commaIndex = linkHeaderValue.indexOf(",", firstUrlEnd); + const partEnd = commaIndex !== -1 ? commaIndex : linkHeaderValue.length; + const part = linkHeaderValue.substring(i, partEnd); + if (partEnd + 1 <= i) { + console.warn("unexpected infinite loop, bailing"); + break; + } + i = partEnd + 1; + const preconnectedOrigin = handleLinkResponseHeaderPart(part.trim()); + if (preconnectedOrigin) { + preconnectedOrigins.push(preconnectedOrigin); + } + } + return preconnectedOrigins; +} +function generatePreconnectedOrigins(data31, context, contextRequests, preconnectCandidates) { + const preconnectedOrigins = []; + for (const event of data31.NetworkRequests.linkPreconnectEvents) { + preconnectedOrigins.push({ + node_id: event.args.data.node_id, + frame: event.args.data.frame, + url: event.args.data.url, + // For each origin the page wanted to preconnect to: + // - if we found no network requests to that origin at all then we issue a unused warning + unused: !contextRequests.some((request) => getSecurityOrigin(event.args.data.url) === getSecurityOrigin(request.args.data.url)), + // - else (we found network requests to the same origin) and if some of those network requests is too slow (if + // they are preconnect candidates), then we issue a unused warning with crossorigin hint + crossorigin: preconnectCandidates.some((candidate) => candidate.origin === getSecurityOrigin(event.args.data.url)), + source: "DOM" + }); + } + const documentRequest = data31.NetworkRequests.byId.get(context.navigationId); + documentRequest?.args.data.responseHeaders?.forEach((header) => { + if (header.name.toLowerCase() === "link") { + const preconnectedOriginsFromResponseHeader = handleLinkResponseHeader(header.value); + preconnectedOriginsFromResponseHeader?.forEach((origin) => preconnectedOrigins.push({ + url: origin.url, + headerText: origin.headerText, + request: documentRequest, + // For each origin the page wanted to preconnect to: + // - if we found no network requests to that origin at all then we issue a unused warning + unused: !contextRequests.some((request) => getSecurityOrigin(origin.url) === getSecurityOrigin(request.args.data.url)), + // - else (we found network requests to the same origin) and if some of those network requests is too slow (if + // they are preconnect candidates), then we issue a unused warning with crossorigin hint + crossorigin: preconnectCandidates.some((candidate) => candidate.origin === getSecurityOrigin(origin.url)), + source: "ResponseHeader" + })); + } + }); + return preconnectedOrigins; +} +function hasValidTiming(request) { + return !!request.args.data.timing && request.args.data.timing.connectEnd >= 0 && request.args.data.timing.connectStart >= 0; +} +function hasAlreadyConnectedToOrigin(request) { + const { timing } = request.args.data; + if (!timing) { + return false; + } + if (timing.dnsStart === -1 && timing.dnsEnd === -1 && timing.connectStart === -1 && timing.connectEnd === -1) { + return true; + } + if (timing.dnsEnd - timing.dnsStart === 0 && timing.connectEnd - timing.connectStart === 0) { + return true; + } + return false; +} +function socketStartTimeIsBelowThreshold(request, mainResource) { + const timeSinceMainEnd = Math.max(0, request.args.data.syntheticData.sendStartTime - mainResource.args.data.syntheticData.finishTime); + return Timing_exports3.microToMilli(timeSinceMainEnd) < PRECONNECT_SOCKET_MAX_IDLE_IN_MS; +} +function candidateRequestsByOrigin(data31, mainResource, contextRequests, lcpGraphURLs) { + const origins = /* @__PURE__ */ new Map(); + contextRequests.forEach((request) => { + if (!hasValidTiming(request)) { + return; + } + if (data31.NetworkRequests.eventToInitiator.get(request) === mainResource) { + return; + } + const url = new URL(request.args.data.url); + if (url.origin === "null") { + return; + } + const mainOrigin = new URL(mainResource.args.data.url).origin; + if (url.origin === mainOrigin) { + return; + } + if (!lcpGraphURLs.has(request.args.data.url)) { + return; + } + if (hasAlreadyConnectedToOrigin(request)) { + return; + } + if (!socketStartTimeIsBelowThreshold(request, mainResource)) { + return; + } + const originRequests = MapUtilities_exports.getWithDefault(origins, url.origin, () => []); + originRequests.push(request); + }); + return origins; +} +function generatePreconnectCandidates(data31, context, contextRequests) { + if (!context.lantern) { + return []; + } + const documentRequest = data31.NetworkRequests.byId.get(context.navigationId); + if (!documentRequest) { + return []; + } + const { rtt, additionalRttByOrigin } = context.lantern.simulator.getOptions(); + const lcpGraph = context.lantern.metrics.largestContentfulPaint.pessimisticGraph; + const fcpGraph = context.lantern.metrics.firstContentfulPaint.pessimisticGraph; + const lcpGraphURLs = /* @__PURE__ */ new Set(); + lcpGraph.traverse((node) => { + if (node.type === "network") { + lcpGraphURLs.add(node.request.url); + } + }); + const fcpGraphURLs = /* @__PURE__ */ new Set(); + fcpGraph.traverse((node) => { + if (node.type === "network") { + fcpGraphURLs.add(node.request.url); + } + }); + const groupedOrigins = candidateRequestsByOrigin(data31, documentRequest, contextRequests, lcpGraphURLs); + let maxWastedLcp = Timing_exports.Milli(0); + let maxWastedFcp = Timing_exports.Milli(0); + let preconnectCandidates = []; + groupedOrigins.forEach((requests) => { + const firstRequestOfOrigin = requests[0]; + if (!firstRequestOfOrigin.args.data.timing) { + return; + } + const firstRequestOfOriginParsedURL = new ParsedURL(firstRequestOfOrigin.args.data.url); + const origin = firstRequestOfOriginParsedURL.securityOrigin(); + const additionalRtt = additionalRttByOrigin.get(origin) ?? 0; + let connectionTime = Timing_exports.Milli(rtt + additionalRtt); + if (firstRequestOfOriginParsedURL.scheme === "https") { + connectionTime = Timing_exports.Milli(connectionTime * 2); + } + const timeBetweenMainResourceAndDnsStart = Timing_exports.Micro(firstRequestOfOrigin.args.data.syntheticData.sendStartTime - documentRequest.args.data.syntheticData.finishTime + Timing_exports3.milliToMicro(firstRequestOfOrigin.args.data.timing.dnsStart)); + const wastedMs = Math.min(connectionTime, Timing_exports3.microToMilli(timeBetweenMainResourceAndDnsStart)); + if (wastedMs < IGNORE_THRESHOLD_IN_MILLISECONDS) { + return; + } + maxWastedLcp = Math.max(wastedMs, maxWastedLcp); + if (fcpGraphURLs.has(firstRequestOfOrigin.args.data.url)) { + maxWastedFcp = Math.max(wastedMs, maxWastedFcp); + } + preconnectCandidates.push({ + origin, + wastedMs + }); + }); + preconnectCandidates = preconnectCandidates.sort((a, b) => b.wastedMs - a.wastedMs); + return preconnectCandidates.slice(0, TOO_MANY_PRECONNECTS_THRESHOLD); +} +function isNetworkDependencyTreeInsight(model2) { + return model2.insightKey === InsightKeys.NETWORK_DEPENDENCY_TREE; +} +function generateInsight14(data31, context) { + if (!context.navigation) { + return finalize44({ + rootNodes: [], + maxTime: 0, + fail: false, + preconnectedOrigins: [], + preconnectCandidates: [] + }); + } + const { rootNodes, maxTime, fail, relatedEvents } = generateNetworkDependencyTree(context); + const isWithinContext = /* @__PURE__ */ __name((event) => Timing_exports3.eventIsInBounds(event, context.bounds), "isWithinContext"); + const contextRequests = data31.NetworkRequests.byTime.filter(isWithinContext); + const preconnectCandidates = generatePreconnectCandidates(data31, context, contextRequests); + const preconnectedOrigins = generatePreconnectedOrigins(data31, context, contextRequests, preconnectCandidates); + return finalize44({ + rootNodes, + maxTime, + fail, + relatedEvents, + preconnectedOrigins, + preconnectCandidates + }); +} +function createOverlays14(model2) { + function walk(nodes, overlays2) { + nodes.forEach((node) => { + overlays2.push({ + type: "ENTRY_OUTLINE", + entry: node.request, + outlineReason: "ERROR" + }); + walk(node.children, overlays2); + }); + } + __name(walk, "walk"); + const overlays = []; + walk(model2.rootNodes, overlays); + return overlays; +} +function normalizePath(path7) { + if (path7.indexOf("..") === -1 && path7.indexOf(".") === -1) { + return path7; + } + const segments = (path7[0] === "/" ? path7.substring(1) : path7).split("/"); + const normalizedSegments = []; + for (const segment of segments) { + if (segment === ".") { + continue; + } else if (segment === "..") { + normalizedSegments.pop(); + } else { + normalizedSegments.push(segment); + } + } + let normalizedPath = normalizedSegments.join("/"); + if (path7[0] === "/" && normalizedPath) { + normalizedPath = "/" + normalizedPath; + } + if (normalizedPath[normalizedPath.length - 1] !== "/" && (path7[path7.length - 1] === "/" || segments[segments.length - 1] === "." || segments[segments.length - 1] === "..")) { + normalizedPath = normalizedPath + "/"; + } + return normalizedPath; +} +function schemeIs(url, scheme) { + try { + return new URL(url).protocol === scheme; + } catch { + return false; + } +} +var UIStrings15, i18nString14, nonCriticalResourceTypes, PRECONNECT_SOCKET_MAX_IDLE_IN_MS, IGNORE_THRESHOLD_IN_MILLISECONDS, TOO_MANY_PRECONNECTS_THRESHOLD, ParsedURL; +var init_NetworkDependencyTree = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js"() { + init_process_global(); + init_platform(); + init_helpers2(); + init_types2(); + init_types4(); + UIStrings15 = { + /** + * @description Title of an insight that recommends avoiding chaining critical requests. + */ + title: "Network dependency tree", + /** + * @description Description of an insight that recommends avoiding chaining critical requests. + */ + description: "[Avoid chaining critical requests](https://developer.chrome.com/docs/performance/insights/network-dependency-tree) by reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load.", + /** + * @description Description of the warning that recommends avoiding chaining critical requests. + */ + warningDescription: "Avoid chaining critical requests by reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load.", + /** + * @description Text status indicating that there isn't long chaining critical network requests. + */ + noNetworkDependencyTree: "No rendering tasks impacted by network dependencies", + /** + * @description Text for the maximum critical path latency. This refers to the longest chain of network requests that + * the browser must download before it can render the page. + */ + maxCriticalPathLatency: "Max critical path latency:", + /** Label for a column in a data table; entries will be the network request */ + columnRequest: "Request", + /** Label for a column in a data table; entries will be the time from main document till current network request. */ + columnTime: "Time", + /** + * @description Title of the table of the detected preconnect origins. + */ + preconnectOriginsTableTitle: "Preconnected origins", + /** + * @description Description of the table of the detected preconnect origins. + */ + preconnectOriginsTableDescription: "[preconnect](https://developer.chrome.com/docs/lighthouse/performance/uses-rel-preconnect/) hints help the browser establish a connection earlier in the page load, saving time when the first request for that origin is made. The following are the origins that the page preconnected to.", + /** + * @description Text status indicating that there isn't any preconnected origins. + */ + noPreconnectOrigins: "no origins were preconnected", + /** + * @description A warning message that is shown when found more than 4 preconnected links. "preconnect" should not be translated. + */ + tooManyPreconnectLinksWarning: "More than 4 `preconnect` connections were found. These should be used sparingly and only to the most important origins.", + /** + * @description A warning message that is shown when the user added preconnect for some unnecessary origins. "preconnect" should not be translated. + */ + unusedWarning: "Unused preconnect. Only use `preconnect` for origins that the page is likely to request.", + /** + * @description A warning message that is shown when the user forget to set the `crossorigin` HTML attribute, or setting it to an incorrect value, on the link is a common mistake when adding preconnect links. "preconnect" should not be translated. + * */ + crossoriginWarning: "Unused preconnect. Check that the `crossorigin` attribute is used properly.", + /** + * @description Label for a column in a data table; entries will be the source of the origin. + */ + columnSource: "Source", + /** + * @description Text status indicating that there isn't preconnect candidates. + */ + noPreconnectCandidates: "No additional origins are good candidates for preconnecting", + /** + * @description Title of the table that shows the origins that the page should have preconnected to. + */ + estSavingTableTitle: "Preconnect candidates", + /** + * @description Description of the table that recommends preconnecting to the origins to save time. "preconnect" should not be translated. + */ + estSavingTableDescription: "Add [preconnect](https://developer.chrome.com/docs/lighthouse/performance/uses-rel-preconnect/) hints to your most important origins, but try to use no more than 4.", + /** + * @description Label for a column in a data table; entries will be the origin of a web resource + */ + columnOrigin: "Origin", + /** + * @description Label for a column in a data table; entries will be the number of milliseconds the user could reduce page load by if they implemented the suggestions. + */ + columnWastedMs: "Est LCP savings" + }; + i18nString14 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + nonCriticalResourceTypes = /* @__PURE__ */ new Set([ + "Image", + "XHR", + "Fetch", + "EventSource" + ]); + PRECONNECT_SOCKET_MAX_IDLE_IN_MS = Timing_exports.Milli(15e3); + IGNORE_THRESHOLD_IN_MILLISECONDS = Timing_exports.Milli(50); + TOO_MANY_PRECONNECTS_THRESHOLD = 4; + __name(finalize44, "finalize"); + __name(isCritical, "isCritical"); + __name(findMaxLeafNode, "findMaxLeafNode"); + __name(sortRecursively, "sortRecursively"); + __name(generateNetworkDependencyTree, "generateNetworkDependencyTree"); + __name(getSecurityOrigin, "getSecurityOrigin"); + __name(handleLinkResponseHeaderPart, "handleLinkResponseHeaderPart"); + __name(handleLinkResponseHeader, "handleLinkResponseHeader"); + __name(generatePreconnectedOrigins, "generatePreconnectedOrigins"); + __name(hasValidTiming, "hasValidTiming"); + __name(hasAlreadyConnectedToOrigin, "hasAlreadyConnectedToOrigin"); + __name(socketStartTimeIsBelowThreshold, "socketStartTimeIsBelowThreshold"); + __name(candidateRequestsByOrigin, "candidateRequestsByOrigin"); + __name(generatePreconnectCandidates, "generatePreconnectCandidates"); + __name(isNetworkDependencyTreeInsight, "isNetworkDependencyTreeInsight"); + __name(generateInsight14, "generateInsight"); + __name(createOverlays14, "createOverlays"); + __name(normalizePath, "normalizePath"); + __name(schemeIs, "schemeIs"); + ParsedURL = class _ParsedURL { + static { + __name(this, "ParsedURL"); + } + isValid; + url; + scheme; + user; + host; + port; + path; + queryParams; + fragment; + folderPathComponents; + lastPathComponent; + blobInnerScheme; + constructor(url) { + this.isValid = false; + this.url = url; + this.scheme = ""; + this.user = ""; + this.host = ""; + this.port = ""; + this.path = ""; + this.queryParams = ""; + this.fragment = ""; + this.folderPathComponents = ""; + this.lastPathComponent = ""; + const isBlobUrl = this.url.startsWith("blob:"); + const urlToMatch = isBlobUrl ? url.substring(5) : url; + const match = urlToMatch.match(_ParsedURL.urlRegex()); + if (match) { + this.isValid = true; + if (isBlobUrl) { + this.blobInnerScheme = match[2].toLowerCase(); + this.scheme = "blob"; + } else { + this.scheme = match[2].toLowerCase(); + } + this.user = match[3] ?? ""; + this.host = match[4] ?? ""; + this.port = match[5] ?? ""; + this.path = match[6] ?? "/"; + this.queryParams = match[7] ?? ""; + this.fragment = match[8] ?? ""; + } else { + if (this.url.startsWith("data:")) { + this.scheme = "data"; + return; + } + if (this.url.startsWith("blob:")) { + this.scheme = "blob"; + return; + } + if (this.url === "about:blank") { + this.scheme = "about"; + return; + } + this.path = this.url; + } + const lastSlashExceptTrailingIndex = this.path.lastIndexOf("/", this.path.length - 2); + if (lastSlashExceptTrailingIndex !== -1) { + this.lastPathComponent = this.path.substring(lastSlashExceptTrailingIndex + 1); + } else { + this.lastPathComponent = this.path; + } + const lastSlashIndex = this.path.lastIndexOf("/"); + if (lastSlashIndex !== -1) { + this.folderPathComponents = this.path.substring(0, lastSlashIndex); + } + } + static fromString(string) { + const parsedURL = new _ParsedURL(string.toString()); + if (parsedURL.isValid) { + return parsedURL; + } + return null; + } + static preEncodeSpecialCharactersInPath(path7) { + for (const specialChar of ["%", ";", "#", "?", " "]) { + path7 = path7.replaceAll(specialChar, encodeURIComponent(specialChar)); + } + return path7; + } + static rawPathToEncodedPathString(path7) { + const partiallyEncoded = _ParsedURL.preEncodeSpecialCharactersInPath(path7); + if (path7.startsWith("/")) { + return new URL(partiallyEncoded, "file:///").pathname; + } + return new URL("/" + partiallyEncoded, "file:///").pathname.substr(1); + } + /** + * @param name Must not be encoded + */ + static encodedFromParentPathAndName(parentPath, name) { + return _ParsedURL.concatenate(parentPath, "/", _ParsedURL.preEncodeSpecialCharactersInPath(name)); + } + /** + * @param name Must not be encoded + */ + static urlFromParentUrlAndName(parentUrl, name) { + return _ParsedURL.concatenate(parentUrl, "/", _ParsedURL.preEncodeSpecialCharactersInPath(name)); + } + static encodedPathToRawPathString(encPath) { + return decodeURIComponent(encPath); + } + static rawPathToUrlString(fileSystemPath) { + let preEncodedPath = _ParsedURL.preEncodeSpecialCharactersInPath(fileSystemPath.replace(/\\/g, "/")); + preEncodedPath = preEncodedPath.replace(/\\/g, "/"); + if (!preEncodedPath.startsWith("file://")) { + if (preEncodedPath.startsWith("/")) { + preEncodedPath = "file://" + preEncodedPath; + } else { + preEncodedPath = "file:///" + preEncodedPath; + } + } + return new URL(preEncodedPath).toString(); + } + static relativePathToUrlString(relativePath, baseURL) { + const preEncodedPath = _ParsedURL.preEncodeSpecialCharactersInPath(relativePath.replace(/\\/g, "/")); + return new URL(preEncodedPath, baseURL).toString(); + } + static urlToRawPathString(fileURL, isWindows2) { + console.assert(fileURL.startsWith("file://"), "This must be a file URL."); + const decodedFileURL = decodeURIComponent(fileURL); + if (isWindows2) { + return decodedFileURL.substr("file:///".length).replace(/\//g, "\\"); + } + return decodedFileURL.substr("file://".length); + } + static sliceUrlToEncodedPathString(url, start) { + return url.substring(start); + } + static substr(devToolsPath, from, length) { + return devToolsPath.substr(from, length); + } + static substring(devToolsPath, start, end) { + return devToolsPath.substring(start, end); + } + static prepend(prefix, devToolsPath) { + return prefix + devToolsPath; + } + static concatenate(devToolsPath, ...appendage) { + return devToolsPath.concat(...appendage); + } + static trim(devToolsPath) { + return devToolsPath.trim(); + } + static slice(devToolsPath, start, end) { + return devToolsPath.slice(start, end); + } + static join(devToolsPaths, separator) { + return devToolsPaths.join(separator); + } + static split(devToolsPath, separator, limit) { + return devToolsPath.split(separator, limit); + } + static toLowerCase(devToolsPath) { + return devToolsPath.toLowerCase(); + } + static isValidUrlString(str) { + return new _ParsedURL(str).isValid; + } + static urlWithoutHash(url) { + const hashIndex = url.indexOf("#"); + if (hashIndex !== -1) { + return url.substr(0, hashIndex); + } + return url; + } + static urlRegex() { + if (_ParsedURL.urlRegexInstance) { + return _ParsedURL.urlRegexInstance; + } + const schemeRegex = /([A-Za-z][A-Za-z0-9+.-]*):\/\//; + const userRegex = /(?:([A-Za-z0-9\-._~%!$&'()*+,;=:]*)@)?/; + const hostRegex = /((?:\[::\d?\])|(?:[^\s\/:]*))/; + const portRegex = /(?::([\d]+))?/; + const pathRegex = /(\/[^#?]*)?/; + const queryRegex = /(?:\?([^#]*))?/; + const fragmentRegex = /(?:#(.*))?/; + _ParsedURL.urlRegexInstance = new RegExp("^(" + schemeRegex.source + userRegex.source + hostRegex.source + portRegex.source + ")" + pathRegex.source + queryRegex.source + fragmentRegex.source + "$"); + return _ParsedURL.urlRegexInstance; + } + static extractPath(url) { + const parsedURL = this.fromString(url); + return parsedURL ? parsedURL.path : ""; + } + static extractOrigin(url) { + const parsedURL = this.fromString(url); + return parsedURL ? parsedURL.securityOrigin() : ""; + } + static extractExtension(url) { + url = _ParsedURL.urlWithoutHash(url); + const indexOfQuestionMark = url.indexOf("?"); + if (indexOfQuestionMark !== -1) { + url = url.substr(0, indexOfQuestionMark); + } + const lastIndexOfSlash = url.lastIndexOf("/"); + if (lastIndexOfSlash !== -1) { + url = url.substr(lastIndexOfSlash + 1); + } + const lastIndexOfDot = url.lastIndexOf("."); + if (lastIndexOfDot !== -1) { + url = url.substr(lastIndexOfDot + 1); + const lastIndexOfPercent = url.indexOf("%"); + if (lastIndexOfPercent !== -1) { + return url.substr(0, lastIndexOfPercent); + } + return url; + } + return ""; + } + static extractName(url) { + let index = url.lastIndexOf("/"); + const pathAndQuery = index !== -1 ? url.substr(index + 1) : url; + index = pathAndQuery.indexOf("?"); + return index < 0 ? pathAndQuery : pathAndQuery.substr(0, index); + } + static completeURL(baseURL, href) { + if (href.startsWith("data:") || href.startsWith("blob:") || href.startsWith("javascript:") || href.startsWith("mailto:")) { + return href; + } + const trimmedHref = href.trim(); + const parsedHref = this.fromString(trimmedHref); + if (parsedHref?.scheme) { + const securityOrigin2 = parsedHref.securityOrigin(); + const pathText2 = normalizePath(parsedHref.path); + const queryText2 = parsedHref.queryParams && `?${parsedHref.queryParams}`; + const fragmentText = parsedHref.fragment && `#${parsedHref.fragment}`; + return securityOrigin2 + pathText2 + queryText2 + fragmentText; + } + const parsedURL = this.fromString(baseURL); + if (!parsedURL) { + return null; + } + if (parsedURL.isDataURL()) { + return href; + } + if (href.length > 1 && href.charAt(0) === "/" && href.charAt(1) === "/") { + return parsedURL.scheme + ":" + href; + } + const securityOrigin = parsedURL.securityOrigin(); + const pathText = parsedURL.path; + const queryText = parsedURL.queryParams ? "?" + parsedURL.queryParams : ""; + if (!href.length) { + return securityOrigin + pathText + queryText; + } + if (href.charAt(0) === "#") { + return securityOrigin + pathText + queryText + href; + } + if (href.charAt(0) === "?") { + return securityOrigin + pathText + href; + } + const hrefMatches = href.match(/^[^#?]*/); + if (!hrefMatches || !href.length) { + throw new Error("Invalid href"); + } + let hrefPath = hrefMatches[0]; + const hrefSuffix = href.substring(hrefPath.length); + if (hrefPath.charAt(0) !== "/") { + hrefPath = parsedURL.folderPathComponents + "/" + hrefPath; + } + return securityOrigin + normalizePath(hrefPath) + hrefSuffix; + } + static splitLineAndColumn(string) { + const beforePathMatch = string.match(_ParsedURL.urlRegex()); + let beforePath = ""; + let pathAndAfter = string; + if (beforePathMatch) { + beforePath = beforePathMatch[1]; + pathAndAfter = string.substring(beforePathMatch[1].length); + } + const lineColumnRegEx = /(?::(\d+))?(?::(\d+))?$/; + const lineColumnMatch = lineColumnRegEx.exec(pathAndAfter); + let lineNumber; + let columnNumber; + console.assert(Boolean(lineColumnMatch)); + if (!lineColumnMatch) { + return { url: string, lineNumber: 0, columnNumber: 0 }; + } + if (typeof lineColumnMatch[1] === "string") { + lineNumber = parseInt(lineColumnMatch[1], 10); + lineNumber = isNaN(lineNumber) ? void 0 : lineNumber - 1; + } + if (typeof lineColumnMatch[2] === "string") { + columnNumber = parseInt(lineColumnMatch[2], 10); + columnNumber = isNaN(columnNumber) ? void 0 : columnNumber - 1; + } + let url = beforePath + pathAndAfter.substring(0, pathAndAfter.length - lineColumnMatch[0].length); + if (lineColumnMatch[1] === void 0 && lineColumnMatch[2] === void 0) { + const wasmCodeOffsetRegex = /wasm-function\[\d+\]:0x([a-z0-9]+)$/g; + const wasmCodeOffsetMatch = wasmCodeOffsetRegex.exec(pathAndAfter); + if (wasmCodeOffsetMatch && typeof wasmCodeOffsetMatch[1] === "string") { + url = _ParsedURL.removeWasmFunctionInfoFromURL(url); + columnNumber = parseInt(wasmCodeOffsetMatch[1], 16); + columnNumber = isNaN(columnNumber) ? void 0 : columnNumber; + } + } + return { url, lineNumber, columnNumber }; + } + static removeWasmFunctionInfoFromURL(url) { + const wasmFunctionRegEx = /:wasm-function\[\d+\]/; + const wasmFunctionIndex = url.search(wasmFunctionRegEx); + if (wasmFunctionIndex === -1) { + return url; + } + return _ParsedURL.substring(url, 0, wasmFunctionIndex); + } + static beginsWithWindowsDriveLetter(url) { + return /^[A-Za-z]:/.test(url); + } + static beginsWithScheme(url) { + return /^[A-Za-z][A-Za-z0-9+.-]*:/.test(url); + } + static isRelativeURL(url) { + return !this.beginsWithScheme(url) || this.beginsWithWindowsDriveLetter(url); + } + isAboutBlank() { + return this.url === "about:blank"; + } + isDataURL() { + return this.scheme === "data"; + } + extractDataUrlMimeType() { + const regexp = /^data:((?\w+)\/(?\w+))?(;base64)?,/; + const match = this.url.match(regexp); + return { + type: match?.groups?.type, + subtype: match?.groups?.subtype + }; + } + isBlobURL() { + return this.url.startsWith("blob:"); + } + lastPathComponentWithFragment() { + return this.lastPathComponent + (this.fragment ? "#" + this.fragment : ""); + } + domain() { + if (this.isDataURL()) { + return "data:"; + } + return this.host + (this.port ? ":" + this.port : ""); + } + securityOrigin() { + if (this.isDataURL()) { + return "data:"; + } + const scheme = this.isBlobURL() ? this.blobInnerScheme : this.scheme; + return scheme + "://" + this.domain(); + } + urlWithoutScheme() { + if (this.scheme && this.url.startsWith(this.scheme + "://")) { + return this.url.substring(this.scheme.length + 3); + } + return this.url; + } + static urlRegexInstance = null; + }; + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/RenderBlocking.js +var RenderBlocking_exports = {}; +__export(RenderBlocking_exports, { + UIStrings: () => UIStrings16, + createOverlayForRequest: () => createOverlayForRequest4, + createOverlays: () => createOverlays15, + generateInsight: () => generateInsight15, + i18nString: () => i18nString15, + isRenderBlockingInsight: () => isRenderBlockingInsight +}); +function isRenderBlockingInsight(insight) { + return insight.insightKey === "RenderBlocking"; +} +function getNodesAndTimingByRequestId(nodeTimings) { + const requestIdToNode = /* @__PURE__ */ new Map(); + for (const [node, nodeTiming] of nodeTimings) { + if (node.type !== "network") { + continue; + } + requestIdToNode.set(node.request.requestId, { node, nodeTiming }); + } + return requestIdToNode; +} +function estimateSavingsWithGraphs2(deferredIds, lanternContext) { + const simulator = lanternContext.simulator; + const fcpGraph = lanternContext.metrics.firstContentfulPaint.optimisticGraph; + const { nodeTimings } = lanternContext.simulator.simulate(fcpGraph); + const adjustedNodeTimings = new Map(nodeTimings); + const totalChildNetworkBytes = 0; + const minimalFCPGraph = fcpGraph.cloneWithRelationships((node) => { + const canDeferRequest = deferredIds.has(node.id); + return !canDeferRequest; + }); + if (minimalFCPGraph.type !== "network") { + throw new Error("minimalFCPGraph not a NetworkNode"); + } + const estimateBeforeInline = Math.max(...Array.from(Array.from(adjustedNodeTimings).map((timing) => timing[1].endTime))); + const originalTransferSize = minimalFCPGraph.request.transferSize; + const safeTransferSize = originalTransferSize || 0; + minimalFCPGraph.request.transferSize = safeTransferSize + totalChildNetworkBytes; + const estimateAfterInline = simulator.simulate(minimalFCPGraph).timeInMs; + minimalFCPGraph.request.transferSize = originalTransferSize; + return Math.round(Math.max(estimateBeforeInline - estimateAfterInline, 0)); +} +function hasImageLCP(data31, context) { + return data31.LargestImagePaint.lcpRequestByNavigationId.has(context.navigationId); +} +function computeSavings(data31, context, renderBlockingRequests) { + if (!context.lantern) { + return; + } + const nodesAndTimingsByRequestId = getNodesAndTimingByRequestId(context.lantern.metrics.firstContentfulPaint.optimisticEstimate.nodeTimings); + const metricSavings = { FCP: 0, LCP: 0 }; + const requestIdToWastedMs = /* @__PURE__ */ new Map(); + const deferredNodeIds = /* @__PURE__ */ new Set(); + for (const request of renderBlockingRequests) { + const nodeAndTiming = nodesAndTimingsByRequestId.get(request.args.data.requestId); + if (!nodeAndTiming) { + continue; + } + const { node, nodeTiming } = nodeAndTiming; + node.traverse((node2) => deferredNodeIds.add(node2.id)); + const wastedMs = Math.round(nodeTiming.duration); + if (wastedMs < MINIMUM_WASTED_MS) { + continue; + } + requestIdToWastedMs.set(node.id, wastedMs); + } + if (requestIdToWastedMs.size) { + metricSavings.FCP = estimateSavingsWithGraphs2(deferredNodeIds, context.lantern); + if (!hasImageLCP(data31, context)) { + metricSavings.LCP = metricSavings.FCP; + } + } + return { metricSavings, requestIdToWastedMs }; +} +function finalize45(partialModel) { + return { + insightKey: InsightKeys.RENDER_BLOCKING, + strings: UIStrings16, + title: i18nString15(UIStrings16.title), + description: i18nString15(UIStrings16.description), + docs: "https://developer.chrome.com/docs/performance/insights/render-blocking", + category: InsightCategory.LCP, + state: partialModel.renderBlockingRequests.length > 0 ? "fail" : "pass", + ...partialModel + }; +} +function generateInsight15(data31, context) { + if (!context.navigation) { + return finalize45({ + renderBlockingRequests: [] + }); + } + const firstPaintTs = data31.PageLoadMetrics.metricScoresByFrameId.get(context.frameId)?.get(context.navigationId)?.get(ModelHandlers_exports.PageLoadMetrics.MetricName.FP)?.event?.ts; + if (!firstPaintTs) { + return finalize45({ + renderBlockingRequests: [], + warnings: [InsightWarning.NO_FP] + }); + } + let renderBlockingRequests = []; + for (const req of data31.NetworkRequests.byTime) { + if (req.args.data.frame !== context.frameId) { + continue; + } + if (!Network_exports.isSyntheticNetworkRequestEventRenderBlocking(req)) { + continue; + } + if (req.args.data.syntheticData.finishTime > firstPaintTs) { + continue; + } + if (req.args.data.renderBlocking === "in_body_parser_blocking") { + const priority = req.args.data.priority; + const isScript = req.args.data.resourceType === "Script"; + const isBlockingScript = isScript && priority === "High"; + if (priority !== "VeryHigh" && !isBlockingScript) { + continue; + } + } + const navigation2 = Trace_exports.getNavigationForTraceEvent(req, context.frameId, data31.Meta.navigationsByFrameId); + if (navigation2 === context.navigation) { + renderBlockingRequests.push(req); + } + } + const savings = computeSavings(data31, context, renderBlockingRequests); + renderBlockingRequests = renderBlockingRequests.sort((a, b) => { + return b.dur - a.dur; + }); + return finalize45({ + relatedEvents: renderBlockingRequests, + renderBlockingRequests, + ...savings + }); +} +function createOverlayForRequest4(request) { + return { + type: "ENTRY_OUTLINE", + entry: request, + outlineReason: "ERROR" + }; +} +function createOverlays15(model2) { + return model2.renderBlockingRequests.map((request) => createOverlayForRequest4(request)); +} +var UIStrings16, i18nString15, MINIMUM_WASTED_MS; +var init_RenderBlocking = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/RenderBlocking.js"() { + init_process_global(); + init_handlers(); + init_helpers2(); + init_types4(); + UIStrings16 = { + /** + * @description Title of an insight that provides the user with the list of network requests that blocked and therefore slowed down the page rendering and becoming visible to the user. + */ + title: "Render blocking requests", + /** + * @description Text to describe that there are requests blocking rendering, which may affect LCP. + */ + description: "Requests are blocking the page's initial render, which may delay LCP. [Deferring or inlining](https://developer.chrome.com/docs/performance/insights/render-blocking) can move these network requests out of the critical path.", + /** + * @description Label to describe a network request (that happens to be render-blocking). + */ + renderBlockingRequest: "Request", + /** + * @description Label used for a time duration. + */ + duration: "Duration", + /** + * @description Text status indicating that no requests blocked the initial render of a navigation + */ + noRenderBlocking: "No render blocking requests for this navigation" + }; + i18nString15 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(isRenderBlockingInsight, "isRenderBlockingInsight"); + MINIMUM_WASTED_MS = 50; + __name(getNodesAndTimingByRequestId, "getNodesAndTimingByRequestId"); + __name(estimateSavingsWithGraphs2, "estimateSavingsWithGraphs"); + __name(hasImageLCP, "hasImageLCP"); + __name(computeSavings, "computeSavings"); + __name(finalize45, "finalize"); + __name(generateInsight15, "generateInsight"); + __name(createOverlayForRequest4, "createOverlayForRequest"); + __name(createOverlays15, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/SlowCSSSelector.js +var SlowCSSSelector_exports = {}; +__export(SlowCSSSelector_exports, { + UIStrings: () => UIStrings17, + createOverlays: () => createOverlays16, + generateInsight: () => generateInsight16, + i18nString: () => i18nString16, + isSlowCSSSelectorInsight: () => isSlowCSSSelectorInsight +}); +function aggregateSelectorStats(data31, context) { + const selectorMap = /* @__PURE__ */ new Map(); + for (const [event, value] of data31.dataForRecalcStyleEvent) { + if (event.args.beginData?.frame !== context.frameId) { + continue; + } + if (!Timing_exports3.eventIsInBounds(event, context.bounds)) { + continue; + } + for (const timing of value.timings) { + const key = timing[SelectorTimingsKey.Selector] + "_" + timing[SelectorTimingsKey.StyleSheetId]; + const findTiming = selectorMap.get(key); + if (findTiming !== void 0) { + findTiming[SelectorTimingsKey.Elapsed] += timing[SelectorTimingsKey.Elapsed]; + findTiming[SelectorTimingsKey.FastRejectCount] += timing[SelectorTimingsKey.FastRejectCount]; + findTiming[SelectorTimingsKey.MatchAttempts] += timing[SelectorTimingsKey.MatchAttempts]; + findTiming[SelectorTimingsKey.MatchCount] += timing[SelectorTimingsKey.MatchCount]; + } else { + selectorMap.set(key, { ...timing }); + } + } + } + return [...selectorMap.values()]; +} +function finalize46(partialModel) { + return { + insightKey: InsightKeys.SLOW_CSS_SELECTOR, + strings: UIStrings17, + title: i18nString16(UIStrings17.title), + description: i18nString16(UIStrings17.description), + docs: "https://developer.chrome.com/docs/performance/insights/slow-css-selector", + category: InsightCategory.ALL, + state: partialModel.topSelectorElapsedMs && partialModel.topSelectorMatchAttempts ? "informative" : "pass", + ...partialModel + }; +} +function isSlowCSSSelectorInsight(model2) { + return model2.insightKey === InsightKeys.SLOW_CSS_SELECTOR; +} +function generateInsight16(data31, context) { + const selectorStatsData = data31.SelectorStats; + if (!selectorStatsData) { + throw new Error("no selector stats data"); + } + const selectorTimings = aggregateSelectorStats(selectorStatsData, context); + let totalElapsedUs = 0; + let totalMatchAttempts = 0; + let totalMatchCount = 0; + selectorTimings.map((timing) => { + totalElapsedUs += timing[SelectorTimingsKey.Elapsed]; + totalMatchAttempts += timing[SelectorTimingsKey.MatchAttempts]; + totalMatchCount += timing[SelectorTimingsKey.MatchCount]; + }); + let topSelectorElapsedMs = null; + let topSelectorMatchAttempts = null; + if (selectorTimings.length > 0) { + topSelectorElapsedMs = selectorTimings.reduce((a, b) => { + return a[SelectorTimingsKey.Elapsed] > b[SelectorTimingsKey.Elapsed] ? a : b; + }); + if (topSelectorElapsedMs && topSelectorElapsedMs[SelectorTimingsKey.Elapsed] < slowCSSSelectorThreshold) { + topSelectorElapsedMs = null; + } + topSelectorMatchAttempts = selectorTimings.reduce((a, b) => { + return a[SelectorTimingsKey.MatchAttempts] > b[SelectorTimingsKey.MatchAttempts] ? a : b; + }); + } + return finalize46({ + // TODO: should we identify RecalcStyle events as linked to this insight? + relatedEvents: [], + totalElapsedMs: Timing_exports.Milli(totalElapsedUs / 1e3), + totalMatchAttempts, + totalMatchCount, + topSelectorElapsedMs, + topSelectorMatchAttempts + }); +} +function createOverlays16(_) { + return []; +} +var UIStrings17, i18nString16, slowCSSSelectorThreshold; +var init_SlowCSSSelector = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/SlowCSSSelector.js"() { + init_process_global(); + init_helpers2(); + init_TraceEvents(); + init_types2(); + init_types4(); + UIStrings17 = { + /** + * @description Title of an insight that provides details about slow CSS selectors. + */ + title: "CSS Selector costs", + /** + * @description Text to describe how to improve the performance of CSS selectors. + */ + description: "If Recalculate Style costs remain high, selector optimization can reduce them. [Optimize the selectors](https://developer.chrome.com/docs/performance/insights/slow-css-selector) with both high elapsed time and high slow-path %. Simpler selectors, fewer selectors, a smaller DOM, and a shallower DOM will all reduce matching costs.", + /** + * @description Column name for count of elements that the engine attempted to match against a style rule + */ + matchAttempts: "Match attempts", + /** + * @description Column name for count of elements that matched a style rule + */ + matchCount: "Match count", + /** + * @description Column name for elapsed time spent computing a style rule + */ + elapsed: "Elapsed time", + /** + * @description Column name for the selectors that took the longest amount of time/effort. + */ + topSelectors: "Top selectors", + /** + * @description Column name for a total sum. + */ + total: "Total", + /** + * @description Text status indicating that no CSS selector data was found. + */ + enableSelectorData: "No CSS selector data was found. CSS selector stats need to be enabled in the performance panel settings.", + /** + * @description top CSS selector when ranked by elapsed time in ms + */ + topSelectorElapsedTime: "Top selector elapsed time", + /** + * @description top CSS selector when ranked by match attempt + */ + topSelectorMatchAttempt: "Top selector match attempt" + }; + i18nString16 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + slowCSSSelectorThreshold = 500; + __name(aggregateSelectorStats, "aggregateSelectorStats"); + __name(finalize46, "finalize"); + __name(isSlowCSSSelectorInsight, "isSlowCSSSelectorInsight"); + __name(generateInsight16, "generateInsight"); + __name(createOverlays16, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/ThirdParties.js +var ThirdParties_exports2 = {}; +__export(ThirdParties_exports2, { + UIStrings: () => UIStrings18, + createOverlays: () => createOverlays17, + createOverlaysForSummary: () => createOverlaysForSummary, + generateInsight: () => generateInsight17, + i18nString: () => i18nString17, + isThirdPartyInsight: () => isThirdPartyInsight +}); +function getRelatedEvents(summaries, firstPartyEntity) { + const relatedEvents = []; + for (const summary of summaries) { + if (summary.entity !== firstPartyEntity) { + relatedEvents.push(...summary.relatedEvents); + } + } + return relatedEvents; +} +function finalize47(partialModel) { + return { + insightKey: InsightKeys.THIRD_PARTIES, + strings: UIStrings18, + title: i18nString17(UIStrings18.title), + description: i18nString17(UIStrings18.description), + docs: "https://developer.chrome.com/docs/performance/insights/third-parties", + category: InsightCategory.ALL, + state: partialModel.entitySummaries.find((summary) => summary.entity !== partialModel.firstPartyEntity) ? "informative" : "pass", + ...partialModel + }; +} +function isThirdPartyInsight(model2) { + return model2.insightKey === InsightKeys.THIRD_PARTIES; +} +function generateInsight17(data31, context) { + const entitySummaries = ThirdParties_exports.summarizeByThirdParty(data31, context.bounds); + const firstPartyUrl = context.navigation?.args.data?.documentLoaderURL ?? data31.Meta.mainFrameURL; + const firstPartyEntity = import_third_party_web.default.getEntity(firstPartyUrl) || helpers_exports.makeUpEntity(data31.Renderer.entityMappings.createdEntityCache, firstPartyUrl); + return finalize47({ + relatedEvents: getRelatedEvents(entitySummaries, firstPartyEntity), + firstPartyEntity, + entitySummaries + }); +} +function createOverlaysForSummary(summary) { + const overlays = []; + for (const event of summary.relatedEvents) { + if (event.dur === void 0 || event.dur < 1e3) { + continue; + } + const overlay = { + type: "ENTRY_OUTLINE", + entry: event, + outlineReason: "INFO" + }; + overlays.push(overlay); + } + return overlays; +} +function createOverlays17(model2) { + const overlays = []; + const summaries = model2.entitySummaries ?? []; + for (const summary of summaries) { + if (summary.entity === model2.firstPartyEntity) { + continue; + } + const summaryOverlays = createOverlaysForSummary(summary); + overlays.push(...summaryOverlays); + } + return overlays; +} +var UIStrings18, i18nString17; +var init_ThirdParties2 = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/ThirdParties.js"() { + init_process_global(); + init_third_party_web(); + init_extras(); + init_handlers(); + init_types4(); + UIStrings18 = { + /** Title of an insight that provides details about the code on a web page that the user doesn't control (referred to as "third-party code"). */ + title: "3rd parties", + /** + * @description Description of a DevTools insight that identifies the code on the page that the user doesn't control. + * This is displayed after a user expands the section to see more. No character length limits. + */ + description: "3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://developer.chrome.com/docs/performance/insights/third-parties) to prioritize your page's content.", + /** Label for a table column that displays the name of a third-party provider. */ + columnThirdParty: "3rd party", + /** Label for a column in a data table; entries will be the download size of a web resource in kilobytes. */ + columnTransferSize: "Transfer size", + /** Label for a table column that displays how much time each row spent running on the main thread, entries will be the number of milliseconds spent. */ + columnMainThreadTime: "Main thread time", + /** + * @description Text block indicating that no third party content was detected on the page + */ + noThirdParties: "No third parties found" + }; + i18nString17 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(getRelatedEvents, "getRelatedEvents"); + __name(finalize47, "finalize"); + __name(isThirdPartyInsight, "isThirdPartyInsight"); + __name(generateInsight17, "generateInsight"); + __name(createOverlaysForSummary, "createOverlaysForSummary"); + __name(createOverlays17, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/Viewport.js +var Viewport_exports = {}; +__export(Viewport_exports, { + UIStrings: () => UIStrings19, + createOverlays: () => createOverlays18, + generateInsight: () => generateInsight18, + i18nString: () => i18nString18, + isViewportInsight: () => isViewportInsight +}); +function finalize48(partialModel) { + return { + insightKey: InsightKeys.VIEWPORT, + strings: UIStrings19, + title: i18nString18(UIStrings19.title), + description: i18nString18(UIStrings19.description), + docs: "https://developer.chrome.com/docs/performance/insights/viewport", + category: InsightCategory.INP, + state: partialModel.mobileOptimized === false ? "fail" : "pass", + ...partialModel + }; +} +function isViewportInsight(model2) { + return model2.insightKey === InsightKeys.VIEWPORT; +} +function generateInsight18(data31, context) { + const viewportEvent = data31.UserInteractions.parseMetaViewportEvents.find((event) => { + if (event.args.data.frame !== context.frameId) { + return false; + } + return Timing_exports3.eventIsInBounds(event, context.bounds); + }); + const compositorEvents = data31.UserInteractions.beginCommitCompositorFrameEvents.filter((event) => { + if (event.args.frame !== context.frameId) { + return false; + } + if (viewportEvent && event.ts < viewportEvent.ts) { + return false; + } + return Timing_exports3.eventIsInBounds(event, context.bounds); + }); + if (!compositorEvents.length) { + return finalize48({ + mobileOptimized: null, + warnings: [InsightWarning.NO_LAYOUT] + }); + } + for (const event of compositorEvents) { + if (!event.args.is_mobile_optimized) { + const longPointerInteractions = [...data31.UserInteractions.interactionsOverThreshold.values()].filter((interaction) => ModelHandlers_exports.UserInteractions.categoryOfInteraction(interaction) === "POINTER" && interaction.inputDelay >= 5e4); + const inputDelay = Math.max(0, ...longPointerInteractions.map((interaction) => interaction.inputDelay)) / 1e3; + const inpMetricSavings = NumberUtilities_exports.clamp(inputDelay, 0, 300); + return finalize48({ + mobileOptimized: false, + viewportEvent, + longPointerInteractions, + metricSavings: { INP: inpMetricSavings } + }); + } + } + return finalize48({ + mobileOptimized: true, + viewportEvent + }); +} +function createOverlays18(model2) { + if (!model2.longPointerInteractions) { + return []; + } + return model2.longPointerInteractions.map((interaction) => { + const delay = Math.min(interaction.inputDelay, 300 * 1e3); + const bounds = Timing_exports3.traceWindowFromMicroSeconds(Timing_exports.Micro(interaction.ts), Timing_exports.Micro(interaction.ts + delay)); + return { + type: "TIMESPAN_BREAKDOWN", + entry: interaction, + sections: [{ bounds, label: i18nString18(UIStrings19.mobileTapDelayLabel), showDuration: true }], + renderLocation: "ABOVE_EVENT" + }; + }); +} +var UIStrings19, i18nString18; +var init_Viewport = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/Viewport.js"() { + init_process_global(); + init_platform(); + init_handlers(); + init_helpers2(); + init_types2(); + init_types4(); + UIStrings19 = { + /** Title of an insight that provides details about if the page's viewport is optimized for mobile viewing. */ + title: "Optimize viewport for mobile", + /** + * @description Text to tell the user how a viewport meta element can improve performance. \xa0 is a non-breaking space + */ + description: "Tap interactions may be [delayed by up to 300 ms](https://developer.chrome.com/docs/performance/insights/viewport) if the viewport is not optimized for mobile.", + /** + * @description Text for a label describing the portion of an interaction event that was delayed due to a bad mobile viewport. + */ + mobileTapDelayLabel: "Mobile tap delay" + }; + i18nString18 = /* @__PURE__ */ __name((i18nId, values) => ({ i18nId, values }), "i18nString"); + __name(finalize48, "finalize"); + __name(isViewportInsight, "isViewportInsight"); + __name(generateInsight18, "generateInsight"); + __name(createOverlays18, "createOverlays"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/Models.js +var Models_exports = {}; +__export(Models_exports, { + CLSCulprits: () => CLSCulprits_exports, + Cache: () => Cache_exports, + DOMSize: () => DOMSize_exports, + DocumentLatency: () => DocumentLatency_exports, + DuplicatedJavaScript: () => DuplicatedJavaScript_exports, + FontDisplay: () => FontDisplay_exports, + ForcedReflow: () => ForcedReflow_exports, + INPBreakdown: () => INPBreakdown_exports, + ImageDelivery: () => ImageDelivery_exports, + LCPBreakdown: () => LCPBreakdown_exports, + LCPDiscovery: () => LCPDiscovery_exports, + LegacyJavaScript: () => LegacyJavaScript_exports, + ModernHTTP: () => ModernHTTP_exports, + NetworkDependencyTree: () => NetworkDependencyTree_exports, + RenderBlocking: () => RenderBlocking_exports, + SlowCSSSelector: () => SlowCSSSelector_exports, + ThirdParties: () => ThirdParties_exports2, + Viewport: () => Viewport_exports +}); +var init_Models = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/Models.js"() { + init_process_global(); + init_Cache(); + init_CLSCulprits(); + init_DocumentLatency(); + init_DOMSize(); + init_DuplicatedJavaScript(); + init_FontDisplay(); + init_ForcedReflow(); + init_ImageDelivery(); + init_INPBreakdown(); + init_LCPBreakdown(); + init_LCPDiscovery(); + init_LegacyJavaScript(); + init_ModernHTTP(); + init_NetworkDependencyTree(); + init_RenderBlocking(); + init_SlowCSSSelector(); + init_ThirdParties2(); + init_Viewport(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/insights/insights.js +var init_insights = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/insights/insights.js"() { + init_process_global(); + init_Cache(); + init_Common(); + init_Models(); + init_ModernHTTP(); + init_Statistics(); + init_types4(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/LanternComputationData.js +function createProcessedNavigation(data31, frameId, navigationId) { + const scoresByNav = data31.PageLoadMetrics.metricScoresByFrameId.get(frameId); + if (!scoresByNav) { + throw new core_exports.LanternError("missing metric scores for frame"); + } + const scores = scoresByNav.get(navigationId); + if (!scores) { + throw new core_exports.LanternError("missing metric scores for specified navigation"); + } + const getTimestampOrUndefined = /* @__PURE__ */ __name((metric) => { + const metricScore = scores.get(metric); + if (!metricScore?.event) { + return; + } + return metricScore.event.ts; + }, "getTimestampOrUndefined"); + const getTimestamp = /* @__PURE__ */ __name((metric) => { + const metricScore = scores.get(metric); + if (!metricScore?.event) { + throw new core_exports.LanternError(`missing metric: ${metric}`); + } + return metricScore.event.ts; + }, "getTimestamp"); + return { + timestamps: { + firstContentfulPaint: getTimestamp(ModelHandlers_exports.PageLoadMetrics.MetricName.FCP), + largestContentfulPaint: getTimestampOrUndefined(ModelHandlers_exports.PageLoadMetrics.MetricName.LCP) + } + }; +} +function createParsedUrl(url) { + if (typeof url === "string") { + url = new URL(url); + } + return { + scheme: url.protocol.split(":")[0], + // Intentional, DevTools uses different terminology + host: url.hostname, + securityOrigin: url.origin + }; +} +function findWorkerThreads(trace) { + const workerThreads = /* @__PURE__ */ new Map(); + const workerCreationEvents = ["ServiceWorker thread", "DedicatedWorker thread"]; + for (const event of trace.traceEvents) { + if (event.name !== "thread_name" || !event.args.name) { + continue; + } + if (!workerCreationEvents.includes(event.args.name)) { + continue; + } + const tids = workerThreads.get(event.pid); + if (tids) { + tids.push(event.tid); + } else { + workerThreads.set(event.pid, [event.tid]); + } + } + return workerThreads; +} +function createLanternRequest(parsedTrace, workerThreads, request) { + if (request.args.data.hasResponse && request.args.data.connectionId === void 0) { + throw new core_exports.LanternError("Trace is too old"); + } + let url; + try { + url = new URL(request.args.data.url); + } catch { + return; + } + const timing = request.args.data.timing ? { + // These two timings are not included in the trace. + workerFetchStart: -1, + workerRespondWithSettled: -1, + receiveHeadersStart: -1, + ...request.args.data.timing + } : void 0; + const networkRequestTime = timing ? timing.requestTime * 1e3 : request.args.data.syntheticData.downloadStart / 1e3; + let fromWorker = false; + const tids = workerThreads.get(request.pid); + if (tids?.includes(request.tid)) { + fromWorker = true; + } + if (parsedTrace.Workers.workerIdByThread.has(request.tid)) { + fromWorker = true; + } + const initiator = request.args.data.initiator ?? { + type: "other" + /* Protocol.Network.InitiatorType.Other */ + }; + if (request.args.data.stackTrace) { + const callFrames = request.args.data.stackTrace.map((f) => { + return { + scriptId: String(f.scriptId), + url: f.url, + lineNumber: f.lineNumber - 1, + columnNumber: f.columnNumber - 1, + functionName: f.functionName + }; + }); + initiator.stack = { callFrames }; + } + let resourceType = request.args.data.resourceType; + if (request.args.data.initiator?.fetchType === "xmlhttprequest") { + resourceType = "XHR"; + } else if (request.args.data.initiator?.fetchType === "fetch") { + resourceType = "Fetch"; + } + let resourceSize = request.args.data.decodedBodyLength ?? 0; + if (url.protocol === "data:" && resourceSize === 0) { + const commaIndex = url.pathname.indexOf(","); + if (url.pathname.substring(0, commaIndex).includes(";base64")) { + resourceSize = atob(url.pathname.substring(commaIndex + 1)).length; + } else { + resourceSize = url.pathname.length - commaIndex - 1; + } + } + return { + rawRequest: request, + requestId: request.args.data.requestId, + connectionId: request.args.data.connectionId ?? 0, + connectionReused: request.args.data.connectionReused ?? false, + url: request.args.data.url, + protocol: request.args.data.protocol, + parsedURL: createParsedUrl(url), + documentURL: request.args.data.requestingFrameUrl, + rendererStartTime: request.ts / 1e3, + networkRequestTime, + responseHeadersEndTime: request.args.data.syntheticData.downloadStart / 1e3, + networkEndTime: request.args.data.syntheticData.finishTime / 1e3, + transferSize: request.args.data.encodedDataLength, + resourceSize, + fromDiskCache: request.args.data.syntheticData.isDiskCached, + fromMemoryCache: request.args.data.syntheticData.isMemoryCached, + isLinkPreload: request.args.data.isLinkPreload, + finished: request.args.data.finished, + failed: request.args.data.failed, + statusCode: request.args.data.statusCode, + initiator, + timing, + resourceType, + mimeType: request.args.data.mimeType, + priority: request.args.data.priority, + frameId: request.args.data.frame, + fromWorker, + serverResponseTime: request.args.data.lrServerResponseTime ?? void 0, + // Set later. + redirects: void 0, + redirectSource: void 0, + redirectDestination: void 0, + initiatorRequest: void 0 + }; +} +function chooseInitiatorRequest(request, requestsByURL) { + if (request.redirectSource) { + return request.redirectSource; + } + const initiatorURL = graph_exports.PageDependencyGraph.getNetworkInitiators(request)[0]; + let candidates = requestsByURL.get(initiatorURL) || []; + candidates = candidates.filter((c) => { + return c.responseHeadersEndTime <= request.rendererStartTime && c.finished && !c.failed; + }); + if (candidates.length > 1) { + const nonPrefetchCandidates = candidates.filter((cand) => cand.resourceType !== types_exports.NetworkRequestTypes.Other); + if (nonPrefetchCandidates.length) { + candidates = nonPrefetchCandidates; + } + } + if (candidates.length > 1) { + const sameFrameCandidates = candidates.filter((cand) => cand.frameId === request.frameId); + if (sameFrameCandidates.length) { + candidates = sameFrameCandidates; + } + } + if (candidates.length > 1 && request.initiator.type === "parser") { + const documentCandidates = candidates.filter((cand) => cand.resourceType === types_exports.NetworkRequestTypes.Document); + if (documentCandidates.length) { + candidates = documentCandidates; + } + } + if (candidates.length > 1) { + const linkPreloadCandidates = candidates.filter((c) => c.isLinkPreload); + if (linkPreloadCandidates.length) { + const nonPreloadCandidates = candidates.filter((c) => !c.isLinkPreload); + const allPreloaded = nonPreloadCandidates.every((c) => c.fromDiskCache || c.fromMemoryCache); + if (nonPreloadCandidates.length && allPreloaded) { + candidates = linkPreloadCandidates; + } + } + } + return candidates.length === 1 ? candidates[0] : null; +} +function linkInitiators(lanternRequests) { + const requestsByURL = /* @__PURE__ */ new Map(); + for (const request of lanternRequests) { + const requests = requestsByURL.get(request.url) || []; + requests.push(request); + requestsByURL.set(request.url, requests); + } + for (const request of lanternRequests) { + const initiatorRequest = chooseInitiatorRequest(request, requestsByURL); + if (initiatorRequest) { + request.initiatorRequest = initiatorRequest; + } + } +} +function createNetworkRequests(trace, data31, startTime = 0, endTime = Number.POSITIVE_INFINITY) { + const workerThreads = findWorkerThreads(trace); + const lanternRequestsNoRedirects = []; + for (const request of data31.NetworkRequests.byTime) { + if (request.ts >= startTime && request.ts < endTime) { + const lanternRequest = createLanternRequest(data31, workerThreads, request); + if (lanternRequest) { + lanternRequestsNoRedirects.push(lanternRequest); + } + } + } + const lanternRequests = []; + for (const request of [...lanternRequestsNoRedirects]) { + if (!request.rawRequest) { + continue; + } + const redirects = request.rawRequest.args.data.redirects; + if (!redirects.length) { + lanternRequests.push(request); + continue; + } + const requestChain = []; + for (const redirect of redirects) { + const redirectedRequest = structuredClone(request); + redirectedRequest.networkRequestTime = redirect.ts / 1e3; + redirectedRequest.rendererStartTime = redirectedRequest.networkRequestTime; + redirectedRequest.networkEndTime = (redirect.ts + redirect.dur) / 1e3; + redirectedRequest.responseHeadersEndTime = redirectedRequest.networkEndTime; + redirectedRequest.timing = { + requestTime: redirectedRequest.networkRequestTime / 1e3, + receiveHeadersStart: redirectedRequest.responseHeadersEndTime, + receiveHeadersEnd: redirectedRequest.responseHeadersEndTime, + proxyStart: -1, + proxyEnd: -1, + dnsStart: -1, + dnsEnd: -1, + connectStart: -1, + connectEnd: -1, + sslStart: -1, + sslEnd: -1, + sendStart: -1, + sendEnd: -1, + workerStart: -1, + workerReady: -1, + workerFetchStart: -1, + workerRespondWithSettled: -1, + pushStart: -1, + pushEnd: -1 + }; + redirectedRequest.url = redirect.url; + redirectedRequest.parsedURL = createParsedUrl(redirect.url); + redirectedRequest.statusCode = 302; + redirectedRequest.resourceType = void 0; + redirectedRequest.transferSize = 400; + requestChain.push(redirectedRequest); + lanternRequests.push(redirectedRequest); + } + requestChain.push(request); + lanternRequests.push(request); + for (let i = 0; i < requestChain.length; i++) { + const request2 = requestChain[i]; + if (i > 0) { + request2.redirectSource = requestChain[i - 1]; + request2.redirects = requestChain.slice(0, i); + } + if (i !== requestChain.length - 1) { + request2.redirectDestination = requestChain[i + 1]; + } + } + for (let i = 1; i < requestChain.length; i++) { + requestChain[i].requestId = `${requestChain[i - 1].requestId}:redirect`; + } + } + linkInitiators(lanternRequests); + return lanternRequests; +} +function collectMainThreadEvents(trace, data31) { + const Meta = data31.Meta; + const mainFramePids = Meta.mainFrameNavigations.length ? new Set(Meta.mainFrameNavigations.map((nav) => nav.pid)) : Meta.topLevelRendererIds; + const rendererPidToTid = /* @__PURE__ */ new Map(); + for (const pid of mainFramePids) { + const threads = Meta.threadsInProcess.get(pid) ?? []; + let found = false; + for (const [tid, thread] of threads) { + if (thread.args.name === "CrRendererMain") { + rendererPidToTid.set(pid, tid); + found = true; + break; + } + } + if (found) { + continue; + } + for (const [tid, thread] of threads) { + if (thread.args.name === "CrBrowserMain") { + rendererPidToTid.set(pid, tid); + found = true; + break; + } + } + } + return trace.traceEvents.filter((e) => rendererPidToTid.get(e.pid) === e.tid); +} +function createGraph(requests, trace, data31, url) { + const mainThreadEvents = collectMainThreadEvents(trace, data31); + if (!url) { + url = { + requestedUrl: requests[0].url, + mainDocumentUrl: "" + }; + let request = requests[0]; + while (request.redirectDestination) { + request = request.redirectDestination; + } + url.mainDocumentUrl = request.url; + } + return graph_exports.PageDependencyGraph.createGraph(mainThreadEvents, requests, url); +} +var init_LanternComputationData = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/LanternComputationData.js"() { + init_process_global(); + init_handlers(); + init_lantern(); + __name(createProcessedNavigation, "createProcessedNavigation"); + __name(createParsedUrl, "createParsedUrl"); + __name(findWorkerThreads, "findWorkerThreads"); + __name(createLanternRequest, "createLanternRequest"); + __name(chooseInitiatorRequest, "chooseInitiatorRequest"); + __name(linkInitiators, "linkInitiators"); + __name(createNetworkRequests, "createNetworkRequests"); + __name(collectMainThreadEvents, "collectMainThreadEvents"); + __name(createGraph, "createGraph"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/Processor.js +function calculateProgress(value, phase) { + if (phase === 0.8) { + return value * (0.8 - 0.2) + 0.2; + } + return value * phase; +} +function sortHandlers(traceHandlers) { + const sortedMap = /* @__PURE__ */ new Map(); + const visited = /* @__PURE__ */ new Set(); + const visitHandler = /* @__PURE__ */ __name((handlerName) => { + if (sortedMap.has(handlerName)) { + return; + } + if (visited.has(handlerName)) { + let stackPath = ""; + for (const handler2 of visited) { + if (stackPath || handler2 === handlerName) { + stackPath += `${handler2}->`; + } + } + stackPath += handlerName; + throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`); + } + visited.add(handlerName); + const handler = traceHandlers[handlerName]; + if (!handler) { + return; + } + const deps17 = handler.deps?.(); + if (deps17) { + deps17.forEach(visitHandler); + } + sortedMap.set(handlerName, handler); + }, "visitHandler"); + for (const handlerName of Object.keys(traceHandlers)) { + visitHandler(handlerName); + } + return sortedMap; +} +var _a2, TraceParseProgressEvent, TraceProcessor; +var init_Processor = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/Processor.js"() { + init_process_global(); + init_handlers(); + init_helpers2(); + init_insights(); + init_lantern(); + init_LanternComputationData(); + init_types2(); + TraceParseProgressEvent = class _TraceParseProgressEvent extends Event { + static { + __name(this, "TraceParseProgressEvent"); + } + data; + static eventName = "traceparseprogress"; + constructor(data31, init2 = { bubbles: true }) { + super(_TraceParseProgressEvent.eventName, init2); + this.data = data31; + } + }; + __name(calculateProgress, "calculateProgress"); + TraceProcessor = class extends EventTarget { + static { + __name(this, "TraceProcessor"); + } + // We force the Meta handler to be enabled, so the TraceHandlers type here is + // the model handlers the user passes in and the Meta handler. + #traceHandlers; + #status = "IDLE"; + #modelConfiguration = Configuration_exports.defaults(); + #data = null; + #insights = null; + static createWithAllHandlers() { + return new _a2(ModelHandlers_exports, Configuration_exports.defaults()); + } + /** + * This function is kept for testing with `stub`. + */ + static getInsightRunners() { + return { ...Models_exports }; + } + constructor(traceHandlers, modelConfiguration) { + super(); + this.#verifyHandlers(traceHandlers); + this.#traceHandlers = { + Meta: ModelHandlers_exports.Meta, + ...traceHandlers + }; + if (modelConfiguration) { + this.#modelConfiguration = modelConfiguration; + } + this.#passConfigToHandlers(); + } + #passConfigToHandlers() { + for (const handler of Object.values(this.#traceHandlers)) { + if ("handleUserConfig" in handler && handler.handleUserConfig) { + handler.handleUserConfig(this.#modelConfiguration); + } + } + } + /** + * When the user passes in a set of handlers, we want to ensure that we have all + * the required handlers. Handlers can depend on other handlers, so if the user + * passes in FooHandler which depends on BarHandler, they must also pass in + * BarHandler too. This method verifies that all dependencies are met, and + * throws if not. + **/ + #verifyHandlers(providedHandlers) { + if (Object.keys(providedHandlers).length === Object.keys(ModelHandlers_exports).length) { + return; + } + const requiredHandlerKeys = /* @__PURE__ */ new Set(); + for (const [handlerName, handler] of Object.entries(providedHandlers)) { + requiredHandlerKeys.add(handlerName); + const deps17 = "deps" in handler ? handler.deps() : []; + for (const depName of deps17) { + requiredHandlerKeys.add(depName); + } + } + const providedHandlerKeys = new Set(Object.keys(providedHandlers)); + requiredHandlerKeys.delete("Meta"); + for (const requiredKey of requiredHandlerKeys) { + if (!providedHandlerKeys.has(requiredKey)) { + throw new Error(`Required handler ${requiredKey} not provided.`); + } + } + } + reset() { + if (this.#status === "PARSING") { + throw new Error("Trace processor can't reset while parsing."); + } + const handlers = Object.values(this.#traceHandlers); + for (const handler of handlers) { + handler.reset(); + } + this.#data = null; + this.#insights = null; + this.#status = "IDLE"; + } + async parse(traceEvents, options) { + if (this.#status !== "IDLE") { + throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`); + } + if (typeof options.isCPUProfile === "undefined" && options.metadata) { + options.isCPUProfile = options.metadata.dataOrigin === File_exports.DataOrigin.CPU_PROFILE; + } + options.logger?.start("total"); + try { + this.#status = "PARSING"; + options.logger?.start("parse"); + await this.#computeParsedTrace(traceEvents, options); + options.logger?.end("parse"); + if (this.#data && !options.isCPUProfile) { + options.logger?.start("insights"); + this.#computeInsights(this.#data, traceEvents, options); + options.logger?.end("insights"); + } + this.#status = "FINISHED_PARSING"; + } catch (e) { + this.#status = "ERRORED_WHILE_PARSING"; + throw e; + } finally { + options.logger?.end("total"); + } + } + /** + * Run all the handlers and set the result to `#data`. + */ + async #computeParsedTrace(traceEvents, options) { + const eventsPerChunk = 5e4; + const sortedHandlers = [...sortHandlers(this.#traceHandlers).entries()]; + for (const [, handler] of sortedHandlers) { + handler.reset(); + } + options.logger?.start("parse:handleEvent"); + for (let i = 0; i < traceEvents.length; ++i) { + if (i % eventsPerChunk === 0 && i) { + const percent = calculateProgress( + i / traceEvents.length, + 0.2 + /* ProgressPhase.HANDLE_EVENT */ + ); + this.dispatchEvent(new TraceParseProgressEvent({ percent })); + await new Promise((resolve) => setTimeout(resolve, 0)); + } + const event = traceEvents[i]; + for (let j = 0; j < sortedHandlers.length; ++j) { + const [, handler] = sortedHandlers[j]; + handler.handleEvent(event); + } + } + options.logger?.end("parse:handleEvent"); + const finalizeOptions = { + ...options, + allTraceEvents: traceEvents + }; + for (let i = 0; i < sortedHandlers.length; i++) { + const [name, handler] = sortedHandlers[i]; + if (handler.finalize) { + options.logger?.start(`parse:${name}:finalize`); + await new Promise((resolve) => setTimeout(resolve, 0)); + await handler.finalize(finalizeOptions); + options.logger?.end(`parse:${name}:finalize`); + } + const percent = calculateProgress( + i / sortedHandlers.length, + 0.8 + /* ProgressPhase.FINALIZE */ + ); + this.dispatchEvent(new TraceParseProgressEvent({ percent })); + } + options.logger?.start("parse:handler.data()"); + const parsedTrace = {}; + for (const [name, handler] of Object.entries(this.#traceHandlers)) { + Object.assign(parsedTrace, { [name]: handler.data() }); + } + options.logger?.end("parse:handler.data()"); + this.dispatchEvent(new TraceParseProgressEvent({ + percent: 1 + /* ProgressPhase.CLONE */ + })); + this.#data = parsedTrace; + } + get data() { + if (this.#status !== "FINISHED_PARSING") { + return null; + } + return this.#data; + } + get insights() { + if (this.#status !== "FINISHED_PARSING") { + return null; + } + return this.#insights; + } + #createLanternContext(data31, traceEvents, frameId, navigationId, options) { + if (!data31.NetworkRequests || !data31.Workers || !data31.PageLoadMetrics) { + return; + } + if (!data31.NetworkRequests.byTime.length) { + throw new core_exports.LanternError("No network requests found in trace"); + } + const navStarts = data31.Meta.navigationsByFrameId.get(frameId); + const navStartIndex = navStarts?.findIndex((n) => n.args.data?.navigationId === navigationId); + if (!navStarts || navStartIndex === void 0 || navStartIndex === -1) { + throw new core_exports.LanternError("Could not find navigation start"); + } + const startTime = navStarts[navStartIndex].ts; + const endTime = navStartIndex + 1 < navStarts.length ? navStarts[navStartIndex + 1].ts : Number.POSITIVE_INFINITY; + const boundedTraceEvents = traceEvents.filter((e) => e.ts >= startTime && e.ts < endTime); + const trace = { + traceEvents: boundedTraceEvents + }; + const requests = createNetworkRequests(trace, data31, startTime, endTime); + const graph2 = createGraph(requests, trace, data31); + const processedNavigation = createProcessedNavigation(data31, frameId, navigationId); + const networkAnalysis = core_exports.NetworkAnalyzer.analyze(requests); + if (!networkAnalysis) { + return; + } + const lanternSettings = { + // TODO(crbug.com/372674229): if devtools throttling was on, does this network analysis capture + // that? Do we need to set 'devtools' throttlingMethod? + networkAnalysis, + throttlingMethod: "provided", + ...options.lanternSettings + }; + const simulator = simulation_exports.Simulator.createSimulator(lanternSettings); + const computeData = { graph: graph2, simulator, processedNavigation }; + const fcpResult = metrics_exports.FirstContentfulPaint.compute(computeData); + const lcpResult = metrics_exports.LargestContentfulPaint.compute(computeData, { fcpResult }); + const interactiveResult = metrics_exports.Interactive.compute(computeData, { lcpResult }); + const tbtResult = metrics_exports.TotalBlockingTime.compute(computeData, { fcpResult, interactiveResult }); + const metrics = { + firstContentfulPaint: fcpResult, + interactive: interactiveResult, + largestContentfulPaint: lcpResult, + totalBlockingTime: tbtResult + }; + return { requests, graph: graph2, simulator, metrics }; + } + /** + * Sort the insight models based on the impact of each insight's estimated savings, additionally weighted by the + * worst metrics according to field data (if present). + */ + sortInsightSet(insightSet, metadata) { + const baselineOrder = { + INPBreakdown: null, + LCPBreakdown: null, + LCPDiscovery: null, + CLSCulprits: null, + RenderBlocking: null, + NetworkDependencyTree: null, + ImageDelivery: null, + DocumentLatency: null, + FontDisplay: null, + Viewport: null, + DOMSize: null, + ThirdParties: null, + DuplicatedJavaScript: null, + SlowCSSSelector: null, + ForcedReflow: null, + Cache: null, + ModernHTTP: null, + LegacyJavaScript: null + }; + const weights = Common_exports.calculateMetricWeightsForSorting(insightSet, metadata); + const observedLcpMicro = Common_exports.getLCP(insightSet)?.value; + const observedLcp = observedLcpMicro ? Timing_exports3.microToMilli(observedLcpMicro) : Timing_exports.Milli(0); + const observedCls = Common_exports.getCLS(insightSet).value; + const observedInpMicro = Common_exports.getINP(insightSet)?.value; + const observedInp = observedInpMicro ? Timing_exports3.microToMilli(observedInpMicro) : Timing_exports.Milli(200); + const observedLcpScore = observedLcp !== void 0 ? Common_exports.evaluateLCPMetricScore(observedLcp) : void 0; + const observedInpScore = Common_exports.evaluateINPMetricScore(observedInp); + const observedClsScore = Common_exports.evaluateCLSMetricScore(observedCls); + const insightToSortingRank = /* @__PURE__ */ new Map(); + for (const [name, model2] of Object.entries(insightSet.model)) { + const lcp = model2.metricSavings?.LCP ?? 0; + const inp = model2.metricSavings?.INP ?? 0; + const cls = model2.metricSavings?.CLS ?? 0; + const lcpPostSavings = observedLcp !== void 0 ? Math.max(0, observedLcp - lcp) : void 0; + const inpPostSavings = Math.max(0, observedInp - inp); + const clsPostSavings = Math.max(0, observedCls - cls); + let score = 0; + if (weights.lcp && lcp && observedLcpScore !== void 0 && lcpPostSavings !== void 0) { + score += weights.lcp * (Common_exports.evaluateLCPMetricScore(lcpPostSavings) - observedLcpScore); + } + if (weights.inp && inp && observedInpScore !== void 0) { + score += weights.inp * (Common_exports.evaluateINPMetricScore(inpPostSavings) - observedInpScore); + } + if (weights.cls && cls && observedClsScore !== void 0) { + score += weights.cls * (Common_exports.evaluateCLSMetricScore(clsPostSavings) - observedClsScore); + } + insightToSortingRank.set(name, score); + } + const baselineOrderKeys = Object.keys(baselineOrder); + const orderedKeys = Object.keys(insightSet.model); + orderedKeys.sort((a, b) => { + const a1 = baselineOrderKeys.indexOf(a); + const b1 = baselineOrderKeys.indexOf(b); + if (a1 >= 0 && b1 >= 0) { + return a1 - b1; + } + if (a1 >= 0) { + return -1; + } + if (b1 >= 0) { + return 1; + } + return 0; + }); + orderedKeys.sort((a, b) => (insightToSortingRank.get(b) ?? 0) - (insightToSortingRank.get(a) ?? 0)); + const newModel = {}; + for (const key of orderedKeys) { + const model2 = insightSet.model[key]; + newModel[key] = model2; + } + insightSet.model = newModel; + } + #computeInsightSet(data31, context) { + const logger = context.options.logger; + let id, urlString, navigation2; + if (context.navigation) { + id = context.navigationId; + urlString = data31.Meta.finalDisplayUrlByNavigationId.get(context.navigationId) ?? data31.Meta.mainFrameURL; + navigation2 = context.navigation; + } else { + id = TraceEvents_exports.NO_NAVIGATION; + urlString = data31.Meta.finalDisplayUrlByNavigationId.get("") ?? data31.Meta.mainFrameURL; + } + const insightSetModel = {}; + for (const [name, insight] of Object.entries(_a2.getInsightRunners())) { + let model2; + try { + logger?.start(`insights:${name}`); + model2 = insight.generateInsight(data31, context); + model2.frameId = context.frameId; + const navId = context.navigation?.args.data?.navigationId; + if (navId) { + model2.navigationId = navId; + } + model2.createOverlays = () => { + return insight.createOverlays(model2); + }; + } catch (err) { + model2 = err; + } finally { + logger?.end(`insights:${name}`); + } + Object.assign(insightSetModel, { [name]: model2 }); + } + const isNavigation = id === TraceEvents_exports.NO_NAVIGATION; + const trivialThreshold = Timing_exports3.milliToMicro(Timing_exports.Milli(5e3)); + const everyInsightPasses = Object.values(insightSetModel).filter((model2) => !(model2 instanceof Error)).every((model2) => model2.state === "pass"); + const noLcp = !insightSetModel.LCPBreakdown.lcpEvent; + const noInp = !insightSetModel.INPBreakdown.longestInteractionEvent; + const noLayoutShifts = insightSetModel.CLSCulprits.shifts?.size === 0; + const shouldExclude = isNavigation && context.bounds.range < trivialThreshold && everyInsightPasses && noLcp && noInp && noLayoutShifts; + if (shouldExclude) { + return; + } + let url; + try { + url = new URL(urlString); + } catch { + return; + } + const insightSet = { + id, + url, + navigation: navigation2, + frameId: context.frameId, + bounds: context.bounds, + model: insightSetModel + }; + if (!this.#insights) { + this.#insights = /* @__PURE__ */ new Map(); + } + this.#insights.set(insightSet.id, insightSet); + this.sortInsightSet(insightSet, context.options.metadata ?? null); + } + /** + * Run all the insights and set the result to `#insights`. + */ + #computeInsights(data31, traceEvents, options) { + this.#insights = /* @__PURE__ */ new Map(); + const navigations = data31.Meta.mainFrameNavigations.filter((navigation2) => navigation2.args.frame && navigation2.args.data?.navigationId); + this.#computeInsightsForInitialTracePeriod(data31, navigations, options); + for (const [index, navigation2] of navigations.entries()) { + const min = navigation2.ts; + const max = index + 1 < navigations.length ? navigations[index + 1].ts : data31.Meta.traceBounds.max; + const bounds = Timing_exports3.traceWindowFromMicroSeconds(min, max); + this.#computeInsightsForNavigation(navigation2, bounds, data31, traceEvents, options); + } + } + /** + * Computes insights for the period before the first navigation, or for the entire trace if no navigations exist. + */ + #computeInsightsForInitialTracePeriod(data31, navigations, options) { + const bounds = navigations.length > 0 ? Timing_exports3.traceWindowFromMicroSeconds(data31.Meta.traceBounds.min, navigations[0].ts) : data31.Meta.traceBounds; + const context = { + options, + bounds, + frameId: data31.Meta.mainFrameId + // No navigation or lantern context applies to this initial/no-navigation period. + }; + this.#computeInsightSet(data31, context); + } + /** + * Computes insights for a specific navigation event. + */ + #computeInsightsForNavigation(navigation2, bounds, data31, traceEvents, options) { + const frameId = navigation2.args.frame; + const navigationId = navigation2.args.data?.navigationId; + let lantern; + try { + options.logger?.start("insights:createLanternContext"); + lantern = this.#createLanternContext(data31, traceEvents, frameId, navigationId, options); + } catch (e) { + const expectedErrors = [ + "mainDocumentRequest not found", + "missing metric scores for main frame", + "missing metric: FCP", + "missing metric: LCP", + "No network requests found in trace", + "Trace is too old" + ]; + if (!(e instanceof core_exports.LanternError)) { + console.error(e); + } else if (!expectedErrors.some((err) => e.message === err)) { + console.error(e); + } + } finally { + options.logger?.end("insights:createLanternContext"); + } + const context = { + options, + bounds, + frameId, + navigation: navigation2, + navigationId, + lantern + }; + this.#computeInsightSet(data31, context); + } + }; + _a2 = TraceProcessor; + __name(sortHandlers, "sortHandlers"); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/ModelImpl.js +var init_ModelImpl = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/ModelImpl.js"() { + init_process_global(); + init_platform(); + init_handlers(); + init_helpers2(); + init_Processor(); + init_types2(); + } +}); + +// node_modules/@paulirish/trace_engine/core/common/common.js +var init_common = __esm({ + "node_modules/@paulirish/trace_engine/core/common/common.js"() { + init_process_global(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/Styles.js +var EventCategory; +var init_Styles = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/Styles.js"() { + init_process_global(); + init_handlers(); + init_helpers2(); + init_types2(); + (function(EventCategory2) { + EventCategory2["DRAWING"] = "drawing"; + EventCategory2["RASTERIZING"] = "rasterizing"; + EventCategory2["LAYOUT"] = "layout"; + EventCategory2["LOADING"] = "loading"; + EventCategory2["EXPERIENCE"] = "experience"; + EventCategory2["SCRIPTING"] = "scripting"; + EventCategory2["MESSAGING"] = "messaging"; + EventCategory2["RENDERING"] = "rendering"; + EventCategory2["PAINTING"] = "painting"; + EventCategory2["GPU"] = "gpu"; + EventCategory2["ASYNC"] = "async"; + EventCategory2["OTHER"] = "other"; + EventCategory2["IDLE"] = "idle"; + })(EventCategory || (EventCategory = {})); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/Name.js +var init_Name = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/Name.js"() { + init_process_global(); + init_common(); + init_handlers(); + init_Styles(); + init_types2(); + } +}); + +// node_modules/@paulirish/trace_engine/models/trace/trace.js +var init_trace2 = __esm({ + "node_modules/@paulirish/trace_engine/models/trace/trace.js"() { + init_process_global(); + init_EntityMapper(); + init_EventsSerializer(); + init_extras(); + init_handlers(); + init_helpers2(); + init_insights(); + init_lantern(); + init_LanternComputationData(); + init_ModelImpl(); + init_Name(); + init_Processor(); + init_Styles(); + init_types2(); + } +}); + +// core/lib/lantern/lantern.js +var init_lantern2 = __esm({ + "core/lib/lantern/lantern.js"() { + "use strict"; + init_process_global(); + init_lantern(); + init_trace2(); + /** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + } +}); + +// core/lib/lantern-trace-saver.js +var init_lantern_trace_saver = __esm({ + "core/lib/lantern-trace-saver.js"() { + "use strict"; + init_process_global(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + } +}); + +// core/lib/tracehouse/trace-processor.js +var ACCEPTABLE_NAVIGATION_URL_REGEX, BASE_RESPONSE_LATENCY, SCHEDULABLE_TASK_TITLE_LH2, SCHEDULABLE_TASK_TITLE_ALT12, SCHEDULABLE_TASK_TITLE_ALT22, SCHEDULABLE_TASK_TITLE_ALT32, TraceProcessor2; +var init_trace_processor = __esm({ + "core/lib/tracehouse/trace-processor.js"() { + "use strict"; + init_process_global(); + init_lighthouse_logger(); + /** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + ACCEPTABLE_NAVIGATION_URL_REGEX = /^(chrome|https?):/; + BASE_RESPONSE_LATENCY = 16; + SCHEDULABLE_TASK_TITLE_LH2 = "RunTask"; + SCHEDULABLE_TASK_TITLE_ALT12 = "ThreadControllerImpl::RunTask"; + SCHEDULABLE_TASK_TITLE_ALT22 = "ThreadControllerImpl::DoWork"; + SCHEDULABLE_TASK_TITLE_ALT32 = "TaskQueueManager::ProcessTaskFromWorkQueue"; + TraceProcessor2 = class _TraceProcessor { + static { + __name(this, "TraceProcessor"); + } + static get TIMESPAN_MARKER_ID() { + return "__lighthouseTimespanStart__"; + } + /** + * @return {Error} + */ + static createNoNavstartError() { + return new Error("No navigationStart event found"); + } + /** + * @return {Error} + */ + static createNoResourceSendRequestError() { + return new Error("No ResourceSendRequest event found"); + } + /** + * @return {Error} + */ + static createNoTracingStartedError() { + return new Error("No tracingStartedInBrowser event found"); + } + /** + * @return {Error} + */ + static createNoFirstContentfulPaintError() { + return new Error("No FirstContentfulPaint event found"); + } + /** + * @return {Error} + */ + static createNoLighthouseMarkerError() { + return new Error("No Lighthouse timespan marker event found"); + } + /** + * Returns true if the event is a navigation start event of a document whose URL seems valid. + * + * @param {LH.TraceEvent} event + * @return {boolean} + */ + static _isNavigationStartOfInterest(event) { + if (event.name !== "navigationStart") return false; + if (event.args.data?.documentLoaderURL === void 0) return true; + if (!event.args.data?.documentLoaderURL) return false; + return ACCEPTABLE_NAVIGATION_URL_REGEX.test(event.args.data.documentLoaderURL); + } + /** + * This method sorts a group of trace events that have the same timestamp. We want to... + * + * 1. Put E events first, we finish off our existing events before we start new ones. + * 2. Order B/X events by their duration, we want parents to start before child events. + * 3. If we don't have any of this to go on, just use the position in the original array (stable sort). + * + * Note that the typical group size with the same timestamp will be quite small (<10 or so events), + * and the number of groups typically ~1% of total trace, so the same ultra-performance-sensitive consideration + * given to functions that run on entire traces does not necessarily apply here. + * + * @param {number[]} tsGroupIndices + * @param {number[]} timestampSortedIndices + * @param {number} indexOfTsGroupIndicesStart + * @param {LH.TraceEvent[]} traceEvents + * @return {number[]} + */ + static _sortTimestampEventGroup(tsGroupIndices, timestampSortedIndices, indexOfTsGroupIndicesStart, traceEvents) { + const lookupArrayIndexByTsIndex = /* @__PURE__ */ __name((i) => timestampSortedIndices[i], "lookupArrayIndexByTsIndex"); + const lookupEventByTsIndex = /* @__PURE__ */ __name((i) => traceEvents[lookupArrayIndexByTsIndex(i)], "lookupEventByTsIndex"); + const eEventIndices = []; + const bxEventIndices = []; + const otherEventIndices = []; + for (const tsIndex of tsGroupIndices) { + const arrayIndex = lookupArrayIndexByTsIndex(tsIndex); + const event = lookupEventByTsIndex(tsIndex); + if (event.ph === "E") eEventIndices.push(arrayIndex); + else if (event.ph === "X" || event.ph === "B") bxEventIndices.push(arrayIndex); + else otherEventIndices.push(arrayIndex); + } + const effectiveDuration = /* @__PURE__ */ new Map(); + for (const index of bxEventIndices) { + const event = traceEvents[index]; + if (event.ph === "X") { + effectiveDuration.set(index, event.dur); + } else { + let duration = Number.MAX_SAFE_INTEGER; + let additionalNestedEventsWithSameName = 0; + const startIndex = indexOfTsGroupIndicesStart + tsGroupIndices.length; + for (let j = startIndex; j < timestampSortedIndices.length; j++) { + const potentialMatchingEvent = lookupEventByTsIndex(j); + const eventMatches = potentialMatchingEvent.name === event.name && potentialMatchingEvent.pid === event.pid && potentialMatchingEvent.tid === event.tid; + if (!eventMatches) continue; + if (potentialMatchingEvent.ph === "E" && additionalNestedEventsWithSameName === 0) { + duration = potentialMatchingEvent.ts - event.ts; + break; + } else if (potentialMatchingEvent.ph === "E") { + additionalNestedEventsWithSameName--; + } else if (potentialMatchingEvent.ph === "B") { + additionalNestedEventsWithSameName++; + } + } + effectiveDuration.set(index, duration); + } + } + bxEventIndices.sort((indexA, indexB) => (effectiveDuration.get(indexB) || 0) - (effectiveDuration.get(indexA) || 0) || indexA - indexB); + otherEventIndices.sort((indexA, indexB) => indexA - indexB); + return [...eEventIndices, ...bxEventIndices, ...otherEventIndices]; + } + /** + * Sorts and filters trace events by timestamp and respecting the nesting structure inherent to + * parent/child event relationships. + * + * @param {LH.TraceEvent[]} traceEvents + * @param {(e: LH.TraceEvent) => boolean} filter + */ + static filteredTraceSort(traceEvents, filter) { + const indices = []; + for (let srcIndex = 0; srcIndex < traceEvents.length; srcIndex++) { + if (filter(traceEvents[srcIndex])) { + indices.push(srcIndex); + } + } + indices.sort((indexA, indexB) => traceEvents[indexA].ts - traceEvents[indexB].ts); + for (let i = 0; i < indices.length - 1; i++) { + const ts = traceEvents[indices[i]].ts; + const tsGroupIndices = [i]; + for (let j = i + 1; j < indices.length; j++) { + if (traceEvents[indices[j]].ts !== ts) break; + tsGroupIndices.push(j); + } + if (tsGroupIndices.length === 1) continue; + const finalIndexOrder = _TraceProcessor._sortTimestampEventGroup( + tsGroupIndices, + indices, + i, + traceEvents + ); + indices.splice(i, finalIndexOrder.length, ...finalIndexOrder); + i += tsGroupIndices.length - 1; + } + const sorted2 = []; + for (let i = 0; i < indices.length; i++) { + sorted2.push(traceEvents[indices[i]]); + } + return sorted2; + } + /** + * There should *always* be at least one top level event, having 0 typically means something is + * drastically wrong with the trace and we should just give up early and loudly. + * + * @param {LH.TraceEvent[]} events + */ + static assertHasToplevelEvents(events) { + const hasToplevelTask = events.some(this.isScheduleableTask); + if (!hasToplevelTask) { + throw new Error("Could not find any top level events"); + } + } + /** + * Calculate duration at specified percentiles for given population of + * durations. + * If one of the durations overlaps the end of the window, the full + * duration should be in the duration array, but the length not included + * within the window should be given as `clippedLength`. For instance, if a + * 50ms duration occurs 10ms before the end of the window, `50` should be in + * the `durations` array, and `clippedLength` should be set to 40. + * @see https://docs.google.com/document/d/1b9slyaB9yho91YTOkAQfpCdULFkZM9LqsipcX3t7He8/preview + * @param {!Array} durations Array of durations, sorted in ascending order. + * @param {number} totalTime Total time (in ms) of interval containing durations. + * @param {!Array} percentiles Array of percentiles of interest, in ascending order. + * @param {number=} clippedLength Optional length clipped from a duration overlapping end of window. Default of 0. + * @return {!Array<{percentile: number, time: number}>} + * @private + */ + static _riskPercentiles(durations, totalTime, percentiles, clippedLength = 0) { + let busyTime = 0; + for (let i = 0; i < durations.length; i++) { + busyTime += durations[i]; + } + busyTime -= clippedLength; + let completedTime = totalTime - busyTime; + let duration = 0; + let cdfTime = completedTime; + const results = []; + let durationIndex = -1; + let remainingCount = durations.length + 1; + if (clippedLength > 0) { + remainingCount--; + } + for (const percentile of percentiles) { + const percentileTime = percentile * totalTime; + while (cdfTime < percentileTime && durationIndex < durations.length - 1) { + completedTime += duration; + remainingCount -= duration < 0 ? -1 : 1; + if (clippedLength > 0 && clippedLength < durations[durationIndex + 1]) { + duration = -clippedLength; + clippedLength = 0; + } else { + durationIndex++; + duration = durations[durationIndex]; + } + cdfTime = completedTime + Math.abs(duration) * remainingCount; + } + results.push({ + percentile, + time: Math.max(0, (percentileTime - completedTime) / remainingCount) + BASE_RESPONSE_LATENCY + }); + } + return results; + } + /** + * Calculates the maximum queueing time (in ms) of high priority tasks for + * selected percentiles within a window of the main thread. + * @see https://docs.google.com/document/d/1b9slyaB9yho91YTOkAQfpCdULFkZM9LqsipcX3t7He8/preview + * @param {Array} events + * @param {number} startTime Start time (in ms relative to timeOrigin) of range of interest. + * @param {number} endTime End time (in ms relative to timeOrigin) of range of interest. + * @param {!Array=} percentiles Optional array of percentiles to compute. Defaults to [0.5, 0.75, 0.9, 0.99, 1]. + * @return {!Array<{percentile: number, time: number}>} + */ + static getRiskToResponsiveness(events, startTime, endTime, percentiles = [0.5, 0.75, 0.9, 0.99, 1]) { + const totalTime = endTime - startTime; + percentiles.sort((a, b) => a - b); + const ret = this.getMainThreadTopLevelEventDurations(events, startTime, endTime); + return this._riskPercentiles( + ret.durations, + totalTime, + percentiles, + ret.clippedLength + ); + } + /** + * Provides durations in ms of all main thread top-level events + * @param {Array} topLevelEvents + * @param {number} startTime Optional start time (in ms relative to timeOrigin) of range of interest. Defaults to 0. + * @param {number} endTime Optional end time (in ms relative to timeOrigin) of range of interest. Defaults to trace end. + * @return {{durations: Array, clippedLength: number}} + */ + static getMainThreadTopLevelEventDurations(topLevelEvents, startTime = 0, endTime = Infinity) { + const durations = []; + let clippedLength = 0; + for (const event of topLevelEvents) { + if (event.end < startTime || event.start > endTime) { + continue; + } + let duration = event.duration; + let eventStart = event.start; + if (eventStart < startTime) { + eventStart = startTime; + duration = event.end - startTime; + } + if (event.end > endTime) { + clippedLength = duration - (endTime - eventStart); + } + durations.push(duration); + } + durations.sort((a, b) => a - b); + return { + durations, + clippedLength + }; + } + /** + * Provides the top level events on the main thread with timestamps in ms relative to timeOrigin. + * start. + * @param {LH.Artifacts.ProcessedTrace} trace + * @param {number=} startTime Optional start time (in ms relative to timeOrigin) of range of interest. Defaults to 0. + * @param {number=} endTime Optional end time (in ms relative to timeOrigin) of range of interest. Defaults to trace end. + * @return {Array} + */ + static getMainThreadTopLevelEvents(trace, startTime = 0, endTime = Infinity) { + const topLevelEvents = []; + let prevToplevel = void 0; + for (const event of trace.mainThreadEvents) { + if (!this.isScheduleableTask(event) || !event.dur) continue; + const start = (event.ts - trace.timeOriginEvt.ts) / 1e3; + const end = (event.ts + event.dur - trace.timeOriginEvt.ts) / 1e3; + if (start > endTime || end < startTime) continue; + if (prevToplevel && start < prevToplevel.end) { + prevToplevel.end = start - 1e-3; + } + prevToplevel = { + start, + end, + duration: event.dur / 1e3 + }; + topLevelEvents.push(prevToplevel); + } + return topLevelEvents; + } + /** + * @param {LH.TraceEvent[]} events + * @return {{startingPid: number, frameId: string}} + */ + static findMainFrameIds(events) { + const startedInBrowserEvt = events.find((e) => e.name === "TracingStartedInBrowser"); + if (startedInBrowserEvt?.args.data?.frames) { + const mainFrame = startedInBrowserEvt.args.data.frames.find((frame) => !frame.parent); + const frameId = mainFrame?.frame; + const pid = mainFrame?.processId; + if (pid && frameId) { + return { + startingPid: pid, + frameId + }; + } + } + const startedInPageEvt = events.find((e) => e.name === "TracingStartedInPage"); + if (startedInPageEvt?.args?.data) { + const frameId = startedInPageEvt.args.data.page; + if (frameId) { + return { + startingPid: startedInPageEvt.pid, + frameId + }; + } + } + const navStartEvt = events.find( + (e) => this._isNavigationStartOfInterest(e) && e.args.data?.isLoadingMainFrame + ); + const firstResourceSendEvt = events.find((e) => e.name === "ResourceSendRequest"); + if (navStartEvt?.args?.data && firstResourceSendEvt && firstResourceSendEvt.pid === navStartEvt.pid && firstResourceSendEvt.tid === navStartEvt.tid) { + const frameId = navStartEvt.args.frame; + if (frameId) { + return { + startingPid: navStartEvt.pid, + frameId + }; + } + } + throw this.createNoTracingStartedError(); + } + /** + * If there were any cross-origin navigations, there'll be more than one pid returned + * @param {{startingPid: number, frameId: string}} mainFrameInfo + * @param {LH.TraceEvent[]} keyEvents + * @return {Map} Map where keys are process IDs and their values are thread IDs + */ + static findMainFramePidTids(mainFrameInfo, keyEvents) { + const frameProcessEvts = keyEvents.filter( + (evt) => ( + // ProcessReadyInBrowser is used when a processID isn't available when the FrameCommittedInBrowser trace event is emitted. + // In that case. FrameCommittedInBrowser has no processId, but a processPseudoId. and the ProcessReadyInBrowser event declares the proper processId. + (evt.name === "FrameCommittedInBrowser" || evt.name === "ProcessReadyInBrowser") && evt.args?.data?.frame === mainFrameInfo.frameId && evt?.args?.data?.processId + ) + ); + const mainFramePids = frameProcessEvts.length ? frameProcessEvts.map((e) => e?.args?.data?.processId) : [mainFrameInfo.startingPid]; + const pidToTid = /* @__PURE__ */ new Map(); + for (const pid of new Set(mainFramePids)) { + const threadEvents = keyEvents.filter( + (e) => e.cat === "__metadata" && e.pid === pid && e.ph === "M" && e.name === "thread_name" + ); + let threadNameEvt = threadEvents.find((e) => e.args.name === "CrRendererMain"); + if (!threadNameEvt) { + threadNameEvt = threadEvents.find((e) => e.args.name === "CrBrowserMain"); + } + const tid = threadNameEvt?.tid; + if (!tid) { + throw new Error("Unable to determine tid for renderer process"); + } + pidToTid.set(pid, tid); + } + return pidToTid; + } + /** + * @param {LH.TraceEvent} evt + * @return {boolean} + */ + static isScheduleableTask(evt) { + return evt.name === SCHEDULABLE_TASK_TITLE_LH2 || evt.name === SCHEDULABLE_TASK_TITLE_ALT12 || evt.name === SCHEDULABLE_TASK_TITLE_ALT22 || evt.name === SCHEDULABLE_TASK_TITLE_ALT32; + } + /** + * @param {LH.TraceEvent} evt + * @return {evt is LCPEvent} + */ + static isLCPEvent(evt) { + if (evt.name !== "largestContentfulPaint::Invalidate" && evt.name !== "largestContentfulPaint::Candidate") return false; + return Boolean(evt.args?.frame); + } + /** + * @param {LH.TraceEvent} evt + * @return {evt is LCPCandidateEvent} + */ + static isLCPCandidateEvent(evt) { + return Boolean( + evt.name === "largestContentfulPaint::Candidate" && evt.args?.frame && evt.args.data && evt.args.data.size !== void 0 + ); + } + /** + * The associated frame ID is set in different locations for different trace events. + * This function checks all known locations for the frame ID and returns `undefined` if it's not found. + * + * @param {LH.TraceEvent} evt + * @return {string|undefined} + */ + static getFrameId(evt) { + return evt.args?.data?.frame || evt.args.data?.frameID || evt.args.frame; + } + /** + * Returns the maximum LCP event across all frames in `events`. + * Sets `invalidated` flag if LCP of every frame is invalidated. + * + * LCP's trace event was first introduced in m78. We can't surface an LCP for older Chrome versions. + * LCP comes from a frame's latest `largestContentfulPaint::Candidate`, but it can be invalidated by a `largestContentfulPaint::Invalidate` event. + * + * @param {LH.TraceEvent[]} events + * @param {LH.TraceEvent} timeOriginEvent + * @return {{lcp: LCPEvent | undefined, invalidated: boolean}} + */ + static computeValidLCPAllFrames(events, timeOriginEvent) { + const lcpEvents = events.filter(this.isLCPEvent).reverse(); + const finalLcpEventsByFrame = /* @__PURE__ */ new Map(); + for (const e of lcpEvents) { + if (e.ts <= timeOriginEvent.ts) break; + const frame = e.args.frame; + if (finalLcpEventsByFrame.has(frame)) continue; + finalLcpEventsByFrame.set(frame, e); + } + let maxLcpAcrossFrames; + for (const lcp of finalLcpEventsByFrame.values()) { + if (!this.isLCPCandidateEvent(lcp)) continue; + if (!maxLcpAcrossFrames || lcp.args.data.size > maxLcpAcrossFrames.args.data.size) { + maxLcpAcrossFrames = lcp; + } + } + return { + lcp: maxLcpAcrossFrames, + // LCP events were found, but final LCP event of every frame was an invalidate event. + invalidated: Boolean(!maxLcpAcrossFrames && finalLcpEventsByFrame.size) + }; + } + /** + * @param {Array<{id: string, url: string, parent?: string}>} frames + * @return {Map} + */ + static resolveRootFrames(frames2) { + const parentFrames = /* @__PURE__ */ new Map(); + for (const frame of frames2) { + if (!frame.parent) continue; + parentFrames.set(frame.id, frame.parent); + } + const frameIdToRootFrameId = /* @__PURE__ */ new Map(); + for (const frame of frames2) { + let cur = frame.id; + while (parentFrames.has(cur)) { + cur = /** @type {string} */ + parentFrames.get(cur); + } + if (cur === void 0) { + throw new Error("Unexpected undefined frameId"); + } + frameIdToRootFrameId.set(frame.id, cur); + } + return frameIdToRootFrameId; + } + /** + * Finds key trace events, identifies main process/thread, and returns timings of trace events + * in milliseconds since the time origin in addition to the standard microsecond monotonic timestamps. + * @param {LH.Trace} trace + * @param {{timeOriginDeterminationMethod?: TimeOriginDeterminationMethod}} [options] + * @return {LH.Artifacts.ProcessedTrace} + */ + static processTrace(trace, options) { + const { timeOriginDeterminationMethod = "auto" } = options || {}; + const keyEvents = this.filteredTraceSort(trace.traceEvents, (e) => { + return e.cat.includes("blink.user_timing") || e.cat.includes("loading") || e.cat.includes("devtools.timeline") || e.cat === "__metadata"; + }); + const mainFrameInfo = this.findMainFrameIds(keyEvents); + const rendererPidToTid = this.findMainFramePidTids(mainFrameInfo, keyEvents); + const processEvents = _TraceProcessor.filteredTraceSort(trace.traceEvents, (e) => rendererPidToTid.has(e.pid)); + const framesById = /* @__PURE__ */ new Map(); + const tracingStartedFrames = keyEvents.find((e) => e.name === "TracingStartedInBrowser")?.args?.data?.frames; + if (tracingStartedFrames) { + for (const frame of tracingStartedFrames) { + framesById.set(frame.frame, { + id: frame.frame, + url: frame.url, + parent: frame.parent + }); + } + } + keyEvents.filter( + /** @return {evt is FrameCommittedEvent} */ + (evt) => { + return Boolean( + evt.name === "FrameCommittedInBrowser" && evt.args.data?.frame && evt.args.data.url !== void 0 + ); + } + ).forEach((evt) => { + framesById.set(evt.args.data.frame, { + id: evt.args.data.frame, + url: evt.args.data.url, + parent: evt.args.data.parent + }); + }); + const frames2 = [...framesById.values()]; + const frameIdToRootFrameId = this.resolveRootFrames(frames2); + const inspectedTreeFrameIds = [...frameIdToRootFrameId.entries()].filter(([, rootFrameId]) => rootFrameId === mainFrameInfo.frameId).map(([child]) => child); + function associatedToMainFrame(e) { + const frameId = _TraceProcessor.getFrameId(e); + return frameId === mainFrameInfo.frameId; + } + __name(associatedToMainFrame, "associatedToMainFrame"); + function associatedToAllFrames(e) { + const frameId = _TraceProcessor.getFrameId(e); + return frameId ? inspectedTreeFrameIds.includes(frameId) : false; + } + __name(associatedToAllFrames, "associatedToAllFrames"); + const frameEvents = keyEvents.filter((e) => associatedToMainFrame(e)); + let frameTreeEvents = []; + if (frameIdToRootFrameId.has(mainFrameInfo.frameId)) { + frameTreeEvents = keyEvents.filter((e) => associatedToAllFrames(e)); + } else { + lighthouse_logger_default.warn( + "TraceProcessor", + "frameTreeEvents may be incomplete, make sure the trace has frame events" + ); + frameIdToRootFrameId.set(mainFrameInfo.frameId, mainFrameInfo.frameId); + frameTreeEvents = frameEvents; + } + const timeOriginEvt = this.computeTimeOrigin( + { keyEvents, frameEvents, mainFrameInfo }, + timeOriginDeterminationMethod + ); + const mainThreadEvents = processEvents.filter((e) => e.tid === rendererPidToTid.get(e.pid)); + const traceEnd = this.computeTraceEnd(trace.traceEvents, timeOriginEvt); + return { + frames: frames2, + mainThreadEvents, + frameEvents, + frameTreeEvents, + processEvents, + mainFrameInfo, + timeOriginEvt, + timings: { + timeOrigin: 0, + traceEnd: traceEnd.timing + }, + timestamps: { + timeOrigin: timeOriginEvt.ts, + traceEnd: traceEnd.timestamp + }, + _keyEvents: keyEvents, + _rendererPidToTid: rendererPidToTid + }; + } + /** + * Finds key navigation trace events and computes timings of events in milliseconds since the time + * origin in addition to the standard microsecond monotonic timestamps. + * @param {LH.Artifacts.ProcessedTrace} processedTrace + * @return {LH.Artifacts.ProcessedNavigation} + */ + static processNavigation(processedTrace) { + const { frameEvents, frameTreeEvents, timeOriginEvt, timings, timestamps } = processedTrace; + const frameTimings = this.computeNavigationTimingsForFrame(frameEvents, { timeOriginEvt }); + const fcpAllFramesEvt = frameTreeEvents.find( + (e) => e.name === "firstContentfulPaint" && e.ts > timeOriginEvt.ts + ); + if (!fcpAllFramesEvt) { + throw this.createNoFirstContentfulPaintError(); + } + const lcpAllFramesEvt = this.computeValidLCPAllFrames(frameTreeEvents, timeOriginEvt).lcp; + const getTiming = /* @__PURE__ */ __name((ts) => (ts - timeOriginEvt.ts) / 1e3, "getTiming"); + const maybeGetTiming = /* @__PURE__ */ __name((ts) => ts === void 0 ? void 0 : getTiming(ts), "maybeGetTiming"); + return { + timings: { + timeOrigin: timings.timeOrigin, + firstPaint: frameTimings.timings.firstPaint, + firstContentfulPaint: frameTimings.timings.firstContentfulPaint, + firstContentfulPaintAllFrames: getTiming(fcpAllFramesEvt.ts), + largestContentfulPaint: frameTimings.timings.largestContentfulPaint, + largestContentfulPaintAllFrames: maybeGetTiming(lcpAllFramesEvt?.ts), + load: frameTimings.timings.load, + domContentLoaded: frameTimings.timings.domContentLoaded, + traceEnd: timings.traceEnd + }, + timestamps: { + timeOrigin: timestamps.timeOrigin, + firstPaint: frameTimings.timestamps.firstPaint, + firstContentfulPaint: frameTimings.timestamps.firstContentfulPaint, + firstContentfulPaintAllFrames: fcpAllFramesEvt.ts, + largestContentfulPaint: frameTimings.timestamps.largestContentfulPaint, + largestContentfulPaintAllFrames: lcpAllFramesEvt?.ts, + load: frameTimings.timestamps.load, + domContentLoaded: frameTimings.timestamps.domContentLoaded, + traceEnd: timestamps.traceEnd + }, + firstPaintEvt: frameTimings.firstPaintEvt, + firstContentfulPaintEvt: frameTimings.firstContentfulPaintEvt, + firstContentfulPaintAllFramesEvt: fcpAllFramesEvt, + largestContentfulPaintEvt: frameTimings.largestContentfulPaintEvt, + largestContentfulPaintAllFramesEvt: lcpAllFramesEvt, + loadEvt: frameTimings.loadEvt, + domContentLoadedEvt: frameTimings.domContentLoadedEvt, + lcpInvalidated: frameTimings.lcpInvalidated + }; + } + /** + * Computes the last observable timestamp in a set of trace events. + * + * @param {Array} events + * @param {LH.TraceEvent} timeOriginEvt + * @return {{timing: number, timestamp: number}} + */ + static computeTraceEnd(events, timeOriginEvt) { + let maxTs = -Infinity; + for (const event of events) { + maxTs = Math.max(event.ts + (event.dur || 0), maxTs); + } + return { timestamp: maxTs, timing: (maxTs - timeOriginEvt.ts) / 1e3 }; + } + /** + * Computes the time origin using the specified method. + * + * - firstResourceSendRequest + * Uses the time that the very first network request is sent in the main frame. + * Eventually should be used in place of lastNavigationStart as the default for navigations. + * This method includes the cost of all redirects when evaluating a navigation (which matches lantern behavior). + * The only difference between firstResourceSendRequest and the first `navigationStart` is + * the unload time of `about:blank` (which is a Lighthouse implementation detail and shouldn't be included). + * + * - lastNavigationStart + * Uses the time of the last `navigationStart` event in the main frame. + * The historical time origin of Lighthouse from 2016-Present. + * This method excludes the cost of client-side redirects when evaluating a navigation. + * Can also be skewed by several hundred milliseconds or even seconds when the browser takes a long + * time to unload `about:blank`. + * + * @param {{keyEvents: Array, frameEvents: Array, mainFrameInfo: {frameId: string}}} traceEventSubsets + * @param {TimeOriginDeterminationMethod} method + * @return {LH.TraceEvent} + */ + static computeTimeOrigin(traceEventSubsets, method) { + const lastNavigationStart = /* @__PURE__ */ __name(() => { + const frameEvents = traceEventSubsets.frameEvents; + return frameEvents.filter(this._isNavigationStartOfInterest).pop(); + }, "lastNavigationStart"); + const lighthouseMarker = /* @__PURE__ */ __name(() => { + const frameEvents = traceEventSubsets.keyEvents; + return frameEvents.find( + (evt) => evt.name === "clock_sync" && evt.args.sync_id === _TraceProcessor.TIMESPAN_MARKER_ID + ); + }, "lighthouseMarker"); + switch (method) { + case "firstResourceSendRequest": { + const fetchStart = traceEventSubsets.keyEvents.find((event) => { + if (event.name !== "ResourceSendRequest") return false; + const data31 = event.args.data || {}; + return data31.frame === traceEventSubsets.mainFrameInfo.frameId; + }); + if (!fetchStart) throw this.createNoResourceSendRequestError(); + return fetchStart; + } + case "lastNavigationStart": { + const navigationStart = lastNavigationStart(); + if (!navigationStart) throw this.createNoNavstartError(); + return navigationStart; + } + case "lighthouseMarker": { + const marker = lighthouseMarker(); + if (!marker) throw this.createNoLighthouseMarkerError(); + return marker; + } + case "auto": { + const marker = lighthouseMarker() || lastNavigationStart(); + if (!marker) throw this.createNoNavstartError(); + return marker; + } + } + } + /** + * Computes timings of trace events of key trace events in milliseconds since the time origin + * in addition to the standard microsecond monotonic timestamps. + * @param {Array} frameEvents + * @param {{timeOriginEvt: LH.TraceEvent}} options + */ + static computeNavigationTimingsForFrame(frameEvents, options) { + const { timeOriginEvt } = options; + const firstPaint = frameEvents.find((e) => e.name === "firstPaint" && e.ts > timeOriginEvt.ts); + const firstContentfulPaint = frameEvents.find( + (e) => e.name === "firstContentfulPaint" && e.ts > timeOriginEvt.ts + ); + if (!firstContentfulPaint) { + throw this.createNoFirstContentfulPaintError(); + } + const lcpResult = this.computeValidLCPAllFrames(frameEvents, timeOriginEvt); + const load = frameEvents.find((e) => e.name === "loadEventEnd" && e.ts > timeOriginEvt.ts); + const domContentLoaded = frameEvents.find( + (e) => e.name === "domContentLoadedEventEnd" && e.ts > timeOriginEvt.ts + ); + const getTimestamp = /* @__PURE__ */ __name((event) => event?.ts, "getTimestamp"); + const timestamps = { + timeOrigin: timeOriginEvt.ts, + firstPaint: getTimestamp(firstPaint), + firstContentfulPaint: firstContentfulPaint.ts, + largestContentfulPaint: getTimestamp(lcpResult.lcp), + load: getTimestamp(load), + domContentLoaded: getTimestamp(domContentLoaded) + }; + const getTiming = /* @__PURE__ */ __name((ts) => (ts - timeOriginEvt.ts) / 1e3, "getTiming"); + const maybeGetTiming = /* @__PURE__ */ __name((ts) => ts === void 0 ? void 0 : getTiming(ts), "maybeGetTiming"); + const timings = { + timeOrigin: 0, + firstPaint: maybeGetTiming(timestamps.firstPaint), + firstContentfulPaint: getTiming(timestamps.firstContentfulPaint), + largestContentfulPaint: maybeGetTiming(timestamps.largestContentfulPaint), + load: maybeGetTiming(timestamps.load), + domContentLoaded: maybeGetTiming(timestamps.domContentLoaded) + }; + return { + timings, + timestamps, + timeOriginEvt, + firstPaintEvt: firstPaint, + firstContentfulPaintEvt: firstContentfulPaint, + largestContentfulPaintEvt: lcpResult.lcp, + loadEvt: load, + domContentLoadedEvt: domContentLoaded, + lcpInvalidated: lcpResult.invalidated + }; + } + }; + } +}); + +// core/lib/traces/metric-trace-events.js +var init_metric_trace_events = __esm({ + "core/lib/traces/metric-trace-events.js"() { + "use strict"; + init_process_global(); + init_lighthouse_logger(); + init_trace_processor(); + /** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + } +}); + +// core/lib/arbitrary-equality-map.js +var ArbitraryEqualityMap; +var init_arbitrary_equality_map = __esm({ + "core/lib/arbitrary-equality-map.js"() { + "use strict"; + init_process_global(); + init_lodash(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + ArbitraryEqualityMap = class _ArbitraryEqualityMap { + static { + __name(this, "ArbitraryEqualityMap"); + } + constructor() { + this._equalsFn = _ArbitraryEqualityMap.deepEquals; + this._entries = []; + } + /** + * @param {function(*,*):boolean} equalsFn + */ + setEqualityFn(equalsFn) { + this._equalsFn = equalsFn; + } + /** + * @param {*} key + * @return {boolean} + */ + has(key) { + return this._findIndexOf(key) !== -1; + } + /** + * @param {*} key + * @return {*} + */ + get(key) { + const entry = this._entries[this._findIndexOf(key)]; + return entry?.value; + } + /** + * @param {*} key + * @param {*} value + */ + set(key, value) { + let index = this._findIndexOf(key); + if (index === -1) index = this._entries.length; + this._entries[index] = { key, value }; + } + /** + * @param {*} key + * @return {number} + */ + _findIndexOf(key) { + for (let i = 0; i < this._entries.length; i++) { + if (this._equalsFn(key, this._entries[i].key)) return i; + } + return -1; + } + /** + * Determines whether two objects are deeply equal. Defers to lodash isEqual, but is kept here for + * easy usage by consumers. + * See https://lodash.com/docs/4.17.5#isEqual. + * @param {*} objA + * @param {*} objB + * @return {boolean} + */ + static deepEquals(objA, objB) { + return isEqual_default(objA, objB); + } + }; + } +}); + +// core/computed/computed-artifact.js +function makeComputedArtifact(computableArtifact, keys2) { + const request = /* @__PURE__ */ __name((dependencies, context) => { + const computedName = computableArtifact.name; + for (const key of keys2 || []) { + if (dependencies && typeof dependencies === "object" && dependencies[key] === void 0) { + const err = new Error(`missing required key "${String(key)}" for computed artifact ${computableArtifact.name}`); + if (isUnderTest) { + throw err; + } else { + lighthouse_logger_default.error(`lh:computed:${computedName}`, err); + } + } + } + const pickedDependencies = keys2 ? Object.fromEntries(keys2.map((key) => [key, dependencies[key]])) : dependencies; + const computedCache = ( + /** @type {Map} */ + context.computedCache + ); + const cache = computedCache.get(computedName) || new ArbitraryEqualityMap(); + computedCache.set(computedName, cache); + const computed = cache.get(pickedDependencies); + if (computed) { + return computed; + } + const status = { msg: `Computing artifact: ${computedName}`, id: `lh:computed:${computedName}` }; + lighthouse_logger_default.time(status, "verbose"); + const artifactPromise = ( + /** @type {ReturnType} */ + computableArtifact.compute_(pickedDependencies, context) + ); + cache.set(pickedDependencies, artifactPromise); + artifactPromise.then(() => lighthouse_logger_default.timeEnd(status)).catch(() => lighthouse_logger_default.timeEnd(status)); + return artifactPromise; + }, "request"); + return Object.assign(computableArtifact, { request }); +} +var init_computed_artifact = __esm({ + "core/computed/computed-artifact.js"() { + "use strict"; + init_process_global(); + init_lighthouse_logger(); + init_arbitrary_equality_map(); + init_lh_env(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + __name(makeComputedArtifact, "makeComputedArtifact"); + } +}); + +// node_modules/tldts-icann/dist/cjs/index.js +var require_cjs = __commonJS({ + "node_modules/tldts-icann/dist/cjs/index.js"(exports2) { + "use strict"; + init_process_global(); + function shareSameDomainSuffix(hostname, vhost) { + if (hostname.endsWith(vhost)) { + return hostname.length === vhost.length || hostname[hostname.length - vhost.length - 1] === "."; + } + return false; + } + __name(shareSameDomainSuffix, "shareSameDomainSuffix"); + function extractDomainWithSuffix(hostname, publicSuffix) { + const publicSuffixIndex = hostname.length - publicSuffix.length - 2; + const lastDotBeforeSuffixIndex = hostname.lastIndexOf(".", publicSuffixIndex); + if (lastDotBeforeSuffixIndex === -1) { + return hostname; + } + return hostname.slice(lastDotBeforeSuffixIndex + 1); + } + __name(extractDomainWithSuffix, "extractDomainWithSuffix"); + function getDomain$1(suffix, hostname, options) { + if (options.validHosts !== null) { + const validHosts = options.validHosts; + for (const vhost of validHosts) { + if ( + /*@__INLINE__*/ + shareSameDomainSuffix(hostname, vhost) + ) { + return vhost; + } + } + } + let numberOfLeadingDots = 0; + if (hostname.startsWith(".")) { + while (numberOfLeadingDots < hostname.length && hostname[numberOfLeadingDots] === ".") { + numberOfLeadingDots += 1; + } + } + if (suffix.length === hostname.length - numberOfLeadingDots) { + return null; + } + return ( + /*@__INLINE__*/ + extractDomainWithSuffix(hostname, suffix) + ); + } + __name(getDomain$1, "getDomain$1"); + function getDomainWithoutSuffix$1(domain, suffix) { + return domain.slice(0, -suffix.length - 1); + } + __name(getDomainWithoutSuffix$1, "getDomainWithoutSuffix$1"); + function extractHostname(url, urlIsValidHostname) { + let start = 0; + let end = url.length; + let hasUpper = false; + if (!urlIsValidHostname) { + if (url.startsWith("data:")) { + return null; + } + while (start < url.length && url.charCodeAt(start) <= 32) { + start += 1; + } + while (end > start + 1 && url.charCodeAt(end - 1) <= 32) { + end -= 1; + } + if (url.charCodeAt(start) === 47 && url.charCodeAt(start + 1) === 47) { + start += 2; + } else { + const indexOfProtocol = url.indexOf(":/", start); + if (indexOfProtocol !== -1) { + const protocolSize = indexOfProtocol - start; + const c0 = url.charCodeAt(start); + const c1 = url.charCodeAt(start + 1); + const c2 = url.charCodeAt(start + 2); + const c3 = url.charCodeAt(start + 3); + const c4 = url.charCodeAt(start + 4); + if (protocolSize === 5 && c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112 && c4 === 115) ; + else if (protocolSize === 4 && c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112) ; + else if (protocolSize === 3 && c0 === 119 && c1 === 115 && c2 === 115) ; + else if (protocolSize === 2 && c0 === 119 && c1 === 115) ; + else { + for (let i = start; i < indexOfProtocol; i += 1) { + const lowerCaseCode = url.charCodeAt(i) | 32; + if (!(lowerCaseCode >= 97 && lowerCaseCode <= 122 || // [a, z] + lowerCaseCode >= 48 && lowerCaseCode <= 57 || // [0, 9] + lowerCaseCode === 46 || // '.' + lowerCaseCode === 45 || // '-' + lowerCaseCode === 43)) { + return null; + } + } + } + start = indexOfProtocol + 2; + while (url.charCodeAt(start) === 47) { + start += 1; + } + } + } + let indexOfIdentifier = -1; + let indexOfClosingBracket = -1; + let indexOfPort = -1; + for (let i = start; i < end; i += 1) { + const code = url.charCodeAt(i); + if (code === 35 || // '#' + code === 47 || // '/' + code === 63) { + end = i; + break; + } else if (code === 64) { + indexOfIdentifier = i; + } else if (code === 93) { + indexOfClosingBracket = i; + } else if (code === 58) { + indexOfPort = i; + } else if (code >= 65 && code <= 90) { + hasUpper = true; + } + } + if (indexOfIdentifier !== -1 && indexOfIdentifier > start && indexOfIdentifier < end) { + start = indexOfIdentifier + 1; + } + if (url.charCodeAt(start) === 91) { + if (indexOfClosingBracket !== -1) { + return url.slice(start + 1, indexOfClosingBracket).toLowerCase(); + } + return null; + } else if (indexOfPort !== -1 && indexOfPort > start && indexOfPort < end) { + end = indexOfPort; + } + } + while (end > start + 1 && url.charCodeAt(end - 1) === 46) { + end -= 1; + } + const hostname = start !== 0 || end !== url.length ? url.slice(start, end) : url; + if (hasUpper) { + return hostname.toLowerCase(); + } + return hostname; + } + __name(extractHostname, "extractHostname"); + function isProbablyIpv4(hostname) { + if (hostname.length < 7) { + return false; + } + if (hostname.length > 15) { + return false; + } + let numberOfDots = 0; + for (let i = 0; i < hostname.length; i += 1) { + const code = hostname.charCodeAt(i); + if (code === 46) { + numberOfDots += 1; + } else if (code < 48 || code > 57) { + return false; + } + } + return numberOfDots === 3 && hostname.charCodeAt(0) !== 46 && hostname.charCodeAt(hostname.length - 1) !== 46; + } + __name(isProbablyIpv4, "isProbablyIpv4"); + function isProbablyIpv6(hostname) { + if (hostname.length < 3) { + return false; + } + let start = hostname.startsWith("[") ? 1 : 0; + let end = hostname.length; + if (hostname[end - 1] === "]") { + end -= 1; + } + if (end - start > 39) { + return false; + } + let hasColon = false; + for (; start < end; start += 1) { + const code = hostname.charCodeAt(start); + if (code === 58) { + hasColon = true; + } else if (!(code >= 48 && code <= 57 || // 0-9 + code >= 97 && code <= 102 || // a-f + code >= 65 && code <= 90)) { + return false; + } + } + return hasColon; + } + __name(isProbablyIpv6, "isProbablyIpv6"); + function isIp(hostname) { + return isProbablyIpv6(hostname) || isProbablyIpv4(hostname); + } + __name(isIp, "isIp"); + function isValidAscii(code) { + return code >= 97 && code <= 122 || code >= 48 && code <= 57 || code > 127; + } + __name(isValidAscii, "isValidAscii"); + function isValidHostname(hostname) { + if (hostname.length > 255) { + return false; + } + if (hostname.length === 0) { + return false; + } + if ( + /*@__INLINE__*/ + !isValidAscii(hostname.charCodeAt(0)) && hostname.charCodeAt(0) !== 46 && // '.' (dot) + hostname.charCodeAt(0) !== 95 + ) { + return false; + } + let lastDotIndex = -1; + let lastCharCode = -1; + const len = hostname.length; + for (let i = 0; i < len; i += 1) { + const code = hostname.charCodeAt(i); + if (code === 46) { + if ( + // Check that previous label is < 63 bytes long (64 = 63 + '.') + i - lastDotIndex > 64 || // Check that previous character was not already a '.' + lastCharCode === 46 || // Check that the previous label does not end with a '-' (dash) + lastCharCode === 45 || // Check that the previous label does not end with a '_' (underscore) + lastCharCode === 95 + ) { + return false; + } + lastDotIndex = i; + } else if (!/*@__INLINE__*/ + (isValidAscii(code) || code === 45 || code === 95)) { + return false; + } + lastCharCode = code; + } + return ( + // Check that last label is shorter than 63 chars + len - lastDotIndex - 1 <= 63 && // Check that the last character is an allowed trailing label character. + // Since we already checked that the char is a valid hostname character, + // we only need to check that it's different from '-'. + lastCharCode !== 45 + ); + } + __name(isValidHostname, "isValidHostname"); + function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, extractHostname: extractHostname2 = true, mixedInputs = true, validHosts = null, validateHostname = true }) { + return { + allowIcannDomains, + allowPrivateDomains, + detectIp, + extractHostname: extractHostname2, + mixedInputs, + validHosts, + validateHostname + }; + } + __name(setDefaultsImpl, "setDefaultsImpl"); + var DEFAULT_OPTIONS = ( + /*@__INLINE__*/ + setDefaultsImpl({}) + ); + function setDefaults(options) { + if (options === void 0) { + return DEFAULT_OPTIONS; + } + return ( + /*@__INLINE__*/ + setDefaultsImpl(options) + ); + } + __name(setDefaults, "setDefaults"); + function getSubdomain$1(hostname, domain) { + if (domain.length === hostname.length) { + return ""; + } + return hostname.slice(0, -domain.length - 1); + } + __name(getSubdomain$1, "getSubdomain$1"); + function getEmptyResult() { + return { + domain: null, + domainWithoutSuffix: null, + hostname: null, + isIcann: null, + isIp: null, + isPrivate: null, + publicSuffix: null, + subdomain: null + }; + } + __name(getEmptyResult, "getEmptyResult"); + function resetResult(result) { + result.domain = null; + result.domainWithoutSuffix = null; + result.hostname = null; + result.isIcann = null; + result.isIp = null; + result.isPrivate = null; + result.publicSuffix = null; + result.subdomain = null; + } + __name(resetResult, "resetResult"); + function parseImpl(url, step, suffixLookup2, partialOptions, result) { + const options = ( + /*@__INLINE__*/ + setDefaults(partialOptions) + ); + if (typeof url !== "string") { + return result; + } + if (!options.extractHostname) { + result.hostname = url; + } else if (options.mixedInputs) { + result.hostname = extractHostname(url, isValidHostname(url)); + } else { + result.hostname = extractHostname(url, false); + } + if (options.detectIp && result.hostname !== null) { + result.isIp = isIp(result.hostname); + if (result.isIp) { + return result; + } + } + if (options.validateHostname && options.extractHostname && result.hostname !== null && !isValidHostname(result.hostname)) { + result.hostname = null; + return result; + } + if (step === 0 || result.hostname === null) { + return result; + } + suffixLookup2(result.hostname, options, result); + if (step === 2 || result.publicSuffix === null) { + return result; + } + result.domain = getDomain$1(result.publicSuffix, result.hostname, options); + if (step === 3 || result.domain === null) { + return result; + } + result.subdomain = getSubdomain$1(result.hostname, result.domain); + if (step === 4) { + return result; + } + result.domainWithoutSuffix = getDomainWithoutSuffix$1(result.domain, result.publicSuffix); + return result; + } + __name(parseImpl, "parseImpl"); + function fastPathLookup(hostname, options, out) { + if (!options.allowPrivateDomains && hostname.length > 3) { + const last = hostname.length - 1; + const c3 = hostname.charCodeAt(last); + const c2 = hostname.charCodeAt(last - 1); + const c1 = hostname.charCodeAt(last - 2); + const c0 = hostname.charCodeAt(last - 3); + if (c3 === 109 && c2 === 111 && c1 === 99 && c0 === 46) { + out.isIcann = true; + out.isPrivate = false; + out.publicSuffix = "com"; + return true; + } else if (c3 === 103 && c2 === 114 && c1 === 111 && c0 === 46) { + out.isIcann = true; + out.isPrivate = false; + out.publicSuffix = "org"; + return true; + } else if (c3 === 117 && c2 === 100 && c1 === 101 && c0 === 46) { + out.isIcann = true; + out.isPrivate = false; + out.publicSuffix = "edu"; + return true; + } else if (c3 === 118 && c2 === 111 && c1 === 103 && c0 === 46) { + out.isIcann = true; + out.isPrivate = false; + out.publicSuffix = "gov"; + return true; + } else if (c3 === 116 && c2 === 101 && c1 === 110 && c0 === 46) { + out.isIcann = true; + out.isPrivate = false; + out.publicSuffix = "net"; + return true; + } else if (c3 === 101 && c2 === 100 && c1 === 46) { + out.isIcann = true; + out.isPrivate = false; + out.publicSuffix = "de"; + return true; + } + } + return false; + } + __name(fastPathLookup, "fastPathLookup"); + var exceptions = /* @__PURE__ */ (function() { + const _68 = [1, {}], _69 = [0, { "city": _68 }]; + const exceptions2 = [0, { "ck": [0, { "www": _68 }], "jp": [0, { "kawasaki": _69, "kitakyushu": _69, "kobe": _69, "nagoya": _69, "sapporo": _69, "sendai": _69, "yokohama": _69 }] }]; + return exceptions2; + })(); + var rules = /* @__PURE__ */ (function() { + const _70 = [1, {}], _71 = [1, { "com": _70, "edu": _70, "gov": _70, "mil": _70, "net": _70, "org": _70 }], _72 = [1, { "com": _70, "edu": _70, "gov": _70, "net": _70, "org": _70 }], _73 = [1, { "gov": _70 }], _74 = [0, { "*": _70 }], _75 = [1, { "co": _70, "com": _70, "edu": _70, "gov": _70, "net": _70, "org": _70 }], _76 = [1, { "com": _70, "edu": _70, "net": _70, "org": _70 }], _77 = [1, { "co": _70, "net": _70, "org": _70 }], _78 = [1, { "co": _70, "com": _70, "edu": _70, "gov": _70, "mil": _70, "net": _70, "nom": _70, "org": _70 }], _79 = [1, { "biz": _70, "com": _70, "edu": _70, "gov": _70, "info": _70, "net": _70, "org": _70 }], _80 = [1, { "gs": _70 }], _81 = [0, { "nes": _70 }], _82 = [1, { "k12": _70, "cc": _70, "lib": _70 }], _83 = [1, { "cc": _70 }], _84 = [1, { "cc": _70, "lib": _70 }]; + const rules2 = [0, { "ac": _71, "ad": _70, "ae": [1, { "ac": _70, "co": _70, "gov": _70, "mil": _70, "net": _70, "org": _70, "sch": _70 }], "aero": [1, { "airline": _70, "airport": _70, "accident-investigation": _70, "accident-prevention": _70, "aerobatic": _70, "aeroclub": _70, "aerodrome": _70, "agents": _70, "air-surveillance": _70, "air-traffic-control": _70, "aircraft": _70, "airtraffic": _70, "ambulance": _70, "association": _70, "author": _70, "ballooning": _70, "broker": _70, "caa": _70, "cargo": _70, "catering": _70, "certification": _70, "championship": _70, "charter": _70, "civilaviation": _70, "club": _70, "conference": _70, "consultant": _70, "consulting": _70, "control": _70, "council": _70, "crew": _70, "design": _70, "dgca": _70, "educator": _70, "emergency": _70, "engine": _70, "engineer": _70, "entertainment": _70, "equipment": _70, "exchange": _70, "express": _70, "federation": _70, "flight": _70, "freight": _70, "fuel": _70, "gliding": _70, "government": _70, "\ +groundhandling": _70, "group": _70, "hanggliding": _70, "homebuilt": _70, "insurance": _70, "journal": _70, "journalist": _70, "leasing": _70, "logistics": _70, "magazine": _70, "maintenance": _70, "marketplace": _70, "media": _70, "microlight": _70, "modelling": _70, "navigation": _70, "parachuting": _70, "paragliding": _70, "passenger-association": _70, "pilot": _70, "press": _70, "production": _70, "recreation": _70, "repbody": _70, "res": _70, "research": _70, "rotorcraft": _70, "safety": _70, "scientist": _70, "services": _70, "show": _70, "skydiving": _70, "software": _70, "student": _70, "taxi": _70, "trader": _70, "trading": _70, "trainer": _70, "union": _70, "workinggroup": _70, "works": _70 }], "af": _72, "ag": [1, { "co": _70, "com": _70, "net": _70, "nom": _70, "org": _70 }], "ai": [1, { "com": _70, "net": _70, "off": _70, "org": _70 }], "al": _71, "am": [1, { "co": _70, "com": _70, "commune": _70, "net": _70, "org": _70 }], "ao": [1, { "co": _70, "ed": _70, "edu": _70, "go\ +v": _70, "gv": _70, "it": _70, "og": _70, "org": _70, "pb": _70 }], "aq": _70, "ar": [1, { "bet": _70, "com": _70, "coop": _70, "edu": _70, "gob": _70, "gov": _70, "int": _70, "mil": _70, "musica": _70, "mutual": _70, "net": _70, "org": _70, "seg": _70, "senasa": _70, "tur": _70 }], "arpa": [1, { "e164": _70, "home": _70, "in-addr": _70, "ip6": _70, "iris": _70, "uri": _70, "urn": _70 }], "as": _73, "asia": _70, "at": [1, { "ac": [1, { "sth": _70 }], "co": _70, "gv": _70, "or": _70 }], "au": [1, { "asn": _70, "com": _70, "edu": [1, { "act": _70, "catholic": _70, "nsw": _70, "nt": _70, "qld": _70, "sa": _70, "tas": _70, "vic": _70, "wa": _70 }], "gov": [1, { "qld": _70, "sa": _70, "tas": _70, "vic": _70, "wa": _70 }], "id": _70, "net": _70, "org": _70, "conf": _70, "oz": _70, "act": _70, "nsw": _70, "nt": _70, "qld": _70, "sa": _70, "tas": _70, "vic": _70, "wa": _70 }], "aw": [1, { "com": _70 }], "ax": _70, "az": [1, { "biz": _70, "co": _70, "com": _70, "edu": _70, "gov": _70, "info": _70, + "int": _70, "mil": _70, "name": _70, "net": _70, "org": _70, "pp": _70, "pro": _70 }], "ba": _71, "bb": [1, { "biz": _70, "co": _70, "com": _70, "edu": _70, "gov": _70, "info": _70, "net": _70, "org": _70, "store": _70, "tv": _70 }], "bd": _74, "be": [1, { "ac": _70 }], "bf": _73, "bg": [1, { "0": _70, "1": _70, "2": _70, "3": _70, "4": _70, "5": _70, "6": _70, "7": _70, "8": _70, "9": _70, "a": _70, "b": _70, "c": _70, "d": _70, "e": _70, "f": _70, "g": _70, "h": _70, "i": _70, "j": _70, "k": _70, "l": _70, "m": _70, "n": _70, "o": _70, "p": _70, "q": _70, "r": _70, "s": _70, "t": _70, "u": _70, "v": _70, "w": _70, "x": _70, "y": _70, "z": _70 }], "bh": _72, "bi": [1, { "co": _70, "com": _70, "edu": _70, "or": _70, "org": _70 }], "biz": _70, "bj": [1, { "africa": _70, "agro": _70, "architectes": _70, "assur": _70, "avocats": _70, "co": _70, "com": _70, "eco": _70, "econo": _70, "edu": _70, "info": _70, "loisirs": _70, "money": _70, "net": _70, "org": _70, "ote": _70, "restaurant": _70, + "resto": _70, "tourism": _70, "univ": _70 }], "bm": _72, "bn": _72, "bo": [1, { "com": _70, "edu": _70, "gob": _70, "int": _70, "mil": _70, "net": _70, "org": _70, "tv": _70, "web": _70, "academia": _70, "agro": _70, "arte": _70, "blog": _70, "bolivia": _70, "ciencia": _70, "cooperativa": _70, "democracia": _70, "deporte": _70, "ecologia": _70, "economia": _70, "empresa": _70, "indigena": _70, "industria": _70, "info": _70, "medicina": _70, "movimiento": _70, "musica": _70, "natural": _70, "nombre": _70, "noticias": _70, "patria": _70, "plurinacional": _70, "politica": _70, "profesional": _70, "pueblo": _70, "revista": _70, "salud": _70, "tecnologia": _70, "tksat": _70, "transporte": _70, "wiki": _70 }], "br": [1, { "9guacu": _70, "abc": _70, "adm": _70, "adv": _70, "agr": _70, "aju": _70, "am": _70, "anani": _70, "aparecida": _70, "api": _70, "app": _70, "arq": _70, "art": _70, "ato": _70, "b": _70, "barueri": _70, "belem": _70, "bet": _70, "bhz": _70, "bib": _70, "bio": _70, "b\ +log": _70, "bmd": _70, "boavista": _70, "bsb": _70, "campinagrande": _70, "campinas": _70, "caxias": _70, "cim": _70, "cng": _70, "cnt": _70, "com": _70, "contagem": _70, "coop": _70, "coz": _70, "cri": _70, "cuiaba": _70, "curitiba": _70, "def": _70, "des": _70, "det": _70, "dev": _70, "ecn": _70, "eco": _70, "edu": _70, "emp": _70, "enf": _70, "eng": _70, "esp": _70, "etc": _70, "eti": _70, "far": _70, "feira": _70, "flog": _70, "floripa": _70, "fm": _70, "fnd": _70, "fortal": _70, "fot": _70, "foz": _70, "fst": _70, "g12": _70, "geo": _70, "ggf": _70, "goiania": _70, "gov": [1, { "ac": _70, "al": _70, "am": _70, "ap": _70, "ba": _70, "ce": _70, "df": _70, "es": _70, "go": _70, "ma": _70, "mg": _70, "ms": _70, "mt": _70, "pa": _70, "pb": _70, "pe": _70, "pi": _70, "pr": _70, "rj": _70, "rn": _70, "ro": _70, "rr": _70, "rs": _70, "sc": _70, "se": _70, "sp": _70, "to": _70 }], "gru": _70, "ia": _70, "imb": _70, "ind": _70, "inf": _70, "jab": _70, "jampa": _70, "jdf": _70, "joinville": _70, + "jor": _70, "jus": _70, "leg": _70, "leilao": _70, "lel": _70, "log": _70, "londrina": _70, "macapa": _70, "maceio": _70, "manaus": _70, "maringa": _70, "mat": _70, "med": _70, "mil": _70, "morena": _70, "mp": _70, "mus": _70, "natal": _70, "net": _70, "niteroi": _70, "nom": _74, "not": _70, "ntr": _70, "odo": _70, "ong": _70, "org": _70, "osasco": _70, "palmas": _70, "poa": _70, "ppg": _70, "pro": _70, "psc": _70, "psi": _70, "pvh": _70, "qsl": _70, "radio": _70, "rec": _70, "recife": _70, "rep": _70, "ribeirao": _70, "rio": _70, "riobranco": _70, "riopreto": _70, "salvador": _70, "sampa": _70, "santamaria": _70, "santoandre": _70, "saobernardo": _70, "saogonca": _70, "seg": _70, "sjc": _70, "slg": _70, "slz": _70, "social": _70, "sorocaba": _70, "srv": _70, "taxi": _70, "tc": _70, "tec": _70, "teo": _70, "the": _70, "tmp": _70, "trd": _70, "tur": _70, "tv": _70, "udi": _70, "vet": _70, "vix": _70, "vlog": _70, "wiki": _70, "xyz": _70, "zlg": _70 }], "bs": _72, "bt": _72, "bv": _70, + "bw": [1, { "ac": _70, "co": _70, "gov": _70, "net": _70, "org": _70 }], "by": [1, { "gov": _70, "mil": _70, "com": _70, "of": _70 }], "bz": _75, "ca": [1, { "ab": _70, "bc": _70, "mb": _70, "nb": _70, "nf": _70, "nl": _70, "ns": _70, "nt": _70, "nu": _70, "on": _70, "pe": _70, "qc": _70, "sk": _70, "yk": _70, "gc": _70 }], "cat": _70, "cc": _70, "cd": _73, "cf": _70, "cg": _70, "ch": _70, "ci": [1, { "ac": _70, "xn--aroport-bya": _70, "aéroport": _70, "asso": _70, "co": _70, "com": _70, "ed": _70, "edu": _70, "go": _70, "gouv": _70, "int": _70, "net": _70, "or": _70, "org": _70 }], "ck": _74, "cl": [1, { "co": _70, "gob": _70, "gov": _70, "mil": _70 }], "cm": [1, { "co": _70, "com": _70, "gov": _70, "net": _70 }], "cn": [1, { "ac": _70, "com": _70, "edu": _70, "gov": _70, "mil": _70, "net": _70, "org": _70, "xn--55qx5d": _70, "公司": _70, "xn--od0alg": _70, "網絡": _70, "xn--io0a7i": _70, "网络": _70, "ah": _70, "bj": _70, "cq": _70, "fj": _70, "gd": _70, "gs": _70, "gx": _70, + "gz": _70, "ha": _70, "hb": _70, "he": _70, "hi": _70, "hk": _70, "hl": _70, "hn": _70, "jl": _70, "js": _70, "jx": _70, "ln": _70, "mo": _70, "nm": _70, "nx": _70, "qh": _70, "sc": _70, "sd": _70, "sh": _70, "sn": _70, "sx": _70, "tj": _70, "tw": _70, "xj": _70, "xz": _70, "yn": _70, "zj": _70 }], "co": [1, { "com": _70, "edu": _70, "gov": _70, "mil": _70, "net": _70, "nom": _70, "org": _70 }], "com": _70, "coop": _70, "cr": [1, { "ac": _70, "co": _70, "ed": _70, "fi": _70, "go": _70, "or": _70, "sa": _70 }], "cu": [1, { "com": _70, "edu": _70, "gob": _70, "inf": _70, "nat": _70, "net": _70, "org": _70 }], "cv": [1, { "com": _70, "edu": _70, "id": _70, "int": _70, "net": _70, "nome": _70, "org": _70, "publ": _70 }], "cw": _76, "cx": _73, "cy": [1, { "ac": _70, "biz": _70, "com": _70, "ekloges": _70, "gov": _70, "ltd": _70, "mil": _70, "net": _70, "org": _70, "press": _70, "pro": _70, "tm": _70 }], "cz": _73, "de": _70, "dj": _70, "dk": _70, "dm": _75, "do": [1, { "art": _70, "co\ +m": _70, "edu": _70, "gob": _70, "gov": _70, "mil": _70, "net": _70, "org": _70, "sld": _70, "web": _70 }], "dz": [1, { "art": _70, "asso": _70, "com": _70, "edu": _70, "gov": _70, "net": _70, "org": _70, "pol": _70, "soc": _70, "tm": _70 }], "ec": [1, { "abg": _70, "adm": _70, "agron": _70, "arqt": _70, "art": _70, "bar": _70, "chef": _70, "com": _70, "cont": _70, "cpa": _70, "cue": _70, "dent": _70, "dgn": _70, "disco": _70, "doc": _70, "edu": _70, "eng": _70, "esm": _70, "fin": _70, "fot": _70, "gal": _70, "gob": _70, "gov": _70, "gye": _70, "ibr": _70, "info": _70, "k12": _70, "lat": _70, "loj": _70, "med": _70, "mil": _70, "mktg": _70, "mon": _70, "net": _70, "ntr": _70, "odont": _70, "org": _70, "pro": _70, "prof": _70, "psic": _70, "psiq": _70, "pub": _70, "rio": _70, "rrpp": _70, "sal": _70, "tech": _70, "tul": _70, "tur": _70, "uio": _70, "vet": _70, "xxx": _70 }], "edu": _70, "ee": [1, { "aip": _70, "com": _70, "edu": _70, "fie": _70, "gov": _70, "lib": _70, "med": _70, "org": _70, + "pri": _70, "riik": _70 }], "eg": [1, { "ac": _70, "com": _70, "edu": _70, "eun": _70, "gov": _70, "info": _70, "me": _70, "mil": _70, "name": _70, "net": _70, "org": _70, "sci": _70, "sport": _70, "tv": _70 }], "er": _74, "es": [1, { "com": _70, "edu": _70, "gob": _70, "nom": _70, "org": _70 }], "et": [1, { "biz": _70, "com": _70, "edu": _70, "gov": _70, "info": _70, "name": _70, "net": _70, "org": _70 }], "eu": _70, "fi": [1, { "aland": _70 }], "fj": [1, { "ac": _70, "biz": _70, "com": _70, "gov": _70, "info": _70, "mil": _70, "name": _70, "net": _70, "org": _70, "pro": _70 }], "fk": _74, "fm": _76, "fo": _70, "fr": [1, { "asso": _70, "com": _70, "gouv": _70, "nom": _70, "prd": _70, "tm": _70, "avoues": _70, "cci": _70, "greta": _70, "huissier-justice": _70 }], "ga": _70, "gb": _70, "gd": [1, { "edu": _70, "gov": _70 }], "ge": [1, { "com": _70, "edu": _70, "gov": _70, "net": _70, "org": _70, "pvt": _70, "school": _70 }], "gf": _70, "gg": _77, "gh": [1, { "biz": _70, "com": _70, + "edu": _70, "gov": _70, "mil": _70, "net": _70, "org": _70 }], "gi": [1, { "com": _70, "edu": _70, "gov": _70, "ltd": _70, "mod": _70, "org": _70 }], "gl": [1, { "co": _70, "com": _70, "edu": _70, "net": _70, "org": _70 }], "gm": _70, "gn": [1, { "ac": _70, "com": _70, "edu": _70, "gov": _70, "net": _70, "org": _70 }], "gov": _70, "gp": [1, { "asso": _70, "com": _70, "edu": _70, "mobi": _70, "net": _70, "org": _70 }], "gq": _70, "gr": _72, "gs": _70, "gt": [1, { "com": _70, "edu": _70, "gob": _70, "ind": _70, "mil": _70, "net": _70, "org": _70 }], "gu": [1, { "com": _70, "edu": _70, "gov": _70, "guam": _70, "info": _70, "net": _70, "org": _70, "web": _70 }], "gw": _70, "gy": _75, "hk": [1, { "com": _70, "edu": _70, "gov": _70, "idv": _70, "net": _70, "org": _70, "xn--ciqpn": _70, "个人": _70, "xn--gmqw5a": _70, "個人": _70, "xn--55qx5d": _70, "公司": _70, "xn--mxtq1m": _70, "政府": _70, "xn--lcvr32d": _70, "敎育": _70, "xn--wcvs22d": _70, "教育": _70, "xn--gmq050i": _70, + "箇人": _70, "xn--uc0atv": _70, "組織": _70, "xn--uc0ay4a": _70, "組织": _70, "xn--od0alg": _70, "網絡": _70, "xn--zf0avx": _70, "網络": _70, "xn--mk0axi": _70, "组織": _70, "xn--tn0ag": _70, "组织": _70, "xn--od0aq3b": _70, "网絡": _70, "xn--io0a7i": _70, "网络": _70 }], "hm": _70, "hn": [1, { "com": _70, "edu": _70, "gob": _70, "mil": _70, "net": _70, "org": _70 }], "hr": [1, { "com": _70, "from": _70, "iz": _70, "name": _70 }], "ht": [1, { "adult": _70, "art": _70, "asso": _70, "com": _70, "coop": _70, "edu": _70, "firm": _70, "gouv": _70, "info": _70, "med": _70, "net": _70, "org": _70, "perso": _70, "pol": _70, "pro": _70, "rel": _70, "shop": _70 }], "hu": [1, { "2000": _70, "agrar": _70, "bolt": _70, "casino": _70, "city": _70, "co": _70, "erotica": _70, "erotika": _70, "film": _70, "forum": _70, "games": _70, "hotel": _70, "info": _70, "ingatlan": _70, "jogasz": _70, "konyvelo": _70, "lakas": _70, "media": _70, "news": _70, "org": _70, "priv": _70, "rekla\ +m": _70, "sex": _70, "shop": _70, "sport": _70, "suli": _70, "szex": _70, "tm": _70, "tozsde": _70, "utazas": _70, "video": _70 }], "id": [1, { "ac": _70, "biz": _70, "co": _70, "desa": _70, "go": _70, "kop": _70, "mil": _70, "my": _70, "net": _70, "or": _70, "ponpes": _70, "sch": _70, "web": _70 }], "ie": _73, "il": [1, { "ac": _70, "co": _70, "gov": _70, "idf": _70, "k12": _70, "muni": _70, "net": _70, "org": _70 }], "xn--4dbrk0ce": [1, { "xn--4dbgdty6c": _70, "xn--5dbhl8d": _70, "xn--8dbq2a": _70, "xn--hebda8b": _70 }], "ישראל": [1, { "אקדמיה": _70, "ישוב": _70, "צהל": _70, "ממשל": _70 }], "im": [1, { "ac": _70, "co": [1, { "ltd": _70, "plc": _70 }], "com": _70, "net": _70, "org": _70, "tt": _70, "tv": _70 }], "in": [1, { "5g": _70, "6g": _70, "ac": _70, "ai": _70, "am": _70, "bihar": _70, "biz": _70, "business": _70, "ca": _70, "cn": _70, "co": _70, "com": _70, "coop": _70, "cs": _70, "delhi": _70, "dr": _70, "edu": _70, "er": _70, "firm": _70, "gen": _70, "go\ +v": _70, "gujarat": _70, "ind": _70, "info": _70, "int": _70, "internet": _70, "io": _70, "me": _70, "mil": _70, "net": _70, "nic": _70, "org": _70, "pg": _70, "post": _70, "pro": _70, "res": _70, "travel": _70, "tv": _70, "uk": _70, "up": _70, "us": _70 }], "info": _70, "int": [1, { "eu": _70 }], "io": _78, "iq": _71, "ir": [1, { "ac": _70, "co": _70, "gov": _70, "id": _70, "net": _70, "org": _70, "sch": _70, "xn--mgba3a4f16a": _70, "ایران": _70, "xn--mgba3a4fra": _70, "ايران": _70 }], "is": _70, "it": [1, { "edu": _70, "gov": _70, "abr": _70, "abruzzo": _70, "aosta-valley": _70, "aostavalley": _70, "bas": _70, "basilicata": _70, "cal": _70, "calabria": _70, "cam": _70, "campania": _70, "emilia-romagna": _70, "emiliaromagna": _70, "emr": _70, "friuli-v-giulia": _70, "friuli-ve-giulia": _70, "friuli-vegiulia": _70, "friuli-venezia-giulia": _70, "friuli-veneziagiulia": _70, "friuli-vgiulia": _70, "friuliv-giulia": _70, "friulive-giulia": _70, "friulivegiulia": _70, "friulivene\ +zia-giulia": _70, "friuliveneziagiulia": _70, "friulivgiulia": _70, "fvg": _70, "laz": _70, "lazio": _70, "lig": _70, "liguria": _70, "lom": _70, "lombardia": _70, "lombardy": _70, "lucania": _70, "mar": _70, "marche": _70, "mol": _70, "molise": _70, "piedmont": _70, "piemonte": _70, "pmn": _70, "pug": _70, "puglia": _70, "sar": _70, "sardegna": _70, "sardinia": _70, "sic": _70, "sicilia": _70, "sicily": _70, "taa": _70, "tos": _70, "toscana": _70, "trentin-sud-tirol": _70, "xn--trentin-sd-tirol-rzb": _70, "trentin-süd-tirol": _70, "trentin-sudtirol": _70, "xn--trentin-sdtirol-7vb": _70, "trentin-südtirol": _70, "trentin-sued-tirol": _70, "trentin-suedtirol": _70, "trentino": _70, "trentino-a-adige": _70, "trentino-aadige": _70, "trentino-alto-adige": _70, "trentino-altoadige": _70, "trentino-s-tirol": _70, "trentino-stirol": _70, "trentino-sud-tirol": _70, "xn--trentino-sd-tirol-c3b": _70, "trentino-süd-tirol": _70, "trentino-sudtirol": _70, "xn--trentino-sdtirol-szb": _70, "trenti\ +no-südtirol": _70, "trentino-sued-tirol": _70, "trentino-suedtirol": _70, "trentinoa-adige": _70, "trentinoaadige": _70, "trentinoalto-adige": _70, "trentinoaltoadige": _70, "trentinos-tirol": _70, "trentinostirol": _70, "trentinosud-tirol": _70, "xn--trentinosd-tirol-rzb": _70, "trentinosüd-tirol": _70, "trentinosudtirol": _70, "xn--trentinosdtirol-7vb": _70, "trentinosüdtirol": _70, "trentinosued-tirol": _70, "trentinosuedtirol": _70, "trentinsud-tirol": _70, "xn--trentinsd-tirol-6vb": _70, "trentinsüd-tirol": _70, "trentinsudtirol": _70, "xn--trentinsdtirol-nsb": _70, "trentinsüdtirol": _70, "trentinsued-tirol": _70, "trentinsuedtirol": _70, "tuscany": _70, "umb": _70, "umbria": _70, "val-d-aosta": _70, "val-daosta": _70, "vald-aosta": _70, "valdaosta": _70, "valle-aosta": _70, "valle-d-aosta": _70, "valle-daosta": _70, "valleaosta": _70, "valled-aosta": _70, "valledaosta": _70, "vallee-aoste": _70, "xn--valle-aoste-ebb": _70, "vallée-aoste": _70, "vallee-d-aoste": _70, "xn--v\ +alle-d-aoste-ehb": _70, "vallée-d-aoste": _70, "valleeaoste": _70, "xn--valleaoste-e7a": _70, "valléeaoste": _70, "valleedaoste": _70, "xn--valledaoste-ebb": _70, "valléedaoste": _70, "vao": _70, "vda": _70, "ven": _70, "veneto": _70, "ag": _70, "agrigento": _70, "al": _70, "alessandria": _70, "alto-adige": _70, "altoadige": _70, "an": _70, "ancona": _70, "andria-barletta-trani": _70, "andria-trani-barletta": _70, "andriabarlettatrani": _70, "andriatranibarletta": _70, "ao": _70, "aosta": _70, "aoste": _70, "ap": _70, "aq": _70, "aquila": _70, "ar": _70, "arezzo": _70, "ascoli-piceno": _70, "ascolipiceno": _70, "asti": _70, "at": _70, "av": _70, "avellino": _70, "ba": _70, "balsan": _70, "balsan-sudtirol": _70, "xn--balsan-sdtirol-nsb": _70, "balsan-südtirol": _70, "balsan-suedtirol": _70, "bari": _70, "barletta-trani-andria": _70, "barlettatraniandria": _70, "belluno": _70, "benevento": _70, "bergamo": _70, "bg": _70, "bi": _70, "biella": _70, "bl": _70, "bn": _70, "bo": _70, "bol\ +ogna": _70, "bolzano": _70, "bolzano-altoadige": _70, "bozen": _70, "bozen-sudtirol": _70, "xn--bozen-sdtirol-2ob": _70, "bozen-südtirol": _70, "bozen-suedtirol": _70, "br": _70, "brescia": _70, "brindisi": _70, "bs": _70, "bt": _70, "bulsan": _70, "bulsan-sudtirol": _70, "xn--bulsan-sdtirol-nsb": _70, "bulsan-südtirol": _70, "bulsan-suedtirol": _70, "bz": _70, "ca": _70, "cagliari": _70, "caltanissetta": _70, "campidano-medio": _70, "campidanomedio": _70, "campobasso": _70, "carbonia-iglesias": _70, "carboniaiglesias": _70, "carrara-massa": _70, "carraramassa": _70, "caserta": _70, "catania": _70, "catanzaro": _70, "cb": _70, "ce": _70, "cesena-forli": _70, "xn--cesena-forl-mcb": _70, "cesena-forlì": _70, "cesenaforli": _70, "xn--cesenaforl-i8a": _70, "cesenaforlì": _70, "ch": _70, "chieti": _70, "ci": _70, "cl": _70, "cn": _70, "co": _70, "como": _70, "cosenza": _70, "cr": _70, "cremona": _70, "crotone": _70, "cs": _70, "ct": _70, "cuneo": _70, "cz": _70, "dell-ogliastra": _70, "\ +dellogliastra": _70, "en": _70, "enna": _70, "fc": _70, "fe": _70, "fermo": _70, "ferrara": _70, "fg": _70, "fi": _70, "firenze": _70, "florence": _70, "fm": _70, "foggia": _70, "forli-cesena": _70, "xn--forl-cesena-fcb": _70, "forlì-cesena": _70, "forlicesena": _70, "xn--forlcesena-c8a": _70, "forlìcesena": _70, "fr": _70, "frosinone": _70, "ge": _70, "genoa": _70, "genova": _70, "go": _70, "gorizia": _70, "gr": _70, "grosseto": _70, "iglesias-carbonia": _70, "iglesiascarbonia": _70, "im": _70, "imperia": _70, "is": _70, "isernia": _70, "kr": _70, "la-spezia": _70, "laquila": _70, "laspezia": _70, "latina": _70, "lc": _70, "le": _70, "lecce": _70, "lecco": _70, "li": _70, "livorno": _70, "lo": _70, "lodi": _70, "lt": _70, "lu": _70, "lucca": _70, "macerata": _70, "mantova": _70, "massa-carrara": _70, "massacarrara": _70, "matera": _70, "mb": _70, "mc": _70, "me": _70, "medio-campidano": _70, "mediocampidano": _70, "messina": _70, "mi": _70, "milan": _70, "milano": _70, "mn": _70, "m\ +o": _70, "modena": _70, "monza": _70, "monza-brianza": _70, "monza-e-della-brianza": _70, "monzabrianza": _70, "monzaebrianza": _70, "monzaedellabrianza": _70, "ms": _70, "mt": _70, "na": _70, "naples": _70, "napoli": _70, "no": _70, "novara": _70, "nu": _70, "nuoro": _70, "og": _70, "ogliastra": _70, "olbia-tempio": _70, "olbiatempio": _70, "or": _70, "oristano": _70, "ot": _70, "pa": _70, "padova": _70, "padua": _70, "palermo": _70, "parma": _70, "pavia": _70, "pc": _70, "pd": _70, "pe": _70, "perugia": _70, "pesaro-urbino": _70, "pesarourbino": _70, "pescara": _70, "pg": _70, "pi": _70, "piacenza": _70, "pisa": _70, "pistoia": _70, "pn": _70, "po": _70, "pordenone": _70, "potenza": _70, "pr": _70, "prato": _70, "pt": _70, "pu": _70, "pv": _70, "pz": _70, "ra": _70, "ragusa": _70, "ravenna": _70, "rc": _70, "re": _70, "reggio-calabria": _70, "reggio-emilia": _70, "reggiocalabria": _70, "reggioemilia": _70, "rg": _70, "ri": _70, "rieti": _70, "rimini": _70, "rm": _70, "rn": _70, "ro": _70, + "roma": _70, "rome": _70, "rovigo": _70, "sa": _70, "salerno": _70, "sassari": _70, "savona": _70, "si": _70, "siena": _70, "siracusa": _70, "so": _70, "sondrio": _70, "sp": _70, "sr": _70, "ss": _70, "xn--sdtirol-n2a": _70, "südtirol": _70, "suedtirol": _70, "sv": _70, "ta": _70, "taranto": _70, "te": _70, "tempio-olbia": _70, "tempioolbia": _70, "teramo": _70, "terni": _70, "tn": _70, "to": _70, "torino": _70, "tp": _70, "tr": _70, "trani-andria-barletta": _70, "trani-barletta-andria": _70, "traniandriabarletta": _70, "tranibarlettaandria": _70, "trapani": _70, "trento": _70, "treviso": _70, "trieste": _70, "ts": _70, "turin": _70, "tv": _70, "ud": _70, "udine": _70, "urbino-pesaro": _70, "urbinopesaro": _70, "va": _70, "varese": _70, "vb": _70, "vc": _70, "ve": _70, "venezia": _70, "venice": _70, "verbania": _70, "vercelli": _70, "verona": _70, "vi": _70, "vibo-valentia": _70, "vibovalentia": _70, "vicenza": _70, "viterbo": _70, "vr": _70, "vs": _70, "vt": _70, "vv": _70 }], "\ +je": _77, "jm": _74, "jo": [1, { "agri": _70, "ai": _70, "com": _70, "edu": _70, "eng": _70, "fm": _70, "gov": _70, "mil": _70, "net": _70, "org": _70, "per": _70, "phd": _70, "sch": _70, "tv": _70 }], "jobs": _70, "jp": [1, { "ac": _70, "ad": _70, "co": _70, "ed": _70, "go": _70, "gr": _70, "lg": _70, "ne": _70, "or": _70, "aichi": [1, { "aisai": _70, "ama": _70, "anjo": _70, "asuke": _70, "chiryu": _70, "chita": _70, "fuso": _70, "gamagori": _70, "handa": _70, "hazu": _70, "hekinan": _70, "higashiura": _70, "ichinomiya": _70, "inazawa": _70, "inuyama": _70, "isshiki": _70, "iwakura": _70, "kanie": _70, "kariya": _70, "kasugai": _70, "kira": _70, "kiyosu": _70, "komaki": _70, "konan": _70, "kota": _70, "mihama": _70, "miyoshi": _70, "nishio": _70, "nisshin": _70, "obu": _70, "oguchi": _70, "oharu": _70, "okazaki": _70, "owariasahi": _70, "seto": _70, "shikatsu": _70, "shinshiro": _70, "shitara": _70, "tahara": _70, "takahama": _70, "tobishima": _70, "toei": _70, "togo": _70, "tokai": _70, + "tokoname": _70, "toyoake": _70, "toyohashi": _70, "toyokawa": _70, "toyone": _70, "toyota": _70, "tsushima": _70, "yatomi": _70 }], "akita": [1, { "akita": _70, "daisen": _70, "fujisato": _70, "gojome": _70, "hachirogata": _70, "happou": _70, "higashinaruse": _70, "honjo": _70, "honjyo": _70, "ikawa": _70, "kamikoani": _70, "kamioka": _70, "katagami": _70, "kazuno": _70, "kitaakita": _70, "kosaka": _70, "kyowa": _70, "misato": _70, "mitane": _70, "moriyoshi": _70, "nikaho": _70, "noshiro": _70, "odate": _70, "oga": _70, "ogata": _70, "semboku": _70, "yokote": _70, "yurihonjo": _70 }], "aomori": [1, { "aomori": _70, "gonohe": _70, "hachinohe": _70, "hashikami": _70, "hiranai": _70, "hirosaki": _70, "itayanagi": _70, "kuroishi": _70, "misawa": _70, "mutsu": _70, "nakadomari": _70, "noheji": _70, "oirase": _70, "owani": _70, "rokunohe": _70, "sannohe": _70, "shichinohe": _70, "shingo": _70, "takko": _70, "towada": _70, "tsugaru": _70, "tsuruta": _70 }], "chiba": [1, { "abiko": _70, + "asahi": _70, "chonan": _70, "chosei": _70, "choshi": _70, "chuo": _70, "funabashi": _70, "futtsu": _70, "hanamigawa": _70, "ichihara": _70, "ichikawa": _70, "ichinomiya": _70, "inzai": _70, "isumi": _70, "kamagaya": _70, "kamogawa": _70, "kashiwa": _70, "katori": _70, "katsuura": _70, "kimitsu": _70, "kisarazu": _70, "kozaki": _70, "kujukuri": _70, "kyonan": _70, "matsudo": _70, "midori": _70, "mihama": _70, "minamiboso": _70, "mobara": _70, "mutsuzawa": _70, "nagara": _70, "nagareyama": _70, "narashino": _70, "narita": _70, "noda": _70, "oamishirasato": _70, "omigawa": _70, "onjuku": _70, "otaki": _70, "sakae": _70, "sakura": _70, "shimofusa": _70, "shirako": _70, "shiroi": _70, "shisui": _70, "sodegaura": _70, "sosa": _70, "tako": _70, "tateyama": _70, "togane": _70, "tohnosho": _70, "tomisato": _70, "urayasu": _70, "yachimata": _70, "yachiyo": _70, "yokaichiba": _70, "yokoshibahikari": _70, "yotsukaido": _70 }], "ehime": [1, { "ainan": _70, "honai": _70, "ikata": _70, "imabar\ +i": _70, "iyo": _70, "kamijima": _70, "kihoku": _70, "kumakogen": _70, "masaki": _70, "matsuno": _70, "matsuyama": _70, "namikata": _70, "niihama": _70, "ozu": _70, "saijo": _70, "seiyo": _70, "shikokuchuo": _70, "tobe": _70, "toon": _70, "uchiko": _70, "uwajima": _70, "yawatahama": _70 }], "fukui": [1, { "echizen": _70, "eiheiji": _70, "fukui": _70, "ikeda": _70, "katsuyama": _70, "mihama": _70, "minamiechizen": _70, "obama": _70, "ohi": _70, "ono": _70, "sabae": _70, "sakai": _70, "takahama": _70, "tsuruga": _70, "wakasa": _70 }], "fukuoka": [1, { "ashiya": _70, "buzen": _70, "chikugo": _70, "chikuho": _70, "chikujo": _70, "chikushino": _70, "chikuzen": _70, "chuo": _70, "dazaifu": _70, "fukuchi": _70, "hakata": _70, "higashi": _70, "hirokawa": _70, "hisayama": _70, "iizuka": _70, "inatsuki": _70, "kaho": _70, "kasuga": _70, "kasuya": _70, "kawara": _70, "keisen": _70, "koga": _70, "kurate": _70, "kurogi": _70, "kurume": _70, "minami": _70, "miyako": _70, "miyama": _70, "miyawaka": _70, + "mizumaki": _70, "munakata": _70, "nakagawa": _70, "nakama": _70, "nishi": _70, "nogata": _70, "ogori": _70, "okagaki": _70, "okawa": _70, "oki": _70, "omuta": _70, "onga": _70, "onojo": _70, "oto": _70, "saigawa": _70, "sasaguri": _70, "shingu": _70, "shinyoshitomi": _70, "shonai": _70, "soeda": _70, "sue": _70, "tachiarai": _70, "tagawa": _70, "takata": _70, "toho": _70, "toyotsu": _70, "tsuiki": _70, "ukiha": _70, "umi": _70, "usui": _70, "yamada": _70, "yame": _70, "yanagawa": _70, "yukuhashi": _70 }], "fukushima": [1, { "aizubange": _70, "aizumisato": _70, "aizuwakamatsu": _70, "asakawa": _70, "bandai": _70, "date": _70, "fukushima": _70, "furudono": _70, "futaba": _70, "hanawa": _70, "higashi": _70, "hirata": _70, "hirono": _70, "iitate": _70, "inawashiro": _70, "ishikawa": _70, "iwaki": _70, "izumizaki": _70, "kagamiishi": _70, "kaneyama": _70, "kawamata": _70, "kitakata": _70, "kitashiobara": _70, "koori": _70, "koriyama": _70, "kunimi": _70, "miharu": _70, "mishima": _70, + "namie": _70, "nango": _70, "nishiaizu": _70, "nishigo": _70, "okuma": _70, "omotego": _70, "ono": _70, "otama": _70, "samegawa": _70, "shimogo": _70, "shirakawa": _70, "showa": _70, "soma": _70, "sukagawa": _70, "taishin": _70, "tamakawa": _70, "tanagura": _70, "tenei": _70, "yabuki": _70, "yamato": _70, "yamatsuri": _70, "yanaizu": _70, "yugawa": _70 }], "gifu": [1, { "anpachi": _70, "ena": _70, "gifu": _70, "ginan": _70, "godo": _70, "gujo": _70, "hashima": _70, "hichiso": _70, "hida": _70, "higashishirakawa": _70, "ibigawa": _70, "ikeda": _70, "kakamigahara": _70, "kani": _70, "kasahara": _70, "kasamatsu": _70, "kawaue": _70, "kitagata": _70, "mino": _70, "minokamo": _70, "mitake": _70, "mizunami": _70, "motosu": _70, "nakatsugawa": _70, "ogaki": _70, "sakahogi": _70, "seki": _70, "sekigahara": _70, "shirakawa": _70, "tajimi": _70, "takayama": _70, "tarui": _70, "toki": _70, "tomika": _70, "wanouchi": _70, "yamagata": _70, "yaotsu": _70, "yoro": _70 }], "gunma": [1, { "annaka": _70, + "chiyoda": _70, "fujioka": _70, "higashiagatsuma": _70, "isesaki": _70, "itakura": _70, "kanna": _70, "kanra": _70, "katashina": _70, "kawaba": _70, "kiryu": _70, "kusatsu": _70, "maebashi": _70, "meiwa": _70, "midori": _70, "minakami": _70, "naganohara": _70, "nakanojo": _70, "nanmoku": _70, "numata": _70, "oizumi": _70, "ora": _70, "ota": _70, "shibukawa": _70, "shimonita": _70, "shinto": _70, "showa": _70, "takasaki": _70, "takayama": _70, "tamamura": _70, "tatebayashi": _70, "tomioka": _70, "tsukiyono": _70, "tsumagoi": _70, "ueno": _70, "yoshioka": _70 }], "hiroshima": [1, { "asaminami": _70, "daiwa": _70, "etajima": _70, "fuchu": _70, "fukuyama": _70, "hatsukaichi": _70, "higashihiroshima": _70, "hongo": _70, "jinsekikogen": _70, "kaita": _70, "kui": _70, "kumano": _70, "kure": _70, "mihara": _70, "miyoshi": _70, "naka": _70, "onomichi": _70, "osakikamijima": _70, "otake": _70, "saka": _70, "sera": _70, "seranishi": _70, "shinichi": _70, "shobara": _70, "takehara": _70 }], "\ +hokkaido": [1, { "abashiri": _70, "abira": _70, "aibetsu": _70, "akabira": _70, "akkeshi": _70, "asahikawa": _70, "ashibetsu": _70, "ashoro": _70, "assabu": _70, "atsuma": _70, "bibai": _70, "biei": _70, "bifuka": _70, "bihoro": _70, "biratori": _70, "chippubetsu": _70, "chitose": _70, "date": _70, "ebetsu": _70, "embetsu": _70, "eniwa": _70, "erimo": _70, "esan": _70, "esashi": _70, "fukagawa": _70, "fukushima": _70, "furano": _70, "furubira": _70, "haboro": _70, "hakodate": _70, "hamatonbetsu": _70, "hidaka": _70, "higashikagura": _70, "higashikawa": _70, "hiroo": _70, "hokuryu": _70, "hokuto": _70, "honbetsu": _70, "horokanai": _70, "horonobe": _70, "ikeda": _70, "imakane": _70, "ishikari": _70, "iwamizawa": _70, "iwanai": _70, "kamifurano": _70, "kamikawa": _70, "kamishihoro": _70, "kamisunagawa": _70, "kamoenai": _70, "kayabe": _70, "kembuchi": _70, "kikonai": _70, "kimobetsu": _70, "kitahiroshima": _70, "kitami": _70, "kiyosato": _70, "koshimizu": _70, "kunneppu": _70, "kuriyama": _70, + "kuromatsunai": _70, "kushiro": _70, "kutchan": _70, "kyowa": _70, "mashike": _70, "matsumae": _70, "mikasa": _70, "minamifurano": _70, "mombetsu": _70, "moseushi": _70, "mukawa": _70, "muroran": _70, "naie": _70, "nakagawa": _70, "nakasatsunai": _70, "nakatombetsu": _70, "nanae": _70, "nanporo": _70, "nayoro": _70, "nemuro": _70, "niikappu": _70, "niki": _70, "nishiokoppe": _70, "noboribetsu": _70, "numata": _70, "obihiro": _70, "obira": _70, "oketo": _70, "okoppe": _70, "otaru": _70, "otobe": _70, "otofuke": _70, "otoineppu": _70, "oumu": _70, "ozora": _70, "pippu": _70, "rankoshi": _70, "rebun": _70, "rikubetsu": _70, "rishiri": _70, "rishirifuji": _70, "saroma": _70, "sarufutsu": _70, "shakotan": _70, "shari": _70, "shibecha": _70, "shibetsu": _70, "shikabe": _70, "shikaoi": _70, "shimamaki": _70, "shimizu": _70, "shimokawa": _70, "shinshinotsu": _70, "shintoku": _70, "shiranuka": _70, "shiraoi": _70, "shiriuchi": _70, "sobetsu": _70, "sunagawa": _70, "taiki": _70, "takasu": _70, + "takikawa": _70, "takinoue": _70, "teshikaga": _70, "tobetsu": _70, "tohma": _70, "tomakomai": _70, "tomari": _70, "toya": _70, "toyako": _70, "toyotomi": _70, "toyoura": _70, "tsubetsu": _70, "tsukigata": _70, "urakawa": _70, "urausu": _70, "uryu": _70, "utashinai": _70, "wakkanai": _70, "wassamu": _70, "yakumo": _70, "yoichi": _70 }], "hyogo": [1, { "aioi": _70, "akashi": _70, "ako": _70, "amagasaki": _70, "aogaki": _70, "asago": _70, "ashiya": _70, "awaji": _70, "fukusaki": _70, "goshiki": _70, "harima": _70, "himeji": _70, "ichikawa": _70, "inagawa": _70, "itami": _70, "kakogawa": _70, "kamigori": _70, "kamikawa": _70, "kasai": _70, "kasuga": _70, "kawanishi": _70, "miki": _70, "minamiawaji": _70, "nishinomiya": _70, "nishiwaki": _70, "ono": _70, "sanda": _70, "sannan": _70, "sasayama": _70, "sayo": _70, "shingu": _70, "shinonsen": _70, "shiso": _70, "sumoto": _70, "taishi": _70, "taka": _70, "takarazuka": _70, "takasago": _70, "takino": _70, "tamba": _70, "tatsuno": _70, "to\ +yooka": _70, "yabu": _70, "yashiro": _70, "yoka": _70, "yokawa": _70 }], "ibaraki": [1, { "ami": _70, "asahi": _70, "bando": _70, "chikusei": _70, "daigo": _70, "fujishiro": _70, "hitachi": _70, "hitachinaka": _70, "hitachiomiya": _70, "hitachiota": _70, "ibaraki": _70, "ina": _70, "inashiki": _70, "itako": _70, "iwama": _70, "joso": _70, "kamisu": _70, "kasama": _70, "kashima": _70, "kasumigaura": _70, "koga": _70, "miho": _70, "mito": _70, "moriya": _70, "naka": _70, "namegata": _70, "oarai": _70, "ogawa": _70, "omitama": _70, "ryugasaki": _70, "sakai": _70, "sakuragawa": _70, "shimodate": _70, "shimotsuma": _70, "shirosato": _70, "sowa": _70, "suifu": _70, "takahagi": _70, "tamatsukuri": _70, "tokai": _70, "tomobe": _70, "tone": _70, "toride": _70, "tsuchiura": _70, "tsukuba": _70, "uchihara": _70, "ushiku": _70, "yachiyo": _70, "yamagata": _70, "yawara": _70, "yuki": _70 }], "ishikawa": [1, { "anamizu": _70, "hakui": _70, "hakusan": _70, "kaga": _70, "kahoku": _70, "kanazawa": _70, + "kawakita": _70, "komatsu": _70, "nakanoto": _70, "nanao": _70, "nomi": _70, "nonoichi": _70, "noto": _70, "shika": _70, "suzu": _70, "tsubata": _70, "tsurugi": _70, "uchinada": _70, "wajima": _70 }], "iwate": [1, { "fudai": _70, "fujisawa": _70, "hanamaki": _70, "hiraizumi": _70, "hirono": _70, "ichinohe": _70, "ichinoseki": _70, "iwaizumi": _70, "iwate": _70, "joboji": _70, "kamaishi": _70, "kanegasaki": _70, "karumai": _70, "kawai": _70, "kitakami": _70, "kuji": _70, "kunohe": _70, "kuzumaki": _70, "miyako": _70, "mizusawa": _70, "morioka": _70, "ninohe": _70, "noda": _70, "ofunato": _70, "oshu": _70, "otsuchi": _70, "rikuzentakata": _70, "shiwa": _70, "shizukuishi": _70, "sumita": _70, "tanohata": _70, "tono": _70, "yahaba": _70, "yamada": _70 }], "kagawa": [1, { "ayagawa": _70, "higashikagawa": _70, "kanonji": _70, "kotohira": _70, "manno": _70, "marugame": _70, "mitoyo": _70, "naoshima": _70, "sanuki": _70, "tadotsu": _70, "takamatsu": _70, "tonosho": _70, "uchinomi": _70, "\ +utazu": _70, "zentsuji": _70 }], "kagoshima": [1, { "akune": _70, "amami": _70, "hioki": _70, "isa": _70, "isen": _70, "izumi": _70, "kagoshima": _70, "kanoya": _70, "kawanabe": _70, "kinko": _70, "kouyama": _70, "makurazaki": _70, "matsumoto": _70, "minamitane": _70, "nakatane": _70, "nishinoomote": _70, "satsumasendai": _70, "soo": _70, "tarumizu": _70, "yusui": _70 }], "kanagawa": [1, { "aikawa": _70, "atsugi": _70, "ayase": _70, "chigasaki": _70, "ebina": _70, "fujisawa": _70, "hadano": _70, "hakone": _70, "hiratsuka": _70, "isehara": _70, "kaisei": _70, "kamakura": _70, "kiyokawa": _70, "matsuda": _70, "minamiashigara": _70, "miura": _70, "nakai": _70, "ninomiya": _70, "odawara": _70, "oi": _70, "oiso": _70, "sagamihara": _70, "samukawa": _70, "tsukui": _70, "yamakita": _70, "yamato": _70, "yokosuka": _70, "yugawara": _70, "zama": _70, "zushi": _70 }], "kochi": [1, { "aki": _70, "geisei": _70, "hidaka": _70, "higashitsuno": _70, "ino": _70, "kagami": _70, "kami": _70, "kitagawa": _70, + "kochi": _70, "mihara": _70, "motoyama": _70, "muroto": _70, "nahari": _70, "nakamura": _70, "nankoku": _70, "nishitosa": _70, "niyodogawa": _70, "ochi": _70, "okawa": _70, "otoyo": _70, "otsuki": _70, "sakawa": _70, "sukumo": _70, "susaki": _70, "tosa": _70, "tosashimizu": _70, "toyo": _70, "tsuno": _70, "umaji": _70, "yasuda": _70, "yusuhara": _70 }], "kumamoto": [1, { "amakusa": _70, "arao": _70, "aso": _70, "choyo": _70, "gyokuto": _70, "kamiamakusa": _70, "kikuchi": _70, "kumamoto": _70, "mashiki": _70, "mifune": _70, "minamata": _70, "minamioguni": _70, "nagasu": _70, "nishihara": _70, "oguni": _70, "ozu": _70, "sumoto": _70, "takamori": _70, "uki": _70, "uto": _70, "yamaga": _70, "yamato": _70, "yatsushiro": _70 }], "kyoto": [1, { "ayabe": _70, "fukuchiyama": _70, "higashiyama": _70, "ide": _70, "ine": _70, "joyo": _70, "kameoka": _70, "kamo": _70, "kita": _70, "kizu": _70, "kumiyama": _70, "kyotamba": _70, "kyotanabe": _70, "kyotango": _70, "maizuru": _70, "minami": _70, "\ +minamiyamashiro": _70, "miyazu": _70, "muko": _70, "nagaokakyo": _70, "nakagyo": _70, "nantan": _70, "oyamazaki": _70, "sakyo": _70, "seika": _70, "tanabe": _70, "uji": _70, "ujitawara": _70, "wazuka": _70, "yamashina": _70, "yawata": _70 }], "mie": [1, { "asahi": _70, "inabe": _70, "ise": _70, "kameyama": _70, "kawagoe": _70, "kiho": _70, "kisosaki": _70, "kiwa": _70, "komono": _70, "kumano": _70, "kuwana": _70, "matsusaka": _70, "meiwa": _70, "mihama": _70, "minamiise": _70, "misugi": _70, "miyama": _70, "nabari": _70, "shima": _70, "suzuka": _70, "tado": _70, "taiki": _70, "taki": _70, "tamaki": _70, "toba": _70, "tsu": _70, "udono": _70, "ureshino": _70, "watarai": _70, "yokkaichi": _70 }], "miyagi": [1, { "furukawa": _70, "higashimatsushima": _70, "ishinomaki": _70, "iwanuma": _70, "kakuda": _70, "kami": _70, "kawasaki": _70, "marumori": _70, "matsushima": _70, "minamisanriku": _70, "misato": _70, "murata": _70, "natori": _70, "ogawara": _70, "ohira": _70, "onagawa": _70, "osaki": _70, + "rifu": _70, "semine": _70, "shibata": _70, "shichikashuku": _70, "shikama": _70, "shiogama": _70, "shiroishi": _70, "tagajo": _70, "taiwa": _70, "tome": _70, "tomiya": _70, "wakuya": _70, "watari": _70, "yamamoto": _70, "zao": _70 }], "miyazaki": [1, { "aya": _70, "ebino": _70, "gokase": _70, "hyuga": _70, "kadogawa": _70, "kawaminami": _70, "kijo": _70, "kitagawa": _70, "kitakata": _70, "kitaura": _70, "kobayashi": _70, "kunitomi": _70, "kushima": _70, "mimata": _70, "miyakonojo": _70, "miyazaki": _70, "morotsuka": _70, "nichinan": _70, "nishimera": _70, "nobeoka": _70, "saito": _70, "shiiba": _70, "shintomi": _70, "takaharu": _70, "takanabe": _70, "takazaki": _70, "tsuno": _70 }], "nagano": [1, { "achi": _70, "agematsu": _70, "anan": _70, "aoki": _70, "asahi": _70, "azumino": _70, "chikuhoku": _70, "chikuma": _70, "chino": _70, "fujimi": _70, "hakuba": _70, "hara": _70, "hiraya": _70, "iida": _70, "iijima": _70, "iiyama": _70, "iizuna": _70, "ikeda": _70, "ikusaka": _70, "ina": _70, + "karuizawa": _70, "kawakami": _70, "kiso": _70, "kisofukushima": _70, "kitaaiki": _70, "komagane": _70, "komoro": _70, "matsukawa": _70, "matsumoto": _70, "miasa": _70, "minamiaiki": _70, "minamimaki": _70, "minamiminowa": _70, "minowa": _70, "miyada": _70, "miyota": _70, "mochizuki": _70, "nagano": _70, "nagawa": _70, "nagiso": _70, "nakagawa": _70, "nakano": _70, "nozawaonsen": _70, "obuse": _70, "ogawa": _70, "okaya": _70, "omachi": _70, "omi": _70, "ookuwa": _70, "ooshika": _70, "otaki": _70, "otari": _70, "sakae": _70, "sakaki": _70, "saku": _70, "sakuho": _70, "shimosuwa": _70, "shinanomachi": _70, "shiojiri": _70, "suwa": _70, "suzaka": _70, "takagi": _70, "takamori": _70, "takayama": _70, "tateshina": _70, "tatsuno": _70, "togakushi": _70, "togura": _70, "tomi": _70, "ueda": _70, "wada": _70, "yamagata": _70, "yamanouchi": _70, "yasaka": _70, "yasuoka": _70 }], "nagasaki": [1, { "chijiwa": _70, "futsu": _70, "goto": _70, "hasami": _70, "hirado": _70, "iki": _70, "isahaya": _70, + "kawatana": _70, "kuchinotsu": _70, "matsuura": _70, "nagasaki": _70, "obama": _70, "omura": _70, "oseto": _70, "saikai": _70, "sasebo": _70, "seihi": _70, "shimabara": _70, "shinkamigoto": _70, "togitsu": _70, "tsushima": _70, "unzen": _70 }], "nara": [1, { "ando": _70, "gose": _70, "heguri": _70, "higashiyoshino": _70, "ikaruga": _70, "ikoma": _70, "kamikitayama": _70, "kanmaki": _70, "kashiba": _70, "kashihara": _70, "katsuragi": _70, "kawai": _70, "kawakami": _70, "kawanishi": _70, "koryo": _70, "kurotaki": _70, "mitsue": _70, "miyake": _70, "nara": _70, "nosegawa": _70, "oji": _70, "ouda": _70, "oyodo": _70, "sakurai": _70, "sango": _70, "shimoichi": _70, "shimokitayama": _70, "shinjo": _70, "soni": _70, "takatori": _70, "tawaramoto": _70, "tenkawa": _70, "tenri": _70, "uda": _70, "yamatokoriyama": _70, "yamatotakada": _70, "yamazoe": _70, "yoshino": _70 }], "niigata": [1, { "aga": _70, "agano": _70, "gosen": _70, "itoigawa": _70, "izumozaki": _70, "joetsu": _70, "kamo": _70, + "kariwa": _70, "kashiwazaki": _70, "minamiuonuma": _70, "mitsuke": _70, "muika": _70, "murakami": _70, "myoko": _70, "nagaoka": _70, "niigata": _70, "ojiya": _70, "omi": _70, "sado": _70, "sanjo": _70, "seiro": _70, "seirou": _70, "sekikawa": _70, "shibata": _70, "tagami": _70, "tainai": _70, "tochio": _70, "tokamachi": _70, "tsubame": _70, "tsunan": _70, "uonuma": _70, "yahiko": _70, "yoita": _70, "yuzawa": _70 }], "oita": [1, { "beppu": _70, "bungoono": _70, "bungotakada": _70, "hasama": _70, "hiji": _70, "himeshima": _70, "hita": _70, "kamitsue": _70, "kokonoe": _70, "kuju": _70, "kunisaki": _70, "kusu": _70, "oita": _70, "saiki": _70, "taketa": _70, "tsukumi": _70, "usa": _70, "usuki": _70, "yufu": _70 }], "okayama": [1, { "akaiwa": _70, "asakuchi": _70, "bizen": _70, "hayashima": _70, "ibara": _70, "kagamino": _70, "kasaoka": _70, "kibichuo": _70, "kumenan": _70, "kurashiki": _70, "maniwa": _70, "misaki": _70, "nagi": _70, "niimi": _70, "nishiawakura": _70, "okayama": _70, "\ +satosho": _70, "setouchi": _70, "shinjo": _70, "shoo": _70, "soja": _70, "takahashi": _70, "tamano": _70, "tsuyama": _70, "wake": _70, "yakage": _70 }], "okinawa": [1, { "aguni": _70, "ginowan": _70, "ginoza": _70, "gushikami": _70, "haebaru": _70, "higashi": _70, "hirara": _70, "iheya": _70, "ishigaki": _70, "ishikawa": _70, "itoman": _70, "izena": _70, "kadena": _70, "kin": _70, "kitadaito": _70, "kitanakagusuku": _70, "kumejima": _70, "kunigami": _70, "minamidaito": _70, "motobu": _70, "nago": _70, "naha": _70, "nakagusuku": _70, "nakijin": _70, "nanjo": _70, "nishihara": _70, "ogimi": _70, "okinawa": _70, "onna": _70, "shimoji": _70, "taketomi": _70, "tarama": _70, "tokashiki": _70, "tomigusuku": _70, "tonaki": _70, "urasoe": _70, "uruma": _70, "yaese": _70, "yomitan": _70, "yonabaru": _70, "yonaguni": _70, "zamami": _70 }], "osaka": [1, { "abeno": _70, "chihayaakasaka": _70, "chuo": _70, "daito": _70, "fujiidera": _70, "habikino": _70, "hannan": _70, "higashiosaka": _70, "higashis\ +umiyoshi": _70, "higashiyodogawa": _70, "hirakata": _70, "ibaraki": _70, "ikeda": _70, "izumi": _70, "izumiotsu": _70, "izumisano": _70, "kadoma": _70, "kaizuka": _70, "kanan": _70, "kashiwara": _70, "katano": _70, "kawachinagano": _70, "kishiwada": _70, "kita": _70, "kumatori": _70, "matsubara": _70, "minato": _70, "minoh": _70, "misaki": _70, "moriguchi": _70, "neyagawa": _70, "nishi": _70, "nose": _70, "osakasayama": _70, "sakai": _70, "sayama": _70, "sennan": _70, "settsu": _70, "shijonawate": _70, "shimamoto": _70, "suita": _70, "tadaoka": _70, "taishi": _70, "tajiri": _70, "takaishi": _70, "takatsuki": _70, "tondabayashi": _70, "toyonaka": _70, "toyono": _70, "yao": _70 }], "saga": [1, { "ariake": _70, "arita": _70, "fukudomi": _70, "genkai": _70, "hamatama": _70, "hizen": _70, "imari": _70, "kamimine": _70, "kanzaki": _70, "karatsu": _70, "kashima": _70, "kitagata": _70, "kitahata": _70, "kiyama": _70, "kouhoku": _70, "kyuragi": _70, "nishiarita": _70, "ogi": _70, "omachi": _70, + "ouchi": _70, "saga": _70, "shiroishi": _70, "taku": _70, "tara": _70, "tosu": _70, "yoshinogari": _70 }], "saitama": [1, { "arakawa": _70, "asaka": _70, "chichibu": _70, "fujimi": _70, "fujimino": _70, "fukaya": _70, "hanno": _70, "hanyu": _70, "hasuda": _70, "hatogaya": _70, "hatoyama": _70, "hidaka": _70, "higashichichibu": _70, "higashimatsuyama": _70, "honjo": _70, "ina": _70, "iruma": _70, "iwatsuki": _70, "kamiizumi": _70, "kamikawa": _70, "kamisato": _70, "kasukabe": _70, "kawagoe": _70, "kawaguchi": _70, "kawajima": _70, "kazo": _70, "kitamoto": _70, "koshigaya": _70, "kounosu": _70, "kuki": _70, "kumagaya": _70, "matsubushi": _70, "minano": _70, "misato": _70, "miyashiro": _70, "miyoshi": _70, "moroyama": _70, "nagatoro": _70, "namegawa": _70, "niiza": _70, "ogano": _70, "ogawa": _70, "ogose": _70, "okegawa": _70, "omiya": _70, "otaki": _70, "ranzan": _70, "ryokami": _70, "saitama": _70, "sakado": _70, "satte": _70, "sayama": _70, "shiki": _70, "shiraoka": _70, "soka": _70, + "sugito": _70, "toda": _70, "tokigawa": _70, "tokorozawa": _70, "tsurugashima": _70, "urawa": _70, "warabi": _70, "yashio": _70, "yokoze": _70, "yono": _70, "yorii": _70, "yoshida": _70, "yoshikawa": _70, "yoshimi": _70 }], "shiga": [1, { "aisho": _70, "gamo": _70, "higashiomi": _70, "hikone": _70, "koka": _70, "konan": _70, "kosei": _70, "koto": _70, "kusatsu": _70, "maibara": _70, "moriyama": _70, "nagahama": _70, "nishiazai": _70, "notogawa": _70, "omihachiman": _70, "otsu": _70, "ritto": _70, "ryuoh": _70, "takashima": _70, "takatsuki": _70, "torahime": _70, "toyosato": _70, "yasu": _70 }], "shimane": [1, { "akagi": _70, "ama": _70, "gotsu": _70, "hamada": _70, "higashiizumo": _70, "hikawa": _70, "hikimi": _70, "izumo": _70, "kakinoki": _70, "masuda": _70, "matsue": _70, "misato": _70, "nishinoshima": _70, "ohda": _70, "okinoshima": _70, "okuizumo": _70, "shimane": _70, "tamayu": _70, "tsuwano": _70, "unnan": _70, "yakumo": _70, "yasugi": _70, "yatsuka": _70 }], "shizuoka": [ + 1, { "arai": _70, "atami": _70, "fuji": _70, "fujieda": _70, "fujikawa": _70, "fujinomiya": _70, "fukuroi": _70, "gotemba": _70, "haibara": _70, "hamamatsu": _70, "higashiizu": _70, "ito": _70, "iwata": _70, "izu": _70, "izunokuni": _70, "kakegawa": _70, "kannami": _70, "kawanehon": _70, "kawazu": _70, "kikugawa": _70, "kosai": _70, "makinohara": _70, "matsuzaki": _70, "minamiizu": _70, "mishima": _70, "morimachi": _70, "nishiizu": _70, "numazu": _70, "omaezaki": _70, "shimada": _70, "shimizu": _70, "shimoda": _70, "shizuoka": _70, "susono": _70, "yaizu": _70, "yoshida": _70 }], "tochigi": [1, { "ashikaga": _70, "bato": _70, "haga": _70, "ichikai": _70, "iwafune": _70, "kaminokawa": _70, "kanuma": _70, "karasuyama": _70, "kuroiso": _70, "mashiko": _70, "mibu": _70, "moka": _70, "motegi": _70, "nasu": _70, "nasushiobara": _70, "nikko": _70, "nishikata": _70, "nogi": _70, "ohira": _70, "ohtawara": _70, "oyama": _70, "sakura": _70, "sano": _70, "shimotsuke": _70, "shioya": _70, "tak\ +anezawa": _70, "tochigi": _70, "tsuga": _70, "ujiie": _70, "utsunomiya": _70, "yaita": _70 }], "tokushima": [1, { "aizumi": _70, "anan": _70, "ichiba": _70, "itano": _70, "kainan": _70, "komatsushima": _70, "matsushige": _70, "mima": _70, "minami": _70, "miyoshi": _70, "mugi": _70, "nakagawa": _70, "naruto": _70, "sanagochi": _70, "shishikui": _70, "tokushima": _70, "wajiki": _70 }], "tokyo": [1, { "adachi": _70, "akiruno": _70, "akishima": _70, "aogashima": _70, "arakawa": _70, "bunkyo": _70, "chiyoda": _70, "chofu": _70, "chuo": _70, "edogawa": _70, "fuchu": _70, "fussa": _70, "hachijo": _70, "hachioji": _70, "hamura": _70, "higashikurume": _70, "higashimurayama": _70, "higashiyamato": _70, "hino": _70, "hinode": _70, "hinohara": _70, "inagi": _70, "itabashi": _70, "katsushika": _70, "kita": _70, "kiyose": _70, "kodaira": _70, "koganei": _70, "kokubunji": _70, "komae": _70, "koto": _70, "kouzushima": _70, "kunitachi": _70, "machida": _70, "meguro": _70, "minato": _70, "mitaka": _70, "\ +mizuho": _70, "musashimurayama": _70, "musashino": _70, "nakano": _70, "nerima": _70, "ogasawara": _70, "okutama": _70, "ome": _70, "oshima": _70, "ota": _70, "setagaya": _70, "shibuya": _70, "shinagawa": _70, "shinjuku": _70, "suginami": _70, "sumida": _70, "tachikawa": _70, "taito": _70, "tama": _70, "toshima": _70 }], "tottori": [1, { "chizu": _70, "hino": _70, "kawahara": _70, "koge": _70, "kotoura": _70, "misasa": _70, "nanbu": _70, "nichinan": _70, "sakaiminato": _70, "tottori": _70, "wakasa": _70, "yazu": _70, "yonago": _70 }], "toyama": [1, { "asahi": _70, "fuchu": _70, "fukumitsu": _70, "funahashi": _70, "himi": _70, "imizu": _70, "inami": _70, "johana": _70, "kamiichi": _70, "kurobe": _70, "nakaniikawa": _70, "namerikawa": _70, "nanto": _70, "nyuzen": _70, "oyabe": _70, "taira": _70, "takaoka": _70, "tateyama": _70, "toga": _70, "tonami": _70, "toyama": _70, "unazuki": _70, "uozu": _70, "yamada": _70 }], "wakayama": [1, { "arida": _70, "aridagawa": _70, "gobo": _70, "hashimot\ +o": _70, "hidaka": _70, "hirogawa": _70, "inami": _70, "iwade": _70, "kainan": _70, "kamitonda": _70, "katsuragi": _70, "kimino": _70, "kinokawa": _70, "kitayama": _70, "koya": _70, "koza": _70, "kozagawa": _70, "kudoyama": _70, "kushimoto": _70, "mihama": _70, "misato": _70, "nachikatsuura": _70, "shingu": _70, "shirahama": _70, "taiji": _70, "tanabe": _70, "wakayama": _70, "yuasa": _70, "yura": _70 }], "yamagata": [1, { "asahi": _70, "funagata": _70, "higashine": _70, "iide": _70, "kahoku": _70, "kaminoyama": _70, "kaneyama": _70, "kawanishi": _70, "mamurogawa": _70, "mikawa": _70, "murayama": _70, "nagai": _70, "nakayama": _70, "nanyo": _70, "nishikawa": _70, "obanazawa": _70, "oe": _70, "oguni": _70, "ohkura": _70, "oishida": _70, "sagae": _70, "sakata": _70, "sakegawa": _70, "shinjo": _70, "shirataka": _70, "shonai": _70, "takahata": _70, "tendo": _70, "tozawa": _70, "tsuruoka": _70, "yamagata": _70, "yamanobe": _70, "yonezawa": _70, "yuza": _70 }], "yamaguchi": [1, { "abu": _70, "\ +hagi": _70, "hikari": _70, "hofu": _70, "iwakuni": _70, "kudamatsu": _70, "mitou": _70, "nagato": _70, "oshima": _70, "shimonoseki": _70, "shunan": _70, "tabuse": _70, "tokuyama": _70, "toyota": _70, "ube": _70, "yuu": _70 }], "yamanashi": [1, { "chuo": _70, "doshi": _70, "fuefuki": _70, "fujikawa": _70, "fujikawaguchiko": _70, "fujiyoshida": _70, "hayakawa": _70, "hokuto": _70, "ichikawamisato": _70, "kai": _70, "kofu": _70, "koshu": _70, "kosuge": _70, "minami-alps": _70, "minobu": _70, "nakamichi": _70, "nanbu": _70, "narusawa": _70, "nirasaki": _70, "nishikatsura": _70, "oshino": _70, "otsuki": _70, "showa": _70, "tabayama": _70, "tsuru": _70, "uenohara": _70, "yamanakako": _70, "yamanashi": _70 }], "xn--ehqz56n": _70, "三重": _70, "xn--1lqs03n": _70, "京都": _70, "xn--qqqt11m": _70, "佐賀": _70, "xn--f6qx53a": _70, "兵庫": _70, "xn--djrs72d6uy": _70, "北海道": _70, "xn--mkru45i": _70, "千葉": _70, "xn--0trq7p7nn": _70, "和歌山": _70, "xn--5js045d": _70, "埼玉": _70, + "xn--kbrq7o": _70, "大分": _70, "xn--pssu33l": _70, "大阪": _70, "xn--ntsq17g": _70, "奈良": _70, "xn--uisz3g": _70, "宮城": _70, "xn--6btw5a": _70, "宮崎": _70, "xn--1ctwo": _70, "富山": _70, "xn--6orx2r": _70, "山口": _70, "xn--rht61e": _70, "山形": _70, "xn--rht27z": _70, "山梨": _70, "xn--nit225k": _70, "岐阜": _70, "xn--rht3d": _70, "岡山": _70, "xn--djty4k": _70, "岩手": _70, "xn--klty5x": _70, "島根": _70, "xn--kltx9a": _70, "広島": _70, "xn--kltp7d": _70, "徳島": _70, "xn--c3s14m": _70, "愛媛": _70, "xn--vgu402c": _70, "愛知": _70, "xn--efvn9s": _70, "新潟": _70, "xn--1lqs71d": _70, "東京": _70, "xn--4pvxs": _70, "栃木": _70, "xn--uuwu58a": _70, "沖縄": _70, "xn--zbx025d": _70, "滋賀": _70, "xn--8pvr4u": _70, "熊本": _70, "xn--5rtp49c": _70, "石川": _70, "xn--ntso0iqx3a": _70, "神奈川": _70, "xn--elqq16h": _70, "福井": _70, "xn--4it168d": _70, "福岡": _70, "xn--klt787d": _70, "福島": _70, "xn--rny31h": _70, "秋田": _70, + "xn--7t0a264c": _70, "群馬": _70, "xn--uist22h": _70, "茨城": _70, "xn--8ltr62k": _70, "長崎": _70, "xn--2m4a15e": _70, "長野": _70, "xn--32vp30h": _70, "青森": _70, "xn--4it797k": _70, "静岡": _70, "xn--5rtq34k": _70, "香川": _70, "xn--k7yn95e": _70, "高知": _70, "xn--tor131o": _70, "鳥取": _70, "xn--d5qv7z876c": _70, "鹿児島": _70, "kawasaki": _74, "kitakyushu": _74, "kobe": _74, "nagoya": _74, "sapporo": _74, "sendai": _74, "yokohama": _74 }], "ke": [1, { "ac": _70, "co": _70, "go": _70, "info": _70, "me": _70, "mobi": _70, "ne": _70, "or": _70, "sc": _70 }], "kg": _71, "kh": _74, "ki": _79, "km": [1, { "ass": _70, "com": _70, "edu": _70, "gov": _70, "mil": _70, "nom": _70, "org": _70, "prd": _70, "tm": _70, "asso": _70, "coop": _70, "gouv": _70, "medecin": _70, "notaires": _70, "pharmaciens": _70, "presse": _70, "veterinaire": _70 }], "kn": [1, { "edu": _70, "gov": _70, "net": _70, "org": _70 }], "kp": [1, { "com": _70, "edu": _70, "gov": _70, "org": _70, + "rep": _70, "tra": _70 }], "kr": [1, { "ac": _70, "ai": _70, "co": _70, "es": _70, "go": _70, "hs": _70, "io": _70, "it": _70, "kg": _70, "me": _70, "mil": _70, "ms": _70, "ne": _70, "or": _70, "pe": _70, "re": _70, "sc": _70, "busan": _70, "chungbuk": _70, "chungnam": _70, "daegu": _70, "daejeon": _70, "gangwon": _70, "gwangju": _70, "gyeongbuk": _70, "gyeonggi": _70, "gyeongnam": _70, "incheon": _70, "jeju": _70, "jeonbuk": _70, "jeonnam": _70, "seoul": _70, "ulsan": _70 }], "kw": [1, { "com": _70, "edu": _70, "emb": _70, "gov": _70, "ind": _70, "net": _70, "org": _70 }], "ky": _76, "kz": _71, "la": [1, { "com": _70, "edu": _70, "gov": _70, "info": _70, "int": _70, "net": _70, "org": _70, "per": _70 }], "lb": _72, "lc": _75, "li": _70, "lk": [1, { "ac": _70, "assn": _70, "com": _70, "edu": _70, "gov": _70, "grp": _70, "hotel": _70, "int": _70, "ltd": _70, "net": _70, "ngo": _70, "org": _70, "sch": _70, "soc": _70, "web": _70 }], "lr": _72, "ls": [1, { "ac": _70, "biz": _70, "co": _70, + "edu": _70, "gov": _70, "info": _70, "net": _70, "org": _70, "sc": _70 }], "lt": _73, "lu": _70, "lv": [1, { "asn": _70, "com": _70, "conf": _70, "edu": _70, "gov": _70, "id": _70, "mil": _70, "net": _70, "org": _70 }], "ly": [1, { "com": _70, "edu": _70, "gov": _70, "id": _70, "med": _70, "net": _70, "org": _70, "plc": _70, "sch": _70 }], "ma": [1, { "ac": _70, "co": _70, "gov": _70, "net": _70, "org": _70, "press": _70 }], "mc": [1, { "asso": _70, "tm": _70 }], "md": _70, "me": [1, { "ac": _70, "co": _70, "edu": _70, "gov": _70, "its": _70, "net": _70, "org": _70, "priv": _70 }], "mg": [1, { "co": _70, "com": _70, "edu": _70, "gov": _70, "mil": _70, "nom": _70, "org": _70, "prd": _70 }], "mh": _70, "mil": _70, "mk": [1, { "com": _70, "edu": _70, "gov": _70, "inf": _70, "name": _70, "net": _70, "org": _70 }], "ml": [1, { "ac": _70, "art": _70, "asso": _70, "com": _70, "edu": _70, "gouv": _70, "gov": _70, "info": _70, "inst": _70, "net": _70, "org": _70, "pr": _70, "presse": _70 }], + "mm": _74, "mn": [1, { "edu": _70, "gov": _70, "org": _70 }], "mo": _72, "mobi": _70, "mp": _70, "mq": _70, "mr": _73, "ms": _72, "mt": _76, "mu": [1, { "ac": _70, "co": _70, "com": _70, "gov": _70, "net": _70, "or": _70, "org": _70 }], "museum": _70, "mv": [1, { "aero": _70, "biz": _70, "com": _70, "coop": _70, "edu": _70, "gov": _70, "info": _70, "int": _70, "mil": _70, "museum": _70, "name": _70, "net": _70, "org": _70, "pro": _70 }], "mw": [1, { "ac": _70, "biz": _70, "co": _70, "com": _70, "coop": _70, "edu": _70, "gov": _70, "int": _70, "net": _70, "org": _70 }], "mx": [1, { "com": _70, "edu": _70, "gob": _70, "net": _70, "org": _70 }], "my": [1, { "biz": _70, "com": _70, "edu": _70, "gov": _70, "mil": _70, "name": _70, "net": _70, "org": _70 }], "mz": [1, { "ac": _70, "adv": _70, "co": _70, "edu": _70, "gov": _70, "mil": _70, "net": _70, "org": _70 }], "na": [1, { "alt": _70, "co": _70, "com": _70, "gov": _70, "net": _70, "org": _70 }], "name": _70, "nc": [1, { "asso": _70, + "nom": _70 }], "ne": _70, "net": _70, "nf": [1, { "arts": _70, "com": _70, "firm": _70, "info": _70, "net": _70, "other": _70, "per": _70, "rec": _70, "store": _70, "web": _70 }], "ng": [1, { "com": _70, "edu": _70, "gov": _70, "i": _70, "mil": _70, "mobi": _70, "name": _70, "net": _70, "org": _70, "sch": _70 }], "ni": [1, { "ac": _70, "biz": _70, "co": _70, "com": _70, "edu": _70, "gob": _70, "in": _70, "info": _70, "int": _70, "mil": _70, "net": _70, "nom": _70, "org": _70, "web": _70 }], "nl": _70, "no": [1, { "fhs": _70, "folkebibl": _70, "fylkesbibl": _70, "idrett": _70, "museum": _70, "priv": _70, "vgs": _70, "dep": _70, "herad": _70, "kommune": _70, "mil": _70, "stat": _70, "aa": _80, "ah": _80, "bu": _80, "fm": _80, "hl": _80, "hm": _80, "jan-mayen": _80, "mr": _80, "nl": _80, "nt": _80, "of": _80, "ol": _80, "oslo": _80, "rl": _80, "sf": _80, "st": _80, "svalbard": _80, "tm": _80, "tr": _80, "va": _80, "vf": _80, "akrehamn": _70, "xn--krehamn-dxa": _70, "åkrehamn": _70, + "algard": _70, "xn--lgrd-poac": _70, "ålgård": _70, "arna": _70, "bronnoysund": _70, "xn--brnnysund-m8ac": _70, "brønnøysund": _70, "brumunddal": _70, "bryne": _70, "drobak": _70, "xn--drbak-wua": _70, "drøbak": _70, "egersund": _70, "fetsund": _70, "floro": _70, "xn--flor-jra": _70, "florø": _70, "fredrikstad": _70, "hokksund": _70, "honefoss": _70, "xn--hnefoss-q1a": _70, "hønefoss": _70, "jessheim": _70, "jorpeland": _70, "xn--jrpeland-54a": _70, "jørpeland": _70, "kirkenes": _70, "kopervik": _70, "krokstadelva": _70, "langevag": _70, "xn--langevg-jxa": _70, "langevåg": _70, "leirvik": _70, "mjondalen": _70, "xn--mjndalen-64a": _70, "mjøndalen": _70, "mo-i-rana": _70, "mosjoen": _70, "xn--mosjen-eya": _70, "mosjøen": _70, "nesoddtangen": _70, "orkanger": _70, "osoyro": _70, "xn--osyro-wua": _70, "osøyro": _70, "raholt": _70, "xn--rholt-mra": _70, "råholt": _70, "sandnessjoen": _70, "xn--sandnessjen-ogb": _70, "sandnessjøen": _70, "skedsmokorset": _70, "slattum": _70, + "spjelkavik": _70, "stathelle": _70, "stavern": _70, "stjordalshalsen": _70, "xn--stjrdalshalsen-sqb": _70, "stjørdalshalsen": _70, "tananger": _70, "tranby": _70, "vossevangen": _70, "aarborte": _70, "aejrie": _70, "afjord": _70, "xn--fjord-lra": _70, "åfjord": _70, "agdenes": _70, "akershus": _81, "aknoluokta": _70, "xn--koluokta-7ya57h": _70, "ákŋoluokta": _70, "al": _70, "xn--l-1fa": _70, "ål": _70, "alaheadju": _70, "xn--laheadju-7ya": _70, "álaheadju": _70, "alesund": _70, "xn--lesund-hua": _70, "ålesund": _70, "alstahaug": _70, "alta": _70, "xn--lt-liac": _70, "áltá": _70, "alvdal": _70, "amli": _70, "xn--mli-tla": _70, "åmli": _70, "amot": _70, "xn--mot-tla": _70, "åmot": _70, "andasuolo": _70, "andebu": _70, "andoy": _70, "xn--andy-ira": _70, "andøy": _70, "ardal": _70, "xn--rdal-poa": _70, "årdal": _70, "aremark": _70, "arendal": _70, "xn--s-1fa": _70, "ås": _70, "aseral": _70, "xn--seral-lra": _70, "åseral": _70, "asker": _70, "askim": _70, "askoy": _70, + "xn--asky-ira": _70, "askøy": _70, "askvoll": _70, "asnes": _70, "xn--snes-poa": _70, "åsnes": _70, "audnedaln": _70, "aukra": _70, "aure": _70, "aurland": _70, "aurskog-holand": _70, "xn--aurskog-hland-jnb": _70, "aurskog-høland": _70, "austevoll": _70, "austrheim": _70, "averoy": _70, "xn--avery-yua": _70, "averøy": _70, "badaddja": _70, "xn--bdddj-mrabd": _70, "bådåddjå": _70, "xn--brum-voa": _70, "bærum": _70, "bahcavuotna": _70, "xn--bhcavuotna-s4a": _70, "báhcavuotna": _70, "bahccavuotna": _70, "xn--bhccavuotna-k7a": _70, "báhccavuotna": _70, "baidar": _70, "xn--bidr-5nac": _70, "báidár": _70, "bajddar": _70, "xn--bjddar-pta": _70, "bájddar": _70, "balat": _70, "xn--blt-elab": _70, "bálát": _70, "balestrand": _70, "ballangen": _70, "balsfjord": _70, "bamble": _70, "bardu": _70, "barum": _70, "batsfjord": _70, "xn--btsfjord-9za": _70, "båtsfjord": _70, "bearalvahki": _70, "xn--bearalvhki-y4a": _70, "bearalváhki": _70, "beardu": _70, "beiarn": _70, "berg": _70, + "bergen": _70, "berlevag": _70, "xn--berlevg-jxa": _70, "berlevåg": _70, "bievat": _70, "xn--bievt-0qa": _70, "bievát": _70, "bindal": _70, "birkenes": _70, "bjarkoy": _70, "xn--bjarky-fya": _70, "bjarkøy": _70, "bjerkreim": _70, "bjugn": _70, "bodo": _70, "xn--bod-2na": _70, "bodø": _70, "bokn": _70, "bomlo": _70, "xn--bmlo-gra": _70, "bømlo": _70, "bremanger": _70, "bronnoy": _70, "xn--brnny-wuac": _70, "brønnøy": _70, "budejju": _70, "buskerud": _81, "bygland": _70, "bykle": _70, "cahcesuolo": _70, "xn--hcesuolo-7ya35b": _70, "čáhcesuolo": _70, "davvenjarga": _70, "xn--davvenjrga-y4a": _70, "davvenjárga": _70, "davvesiida": _70, "deatnu": _70, "dielddanuorri": _70, "divtasvuodna": _70, "divttasvuotna": _70, "donna": _70, "xn--dnna-gra": _70, "dønna": _70, "dovre": _70, "drammen": _70, "drangedal": _70, "dyroy": _70, "xn--dyry-ira": _70, "dyrøy": _70, "eid": _70, "eidfjord": _70, "eidsberg": _70, "eidskog": _70, "eidsvoll": _70, "eigersund": _70, "elverum": _70, "en\ +ebakk": _70, "engerdal": _70, "etne": _70, "etnedal": _70, "evenassi": _70, "xn--eveni-0qa01ga": _70, "evenášši": _70, "evenes": _70, "evje-og-hornnes": _70, "farsund": _70, "fauske": _70, "fedje": _70, "fet": _70, "finnoy": _70, "xn--finny-yua": _70, "finnøy": _70, "fitjar": _70, "fjaler": _70, "fjell": _70, "fla": _70, "xn--fl-zia": _70, "flå": _70, "flakstad": _70, "flatanger": _70, "flekkefjord": _70, "flesberg": _70, "flora": _70, "folldal": _70, "forde": _70, "xn--frde-gra": _70, "førde": _70, "forsand": _70, "fosnes": _70, "xn--frna-woa": _70, "fræna": _70, "frana": _70, "frei": _70, "frogn": _70, "froland": _70, "frosta": _70, "froya": _70, "xn--frya-hra": _70, "frøya": _70, "fuoisku": _70, "fuossko": _70, "fusa": _70, "fyresdal": _70, "gaivuotna": _70, "xn--givuotna-8ya": _70, "gáivuotna": _70, "galsa": _70, "xn--gls-elac": _70, "gálsá": _70, "gamvik": _70, "gangaviika": _70, "xn--ggaviika-8ya47h": _70, "gáŋgaviika": _70, "gaular": _70, "gausdal": _70, "giehtavuoa\ +tna": _70, "gildeskal": _70, "xn--gildeskl-g0a": _70, "gildeskål": _70, "giske": _70, "gjemnes": _70, "gjerdrum": _70, "gjerstad": _70, "gjesdal": _70, "gjovik": _70, "xn--gjvik-wua": _70, "gjøvik": _70, "gloppen": _70, "gol": _70, "gran": _70, "grane": _70, "granvin": _70, "gratangen": _70, "grimstad": _70, "grong": _70, "grue": _70, "gulen": _70, "guovdageaidnu": _70, "ha": _70, "xn--h-2fa": _70, "hå": _70, "habmer": _70, "xn--hbmer-xqa": _70, "hábmer": _70, "hadsel": _70, "xn--hgebostad-g3a": _70, "hægebostad": _70, "hagebostad": _70, "halden": _70, "halsa": _70, "hamar": _70, "hamaroy": _70, "hammarfeasta": _70, "xn--hmmrfeasta-s4ac": _70, "hámmárfeasta": _70, "hammerfest": _70, "hapmir": _70, "xn--hpmir-xqa": _70, "hápmir": _70, "haram": _70, "hareid": _70, "harstad": _70, "hasvik": _70, "hattfjelldal": _70, "haugesund": _70, "hedmark": [0, { "os": _70, "valer": _70, "xn--vler-qoa": _70, "våler": _70 }], "hemne": _70, "hemnes": _70, "hemsedal": _70, "hitra": _70, "hjartda\ +l": _70, "hjelmeland": _70, "hobol": _70, "xn--hobl-ira": _70, "hobøl": _70, "hof": _70, "hol": _70, "hole": _70, "holmestrand": _70, "holtalen": _70, "xn--holtlen-hxa": _70, "holtålen": _70, "hordaland": [0, { "os": _70 }], "hornindal": _70, "horten": _70, "hoyanger": _70, "xn--hyanger-q1a": _70, "høyanger": _70, "hoylandet": _70, "xn--hylandet-54a": _70, "høylandet": _70, "hurdal": _70, "hurum": _70, "hvaler": _70, "hyllestad": _70, "ibestad": _70, "inderoy": _70, "xn--indery-fya": _70, "inderøy": _70, "iveland": _70, "ivgu": _70, "jevnaker": _70, "jolster": _70, "xn--jlster-bya": _70, "jølster": _70, "jondal": _70, "kafjord": _70, "xn--kfjord-iua": _70, "kåfjord": _70, "karasjohka": _70, "xn--krjohka-hwab49j": _70, "kárášjohka": _70, "karasjok": _70, "karlsoy": _70, "karmoy": _70, "xn--karmy-yua": _70, "karmøy": _70, "kautokeino": _70, "klabu": _70, "xn--klbu-woa": _70, "klæbu": _70, "klepp": _70, "kongsberg": _70, "kongsvinger": _70, "kraanghke": _70, "xn--kranghke-b0a": _70, + "kråanghke": _70, "kragero": _70, "xn--krager-gya": _70, "kragerø": _70, "kristiansand": _70, "kristiansund": _70, "krodsherad": _70, "xn--krdsherad-m8a": _70, "krødsherad": _70, "xn--kvfjord-nxa": _70, "kvæfjord": _70, "xn--kvnangen-k0a": _70, "kvænangen": _70, "kvafjord": _70, "kvalsund": _70, "kvam": _70, "kvanangen": _70, "kvinesdal": _70, "kvinnherad": _70, "kviteseid": _70, "kvitsoy": _70, "xn--kvitsy-fya": _70, "kvitsøy": _70, "laakesvuemie": _70, "xn--lrdal-sra": _70, "lærdal": _70, "lahppi": _70, "xn--lhppi-xqa": _70, "láhppi": _70, "lardal": _70, "larvik": _70, "lavagis": _70, "lavangen": _70, "leangaviika": _70, "xn--leagaviika-52b": _70, "leaŋgaviika": _70, "lebesby": _70, "leikanger": _70, "leirfjord": _70, "leka": _70, "leksvik": _70, "lenvik": _70, "lerdal": _70, "lesja": _70, "levanger": _70, "lier": _70, "lierne": _70, "lillehammer": _70, "lillesand": _70, "lindas": _70, "xn--linds-pra": _70, "lindås": _70, "lindesnes": _70, "loabat": _70, "xn--loabt-0q\ +a": _70, "loabát": _70, "lodingen": _70, "xn--ldingen-q1a": _70, "lødingen": _70, "lom": _70, "loppa": _70, "lorenskog": _70, "xn--lrenskog-54a": _70, "lørenskog": _70, "loten": _70, "xn--lten-gra": _70, "løten": _70, "lund": _70, "lunner": _70, "luroy": _70, "xn--lury-ira": _70, "lurøy": _70, "luster": _70, "lyngdal": _70, "lyngen": _70, "malatvuopmi": _70, "xn--mlatvuopmi-s4a": _70, "málatvuopmi": _70, "malselv": _70, "xn--mlselv-iua": _70, "målselv": _70, "malvik": _70, "mandal": _70, "marker": _70, "marnardal": _70, "masfjorden": _70, "masoy": _70, "xn--msy-ula0h": _70, "måsøy": _70, "matta-varjjat": _70, "xn--mtta-vrjjat-k7af": _70, "mátta-várjjat": _70, "meland": _70, "meldal": _70, "melhus": _70, "meloy": _70, "xn--mely-ira": _70, "meløy": _70, "meraker": _70, "xn--merker-kua": _70, "meråker": _70, "midsund": _70, "midtre-gauldal": _70, "moareke": _70, "xn--moreke-jua": _70, "moåreke": _70, "modalen": _70, "modum": _70, "molde": _70, "more-og-romsdal": [0, { "heroy": _70, + "sande": _70 }], "xn--mre-og-romsdal-qqb": [0, { "xn--hery-ira": _70, "sande": _70 }], "møre-og-romsdal": [0, { "herøy": _70, "sande": _70 }], "moskenes": _70, "moss": _70, "mosvik": _70, "muosat": _70, "xn--muost-0qa": _70, "muosát": _70, "naamesjevuemie": _70, "xn--nmesjevuemie-tcba": _70, "nååmesjevuemie": _70, "xn--nry-yla5g": _70, "nærøy": _70, "namdalseid": _70, "namsos": _70, "namsskogan": _70, "nannestad": _70, "naroy": _70, "narviika": _70, "narvik": _70, "naustdal": _70, "navuotna": _70, "xn--nvuotna-hwa": _70, "návuotna": _70, "nedre-eiker": _70, "nesna": _70, "nesodden": _70, "nesseby": _70, "nesset": _70, "nissedal": _70, "nittedal": _70, "nord-aurdal": _70, "nord-fron": _70, "nord-odal": _70, "norddal": _70, "nordkapp": _70, "nordland": [0, { "bo": _70, "xn--b-5ga": _70, "bø": _70, "heroy": _70, "xn--hery-ira": _70, "herøy": _70 }], "nordre-land": _70, "nordreisa": _70, "nore-og-uvdal": _70, "notodden": _70, "notteroy": _70, "xn--nttery-byae": _70, "nøtter\ +øy": _70, "odda": _70, "oksnes": _70, "xn--ksnes-uua": _70, "øksnes": _70, "omasvuotna": _70, "oppdal": _70, "oppegard": _70, "xn--oppegrd-ixa": _70, "oppegård": _70, "orkdal": _70, "orland": _70, "xn--rland-uua": _70, "ørland": _70, "orskog": _70, "xn--rskog-uua": _70, "ørskog": _70, "orsta": _70, "xn--rsta-fra": _70, "ørsta": _70, "osen": _70, "osteroy": _70, "xn--ostery-fya": _70, "osterøy": _70, "ostfold": [0, { "valer": _70 }], "xn--stfold-9xa": [0, { "xn--vler-qoa": _70 }], "østfold": [0, { "våler": _70 }], "ostre-toten": _70, "xn--stre-toten-zcb": _70, "østre-toten": _70, "overhalla": _70, "ovre-eiker": _70, "xn--vre-eiker-k8a": _70, "øvre-eiker": _70, "oyer": _70, "xn--yer-zna": _70, "øyer": _70, "oygarden": _70, "xn--ygarden-p1a": _70, "øygarden": _70, "oystre-slidre": _70, "xn--ystre-slidre-ujb": _70, "øystre-slidre": _70, "porsanger": _70, "porsangu": _70, "xn--porsgu-sta26f": _70, "porsáŋgu": _70, "porsgrunn": _70, "rade": _70, "xn--rde-ula": _70, "råde": _70, + "radoy": _70, "xn--rady-ira": _70, "radøy": _70, "xn--rlingen-mxa": _70, "rælingen": _70, "rahkkeravju": _70, "xn--rhkkervju-01af": _70, "ráhkkerávju": _70, "raisa": _70, "xn--risa-5na": _70, "ráisa": _70, "rakkestad": _70, "ralingen": _70, "rana": _70, "randaberg": _70, "rauma": _70, "rendalen": _70, "rennebu": _70, "rennesoy": _70, "xn--rennesy-v1a": _70, "rennesøy": _70, "rindal": _70, "ringebu": _70, "ringerike": _70, "ringsaker": _70, "risor": _70, "xn--risr-ira": _70, "risør": _70, "rissa": _70, "roan": _70, "rodoy": _70, "xn--rdy-0nab": _70, "rødøy": _70, "rollag": _70, "romsa": _70, "romskog": _70, "xn--rmskog-bya": _70, "rømskog": _70, "roros": _70, "xn--rros-gra": _70, "røros": _70, "rost": _70, "xn--rst-0na": _70, "røst": _70, "royken": _70, "xn--ryken-vua": _70, "røyken": _70, "royrvik": _70, "xn--ryrvik-bya": _70, "røyrvik": _70, "ruovat": _70, "rygge": _70, "salangen": _70, "salat": _70, "xn--slat-5na": _70, "sálat": _70, "xn--slt-elab": _70, "sálát": _70, + "saltdal": _70, "samnanger": _70, "sandefjord": _70, "sandnes": _70, "sandoy": _70, "xn--sandy-yua": _70, "sandøy": _70, "sarpsborg": _70, "sauda": _70, "sauherad": _70, "sel": _70, "selbu": _70, "selje": _70, "seljord": _70, "siellak": _70, "sigdal": _70, "siljan": _70, "sirdal": _70, "skanit": _70, "xn--sknit-yqa": _70, "skánit": _70, "skanland": _70, "xn--sknland-fxa": _70, "skånland": _70, "skaun": _70, "skedsmo": _70, "ski": _70, "skien": _70, "skierva": _70, "xn--skierv-uta": _70, "skiervá": _70, "skiptvet": _70, "skjak": _70, "xn--skjk-soa": _70, "skjåk": _70, "skjervoy": _70, "xn--skjervy-v1a": _70, "skjervøy": _70, "skodje": _70, "smola": _70, "xn--smla-hra": _70, "smøla": _70, "snaase": _70, "xn--snase-nra": _70, "snåase": _70, "snasa": _70, "xn--snsa-roa": _70, "snåsa": _70, "snillfjord": _70, "snoasa": _70, "sogndal": _70, "sogne": _70, "xn--sgne-gra": _70, "søgne": _70, "sokndal": _70, "sola": _70, "solund": _70, "somna": _70, "xn--smna-gra": _70, "sømna": _70, + "sondre-land": _70, "xn--sndre-land-0cb": _70, "søndre-land": _70, "songdalen": _70, "sor-aurdal": _70, "xn--sr-aurdal-l8a": _70, "sør-aurdal": _70, "sor-fron": _70, "xn--sr-fron-q1a": _70, "sør-fron": _70, "sor-odal": _70, "xn--sr-odal-q1a": _70, "sør-odal": _70, "sor-varanger": _70, "xn--sr-varanger-ggb": _70, "sør-varanger": _70, "sorfold": _70, "xn--srfold-bya": _70, "sørfold": _70, "sorreisa": _70, "xn--srreisa-q1a": _70, "sørreisa": _70, "sortland": _70, "sorum": _70, "xn--srum-gra": _70, "sørum": _70, "spydeberg": _70, "stange": _70, "stavanger": _70, "steigen": _70, "steinkjer": _70, "stjordal": _70, "xn--stjrdal-s1a": _70, "stjørdal": _70, "stokke": _70, "stor-elvdal": _70, "stord": _70, "stordal": _70, "storfjord": _70, "strand": _70, "stranda": _70, "stryn": _70, "sula": _70, "suldal": _70, "sund": _70, "sunndal": _70, "surnadal": _70, "sveio": _70, "svelvik": _70, "sykkylven": _70, "tana": _70, "telemark": [0, { "bo": _70, "xn--b-5ga": _70, "bø": _70 }], "ti\ +me": _70, "tingvoll": _70, "tinn": _70, "tjeldsund": _70, "tjome": _70, "xn--tjme-hra": _70, "tjøme": _70, "tokke": _70, "tolga": _70, "tonsberg": _70, "xn--tnsberg-q1a": _70, "tønsberg": _70, "torsken": _70, "xn--trna-woa": _70, "træna": _70, "trana": _70, "tranoy": _70, "xn--trany-yua": _70, "tranøy": _70, "troandin": _70, "trogstad": _70, "xn--trgstad-r1a": _70, "trøgstad": _70, "tromsa": _70, "tromso": _70, "xn--troms-zua": _70, "tromsø": _70, "trondheim": _70, "trysil": _70, "tvedestrand": _70, "tydal": _70, "tynset": _70, "tysfjord": _70, "tysnes": _70, "xn--tysvr-vra": _70, "tysvær": _70, "tysvar": _70, "ullensaker": _70, "ullensvang": _70, "ulvik": _70, "unjarga": _70, "xn--unjrga-rta": _70, "unjárga": _70, "utsira": _70, "vaapste": _70, "vadso": _70, "xn--vads-jra": _70, "vadsø": _70, "xn--vry-yla5g": _70, "værøy": _70, "vaga": _70, "xn--vg-yiab": _70, "vågå": _70, "vagan": _70, "xn--vgan-qoa": _70, "vågan": _70, "vagsoy": _70, "xn--vgsy-qoa0j": _70, "vågsøy": _70, + "vaksdal": _70, "valle": _70, "vang": _70, "vanylven": _70, "vardo": _70, "xn--vard-jra": _70, "vardø": _70, "varggat": _70, "xn--vrggt-xqad": _70, "várggát": _70, "varoy": _70, "vefsn": _70, "vega": _70, "vegarshei": _70, "xn--vegrshei-c0a": _70, "vegårshei": _70, "vennesla": _70, "verdal": _70, "verran": _70, "vestby": _70, "vestfold": [0, { "sande": _70 }], "vestnes": _70, "vestre-slidre": _70, "vestre-toten": _70, "vestvagoy": _70, "xn--vestvgy-ixa6o": _70, "vestvågøy": _70, "vevelstad": _70, "vik": _70, "vikna": _70, "vindafjord": _70, "voagat": _70, "volda": _70, "voss": _70 }], "np": _74, "nr": _79, "nu": _70, "nz": [1, { "ac": _70, "co": _70, "cri": _70, "geek": _70, "gen": _70, "govt": _70, "health": _70, "iwi": _70, "kiwi": _70, "maori": _70, "xn--mori-qsa": _70, "māori": _70, "mil": _70, "net": _70, "org": _70, "parliament": _70, "school": _70 }], "om": [1, { "co": _70, "com": _70, "edu": _70, "gov": _70, "med": _70, "museum": _70, "net": _70, "org": _70, "pro": _70 }], + "onion": _70, "org": _70, "pa": [1, { "abo": _70, "ac": _70, "com": _70, "edu": _70, "gob": _70, "ing": _70, "med": _70, "net": _70, "nom": _70, "org": _70, "sld": _70 }], "pe": [1, { "com": _70, "edu": _70, "gob": _70, "mil": _70, "net": _70, "nom": _70, "org": _70 }], "pf": [1, { "com": _70, "edu": _70, "org": _70 }], "pg": _74, "ph": [1, { "com": _70, "edu": _70, "gov": _70, "i": _70, "mil": _70, "net": _70, "ngo": _70, "org": _70 }], "pk": [1, { "ac": _70, "biz": _70, "com": _70, "edu": _70, "fam": _70, "gkp": _70, "gob": _70, "gog": _70, "gok": _70, "gop": _70, "gos": _70, "gov": _70, "net": _70, "org": _70, "web": _70 }], "pl": [1, { "com": _70, "net": _70, "org": _70, "agro": _70, "aid": _70, "atm": _70, "auto": _70, "biz": _70, "edu": _70, "gmina": _70, "gsm": _70, "info": _70, "mail": _70, "media": _70, "miasta": _70, "mil": _70, "nieruchomosci": _70, "nom": _70, "pc": _70, "powiat": _70, "priv": _70, "realestate": _70, "rel": _70, "sex": _70, "shop": _70, "sklep": _70, "\ +sos": _70, "szkola": _70, "targi": _70, "tm": _70, "tourism": _70, "travel": _70, "turystyka": _70, "gov": [1, { "ap": _70, "griw": _70, "ic": _70, "is": _70, "kmpsp": _70, "konsulat": _70, "kppsp": _70, "kwp": _70, "kwpsp": _70, "mup": _70, "mw": _70, "oia": _70, "oirm": _70, "oke": _70, "oow": _70, "oschr": _70, "oum": _70, "pa": _70, "pinb": _70, "piw": _70, "po": _70, "pr": _70, "psp": _70, "psse": _70, "pup": _70, "rzgw": _70, "sa": _70, "sdn": _70, "sko": _70, "so": _70, "sr": _70, "starostwo": _70, "ug": _70, "ugim": _70, "um": _70, "umig": _70, "upow": _70, "uppo": _70, "us": _70, "uw": _70, "uzs": _70, "wif": _70, "wiih": _70, "winb": _70, "wios": _70, "witd": _70, "wiw": _70, "wkz": _70, "wsa": _70, "wskr": _70, "wsse": _70, "wuoz": _70, "wzmiuw": _70, "zp": _70, "zpisdn": _70 }], "augustow": _70, "babia-gora": _70, "bedzin": _70, "beskidy": _70, "bialowieza": _70, "bialystok": _70, "bielawa": _70, "bieszczady": _70, "boleslawiec": _70, "bydgoszcz": _70, "bytom": _70, "cieszy\ +n": _70, "czeladz": _70, "czest": _70, "dlugoleka": _70, "elblag": _70, "elk": _70, "glogow": _70, "gniezno": _70, "gorlice": _70, "grajewo": _70, "ilawa": _70, "jaworzno": _70, "jelenia-gora": _70, "jgora": _70, "kalisz": _70, "karpacz": _70, "kartuzy": _70, "kaszuby": _70, "katowice": _70, "kazimierz-dolny": _70, "kepno": _70, "ketrzyn": _70, "klodzko": _70, "kobierzyce": _70, "kolobrzeg": _70, "konin": _70, "konskowola": _70, "kutno": _70, "lapy": _70, "lebork": _70, "legnica": _70, "lezajsk": _70, "limanowa": _70, "lomza": _70, "lowicz": _70, "lubin": _70, "lukow": _70, "malbork": _70, "malopolska": _70, "mazowsze": _70, "mazury": _70, "mielec": _70, "mielno": _70, "mragowo": _70, "naklo": _70, "nowaruda": _70, "nysa": _70, "olawa": _70, "olecko": _70, "olkusz": _70, "olsztyn": _70, "opoczno": _70, "opole": _70, "ostroda": _70, "ostroleka": _70, "ostrowiec": _70, "ostrowwlkp": _70, "pila": _70, "pisz": _70, "podhale": _70, "podlasie": _70, "polkowice": _70, "pomorskie": _70, "pomor\ +ze": _70, "prochowice": _70, "pruszkow": _70, "przeworsk": _70, "pulawy": _70, "radom": _70, "rawa-maz": _70, "rybnik": _70, "rzeszow": _70, "sanok": _70, "sejny": _70, "skoczow": _70, "slask": _70, "slupsk": _70, "sosnowiec": _70, "stalowa-wola": _70, "starachowice": _70, "stargard": _70, "suwalki": _70, "swidnica": _70, "swiebodzin": _70, "swinoujscie": _70, "szczecin": _70, "szczytno": _70, "tarnobrzeg": _70, "tgory": _70, "turek": _70, "tychy": _70, "ustka": _70, "walbrzych": _70, "warmia": _70, "warszawa": _70, "waw": _70, "wegrow": _70, "wielun": _70, "wlocl": _70, "wloclawek": _70, "wodzislaw": _70, "wolomin": _70, "wroclaw": _70, "zachpomor": _70, "zagan": _70, "zarow": _70, "zgora": _70, "zgorzelec": _70 }], "pm": _70, "pn": [1, { "co": _70, "edu": _70, "gov": _70, "net": _70, "org": _70 }], "post": _70, "pr": [1, { "biz": _70, "com": _70, "edu": _70, "gov": _70, "info": _70, "isla": _70, "name": _70, "net": _70, "org": _70, "pro": _70, "ac": _70, "est": _70, "prof": _70 }], "\ +pro": [1, { "aaa": _70, "aca": _70, "acct": _70, "avocat": _70, "bar": _70, "cpa": _70, "eng": _70, "jur": _70, "law": _70, "med": _70, "recht": _70 }], "ps": [1, { "com": _70, "edu": _70, "gov": _70, "net": _70, "org": _70, "plo": _70, "sec": _70 }], "pt": [1, { "com": _70, "edu": _70, "gov": _70, "int": _70, "net": _70, "nome": _70, "org": _70, "publ": _70 }], "pw": _73, "py": [1, { "com": _70, "coop": _70, "edu": _70, "gov": _70, "mil": _70, "net": _70, "org": _70 }], "qa": [1, { "com": _70, "edu": _70, "gov": _70, "mil": _70, "name": _70, "net": _70, "org": _70, "sch": _70 }], "re": [1, { "asso": _70, "com": _70 }], "ro": [1, { "arts": _70, "com": _70, "firm": _70, "info": _70, "nom": _70, "nt": _70, "org": _70, "rec": _70, "store": _70, "tm": _70, "www": _70 }], "rs": [1, { "ac": _70, "co": _70, "edu": _70, "gov": _70, "in": _70, "org": _70 }], "ru": _70, "rw": [1, { "ac": _70, "co": _70, "coop": _70, "gov": _70, "mil": _70, "net": _70, "org": _70 }], "sa": [1, { "com": _70, "edu": _70, + "gov": _70, "med": _70, "net": _70, "org": _70, "pub": _70, "sch": _70 }], "sb": _72, "sc": _72, "sd": [1, { "com": _70, "edu": _70, "gov": _70, "info": _70, "med": _70, "net": _70, "org": _70, "tv": _70 }], "se": [1, { "a": _70, "ac": _70, "b": _70, "bd": _70, "brand": _70, "c": _70, "d": _70, "e": _70, "f": _70, "fh": _70, "fhsk": _70, "fhv": _70, "g": _70, "h": _70, "i": _70, "k": _70, "komforb": _70, "kommunalforbund": _70, "komvux": _70, "l": _70, "lanbib": _70, "m": _70, "n": _70, "naturbruksgymn": _70, "o": _70, "org": _70, "p": _70, "parti": _70, "pp": _70, "press": _70, "r": _70, "s": _70, "t": _70, "tm": _70, "u": _70, "w": _70, "x": _70, "y": _70, "z": _70 }], "sg": _72, "sh": [1, { "com": _70, "gov": _70, "mil": _70, "net": _70, "org": _70 }], "si": _70, "sj": _70, "sk": _70, "sl": _72, "sm": _70, "sn": [1, { "art": _70, "com": _70, "edu": _70, "gouv": _70, "org": _70, "perso": _70, "univ": _70 }], "so": [1, { "com": _70, "edu": _70, "gov": _70, "me": _70, "net": _70, + "org": _70 }], "sr": _70, "ss": [1, { "biz": _70, "co": _70, "com": _70, "edu": _70, "gov": _70, "me": _70, "net": _70, "org": _70, "sch": _70 }], "st": [1, { "co": _70, "com": _70, "consulado": _70, "edu": _70, "embaixada": _70, "mil": _70, "net": _70, "org": _70, "principe": _70, "saotome": _70, "store": _70 }], "su": _70, "sv": [1, { "com": _70, "edu": _70, "gob": _70, "org": _70, "red": _70 }], "sx": _73, "sy": _71, "sz": [1, { "ac": _70, "co": _70, "org": _70 }], "tc": _70, "td": _70, "tel": _70, "tf": _70, "tg": _70, "th": [1, { "ac": _70, "co": _70, "go": _70, "in": _70, "mi": _70, "net": _70, "or": _70 }], "tj": [1, { "ac": _70, "biz": _70, "co": _70, "com": _70, "edu": _70, "go": _70, "gov": _70, "int": _70, "mil": _70, "name": _70, "net": _70, "nic": _70, "org": _70, "test": _70, "web": _70 }], "tk": _70, "tl": _73, "tm": _78, "tn": [1, { "com": _70, "ens": _70, "fin": _70, "gov": _70, "ind": _70, "info": _70, "intl": _70, "mincom": _70, "nat": _70, "net": _70, "org": _70, + "perso": _70, "tourism": _70 }], "to": _71, "tr": [1, { "av": _70, "bbs": _70, "bel": _70, "biz": _70, "com": _70, "dr": _70, "edu": _70, "gen": _70, "gov": _70, "info": _70, "k12": _70, "kep": _70, "mil": _70, "name": _70, "net": _70, "org": _70, "pol": _70, "tel": _70, "tsk": _70, "tv": _70, "web": _70, "nc": _73 }], "tt": [1, { "biz": _70, "co": _70, "com": _70, "edu": _70, "gov": _70, "info": _70, "mil": _70, "name": _70, "net": _70, "org": _70, "pro": _70 }], "tv": _70, "tw": [1, { "club": _70, "com": _70, "ebiz": _70, "edu": _70, "game": _70, "gov": _70, "idv": _70, "mil": _70, "net": _70, "org": _70 }], "tz": [1, { "ac": _70, "co": _70, "go": _70, "hotel": _70, "info": _70, "me": _70, "mil": _70, "mobi": _70, "ne": _70, "or": _70, "sc": _70, "tv": _70 }], "ua": [1, { "com": _70, "edu": _70, "gov": _70, "in": _70, "net": _70, "org": _70, "cherkassy": _70, "cherkasy": _70, "chernigov": _70, "chernihiv": _70, "chernivtsi": _70, "chernovtsy": _70, "ck": _70, "cn": _70, "cr": _70, + "crimea": _70, "cv": _70, "dn": _70, "dnepropetrovsk": _70, "dnipropetrovsk": _70, "donetsk": _70, "dp": _70, "if": _70, "ivano-frankivsk": _70, "kh": _70, "kharkiv": _70, "kharkov": _70, "kherson": _70, "khmelnitskiy": _70, "khmelnytskyi": _70, "kiev": _70, "kirovograd": _70, "km": _70, "kr": _70, "kropyvnytskyi": _70, "krym": _70, "ks": _70, "kv": _70, "kyiv": _70, "lg": _70, "lt": _70, "lugansk": _70, "luhansk": _70, "lutsk": _70, "lv": _70, "lviv": _70, "mk": _70, "mykolaiv": _70, "nikolaev": _70, "od": _70, "odesa": _70, "odessa": _70, "pl": _70, "poltava": _70, "rivne": _70, "rovno": _70, "rv": _70, "sb": _70, "sebastopol": _70, "sevastopol": _70, "sm": _70, "sumy": _70, "te": _70, "ternopil": _70, "uz": _70, "uzhgorod": _70, "uzhhorod": _70, "vinnica": _70, "vinnytsia": _70, "vn": _70, "volyn": _70, "yalta": _70, "zakarpattia": _70, "zaporizhzhe": _70, "zaporizhzhia": _70, "zhitomir": _70, "zhytomyr": _70, "zp": _70, "zt": _70 }], "ug": [1, { "ac": _70, "co": _70, "com": _70, + "edu": _70, "go": _70, "gov": _70, "mil": _70, "ne": _70, "or": _70, "org": _70, "sc": _70, "us": _70 }], "uk": [1, { "ac": _70, "co": _70, "gov": _70, "ltd": _70, "me": _70, "net": _70, "nhs": _70, "org": _70, "plc": _70, "police": _70, "sch": _74 }], "us": [1, { "dni": _70, "isa": _70, "nsn": _70, "ak": _82, "al": _82, "ar": _82, "as": _82, "az": _82, "ca": _82, "co": _82, "ct": _82, "dc": _82, "de": _83, "fl": _82, "ga": _82, "gu": _82, "hi": _84, "ia": _82, "id": _82, "il": _82, "in": _82, "ks": _82, "ky": _82, "la": _82, "ma": [1, { "k12": [1, { "chtr": _70, "paroch": _70, "pvt": _70 }], "cc": _70, "lib": _70 }], "md": _82, "me": _82, "mi": [1, { "k12": _70, "cc": _70, "lib": _70, "ann-arbor": _70, "cog": _70, "dst": _70, "eaton": _70, "gen": _70, "mus": _70, "tec": _70, "washtenaw": _70 }], "mn": _82, "mo": _82, "ms": [1, { "k12": _70, "cc": _70 }], "mt": _82, "nc": _82, "nd": _84, "ne": _82, "nh": _82, "nj": _82, "nm": _82, "nv": _82, "ny": _82, "oh": _82, "ok": _82, "or": _82, + "pa": _82, "pr": _82, "ri": _84, "sc": _82, "sd": _84, "tn": _82, "tx": _82, "ut": _82, "va": _82, "vi": _82, "vt": _82, "wa": _82, "wi": _82, "wv": _83, "wy": _82 }], "uy": [1, { "com": _70, "edu": _70, "gub": _70, "mil": _70, "net": _70, "org": _70 }], "uz": [1, { "co": _70, "com": _70, "net": _70, "org": _70 }], "va": _70, "vc": _71, "ve": [1, { "arts": _70, "bib": _70, "co": _70, "com": _70, "e12": _70, "edu": _70, "emprende": _70, "firm": _70, "gob": _70, "gov": _70, "info": _70, "int": _70, "mil": _70, "net": _70, "nom": _70, "org": _70, "rar": _70, "rec": _70, "store": _70, "tec": _70, "web": _70 }], "vg": [1, { "edu": _70 }], "vi": [1, { "co": _70, "com": _70, "k12": _70, "net": _70, "org": _70 }], "vn": [1, { "ac": _70, "ai": _70, "biz": _70, "com": _70, "edu": _70, "gov": _70, "health": _70, "id": _70, "info": _70, "int": _70, "io": _70, "name": _70, "net": _70, "org": _70, "pro": _70, "angiang": _70, "bacgiang": _70, "backan": _70, "baclieu": _70, "bacninh": _70, "bari\ +a-vungtau": _70, "bentre": _70, "binhdinh": _70, "binhduong": _70, "binhphuoc": _70, "binhthuan": _70, "camau": _70, "cantho": _70, "caobang": _70, "daklak": _70, "daknong": _70, "danang": _70, "dienbien": _70, "dongnai": _70, "dongthap": _70, "gialai": _70, "hagiang": _70, "haiduong": _70, "haiphong": _70, "hanam": _70, "hanoi": _70, "hatinh": _70, "haugiang": _70, "hoabinh": _70, "hungyen": _70, "khanhhoa": _70, "kiengiang": _70, "kontum": _70, "laichau": _70, "lamdong": _70, "langson": _70, "laocai": _70, "longan": _70, "namdinh": _70, "nghean": _70, "ninhbinh": _70, "ninhthuan": _70, "phutho": _70, "phuyen": _70, "quangbinh": _70, "quangnam": _70, "quangngai": _70, "quangninh": _70, "quangtri": _70, "soctrang": _70, "sonla": _70, "tayninh": _70, "thaibinh": _70, "thainguyen": _70, "thanhhoa": _70, "thanhphohochiminh": _70, "thuathienhue": _70, "tiengiang": _70, "travinh": _70, "tuyenquang": _70, "vinhlong": _70, "vinhphuc": _70, "yenbai": _70 }], "vu": _76, "wf": _70, "ws": _72, "y\ +t": _70, "xn--mgbaam7a8h": _70, "امارات": _70, "xn--y9a3aq": _70, "հայ": _70, "xn--54b7fta0cc": _70, "বাংলা": _70, "xn--90ae": _70, "бг": _70, "xn--mgbcpq6gpa1a": _70, "البحرين": _70, "xn--90ais": _70, "бел": _70, "xn--fiqs8s": _70, "中国": _70, "xn--fiqz9s": _70, "中國": _70, "xn--lgbbat1ad8j": _70, "الجزائر": _70, "xn--wgbh1c": _70, "مصر": _70, "xn--e1a4c": _70, "ею": _70, "xn--qxa6a": _70, "ευ": _70, "xn--mgbah1a3hjkrd": _70, "موريتانيا": _70, "xn--node": _70, "გე": _70, "xn--qxam": _70, "ελ": _70, "xn--j6w193g": [1, { "xn--gmqw5a": _70, "xn--55qx5d": _70, "xn--mxtq1m": _70, "xn--wcvs22d": _70, "xn--uc0atv": _70, "xn--od0alg": _70 }], "香港": [1, { "個人": _70, "公司": _70, "政府": _70, "教育": _70, "組織": _70, "網絡": _70 }], "xn--2scrj9c": _70, "ಭಾರತ": _70, "xn--3hcrj9c": _70, "ଭାରତ": _70, "xn--45br5cyl": _70, "ভাৰত": _70, "xn--h2breg3eve": _70, "भारतम्": _70, "xn--h2\ +brj9c8c": _70, "भारोत": _70, "xn--mgbgu82a": _70, "ڀارت": _70, "xn--rvc1e0am3e": _70, "ഭാരതം": _70, "xn--h2brj9c": _70, "भारत": _70, "xn--mgbbh1a": _70, "بارت": _70, "xn--mgbbh1a71e": _70, "بھارت": _70, "xn--fpcrj9c3d": _70, "భారత్": _70, "xn--gecrj9c": _70, "ભારત": _70, "xn--s9brj9c": _70, "ਭਾਰਤ": _70, "xn--45brj9c": _70, "ভারত": _70, "xn--xkc2dl3a5ee0h": _70, "இந்தியா": _70, "xn--mgba3a4f16a": _70, "ایران": _70, "xn--mgba3a4fra": _70, "ايران": _70, "xn--mgbtx2b": _70, "عراق": _70, "xn--mgbayh7gpa": _70, "الاردن": _70, "xn--3e0b707e": _70, "한국": _70, "xn--80ao21a": _70, "қаз": _70, "xn--q7ce6a": _70, "ລາວ": _70, "xn--fzc2c9e2c": _70, "ලංකා": _70, "xn--xkc2al3hye2a": _70, "இலங்கை": _70, "xn--mgbc0a9azcg": _70, "المغرب": _70, "xn--d1alf": _70, "мкд": _70, "xn--l1acc": _70, "мон": _70, "xn--mix891f": _70, "澳門": _70, "xn--mix082f": _70, + "澳门": _70, "xn--mgbx4cd0ab": _70, "مليسيا": _70, "xn--mgb9awbf": _70, "عمان": _70, "xn--mgbai9azgqp6j": _70, "پاکستان": _70, "xn--mgbai9a5eva00b": _70, "پاكستان": _70, "xn--ygbi2ammx": _70, "فلسطين": _70, "xn--90a3ac": [1, { "xn--80au": _70, "xn--90azh": _70, "xn--d1at": _70, "xn--c1avg": _70, "xn--o1ac": _70, "xn--o1ach": _70 }], "срб": [1, { "ак": _70, "обр": _70, "од": _70, "орг": _70, "пр": _70, "упр": _70 }], "xn--p1ai": _70, "рф": _70, "xn--wgbl6a": _70, "قطر": _70, "xn--mgberp4a5d4ar": _70, "السعودية": _70, "xn--mgberp4a5d4a87g": _70, "السعودیة": _70, "xn--mgbqly7c0a67fbc": _70, "السعودیۃ": _70, "xn--mgbqly7cvafr": _70, "السعوديه": _70, "xn--mgbpl2fh": _70, "سودان": _70, "xn--yfro4i67o": _70, "新加坡": _70, "xn--clchc0ea0b2g2a9gcd": _70, "சிங்கப்பூர்": _70, "xn--ogbpf8fl": _70, "سورية": _70, "xn--mgbtf8fl": _70, "سوريا": _70, "xn--o3cw4h": [1, { "\ +xn--o3cyx2a": _70, "xn--12co0c3b4eva": _70, "xn--m3ch0j3a": _70, "xn--h3cuzk1di": _70, "xn--12c1fe0br": _70, "xn--12cfi8ixb8l": _70 }], "ไทย": [1, { "ทหาร": _70, "ธุรกิจ": _70, "เน็ต": _70, "รัฐบาล": _70, "ศึกษา": _70, "องค์กร": _70 }], "xn--pgbs0dh": _70, "تونس": _70, "xn--kpry57d": _70, "台灣": _70, "xn--kprw13d": _70, "台湾": _70, "xn--nnx388a": _70, "臺灣": _70, "xn--j1amh": _70, "укр": _70, "xn--mgb2ddes": _70, "اليمن": _70, "xxx": _70, "ye": _71, "za": [0, { "ac": _70, "agric": _70, "alt": _70, "co": _70, "edu": _70, "gov": _70, "grondar": _70, "law": _70, "mil": _70, "net": _70, "ngo": _70, "nic": _70, "nis": _70, "nom": _70, "org": _70, "school": _70, "tm": _70, "web": _70 }], "zm": [1, { "ac": _70, "biz": _70, "co": _70, "com": _70, "edu": _70, "gov": _70, "info": _70, "mil": _70, "net": _70, "org": _70, "sch": _70 }], "zw": [1, { "ac": _70, "co": _70, "gov": _70, "mil": _70, "org": _70 }], "\ +aaa": _70, "aarp": _70, "abb": _70, "abbott": _70, "abbvie": _70, "abc": _70, "able": _70, "abogado": _70, "abudhabi": _70, "academy": _70, "accenture": _70, "accountant": _70, "accountants": _70, "aco": _70, "actor": _70, "ads": _70, "adult": _70, "aeg": _70, "aetna": _70, "afl": _70, "africa": _70, "agakhan": _70, "agency": _70, "aig": _70, "airbus": _70, "airforce": _70, "airtel": _70, "akdn": _70, "alibaba": _70, "alipay": _70, "allfinanz": _70, "allstate": _70, "ally": _70, "alsace": _70, "alstom": _70, "amazon": _70, "americanexpress": _70, "americanfamily": _70, "amex": _70, "amfam": _70, "amica": _70, "amsterdam": _70, "analytics": _70, "android": _70, "anquan": _70, "anz": _70, "aol": _70, "apartments": _70, "app": _70, "apple": _70, "aquarelle": _70, "arab": _70, "aramco": _70, "archi": _70, "army": _70, "art": _70, "arte": _70, "asda": _70, "associates": _70, "athleta": _70, "attorney": _70, "auction": _70, "audi": _70, "audible": _70, "audio": _70, "auspost": _70, "author": _70, + "auto": _70, "autos": _70, "aws": _70, "axa": _70, "azure": _70, "baby": _70, "baidu": _70, "banamex": _70, "band": _70, "bank": _70, "bar": _70, "barcelona": _70, "barclaycard": _70, "barclays": _70, "barefoot": _70, "bargains": _70, "baseball": _70, "basketball": _70, "bauhaus": _70, "bayern": _70, "bbc": _70, "bbt": _70, "bbva": _70, "bcg": _70, "bcn": _70, "beats": _70, "beauty": _70, "beer": _70, "berlin": _70, "best": _70, "bestbuy": _70, "bet": _70, "bharti": _70, "bible": _70, "bid": _70, "bike": _70, "bing": _70, "bingo": _70, "bio": _70, "black": _70, "blackfriday": _70, "blockbuster": _70, "blog": _70, "bloomberg": _70, "blue": _70, "bms": _70, "bmw": _70, "bnpparibas": _70, "boats": _70, "boehringer": _70, "bofa": _70, "bom": _70, "bond": _70, "boo": _70, "book": _70, "booking": _70, "bosch": _70, "bostik": _70, "boston": _70, "bot": _70, "boutique": _70, "box": _70, "bradesco": _70, "bridgestone": _70, "broadway": _70, "broker": _70, "brother": _70, "brussels": _70, "\ +build": _70, "builders": _70, "business": _70, "buy": _70, "buzz": _70, "bzh": _70, "cab": _70, "cafe": _70, "cal": _70, "call": _70, "calvinklein": _70, "cam": _70, "camera": _70, "camp": _70, "canon": _70, "capetown": _70, "capital": _70, "capitalone": _70, "car": _70, "caravan": _70, "cards": _70, "care": _70, "career": _70, "careers": _70, "cars": _70, "casa": _70, "case": _70, "cash": _70, "casino": _70, "catering": _70, "catholic": _70, "cba": _70, "cbn": _70, "cbre": _70, "center": _70, "ceo": _70, "cern": _70, "cfa": _70, "cfd": _70, "chanel": _70, "channel": _70, "charity": _70, "chase": _70, "chat": _70, "cheap": _70, "chintai": _70, "christmas": _70, "chrome": _70, "church": _70, "cipriani": _70, "circle": _70, "cisco": _70, "citadel": _70, "citi": _70, "citic": _70, "city": _70, "claims": _70, "cleaning": _70, "click": _70, "clinic": _70, "clinique": _70, "clothing": _70, "cloud": _70, "club": _70, "clubmed": _70, "coach": _70, "codes": _70, "coffee": _70, "college": _70, "\ +cologne": _70, "commbank": _70, "community": _70, "company": _70, "compare": _70, "computer": _70, "comsec": _70, "condos": _70, "construction": _70, "consulting": _70, "contact": _70, "contractors": _70, "cooking": _70, "cool": _70, "corsica": _70, "country": _70, "coupon": _70, "coupons": _70, "courses": _70, "cpa": _70, "credit": _70, "creditcard": _70, "creditunion": _70, "cricket": _70, "crown": _70, "crs": _70, "cruise": _70, "cruises": _70, "cuisinella": _70, "cymru": _70, "cyou": _70, "dad": _70, "dance": _70, "data": _70, "date": _70, "dating": _70, "datsun": _70, "day": _70, "dclk": _70, "dds": _70, "deal": _70, "dealer": _70, "deals": _70, "degree": _70, "delivery": _70, "dell": _70, "deloitte": _70, "delta": _70, "democrat": _70, "dental": _70, "dentist": _70, "desi": _70, "design": _70, "dev": _70, "dhl": _70, "diamonds": _70, "diet": _70, "digital": _70, "direct": _70, "directory": _70, "discount": _70, "discover": _70, "dish": _70, "diy": _70, "dnp": _70, "docs": _70, "d\ +octor": _70, "dog": _70, "domains": _70, "dot": _70, "download": _70, "drive": _70, "dtv": _70, "dubai": _70, "dunlop": _70, "dupont": _70, "durban": _70, "dvag": _70, "dvr": _70, "earth": _70, "eat": _70, "eco": _70, "edeka": _70, "education": _70, "email": _70, "emerck": _70, "energy": _70, "engineer": _70, "engineering": _70, "enterprises": _70, "epson": _70, "equipment": _70, "ericsson": _70, "erni": _70, "esq": _70, "estate": _70, "eurovision": _70, "eus": _70, "events": _70, "exchange": _70, "expert": _70, "exposed": _70, "express": _70, "extraspace": _70, "fage": _70, "fail": _70, "fairwinds": _70, "faith": _70, "family": _70, "fan": _70, "fans": _70, "farm": _70, "farmers": _70, "fashion": _70, "fast": _70, "fedex": _70, "feedback": _70, "ferrari": _70, "ferrero": _70, "fidelity": _70, "fido": _70, "film": _70, "final": _70, "finance": _70, "financial": _70, "fire": _70, "firestone": _70, "firmdale": _70, "fish": _70, "fishing": _70, "fit": _70, "fitness": _70, "flickr": _70, "\ +flights": _70, "flir": _70, "florist": _70, "flowers": _70, "fly": _70, "foo": _70, "food": _70, "football": _70, "ford": _70, "forex": _70, "forsale": _70, "forum": _70, "foundation": _70, "fox": _70, "free": _70, "fresenius": _70, "frl": _70, "frogans": _70, "frontier": _70, "ftr": _70, "fujitsu": _70, "fun": _70, "fund": _70, "furniture": _70, "futbol": _70, "fyi": _70, "gal": _70, "gallery": _70, "gallo": _70, "gallup": _70, "game": _70, "games": _70, "gap": _70, "garden": _70, "gay": _70, "gbiz": _70, "gdn": _70, "gea": _70, "gent": _70, "genting": _70, "george": _70, "ggee": _70, "gift": _70, "gifts": _70, "gives": _70, "giving": _70, "glass": _70, "gle": _70, "global": _70, "globo": _70, "gmail": _70, "gmbh": _70, "gmo": _70, "gmx": _70, "godaddy": _70, "gold": _70, "goldpoint": _70, "golf": _70, "goo": _70, "goodyear": _70, "goog": _70, "google": _70, "gop": _70, "got": _70, "grainger": _70, "graphics": _70, "gratis": _70, "green": _70, "gripe": _70, "grocery": _70, "group": _70, + "gucci": _70, "guge": _70, "guide": _70, "guitars": _70, "guru": _70, "hair": _70, "hamburg": _70, "hangout": _70, "haus": _70, "hbo": _70, "hdfc": _70, "hdfcbank": _70, "health": _70, "healthcare": _70, "help": _70, "helsinki": _70, "here": _70, "hermes": _70, "hiphop": _70, "hisamitsu": _70, "hitachi": _70, "hiv": _70, "hkt": _70, "hockey": _70, "holdings": _70, "holiday": _70, "homedepot": _70, "homegoods": _70, "homes": _70, "homesense": _70, "honda": _70, "horse": _70, "hospital": _70, "host": _70, "hosting": _70, "hot": _70, "hotel": _70, "hotels": _70, "hotmail": _70, "house": _70, "how": _70, "hsbc": _70, "hughes": _70, "hyatt": _70, "hyundai": _70, "ibm": _70, "icbc": _70, "ice": _70, "icu": _70, "ieee": _70, "ifm": _70, "ikano": _70, "imamat": _70, "imdb": _70, "immo": _70, "immobilien": _70, "inc": _70, "industries": _70, "infiniti": _70, "ing": _70, "ink": _70, "institute": _70, "insurance": _70, "insure": _70, "international": _70, "intuit": _70, "investments": _70, "\ +ipiranga": _70, "irish": _70, "ismaili": _70, "ist": _70, "istanbul": _70, "itau": _70, "itv": _70, "jaguar": _70, "java": _70, "jcb": _70, "jeep": _70, "jetzt": _70, "jewelry": _70, "jio": _70, "jll": _70, "jmp": _70, "jnj": _70, "joburg": _70, "jot": _70, "joy": _70, "jpmorgan": _70, "jprs": _70, "juegos": _70, "juniper": _70, "kaufen": _70, "kddi": _70, "kerryhotels": _70, "kerryproperties": _70, "kfh": _70, "kia": _70, "kids": _70, "kim": _70, "kindle": _70, "kitchen": _70, "kiwi": _70, "koeln": _70, "komatsu": _70, "kosher": _70, "kpmg": _70, "kpn": _70, "krd": _70, "kred": _70, "kuokgroup": _70, "kyoto": _70, "lacaixa": _70, "lamborghini": _70, "lamer": _70, "land": _70, "landrover": _70, "lanxess": _70, "lasalle": _70, "lat": _70, "latino": _70, "latrobe": _70, "law": _70, "lawyer": _70, "lds": _70, "lease": _70, "leclerc": _70, "lefrak": _70, "legal": _70, "lego": _70, "lexus": _70, "lgbt": _70, "lidl": _70, "life": _70, "lifeinsurance": _70, "lifestyle": _70, "lighting": _70, "\ +like": _70, "lilly": _70, "limited": _70, "limo": _70, "lincoln": _70, "link": _70, "live": _70, "living": _70, "llc": _70, "llp": _70, "loan": _70, "loans": _70, "locker": _70, "locus": _70, "lol": _70, "london": _70, "lotte": _70, "lotto": _70, "love": _70, "lpl": _70, "lplfinancial": _70, "ltd": _70, "ltda": _70, "lundbeck": _70, "luxe": _70, "luxury": _70, "madrid": _70, "maif": _70, "maison": _70, "makeup": _70, "man": _70, "management": _70, "mango": _70, "map": _70, "market": _70, "marketing": _70, "markets": _70, "marriott": _70, "marshalls": _70, "mattel": _70, "mba": _70, "mckinsey": _70, "med": _70, "media": _70, "meet": _70, "melbourne": _70, "meme": _70, "memorial": _70, "men": _70, "menu": _70, "merck": _70, "merckmsd": _70, "miami": _70, "microsoft": _70, "mini": _70, "mint": _70, "mit": _70, "mitsubishi": _70, "mlb": _70, "mls": _70, "mma": _70, "mobile": _70, "moda": _70, "moe": _70, "moi": _70, "mom": _70, "monash": _70, "money": _70, "monster": _70, "mormon": _70, "m\ +ortgage": _70, "moscow": _70, "moto": _70, "motorcycles": _70, "mov": _70, "movie": _70, "msd": _70, "mtn": _70, "mtr": _70, "music": _70, "nab": _70, "nagoya": _70, "navy": _70, "nba": _70, "nec": _70, "netbank": _70, "netflix": _70, "network": _70, "neustar": _70, "new": _70, "news": _70, "next": _70, "nextdirect": _70, "nexus": _70, "nfl": _70, "ngo": _70, "nhk": _70, "nico": _70, "nike": _70, "nikon": _70, "ninja": _70, "nissan": _70, "nissay": _70, "nokia": _70, "norton": _70, "now": _70, "nowruz": _70, "nowtv": _70, "nra": _70, "nrw": _70, "ntt": _70, "nyc": _70, "obi": _70, "observer": _70, "office": _70, "okinawa": _70, "olayan": _70, "olayangroup": _70, "ollo": _70, "omega": _70, "one": _70, "ong": _70, "onl": _70, "online": _70, "ooo": _70, "open": _70, "oracle": _70, "orange": _70, "organic": _70, "origins": _70, "osaka": _70, "otsuka": _70, "ott": _70, "ovh": _70, "page": _70, "panasonic": _70, "paris": _70, "pars": _70, "partners": _70, "parts": _70, "party": _70, "pay": _70, + "pccw": _70, "pet": _70, "pfizer": _70, "pharmacy": _70, "phd": _70, "philips": _70, "phone": _70, "photo": _70, "photography": _70, "photos": _70, "physio": _70, "pics": _70, "pictet": _70, "pictures": _70, "pid": _70, "pin": _70, "ping": _70, "pink": _70, "pioneer": _70, "pizza": _70, "place": _70, "play": _70, "playstation": _70, "plumbing": _70, "plus": _70, "pnc": _70, "pohl": _70, "poker": _70, "politie": _70, "porn": _70, "praxi": _70, "press": _70, "prime": _70, "prod": _70, "productions": _70, "prof": _70, "progressive": _70, "promo": _70, "properties": _70, "property": _70, "protection": _70, "pru": _70, "prudential": _70, "pub": _70, "pwc": _70, "qpon": _70, "quebec": _70, "quest": _70, "racing": _70, "radio": _70, "read": _70, "realestate": _70, "realtor": _70, "realty": _70, "recipes": _70, "red": _70, "redumbrella": _70, "rehab": _70, "reise": _70, "reisen": _70, "reit": _70, "reliance": _70, "ren": _70, "rent": _70, "rentals": _70, "repair": _70, "report": _70, "re\ +publican": _70, "rest": _70, "restaurant": _70, "review": _70, "reviews": _70, "rexroth": _70, "rich": _70, "richardli": _70, "ricoh": _70, "ril": _70, "rio": _70, "rip": _70, "rocks": _70, "rodeo": _70, "rogers": _70, "room": _70, "rsvp": _70, "rugby": _70, "ruhr": _70, "run": _70, "rwe": _70, "ryukyu": _70, "saarland": _70, "safe": _70, "safety": _70, "sakura": _70, "sale": _70, "salon": _70, "samsclub": _70, "samsung": _70, "sandvik": _70, "sandvikcoromant": _70, "sanofi": _70, "sap": _70, "sarl": _70, "sas": _70, "save": _70, "saxo": _70, "sbi": _70, "sbs": _70, "scb": _70, "schaeffler": _70, "schmidt": _70, "scholarships": _70, "school": _70, "schule": _70, "schwarz": _70, "science": _70, "scot": _70, "search": _70, "seat": _70, "secure": _70, "security": _70, "seek": _70, "select": _70, "sener": _70, "services": _70, "seven": _70, "sew": _70, "sex": _70, "sexy": _70, "sfr": _70, "shangrila": _70, "sharp": _70, "shell": _70, "shia": _70, "shiksha": _70, "shoes": _70, "shop": _70, "\ +shopping": _70, "shouji": _70, "show": _70, "silk": _70, "sina": _70, "singles": _70, "site": _70, "ski": _70, "skin": _70, "sky": _70, "skype": _70, "sling": _70, "smart": _70, "smile": _70, "sncf": _70, "soccer": _70, "social": _70, "softbank": _70, "software": _70, "sohu": _70, "solar": _70, "solutions": _70, "song": _70, "sony": _70, "soy": _70, "spa": _70, "space": _70, "sport": _70, "spot": _70, "srl": _70, "stada": _70, "staples": _70, "star": _70, "statebank": _70, "statefarm": _70, "stc": _70, "stcgroup": _70, "stockholm": _70, "storage": _70, "store": _70, "stream": _70, "studio": _70, "study": _70, "style": _70, "sucks": _70, "supplies": _70, "supply": _70, "support": _70, "surf": _70, "surgery": _70, "suzuki": _70, "swatch": _70, "swiss": _70, "sydney": _70, "systems": _70, "tab": _70, "taipei": _70, "talk": _70, "taobao": _70, "target": _70, "tatamotors": _70, "tatar": _70, "tattoo": _70, "tax": _70, "taxi": _70, "tci": _70, "tdk": _70, "team": _70, "tech": _70, "technolog\ +y": _70, "temasek": _70, "tennis": _70, "teva": _70, "thd": _70, "theater": _70, "theatre": _70, "tiaa": _70, "tickets": _70, "tienda": _70, "tips": _70, "tires": _70, "tirol": _70, "tjmaxx": _70, "tjx": _70, "tkmaxx": _70, "tmall": _70, "today": _70, "tokyo": _70, "tools": _70, "top": _70, "toray": _70, "toshiba": _70, "total": _70, "tours": _70, "town": _70, "toyota": _70, "toys": _70, "trade": _70, "trading": _70, "training": _70, "travel": _70, "travelers": _70, "travelersinsurance": _70, "trust": _70, "trv": _70, "tube": _70, "tui": _70, "tunes": _70, "tushu": _70, "tvs": _70, "ubank": _70, "ubs": _70, "unicom": _70, "university": _70, "uno": _70, "uol": _70, "ups": _70, "vacations": _70, "vana": _70, "vanguard": _70, "vegas": _70, "ventures": _70, "verisign": _70, "versicherung": _70, "vet": _70, "viajes": _70, "video": _70, "vig": _70, "viking": _70, "villas": _70, "vin": _70, "vip": _70, "virgin": _70, "visa": _70, "vision": _70, "viva": _70, "vivo": _70, "vlaanderen": _70, "vo\ +dka": _70, "volvo": _70, "vote": _70, "voting": _70, "voto": _70, "voyage": _70, "wales": _70, "walmart": _70, "walter": _70, "wang": _70, "wanggou": _70, "watch": _70, "watches": _70, "weather": _70, "weatherchannel": _70, "webcam": _70, "weber": _70, "website": _70, "wed": _70, "wedding": _70, "weibo": _70, "weir": _70, "whoswho": _70, "wien": _70, "wiki": _70, "williamhill": _70, "win": _70, "windows": _70, "wine": _70, "winners": _70, "wme": _70, "wolterskluwer": _70, "woodside": _70, "work": _70, "works": _70, "world": _70, "wow": _70, "wtc": _70, "wtf": _70, "xbox": _70, "xerox": _70, "xihuan": _70, "xin": _70, "xn--11b4c3d": _70, "कॉम": _70, "xn--1ck2e1b": _70, "セール": _70, "xn--1qqw23a": _70, "佛山": _70, "xn--30rr7y": _70, "慈善": _70, "xn--3bst00m": _70, "集团": _70, "xn--3ds443g": _70, "在线": _70, "xn--3pxu8k": _70, "点看": _70, "xn--42c2d9a": _70, "คอม": _70, "xn--45q11c": _70, "八卦": _70, "xn--4gbrim": _70, "موقع": _70, "xn--55qw42g": _70, + "公益": _70, "xn--55qx5d": _70, "公司": _70, "xn--5su34j936bgsg": _70, "香格里拉": _70, "xn--5tzm5g": _70, "网站": _70, "xn--6frz82g": _70, "移动": _70, "xn--6qq986b3xl": _70, "我爱你": _70, "xn--80adxhks": _70, "москва": _70, "xn--80aqecdr1a": _70, "католик": _70, "xn--80asehdb": _70, "онлайн": _70, "xn--80aswg": _70, "сайт": _70, "xn--8y0a063a": _70, "联通": _70, "xn--9dbq2a": _70, "קום": _70, "xn--9et52u": _70, "时尚": _70, "xn--9krt00a": _70, "微博": _70, "xn--b4w605ferd": _70, "淡马锡": _70, "xn--bck1b9a5dre4c": _70, "ファッション": _70, "xn--c1avg": _70, "орг": _70, "xn--c2br7g": _70, "नेट": _70, "xn--cck2b3b": _70, "ストア": _70, "xn--cckwcxetd": _70, "アマゾン": _70, "xn--cg4bki": _70, "삼성": _70, "xn--czr694b": _70, "商标": _70, "xn--czrs0t": _70, "商店": _70, "xn--czru2d": _70, "商城": _70, "xn--d1acj3b": _70, "дети": _70, "xn--eckvdtc9d": _70, "ポイント": _70, "xn--efvy88h": _70, "\ +新闻": _70, "xn--fct429k": _70, "家電": _70, "xn--fhbei": _70, "كوم": _70, "xn--fiq228c5hs": _70, "中文网": _70, "xn--fiq64b": _70, "中信": _70, "xn--fjq720a": _70, "娱乐": _70, "xn--flw351e": _70, "谷歌": _70, "xn--fzys8d69uvgm": _70, "電訊盈科": _70, "xn--g2xx48c": _70, "购物": _70, "xn--gckr3f0f": _70, "クラウド": _70, "xn--gk3at1e": _70, "通販": _70, "xn--hxt814e": _70, "网店": _70, "xn--i1b6b1a6a2e": _70, "संगठन": _70, "xn--imr513n": _70, "餐厅": _70, "xn--io0a7i": _70, "网络": _70, "xn--j1aef": _70, "ком": _70, "xn--jlq480n2rg": _70, "亚马逊": _70, "xn--jvr189m": _70, "食品": _70, "xn--kcrx77d1x4a": _70, "飞利浦": _70, "xn--kput3i": _70, "手机": _70, "xn--mgba3a3ejt": _70, "ارامكو": _70, "xn--mgba7c0bbn0a": _70, "العليان": _70, "xn--mgbab2bd": _70, "بازار": _70, "xn--mgbca7dzdo": _70, "ابوظبي": _70, "xn--mgbi4ecexp": _70, "كاثوليك": _70, "xn--mgbt3dhd": _70, "همراه": _70, "xn--mk1bu44c": _70, + "닷컴": _70, "xn--mxtq1m": _70, "政府": _70, "xn--ngbc5azd": _70, "شبكة": _70, "xn--ngbe9e0a": _70, "بيتك": _70, "xn--ngbrx": _70, "عرب": _70, "xn--nqv7f": _70, "机构": _70, "xn--nqv7fs00ema": _70, "组织机构": _70, "xn--nyqy26a": _70, "健康": _70, "xn--otu796d": _70, "招聘": _70, "xn--p1acf": _70, "рус": _70, "xn--pssy2u": _70, "大拿": _70, "xn--q9jyb4c": _70, "みんな": _70, "xn--qcka1pmc": _70, "グーグル": _70, "xn--rhqv96g": _70, "世界": _70, "xn--rovu88b": _70, "書籍": _70, "xn--ses554g": _70, "网址": _70, "xn--t60b56a": _70, "닷넷": _70, "xn--tckwe": _70, "コム": _70, "xn--tiq49xqyj": _70, "天主教": _70, "xn--unup4y": _70, "游戏": _70, "xn--vermgensberater-ctb": _70, "vermögensberater": _70, "xn--vermgensberatung-pwb": _70, "vermögensberatung": _70, "xn--vhquv": _70, "企业": _70, "xn--vuq861b": _70, "信息": _70, "xn--w4r85el8fhu5dnra": _70, "嘉里大酒店": _70, "xn--w4rs40l": _70, "嘉里": _70, "xn--xhq521b": _70, "\ +广东": _70, "xn--zfr164b": _70, "政务": _70, "xyz": _70, "yachts": _70, "yahoo": _70, "yamaxun": _70, "yandex": _70, "yodobashi": _70, "yoga": _70, "yokohama": _70, "you": _70, "youtube": _70, "yun": _70, "zappos": _70, "zara": _70, "zero": _70, "zip": _70, "zone": _70, "zuerich": _70 }]; + return rules2; + })(); + function lookupInTrie(parts, trie, index) { + let result = null; + let node = trie; + while (node !== void 0) { + if (node[0] === 1) { + result = { + index: index + 1 + }; + } + if (index === -1) { + break; + } + const succ = node[1]; + node = Object.prototype.hasOwnProperty.call(succ, parts[index]) ? succ[parts[index]] : succ["*"]; + index -= 1; + } + return result; + } + __name(lookupInTrie, "lookupInTrie"); + function suffixLookup(hostname, options, out) { + var _a3; + if (fastPathLookup(hostname, options, out)) { + return; + } + const hostnameParts = hostname.split("."); + const exceptionMatch = lookupInTrie(hostnameParts, exceptions, hostnameParts.length - 1); + if (exceptionMatch !== null) { + out.publicSuffix = hostnameParts.slice(exceptionMatch.index + 1).join("."); + return; + } + const rulesMatch = lookupInTrie(hostnameParts, rules, hostnameParts.length - 1); + if (rulesMatch !== null) { + out.publicSuffix = hostnameParts.slice(rulesMatch.index).join("."); + return; + } + out.publicSuffix = (_a3 = hostnameParts[hostnameParts.length - 1]) !== null && _a3 !== void 0 ? _a3 : null; + } + __name(suffixLookup, "suffixLookup"); + var RESULT = getEmptyResult(); + function parse(url, options = {}) { + return parseImpl(url, 5, suffixLookup, options, getEmptyResult()); + } + __name(parse, "parse"); + function getHostname(url, options = {}) { + resetResult(RESULT); + return parseImpl(url, 0, suffixLookup, options, RESULT).hostname; + } + __name(getHostname, "getHostname"); + function getPublicSuffix(url, options = {}) { + resetResult(RESULT); + return parseImpl(url, 2, suffixLookup, options, RESULT).publicSuffix; + } + __name(getPublicSuffix, "getPublicSuffix"); + function getDomain2(url, options = {}) { + resetResult(RESULT); + return parseImpl(url, 3, suffixLookup, options, RESULT).domain; + } + __name(getDomain2, "getDomain"); + function getSubdomain(url, options = {}) { + resetResult(RESULT); + return parseImpl(url, 4, suffixLookup, options, RESULT).subdomain; + } + __name(getSubdomain, "getSubdomain"); + function getDomainWithoutSuffix(url, options = {}) { + resetResult(RESULT); + return parseImpl(url, 5, suffixLookup, options, RESULT).domainWithoutSuffix; + } + __name(getDomainWithoutSuffix, "getDomainWithoutSuffix"); + exports2.getDomain = getDomain2; + exports2.getDomainWithoutSuffix = getDomainWithoutSuffix; + exports2.getHostname = getHostname; + exports2.getPublicSuffix = getPublicSuffix; + exports2.getSubdomain = getSubdomain; + exports2.parse = parse; + } +}); + +// core/lib/lh-error.js +var UIStrings20, str_, LHERROR_SENTINEL, ERROR_SENTINEL, LighthouseError, ERRORS; +var init_lh_error = __esm({ + "core/lib/lh-error.js"() { + "use strict"; + init_process_global(); + init_i18n(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + UIStrings20 = { + /** + * @description Error message explaining that the Lighthouse run was not able to collect screenshots through Chrome. + * @example {NO_SPEEDLINE_FRAMES} errorCode + * */ + didntCollectScreenshots: `Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse. ({errorCode})`, + /** + * @description Error message explaining that the performance trace was not able to be recorded for the Lighthouse run. + * @example {NO_TRACING_STARTED} errorCode + * */ + badTraceRecording: "Something went wrong with recording the trace over your page load. Please run Lighthouse again. ({errorCode})", + /** + * @description Error message explaining that the First Contentful Paint metric was not seen during the page load. + * @example {NO_FCP} errorCode + * */ + noFcp: "The page did not paint any content. Please ensure you keep the browser window in the foreground during the load and try again. ({errorCode})", + /** + * @description Error message explaining that the Largest Contentful Paint metric was not seen during the page load. + * @example {NO_LCP} errorCode + * */ + noLcp: "The page did not display content that qualifies as a Largest Contentful Paint (LCP). Ensure the page has a valid LCP element and then try again. ({errorCode})", + /** + * @description Error message explaining that the page loaded too slowly to perform a Lighthouse run. + * @example {NO_TTI_CPU_IDLE_PERIOD} errorCode + * */ + pageLoadTookTooLong: "Your page took too long to load. Please follow the opportunities in the report to reduce your page load time, and then try re-running Lighthouse. ({errorCode})", + /** Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. */ + pageLoadFailed: "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests.", + /** + * @description Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. + * @example {404} statusCode + * */ + pageLoadFailedWithStatusCode: "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Status code: {statusCode})", + /** + * @description Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. + * @example {FAILED_DOCUMENT_REQUEST} errorDetails + * */ + pageLoadFailedWithDetails: "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Details: {errorDetails})", + /** + * @description Error message explaining that the security certificate of the page Lighthouse observed was invalid, so the URL cannot be accessed. securityMessages will be replaced with one or more strings from the browser explaining what was insecure about the page load. + * @example {net::ERR_CERT_DATE_INVALID} securityMessages + * */ + pageLoadFailedInsecure: "The URL you have provided does not have a valid security certificate. {securityMessages}", + /** Error message explaining that Chrome prevented the page from loading and displayed an interstitial screen instead, so the URL cannot be accessed. */ + pageLoadFailedInterstitial: "Chrome prevented page load with an interstitial. Make sure you are testing the correct URL and that the server is properly responding to all requests.", + /** Error message explaining that Chrome has encountered an error during the Lighthouse run, and that Chrome should be restarted. */ + internalChromeError: "An internal Chrome error occurred. Please restart Chrome and try re-running Lighthouse.", + /** Error message explaining that fetching the resources of the webpage has taken longer than the maximum time. */ + requestContentTimeout: "Fetching resource content has exceeded the allotted time", + /** + * @description Error message explaining that the webpage is non-HTML, so audits are ill-defined. + * @example {application/xml} mimeType + * */ + notHtml: "The page provided is not HTML (served as MIME type {mimeType}).", + /** Error message explaining that the provided URL Lighthouse points to is not valid, and cannot be loaded. */ + urlInvalid: "The URL you have provided appears to be invalid.", + /** + * @description Error message explaining that the Chrome Devtools protocol has exceeded the maximum timeout allowed. + * @example {Network.enable} protocolMethod + * */ + protocolTimeout: "Waiting for DevTools protocol response has exceeded the allotted time. (Method: {protocolMethod})", + /** Error message explaining that the requested page could not be resolved by the DNS server. */ + dnsFailure: "DNS servers could not resolve the provided domain.", + /** Error message explaining that Lighthouse couldn't complete because the page has stopped responding to its instructions. */ + pageLoadFailedHung: "Lighthouse was unable to reliably load the URL you requested because the page stopped responding.", + /** Error message explaining that Lighthouse timed out while waiting for the initial connection to the Chrome Devtools protocol. */ + criTimeout: "Timeout waiting for initial Debugger Protocol connection.", + /** + * @description Error message explaining that a resource that was required for testing was never collected. "artifactName" will be replaced with the name of the resource that wasn't collected. + * @example {MainDocumentContent} artifactName + * */ + missingRequiredArtifact: "Required {artifactName} gatherer did not run.", + /** + * @description Error message explaining that there was an error while trying to collect a resource that was required for testing. "artifactName" will be replaced with the name of the resource that wasn't collected; "errorMessage" will be replaced with a string description of the error that occurred. + * @example {MainDocumentContent} artifactName + * @example {Could not find main document} errorMessage + * */ + erroredRequiredArtifact: "Required {artifactName} gatherer encountered an error: {errorMessage}", + /** + * @description Error message explaining that a feature is unavailable due to an old version of Chrome. "featureName" will be replaced by the name of the feature which is not supported. + * @example {Largest Contentful Paint} featureName + * */ + oldChromeDoesNotSupportFeature: "This version of Chrome is too old to support '{featureName}'. Use a newer version to see full results.", + /** Error message explaining that the browser tab that Lighthouse is inspecting has crashed. */ + targetCrashed: "Browser tab has unexpectedly crashed." + }; + str_ = createIcuMessageFn({ url: "core/lib/lh-error.js" }.url, UIStrings20); + LHERROR_SENTINEL = "__LighthouseErrorSentinel"; + ERROR_SENTINEL = "__ErrorSentinel"; + LighthouseError = class _LighthouseError extends Error { + static { + __name(this, "LighthouseError"); + } + /** + * @param {LighthouseErrorDefinition} errorDefinition + * @param {Record=} properties + * @param {LHErrorOptions=} options + */ + constructor(errorDefinition, properties, options) { + super(errorDefinition.code, options); + this.name = "LighthouseError"; + this.code = errorDefinition.code; + this.friendlyMessage = str_(errorDefinition.message, { errorCode: this.code, ...properties }); + this.lhrRuntimeError = !!errorDefinition.lhrRuntimeError; + if (properties) Object.assign(this, properties); + Error.captureStackTrace(this, _LighthouseError); + } + /** + * @param {string} method + * @param {{message: string, data?: string|undefined}} protocolError + * @return {Error|LighthouseError} + */ + static fromProtocolMessage(method, protocolError) { + const matchedErrorDefinition = Object.values(_LighthouseError.errors).filter((e) => e.pattern).find((e) => e.pattern && e.pattern.test(protocolError.message)); + if (matchedErrorDefinition) { + return new _LighthouseError(matchedErrorDefinition); + } + let errMsg = `(${method}): ${protocolError.message}`; + if (protocolError.data) errMsg += ` (${protocolError.data})`; + const error = new Error(`Protocol error ${errMsg}`); + return Object.assign(error, { protocolMethod: method, protocolError: protocolError.message }); + } + /** + * A JSON.stringify replacer to serialize LighthouseErrors and (as a fallback) Errors. + * Returns a simplified version of the error object that can be reconstituted + * as a copy of the original error at parse time. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter + * @param {Error|LighthouseError} err + * @return {SerializedBaseError|SerializedLighthouseError} + */ + static stringifyReplacer(err) { + if (err instanceof _LighthouseError) { + const { name, code, message, friendlyMessage, lhrRuntimeError, stack, cause, ...properties } = err; + return { + sentinel: LHERROR_SENTINEL, + code, + stack, + cause, + properties: ( + /** @type {{ [p: string]: string | undefined }} */ + properties + ) + }; + } + if (err instanceof Error) { + const { message, stack, cause } = err; + const code = err.code; + return { + sentinel: ERROR_SENTINEL, + message, + code, + stack, + cause + }; + } + throw new Error("Invalid value for LighthouseError stringification"); + } + /** + * A JSON.parse reviver. If any value passed in is a serialized Error or + * LighthouseError, the error is recreated as the original object. Otherwise, the + * value is passed through unchanged. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_the_reviver_parameter + * @param {string} key + * @param {any} possibleError + * @return {any} + */ + static parseReviver(key, possibleError) { + if (typeof possibleError === "object" && possibleError !== null) { + if (possibleError.sentinel === LHERROR_SENTINEL) { + const { code, stack, cause, properties } = ( + /** @type {SerializedLighthouseError} */ + possibleError + ); + const errorDefinition = _LighthouseError.errors[ + /** @type {keyof typeof ERRORS} */ + code + ]; + const lhError = new _LighthouseError(errorDefinition, properties, { cause }); + lhError.stack = stack; + return lhError; + } + if (possibleError.sentinel === ERROR_SENTINEL) { + const { message, code, stack, cause } = ( + /** @type {SerializedBaseError} */ + possibleError + ); + const opts = cause ? { cause } : void 0; + const error = new Error(message, opts); + Object.assign(error, { code, stack }); + return error; + } + } + return possibleError; + } + }; + ERRORS = { + // Screenshot/speedline errors + NO_SPEEDLINE_FRAMES: { + code: "NO_SPEEDLINE_FRAMES", + message: UIStrings20.didntCollectScreenshots, + lhrRuntimeError: true + }, + SPEEDINDEX_OF_ZERO: { + code: "SPEEDINDEX_OF_ZERO", + message: UIStrings20.didntCollectScreenshots, + lhrRuntimeError: true + }, + NO_SCREENSHOTS: { + code: "NO_SCREENSHOTS", + message: UIStrings20.didntCollectScreenshots, + lhrRuntimeError: true + }, + INVALID_SPEEDLINE: { + code: "INVALID_SPEEDLINE", + message: UIStrings20.didntCollectScreenshots, + lhrRuntimeError: true + }, + // Trace parsing errors + NO_TRACING_STARTED: { + code: "NO_TRACING_STARTED", + message: UIStrings20.badTraceRecording, + lhrRuntimeError: true + }, + NO_RESOURCE_REQUEST: { + code: "NO_RESOURCE_REQUEST", + message: UIStrings20.badTraceRecording, + lhrRuntimeError: true + }, + NO_NAVSTART: { + code: "NO_NAVSTART", + message: UIStrings20.badTraceRecording, + lhrRuntimeError: true + }, + NO_FCP: { + code: "NO_FCP", + message: UIStrings20.noFcp, + lhrRuntimeError: true + }, + NO_DCL: { + code: "NO_DCL", + message: UIStrings20.badTraceRecording, + lhrRuntimeError: true + }, + NO_FMP: { + code: "NO_FMP", + message: UIStrings20.badTraceRecording + }, + NO_LCP: { + code: "NO_LCP", + message: UIStrings20.noLcp + }, + NO_LCP_ALL_FRAMES: { + code: "NO_LCP_ALL_FRAMES", + message: UIStrings20.noLcp + }, + UNSUPPORTED_OLD_CHROME: { + code: "UNSUPPORTED_OLD_CHROME", + message: UIStrings20.oldChromeDoesNotSupportFeature + }, + // TTI calculation failures + NO_TTI_CPU_IDLE_PERIOD: { code: "NO_TTI_CPU_IDLE_PERIOD", message: UIStrings20.pageLoadTookTooLong }, + NO_TTI_NETWORK_IDLE_PERIOD: { + code: "NO_TTI_NETWORK_IDLE_PERIOD", + message: UIStrings20.pageLoadTookTooLong + }, + // Page load failures + NO_DOCUMENT_REQUEST: { + code: "NO_DOCUMENT_REQUEST", + message: UIStrings20.pageLoadFailed, + lhrRuntimeError: true + }, + /* Used when DevTools reports loading failed. Usually an internal (Chrome) issue. + * Requries an additional `errorDetails` field for translation. + */ + FAILED_DOCUMENT_REQUEST: { + code: "FAILED_DOCUMENT_REQUEST", + message: UIStrings20.pageLoadFailedWithDetails, + lhrRuntimeError: true + }, + /* Used when status code is 4xx or 5xx. + * Requires an additional `statusCode` field for translation. + */ + ERRORED_DOCUMENT_REQUEST: { + code: "ERRORED_DOCUMENT_REQUEST", + message: UIStrings20.pageLoadFailedWithStatusCode, + lhrRuntimeError: true + }, + /* Used when security error prevents page load. + * Requires an additional `securityMessages` field for translation. + */ + INSECURE_DOCUMENT_REQUEST: { + code: "INSECURE_DOCUMENT_REQUEST", + message: UIStrings20.pageLoadFailedInsecure, + lhrRuntimeError: true + }, + /* Used when any Chrome interstitial error prevents page load. + */ + CHROME_INTERSTITIAL_ERROR: { + code: "CHROME_INTERSTITIAL_ERROR", + message: UIStrings20.pageLoadFailedInterstitial, + lhrRuntimeError: true + }, + /* Used when the page stopped responding and did not finish loading. */ + PAGE_HUNG: { + code: "PAGE_HUNG", + message: UIStrings20.pageLoadFailedHung, + lhrRuntimeError: true + }, + /* Used when the page is non-HTML. */ + NOT_HTML: { + code: "NOT_HTML", + message: UIStrings20.notHtml, + lhrRuntimeError: true + }, + // Protocol internal failures + TRACING_ALREADY_STARTED: { + code: "TRACING_ALREADY_STARTED", + message: UIStrings20.internalChromeError, + pattern: /Tracing.*started/, + lhrRuntimeError: true + }, + PARSING_PROBLEM: { + code: "PARSING_PROBLEM", + message: UIStrings20.internalChromeError, + pattern: /Parsing problem/, + lhrRuntimeError: true + }, + READ_FAILED: { + code: "READ_FAILED", + message: UIStrings20.internalChromeError, + pattern: /Read failed/, + lhrRuntimeError: true + }, + // URL parsing failures + INVALID_URL: { + code: "INVALID_URL", + message: UIStrings20.urlInvalid + }, + /* Protocol timeout failures + * Requires an additional `protocolMethod` field for translation. + */ + PROTOCOL_TIMEOUT: { + code: "PROTOCOL_TIMEOUT", + message: UIStrings20.protocolTimeout, + lhrRuntimeError: true + }, + // DNS failure on main document (no resolution, timed out, etc) + DNS_FAILURE: { + code: "DNS_FAILURE", + message: UIStrings20.dnsFailure, + lhrRuntimeError: true + }, + /** A timeout in the initial connection to the debugger protocol. */ + CRI_TIMEOUT: { + code: "CRI_TIMEOUT", + message: UIStrings20.criTimeout, + lhrRuntimeError: true + }, + /** + * Error internal to Runner used when an artifact required for an audit is missing. + * Requires an additional `artifactName` field for translation. + */ + MISSING_REQUIRED_ARTIFACT: { + code: "MISSING_REQUIRED_ARTIFACT", + message: UIStrings20.missingRequiredArtifact + }, + /** + * Error internal to Runner used when an artifact required for an audit was an error. + * Requires additional `artifactName` and `errorMessage` fields for translation. + */ + ERRORED_REQUIRED_ARTIFACT: { + code: "ERRORED_REQUIRED_ARTIFACT", + message: UIStrings20.erroredRequiredArtifact + }, + /** The page has crashed and will no longer respond to 99% of CDP commmands. */ + TARGET_CRASHED: { + code: "TARGET_CRASHED", + message: UIStrings20.targetCrashed, + lhrRuntimeError: true + } + // Hey! When adding a new error type, update lighthouse-result.proto too. + // Only necessary for runtime errors, which come from artifacts or pageLoadErrors. + }; + LighthouseError.errors = ERRORS; + LighthouseError.NO_ERROR = "NO_ERROR"; + LighthouseError.UNKNOWN_ERROR = "UNKNOWN_ERROR"; + } +}); + +// core/lib/url-utils.js +function rewriteChromeInternalUrl(url) { + if (!url || !url.startsWith("chrome://")) return url; + if (url.endsWith("/")) url = url.replace(/\/$/, ""); + return url.replace(/^chrome:\/\/chrome\//, "chrome://"); +} +var import_tldts_icann, allowedProtocols, SECURE_SCHEMES, SECURE_LOCALHOST_DOMAINS2, NON_NETWORK_SCHEMES3, UrlUtils2, url_utils_default; +var init_url_utils = __esm({ + "core/lib/url-utils.js"() { + "use strict"; + init_process_global(); + import_tldts_icann = __toESM(require_cjs(), 1); + init_util(); + init_lh_error(); + /** + * @license + * Copyright 2016 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + allowedProtocols = [ + "https:", + "http:", + "chrome:", + "chrome-extension:" + ]; + SECURE_SCHEMES = [ + "data", + "https", + "wss", + "blob", + "chrome", + "chrome-extension", + "about", + "filesystem" + ]; + SECURE_LOCALHOST_DOMAINS2 = ["localhost", "127.0.0.1"]; + NON_NETWORK_SCHEMES3 = [ + "blob", + // @see https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL + "data", + // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs + "intent", + // @see https://developer.chrome.com/docs/multidevice/android/intents/ + "file", + // @see https://en.wikipedia.org/wiki/File_URI_scheme + "filesystem", + // @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystem + "chrome-extension" + ]; + __name(rewriteChromeInternalUrl, "rewriteChromeInternalUrl"); + UrlUtils2 = class _UrlUtils { + static { + __name(this, "UrlUtils"); + } + /** + * @param {string} url + * @return {boolean} + */ + static isValid(url) { + try { + new URL(url); + return true; + } catch (e) { + return false; + } + } + /** + * @param {string} urlA + * @param {string} urlB + * @return {boolean} + */ + static hostsMatch(urlA, urlB) { + try { + return new URL(urlA).host === new URL(urlB).host; + } catch (e) { + return false; + } + } + /** + * @param {string} urlA + * @param {string} urlB + * @return {boolean} + */ + static originsMatch(urlA, urlB) { + try { + return new URL(urlA).origin === new URL(urlB).origin; + } catch (e) { + return false; + } + } + /** + * @param {string} url + * @return {?string} + */ + static getOrigin(url) { + try { + const urlInfo = new URL(url); + if (urlInfo.protocol === "chrome-extension:") { + return Util.getChromeExtensionOrigin(url); + } + return urlInfo.host && urlInfo.origin || null; + } catch (e) { + return null; + } + } + /** + * Returns a primary domain for provided hostname (e.g. www.example.com -> example.com). + * @param {string|URL} url hostname or URL object + * @return {string} + */ + static getRootDomain(url) { + const parsedUrl = Util.createOrReturnURL(url); + return (0, import_tldts_icann.getDomain)(parsedUrl.href) || parsedUrl.hostname; + } + /** + * Check if rootDomains matches + * + * @param {string|URL} urlA + * @param {string|URL} urlB + */ + static rootDomainsMatch(urlA, urlB) { + let urlAInfo; + let urlBInfo; + try { + urlAInfo = Util.createOrReturnURL(urlA); + urlBInfo = Util.createOrReturnURL(urlB); + } catch (err) { + return false; + } + if (!urlAInfo.hostname || !urlBInfo.hostname) { + return false; + } + const urlARootDomain = _UrlUtils.getRootDomain(urlAInfo); + const urlBRootDomain = _UrlUtils.getRootDomain(urlBInfo); + return urlARootDomain === urlBRootDomain; + } + /** + * @param {string} url + * @param {{numPathParts: number, preserveQuery: boolean, preserveHost: boolean}=} options + * @return {string} + */ + static getURLDisplayName(url, options) { + return Util.getURLDisplayName(new URL(url), options); + } + /** + * Limits data URIs to 100 characters, returns all other strings untouched. + * @param {string} url + * @return {string} + */ + static elideDataURI(url) { + try { + const parsed = new URL(url); + return parsed.protocol === "data:" ? Util.truncate(url, 100) : url; + } catch (e) { + return url; + } + } + /** + * Determine if url1 equals url2, ignoring URL fragments. + * @param {string} url1 + * @param {string} url2 + * @return {boolean} + */ + static equalWithExcludedFragments(url1, url2) { + [url1, url2] = [url1, url2].map(rewriteChromeInternalUrl); + try { + const urla = new URL(url1); + urla.hash = ""; + const urlb = new URL(url2); + urlb.hash = ""; + return urla.href === urlb.href; + } catch (e) { + return false; + } + } + /** + * Determine if the url has a protocol that we're able to test + * @param {string} url + * @return {boolean} + */ + static isProtocolAllowed(url) { + try { + const parsed = new URL(url); + return allowedProtocols.includes(parsed.protocol); + } catch (e) { + return false; + } + } + /** + * Is the host localhost-enough to satisfy the "secure context" definition + * https://github.com/GoogleChrome/lighthouse/pull/11766#discussion_r582340683 + * @param {string} hostname Either a `new URL(url).hostname` or a `networkRequest.parsedUrl.host` + * @return {boolean} + */ + static isLikeLocalhost(hostname) { + return SECURE_LOCALHOST_DOMAINS2.includes(hostname) || hostname.endsWith(".localhost"); + } + /** + * @param {NetworkRequest['parsedURL']['scheme']} scheme + * @return {boolean} + */ + static isSecureScheme(scheme) { + return SECURE_SCHEMES.includes(scheme); + } + /** + * Use `NetworkRequest.isNonNetworkRequest(req)` if working with a request. + * Note: the `protocol` field from CDP can be 'h2', 'http', (not 'https'!) or it'll be url's scheme. + * https://source.chromium.org/chromium/chromium/src/+/main:content/browser/devtools/protocol/network_handler.cc;l=598-611;drc=56d4a9a9deb30be73adcee8737c73bcb2a5ab64f + * However, a `new URL(href).protocol` has a colon suffix. + * https://url.spec.whatwg.org/#dom-url-protocol + * A URL's `scheme` is specced as the `protocol` sans-colon, but isn't exposed on a URL object. + * This method can take all 3 of these string types as a parameter. + * @param {NetworkRequest['protocol'] | URL['protocol']} protocol Either a networkRequest's `protocol` per CDP or a `new URL(href).protocol` + * @return {boolean} + */ + static isNonNetworkProtocol(protocol) { + const urlScheme = protocol.includes(":") ? protocol.slice(0, protocol.indexOf(":")) : protocol; + return NON_NETWORK_SCHEMES3.includes(urlScheme); + } + /** + * @param {string} src + * @return {string|undefined} + */ + static guessMimeType(src) { + let url; + try { + url = new URL(src); + } catch { + return void 0; + } + if (url.protocol === "data:") { + const match2 = url.pathname.match(/^(image\/(png|jpeg|svg\+xml|webp|gif|avif))[;,]/); + if (!match2) return void 0; + return match2[1]; + } + const match = url.pathname.toLowerCase().match(/\.(png|jpeg|jpg|svg|webp|gif|avif)$/); + if (!match) return void 0; + const ext = match[1]; + if (ext === "svg") return "image/svg+xml"; + if (ext === "jpg") return "image/jpeg"; + return `image/${ext}`; + } + /** + * @param {string|undefined} url + * @return {string} + */ + static normalizeUrl(url) { + if (url && this.isValid(url) && this.isProtocolAllowed(url)) { + return new URL(url).href; + } else { + throw new LighthouseError(LighthouseError.errors.INVALID_URL); + } + } + }; + UrlUtils2.INVALID_URL_DEBUG_STRING = "Lighthouse was unable to determine the URL of some script executions. It's possible a Chrome extension or other eval'd code is the source."; + url_utils_default = UrlUtils2; + } +}); + +// core/lib/network-request.js +var HEADER_TCP, HEADER_SSL, HEADER_REQ, HEADER_RES, HEADER_TOTAL, HEADER_FETCHED_SIZE, HEADER_PROTOCOL_IS_H2, RESOURCE_TYPES, NetworkRequest; +var init_network_request = __esm({ + "core/lib/network-request.js"() { + "use strict"; + init_process_global(); + init_lh(); + init_lantern2(); + init_url_utils(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + HEADER_TCP = "X-TCPMs"; + HEADER_SSL = "X-SSLMs"; + HEADER_REQ = "X-RequestMs"; + HEADER_RES = "X-ResponseMs"; + HEADER_TOTAL = "X-TotalMs"; + HEADER_FETCHED_SIZE = "X-TotalFetchedSize"; + HEADER_PROTOCOL_IS_H2 = "X-ProtocolIsH2"; + RESOURCE_TYPES = { + XHR: "XHR", + Fetch: "Fetch", + EventSource: "EventSource", + Script: "Script", + Stylesheet: "Stylesheet", + Image: "Image", + Media: "Media", + Font: "Font", + Document: "Document", + TextTrack: "TextTrack", + WebSocket: "WebSocket", + Other: "Other", + Manifest: "Manifest", + SignedExchange: "SignedExchange", + Ping: "Ping", + Preflight: "Preflight", + CSPViolationReport: "CSPViolationReport", + Prefetch: "Prefetch", + FedCM: "FedCM" + }; + NetworkRequest = class _NetworkRequest { + static { + __name(this, "NetworkRequest"); + } + constructor() { + this.requestId = ""; + this.connectionId = 0; + this.connectionReused = false; + this.url = ""; + this.protocol = ""; + this.isSecure = false; + this.isValid = false; + this.parsedURL = /** @type {ParsedURL} */ + { scheme: "" }; + this.documentURL = ""; + this.rendererStartTime = -1; + this.networkRequestTime = -1; + this.responseHeadersEndTime = -1; + this.networkEndTime = -1; + this.transferSize = 0; + this.responseHeadersTransferSize = 0; + this.resourceSize = 0; + this.fromDiskCache = false; + this.fromMemoryCache = false; + this.fromPrefetchCache = false; + this.lrStatistics = void 0; + this.finished = false; + this.requestMethod = ""; + this.statusCode = -1; + this.redirectSource = void 0; + this.redirectDestination = void 0; + this.redirects = void 0; + this.failed = false; + this.localizedFailDescription = ""; + this.initiator = { type: "other" }; + this.timing = void 0; + this.resourceType = void 0; + this.mimeType = ""; + this.priority = "Low"; + this.initiatorRequest = void 0; + this.responseHeaders = []; + this.responseHeadersText = ""; + this.fetchedViaServiceWorker = false; + this.frameId = ""; + this.sessionId = void 0; + this.sessionTargetType = void 0; + this.fromWorker = false; + this.isLinkPreload = false; + } + /** + * @return {boolean} + */ + hasErrorStatusCode() { + return this.statusCode >= 400; + } + /** + * @param {NetworkRequest} initiatorRequest + */ + setInitiatorRequest(initiatorRequest) { + this.initiatorRequest = initiatorRequest; + } + /** + * @param {LH.Crdp.Network.RequestWillBeSentEvent} data + */ + onRequestWillBeSent(data31) { + this.requestId = data31.requestId; + let url; + try { + url = new URL(data31.request.url); + } catch (e) { + return; + } + this.url = data31.request.url; + this.documentURL = data31.documentURL; + this.parsedURL = { + scheme: url.protocol.split(":")[0], + // Intentional, DevTools uses different terminology + host: url.hostname, + securityOrigin: url.origin + }; + this.isSecure = url_utils_default.isSecureScheme(this.parsedURL.scheme); + this.rendererStartTime = data31.timestamp * 1e3; + this.networkRequestTime = this.rendererStartTime; + this.responseHeadersEndTime = this.rendererStartTime; + this.requestMethod = data31.request.method; + this.initiator = data31.initiator; + this.resourceType = data31.type && RESOURCE_TYPES[data31.type]; + this.priority = data31.request.initialPriority; + this.frameId = data31.frameId; + this.isLinkPreload = data31.initiator.type === "preload" || !!data31.request.isLinkPreload; + this.isValid = true; + } + onRequestServedFromCache() { + this.fromMemoryCache = true; + } + /** + * @param {LH.Crdp.Network.ResponseReceivedEvent} data + */ + onResponseReceived(data31) { + this._onResponse(data31.response, data31.timestamp, data31.type); + this._updateProtocolForLightrider(); + this.frameId = data31.frameId; + } + /** + * @param {LH.Crdp.Network.ResponseReceivedExtraInfoEvent} data + */ + onResponseReceivedExtraInfo(data31) { + this.responseHeadersText = data31.headersText || ""; + } + /** + * @param {LH.Crdp.Network.DataReceivedEvent} data + */ + onDataReceived(data31) { + this.resourceSize += data31.dataLength; + if (data31.encodedDataLength !== -1) { + this.transferSize += data31.encodedDataLength; + } + } + /** + * @param {LH.Crdp.Network.LoadingFinishedEvent} data + */ + onLoadingFinished(data31) { + if (this.finished) return; + this.finished = true; + this.networkEndTime = data31.timestamp * 1e3; + if (data31.encodedDataLength >= 0) { + this.transferSize = data31.encodedDataLength; + } + this._updateResponseHeadersEndTimeIfNecessary(); + this._updateTransferSizeForLightrider(); + this._updateTimingsForLightrider(); + } + /** + * @param {LH.Crdp.Network.LoadingFailedEvent} data + */ + onLoadingFailed(data31) { + if (this.finished) return; + this.finished = true; + this.networkEndTime = data31.timestamp * 1e3; + this.failed = true; + this.resourceType = data31.type && RESOURCE_TYPES[data31.type]; + this.localizedFailDescription = data31.errorText; + this._updateResponseHeadersEndTimeIfNecessary(); + this._updateTransferSizeForLightrider(); + this._updateTimingsForLightrider(); + } + /** + * @param {LH.Crdp.Network.ResourceChangedPriorityEvent} data + */ + onResourceChangedPriority(data31) { + this.priority = data31.newPriority; + } + /** + * @param {LH.Crdp.Network.RequestWillBeSentEvent} data + */ + onRedirectResponse(data31) { + if (!data31.redirectResponse) throw new Error("Missing redirectResponse data"); + this._onResponse(data31.redirectResponse, data31.timestamp, data31.type); + this.resourceType = void 0; + this.finished = true; + this.networkEndTime = data31.timestamp * 1e3; + this._updateResponseHeadersEndTimeIfNecessary(); + } + /** + * @param {string|undefined} sessionId + */ + setSession(sessionId) { + this.sessionId = sessionId; + } + get isOutOfProcessIframe() { + return this.sessionTargetType === "iframe"; + } + /** + * @param {LH.Crdp.Network.Response} response + * @param {number} timestamp in seconds + * @param {LH.Crdp.Network.ResponseReceivedEvent['type']=} resourceType + */ + _onResponse(response, timestamp, resourceType) { + this.url = response.url; + this.connectionId = response.connectionId; + this.connectionReused = response.connectionReused; + if (response.protocol) this.protocol = response.protocol; + this.responseTimestamp = timestamp * 1e3; + this.transferSize = response.encodedDataLength; + this.responseHeadersTransferSize = response.encodedDataLength; + if (typeof response.fromDiskCache === "boolean") this.fromDiskCache = response.fromDiskCache; + if (typeof response.fromPrefetchCache === "boolean") { + this.fromPrefetchCache = response.fromPrefetchCache; + } + this.statusCode = response.status; + this.timing = response.timing; + if (resourceType) this.resourceType = RESOURCE_TYPES[resourceType]; + this.mimeType = response.mimeType; + this.responseHeaders = _NetworkRequest._headersDictToHeadersArray(response.headers); + this.fetchedViaServiceWorker = !!response.fromServiceWorker; + if (this.fromMemoryCache) this.timing = void 0; + if (this.timing) this._recomputeTimesWithResourceTiming(this.timing); + } + /** + * Resolve differences between conflicting timing signals. Based on the property setters in DevTools. + * @see https://github.com/ChromeDevTools/devtools-frontend/blob/56a99365197b85c24b732ac92b0ac70feed80179/front_end/sdk/NetworkRequest.js#L485-L502 + * @param {LH.Crdp.Network.ResourceTiming} timing + */ + _recomputeTimesWithResourceTiming(timing) { + if (timing.requestTime === -1 || timing.receiveHeadersEnd === -1) return; + this.networkRequestTime = timing.requestTime * 1e3; + const headersReceivedTime = this.networkRequestTime + timing.receiveHeadersEnd; + this.responseHeadersEndTime = headersReceivedTime; + if (this.responseTimestamp !== void 0) { + this.responseHeadersEndTime = Math.min(this.responseHeadersEndTime, this.responseTimestamp); + } + this.responseHeadersEndTime = Math.max(this.responseHeadersEndTime, this.networkRequestTime); + this.networkEndTime = Math.max(this.networkEndTime, this.responseHeadersEndTime); + } + /** + * Update responseHeadersEndTime to the networkEndTime if networkEndTime is earlier. + * A response can't be received after the entire request finished. + */ + _updateResponseHeadersEndTimeIfNecessary() { + this.responseHeadersEndTime = Math.min(this.networkEndTime, this.responseHeadersEndTime); + } + /** + * LR loses transfer size information, but passes it in the 'X-TotalFetchedSize' header. + * 'X-TotalFetchedSize' is the canonical transfer size in LR. Nothing should supersede it. + * + * The total length of the encoded data is spread out among multiple events. The sum of the + * values in onResponseReceived and all the onDataReceived events typically equals the value + * seen on the onLoadingFinished event. In <1% of cases we see the values differ. As we process + * onResponseReceived and onDataReceived we accumulate the total encodedDataLength. When we + * process onLoadingFinished, we override the accumulated total. We do this so that if the + * request is aborted or fails, we still get a value via the accumulation. + * + * In Lightrider, due to instrumentation limitations, our values for encodedDataLength are bogus + * and not valid. However the resource's true encodedDataLength/transferSize is shared via a + * special response header, X-TotalFetchedSize. In this situation, we read this value from + * responseReceived, use it for the transferSize and ignore the encodedDataLength values in + * both dataReceived and loadingFinished. + */ + _updateTransferSizeForLightrider() { + if (!global.isLightrider) return; + const totalFetchedSize = this.responseHeaders.find((item) => item.name === HEADER_FETCHED_SIZE); + if (!totalFetchedSize) return; + const floatValue = parseFloat(totalFetchedSize.value); + if (isNaN(floatValue)) return; + this.transferSize = floatValue; + } + /** + * LR loses protocol information. + */ + _updateProtocolForLightrider() { + if (!global.isLightrider) return; + if (this.responseHeaders.some((item) => item.name === HEADER_PROTOCOL_IS_H2)) { + this.protocol = "h2"; + } + } + /** + * LR gets additional, accurate timing information from its underlying fetch infrastructure. This + * is passed in via X-Headers similar to 'X-TotalFetchedSize'. + */ + _updateTimingsForLightrider() { + if (!global.isLightrider) return; + const totalHeader = this.responseHeaders.find((item) => item.name === HEADER_TOTAL); + if (!totalHeader) return; + let totalMs = parseInt(totalHeader.value); + const TCPMsHeader = this.responseHeaders.find((item) => item.name === HEADER_TCP); + const SSLMsHeader = this.responseHeaders.find((item) => item.name === HEADER_SSL); + const requestMsHeader = this.responseHeaders.find((item) => item.name === HEADER_REQ); + const responseMsHeader = this.responseHeaders.find((item) => item.name === HEADER_RES); + const TCPMs = TCPMsHeader ? Math.max(0, parseInt(TCPMsHeader.value)) : 0; + const SSLMs = SSLMsHeader ? Math.max(0, parseInt(SSLMsHeader.value)) : 0; + const requestMs = requestMsHeader ? Math.max(0, parseInt(requestMsHeader.value)) : 0; + const responseMs = responseMsHeader ? Math.max(0, parseInt(responseMsHeader.value)) : 0; + if (Number.isNaN(TCPMs + requestMs + responseMs + totalMs)) { + return; + } + if (TCPMs + requestMs + responseMs !== totalMs) { + const delta = Math.abs(TCPMs + requestMs + responseMs - totalMs); + if (delta >= 25) return; + totalMs = TCPMs + requestMs + responseMs; + } + if (SSLMs > TCPMs) { + return; + } + this.lrStatistics = { + endTimeDeltaMs: this.networkEndTime - (this.networkRequestTime + totalMs), + TCPMs, + requestMs, + responseMs + }; + this.serverResponseTime = responseMs; + } + /** + * Convert the requestId to backend-version by removing the `:redirect` portion + * + * @param {string} requestId + * @return {string} + */ + static getRequestIdForBackend(requestId) { + return requestId.replace(/(:redirect)+$/, ""); + } + /** + * Based on DevTools NetworkManager. + * @see https://github.com/ChromeDevTools/devtools-frontend/blob/3415ee28e86a3f4bcc2e15b652d22069938df3a6/front_end/sdk/NetworkManager.js#L285-L297 + * @param {LH.Crdp.Network.Headers} headersDict + * @return {Array} + */ + static _headersDictToHeadersArray(headersDict) { + const result = []; + for (const name of Object.keys(headersDict)) { + const values = headersDict[name].split("\n"); + for (let i = 0; i < values.length; ++i) { + result.push({ name, value: values[i] }); + } + } + return result; + } + static get TYPES() { + return RESOURCE_TYPES; + } + /** + * @param {NetworkRequest} record + * @return {Lantern.Types.NetworkRequest} + */ + static asLanternNetworkRequest(record) { + let timing = record.timing; + let serverResponseTime; + if (global.isLightrider && record.lrStatistics) { + if (record.protocol.startsWith("h3")) { + timing = { + connectStart: 0, + connectEnd: record.lrStatistics.TCPMs + }; + } else { + timing = { + connectStart: 0, + sslStart: record.lrStatistics.TCPMs / 2, + connectEnd: record.lrStatistics.TCPMs, + sslEnd: record.lrStatistics.TCPMs + }; + serverResponseTime = record.lrStatistics.requestMs; + } + } + record.fromWorker = record.sessionTargetType === "worker"; + return { + rawRequest: record, + ...record, + timing, + serverResponseTime + }; + } + /** + * @param {Pick} record + * @return {boolean} + */ + static isNonNetworkRequest(record) { + return url_utils_default.isNonNetworkProtocol(record.protocol) || // But `protocol` can fail to be populated if the request fails, so fallback to scheme. + url_utils_default.isNonNetworkProtocol(record.parsedURL.scheme); + } + /** + * Technically there's not alignment on URLs that create "secure connections" vs "secure contexts" + * https://github.com/GoogleChrome/lighthouse/pull/11766#discussion_r582340683 + * But for our purposes, we don't need to worry too much. + * @param {NetworkRequest} record + * @return {boolean} + */ + static isSecureRequest(record) { + return url_utils_default.isSecureScheme(record.parsedURL.scheme) || url_utils_default.isSecureScheme(record.protocol) || url_utils_default.isLikeLocalhost(record.parsedURL.host) || _NetworkRequest.isHstsRequest(record); + } + /** + * Returns whether the network request was an HSTS redirect request. + * @param {NetworkRequest} record + * @return {boolean} + */ + static isHstsRequest(record) { + const destination = record.redirectDestination; + if (!destination) return false; + const reasonHeader = record.responseHeaders.find((header) => header.name === "Non-Authoritative-Reason"); + const reason = reasonHeader?.value; + return reason === "HSTS" && _NetworkRequest.isSecureRequest(destination); + } + /** + * Returns whether the network request was sent encoded. + * @param {NetworkRequest} record + * @return {boolean} + */ + static isContentEncoded(record) { + const patterns = global.isLightrider ? [ + /^x-original-content-encoding$/i + ] : [ + /^content-encoding$/i, + /^x-content-encoding-over-network$/i + ]; + const compressionTypes = ["gzip", "br", "deflate", "zstd"]; + return record.responseHeaders.some( + (header) => patterns.some((p) => header.name.match(p)) && compressionTypes.includes(header.value) + ); + } + /** + * Resource size is almost always the right one to be using because of the below: + * `transferSize = resourceSize + headers.length`. + * HOWEVER, there are some cases where an image is compressed again over the network and transfer size + * is smaller (see https://github.com/GoogleChrome/lighthouse/pull/4968). + * Use the min of the two numbers to be safe. + * `tranferSize` of cached records is 0 + * @param {NetworkRequest} networkRecord + * @return {number} + */ + static getResourceSizeOnNetwork(networkRecord) { + return Math.min(networkRecord.resourceSize || 0, networkRecord.transferSize || Infinity); + } + }; + NetworkRequest.HEADER_TCP = HEADER_TCP; + NetworkRequest.HEADER_SSL = HEADER_SSL; + NetworkRequest.HEADER_REQ = HEADER_REQ; + NetworkRequest.HEADER_RES = HEADER_RES; + NetworkRequest.HEADER_TOTAL = HEADER_TOTAL; + NetworkRequest.HEADER_FETCHED_SIZE = HEADER_FETCHED_SIZE; + NetworkRequest.HEADER_PROTOCOL_IS_H2 = HEADER_PROTOCOL_IS_H2; + } +}); + +// core/lib/network-recorder.js +import { EventEmitter as EventEmitter2 } from "events"; +var RequestEventEmitter, NetworkRecorder; +var init_network_recorder = __esm({ + "core/lib/network-recorder.js"() { + "use strict"; + init_process_global(); + init_lighthouse_logger(); + init_lh(); + init_lantern2(); + init_network_request(); + /** + * @license + * Copyright 2016 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + RequestEventEmitter = /** @type {RequestEmitter} */ + EventEmitter2; + NetworkRecorder = class _NetworkRecorder extends RequestEventEmitter { + static { + __name(this, "NetworkRecorder"); + } + /** + * Creates an instance of NetworkRecorder. + */ + constructor() { + super(); + this._records = []; + this._recordsById = /* @__PURE__ */ new Map(); + } + /** + * Returns the array of raw network request data without finalizing the initiator and + * redirect chain. + * @return {Array} + */ + getRawRecords() { + return Array.from(this._records); + } + /** + * Listener for the DevTools SDK NetworkManager's RequestStarted event, which includes both + * web socket and normal request creation. + * @param {NetworkRequest} request + * @private + */ + onRequestStarted(request) { + this._records.push(request); + this._recordsById.set(request.requestId, request); + this.emit("requeststarted", request); + } + /** + * Listener for the DevTools SDK NetworkManager's RequestFinished event, which includes + * request finish, failure, and redirect, as well as the closing of web sockets. + * @param {NetworkRequest} request + * @private + */ + onRequestFinished(request) { + this.emit("requestfinished", request); + } + // The below methods proxy network data into the NetworkRequest object which mimics the + // DevTools SDK network layer. + /** + * @param {{params: LH.Crdp.Network.RequestWillBeSentEvent, targetType: LH.Protocol.TargetType, sessionId?: string}} event + */ + onRequestWillBeSent(event) { + const data31 = event.params; + const originalRequest = this._findRealRequestAndSetSession( + data31.requestId, + event.targetType, + event.sessionId + ); + if (!originalRequest) { + const request = new NetworkRequest(); + request.onRequestWillBeSent(data31); + request.sessionId = event.sessionId; + request.sessionTargetType = event.targetType; + this.onRequestStarted(request); + lighthouse_logger_default.verbose("network", `request will be sent to ${request.url}`); + return; + } + if (!data31.redirectResponse) { + return; + } + const modifiedData = { + ...data31, + // Copy over the initiator as well to match DevTools behavior + initiator: originalRequest.initiator, + requestId: `${originalRequest.requestId}:redirect` + }; + const redirectedRequest = new NetworkRequest(); + redirectedRequest.onRequestWillBeSent(modifiedData); + originalRequest.onRedirectResponse(data31); + lighthouse_logger_default.verbose("network", `${originalRequest.url} redirected to ${redirectedRequest.url}`); + originalRequest.redirectDestination = redirectedRequest; + redirectedRequest.redirectSource = originalRequest; + this.onRequestStarted(redirectedRequest); + this.onRequestFinished(originalRequest); + } + /** + * @param {{params: LH.Crdp.Network.RequestServedFromCacheEvent, targetType: LH.Protocol.TargetType, sessionId?: string}} event + */ + onRequestServedFromCache(event) { + const data31 = event.params; + const request = this._findRealRequestAndSetSession( + data31.requestId, + event.targetType, + event.sessionId + ); + if (!request) return; + lighthouse_logger_default.verbose("network", `${request.url} served from cache`); + request.onRequestServedFromCache(); + } + /** + * @param {{params: LH.Crdp.Network.ResponseReceivedEvent, targetType: LH.Protocol.TargetType, sessionId?: string}} event + */ + onResponseReceived(event) { + const data31 = event.params; + const request = this._findRealRequestAndSetSession( + data31.requestId, + event.targetType, + event.sessionId + ); + if (!request) return; + lighthouse_logger_default.verbose("network", `${request.url} response received`); + request.onResponseReceived(data31); + } + /** + * @param {{params: LH.Crdp.Network.ResponseReceivedExtraInfoEvent, targetType: LH.Protocol.TargetType, sessionId?: string}} event + */ + onResponseReceivedExtraInfo(event) { + const data31 = event.params; + const request = this._findRealRequestAndSetSession( + data31.requestId, + event.targetType, + event.sessionId + ); + if (!request) return; + lighthouse_logger_default.verbose("network", `${request.url} response received extra info`); + request.onResponseReceivedExtraInfo(data31); + } + /** + * @param {{params: LH.Crdp.Network.DataReceivedEvent, targetType: LH.Protocol.TargetType, sessionId?: string}} event + */ + onDataReceived(event) { + const data31 = event.params; + const request = this._findRealRequestAndSetSession( + data31.requestId, + event.targetType, + event.sessionId + ); + if (!request) return; + lighthouse_logger_default.verbose("network", `${request.url} data received`); + request.onDataReceived(data31); + } + /** + * @param {{params: LH.Crdp.Network.LoadingFinishedEvent, targetType: LH.Protocol.TargetType, sessionId?: string}} event + */ + onLoadingFinished(event) { + const data31 = event.params; + const request = this._findRealRequestAndSetSession( + data31.requestId, + event.targetType, + event.sessionId + ); + if (!request) return; + lighthouse_logger_default.verbose("network", `${request.url} loading finished`); + request.onLoadingFinished(data31); + this.onRequestFinished(request); + } + /** + * @param {{params: LH.Crdp.Network.LoadingFailedEvent, targetType: LH.Protocol.TargetType, sessionId?: string}} event + */ + onLoadingFailed(event) { + const data31 = event.params; + const request = this._findRealRequestAndSetSession( + data31.requestId, + event.targetType, + event.sessionId + ); + if (!request) return; + lighthouse_logger_default.verbose("network", `${request.url} loading failed`); + request.onLoadingFailed(data31); + this.onRequestFinished(request); + } + /** + * @param {{params: LH.Crdp.Network.ResourceChangedPriorityEvent, targetType: LH.Protocol.TargetType, sessionId?: string}} event + */ + onResourceChangedPriority(event) { + const data31 = event.params; + const request = this._findRealRequestAndSetSession( + data31.requestId, + event.targetType, + event.sessionId + ); + if (!request) return; + request.onResourceChangedPriority(data31); + } + /** + * Routes network events to their handlers, so we can construct networkRecords + * @param {LH.Protocol.RawEventMessage} event + */ + dispatch(event) { + switch (event.method) { + case "Network.requestWillBeSent": + return this.onRequestWillBeSent(event); + case "Network.requestServedFromCache": + return this.onRequestServedFromCache(event); + case "Network.responseReceived": + return this.onResponseReceived(event); + case "Network.responseReceivedExtraInfo": + return this.onResponseReceivedExtraInfo(event); + case "Network.dataReceived": + return this.onDataReceived(event); + case "Network.loadingFinished": + return this.onLoadingFinished(event); + case "Network.loadingFailed": + return this.onLoadingFailed(event); + case "Network.resourceChangedPriority": + return this.onResourceChangedPriority(event); + default: + return; + } + } + /** + * Redirected requests all have identical requestIds over the protocol. Once a request has been + * redirected all future messages referrencing that requestId are about the new destination, not + * the original. This method is a helper for finding the real request object to which the current + * message is referring. + * + * @param {string} requestId + * @param {LH.Protocol.TargetType} targetType + * @param {string|undefined} sessionId + * @return {NetworkRequest|undefined} + */ + _findRealRequestAndSetSession(requestId, targetType, sessionId) { + let request = this._recordsById.get(requestId); + if (!request || !request.isValid) return void 0; + while (request.redirectDestination) { + request = request.redirectDestination; + } + request.setSession(sessionId); + request.sessionTargetType = targetType; + return request; + } + /** + * @param {NetworkRequest} record The record to find the initiator of + * @param {Map} recordsByURL + * @return {NetworkRequest|null} + * @private + */ + static _chooseInitiatorRequest(record, recordsByURL) { + if (record.redirectSource) { + return record.redirectSource; + } + const initiatorURL = graph_exports.PageDependencyGraph.getNetworkInitiators(record)[0]; + let candidates = recordsByURL.get(initiatorURL) || []; + candidates = candidates.filter((c) => { + return c.responseHeadersEndTime <= record.rendererStartTime && c.finished && !c.failed; + }); + if (candidates.length > 1) { + const nonPrefetchCandidates = candidates.filter( + (cand) => cand.resourceType !== NetworkRequest.TYPES.Other + ); + if (nonPrefetchCandidates.length) { + candidates = nonPrefetchCandidates; + } + } + if (candidates.length > 1) { + const sameFrameCandidates = candidates.filter((cand) => cand.frameId === record.frameId); + if (sameFrameCandidates.length) { + candidates = sameFrameCandidates; + } + } + if (candidates.length > 1 && record.initiator.type === "parser") { + const documentCandidates = candidates.filter((cand) => cand.resourceType === NetworkRequest.TYPES.Document); + if (documentCandidates.length) { + candidates = documentCandidates; + } + } + if (candidates.length > 1) { + const linkPreloadCandidates = candidates.filter((c) => c.isLinkPreload); + if (linkPreloadCandidates.length) { + const nonPreloadCandidates = candidates.filter((c) => !c.isLinkPreload); + const allPreloaded = nonPreloadCandidates.every((c) => c.fromDiskCache || c.fromMemoryCache); + if (nonPreloadCandidates.length && allPreloaded) { + candidates = linkPreloadCandidates; + } + } + } + return candidates.length === 1 ? candidates[0] : null; + } + /** + * Construct network records from a log of devtools protocol messages. + * @param {LH.DevtoolsLog} devtoolsLog + * @return {Array} + */ + static recordsFromLogs(devtoolsLog) { + const networkRecorder = new _NetworkRecorder(); + devtoolsLog.forEach((message) => networkRecorder.dispatch(message)); + const records = networkRecorder.getRawRecords().filter((record) => record.isValid); + const recordsByURL = /* @__PURE__ */ new Map(); + for (const record of records) { + const records2 = recordsByURL.get(record.url) || []; + records2.push(record); + recordsByURL.set(record.url, records2); + } + for (const record of records) { + const initiatorRequest = _NetworkRecorder._chooseInitiatorRequest(record, recordsByURL); + if (initiatorRequest) { + record.setInitiatorRequest(initiatorRequest); + } + let finalRecord = record; + while (finalRecord.redirectDestination) finalRecord = finalRecord.redirectDestination; + if (finalRecord === record || finalRecord.redirects) continue; + const redirects = []; + for (let redirect = finalRecord.redirectSource; redirect; redirect = redirect.redirectSource) { + redirects.unshift(redirect); + } + finalRecord.redirects = redirects; + } + return records; + } + }; + } +}); + +// core/computed/network-records.js +var NetworkRecords, NetworkRecordsComputed; +var init_network_records = __esm({ + "core/computed/network-records.js"() { + "use strict"; + init_process_global(); + init_lh(); + init_computed_artifact(); + init_network_recorder(); + /** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + NetworkRecords = class { + static { + __name(this, "NetworkRecords"); + } + /** + * @param {LH.DevtoolsLog} devtoolsLog + * @return {Promise>} networkRecords + */ + static async compute_(devtoolsLog) { + return NetworkRecorder.recordsFromLogs(devtoolsLog); + } + }; + NetworkRecordsComputed = makeComputedArtifact(NetworkRecords, null); + } +}); + +// core/computed/network-analysis.js +var NetworkAnalysis, NetworkAnalysisComputed; +var init_network_analysis = __esm({ + "core/computed/network-analysis.js"() { + "use strict"; + init_process_global(); + init_lighthouse_logger(); + init_lantern2(); + init_computed_artifact(); + init_network_records(); + /** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + NetworkAnalysis = class { + static { + __name(this, "NetworkAnalysis"); + } + /** + * @param {LH.DevtoolsLog} devtoolsLog + * @param {LH.Artifacts.ComputedContext} context + * @return {Promise} + */ + static async compute_(devtoolsLog, context) { + const records = await NetworkRecordsComputed.request(devtoolsLog, context); + const analysis = core_exports.NetworkAnalyzer.analyze(records); + if (!analysis) { + lighthouse_logger_default.error("NetworkAnalysis", "Network analysis failed due to lack of transfer data"); + return { + throughput: 0, + rtt: Number.POSITIVE_INFINITY, + additionalRttByOrigin: /* @__PURE__ */ new Map(), + serverResponseTimeByOrigin: /* @__PURE__ */ new Map() + }; + } + return analysis; + } + }; + NetworkAnalysisComputed = makeComputedArtifact(NetworkAnalysis, null); + } +}); + +// core/computed/load-simulator.js +var LoadSimulator, LoadSimulatorComputed; +var init_load_simulator = __esm({ + "core/computed/load-simulator.js"() { + "use strict"; + init_process_global(); + init_computed_artifact(); + init_lantern2(); + init_network_analysis(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + LoadSimulator = class { + static { + __name(this, "LoadSimulator"); + } + /** + * @param {{devtoolsLog: LH.DevtoolsLog, settings: LH.Audit.Context['settings']}} data + * @param {LH.Artifacts.ComputedContext} context + * @return {Promise} + */ + static async compute_(data31, context) { + const networkAnalysis = await NetworkAnalysisComputed.request(data31.devtoolsLog, context); + return simulation_exports.Simulator.createSimulator({ ...data31.settings, networkAnalysis }); + } + /** + * @param {LH.Artifacts.NetworkAnalysis} networkAnalysis + * @return {LH.PrecomputedLanternData} + */ + static convertAnalysisToSaveableLanternData(networkAnalysis) { + const lanternData = { additionalRttByOrigin: {}, serverResponseTimeByOrigin: {} }; + for (const [origin, value] of networkAnalysis.additionalRttByOrigin.entries()) { + if (origin.startsWith("http")) lanternData.additionalRttByOrigin[origin] = value; + } + for (const [origin, value] of networkAnalysis.serverResponseTimeByOrigin.entries()) { + if (origin.startsWith("http")) lanternData.serverResponseTimeByOrigin[origin] = value; + } + return lanternData; + } + }; + LoadSimulatorComputed = makeComputedArtifact(LoadSimulator, ["devtoolsLog", "settings"]); + } +}); + +// core/lib/asset-saver.js +import fs from "fs"; +import path3 from "path"; +import stream from "stream"; +import { createGzip, gunzipSync } from "zlib"; +async function writeJson(contents, path7, gzip) { + const writeStream = fs.createWriteStream(gzip ? path7 + ".gz" : path7); + if (gzip) { + await stream.promises.pipeline(contents, createGzip(), writeStream); + } else { + await stream.promises.pipeline(contents, writeStream); + } +} +function readJson(filename, reviver) { + if (fs.existsSync(filename + ".gz")) { + filename = filename + ".gz"; + } + if (!filename.endsWith(".json.gz")) { + return JSON.parse(fs.readFileSync(filename, "utf8"), reviver); + } + const buffer = gunzipSync(fs.readFileSync(filename)); + return JSON.parse(buffer.toString("utf8"), reviver); +} +function endsWithSuffix(filename, suffix) { + return filename.endsWith(suffix) || filename.endsWith(suffix + ".gz"); +} +function loadArtifacts(basePath) { + lighthouse_logger_default.log("Reading artifacts from disk:", basePath); + if (!fs.existsSync(basePath)) { + throw new Error("No saved artifacts found at " + basePath); + } + const artifacts = readJson(path3.join(basePath, artifactsFilename), LighthouseError.parseReviver); + const filenames = fs.readdirSync(basePath); + filenames.filter((f) => endsWithSuffix(f, devtoolsFilename)).forEach((filename) => { + const devtoolsLog = readJson(path3.join(basePath, filename)); + if (filename.startsWith(devtoolsFilename)) { + artifacts.DevtoolsLog = devtoolsLog; + } else if (filename.startsWith(errorPrefix)) { + artifacts.DevtoolsLogError = devtoolsLog; + } + }); + filenames.filter((f) => endsWithSuffix(f, traceFilename)).forEach((filename) => { + let trace = readJson(path3.join(basePath, filename)); + if (Array.isArray(trace)) { + trace = { traceEvents: trace }; + } + if (filename.startsWith(traceFilename)) { + artifacts.Trace = trace; + } else if (filename.startsWith(errorPrefix)) { + artifacts.TraceError = trace; + } + }); + if (Array.isArray(artifacts.Timing)) { + artifacts.Timing.forEach((entry) => entry.gather = true); + } + return artifacts; +} +function stringifyReplacer(key, value) { + if (value instanceof Error) { + return LighthouseError.stringifyReplacer(value); + } + return value; +} +async function saveArtifacts(artifacts, basePath, options = {}) { + const status = { msg: "Saving artifacts", id: "lh:assetSaver:saveArtifacts" }; + lighthouse_logger_default.time(status); + fs.mkdirSync(basePath, { recursive: true }); + const filenames = fs.readdirSync(basePath); + for (const filename of filenames) { + const isPreviousFile = filename.endsWith(traceFilename) || filename.endsWith(devtoolsFilename) || filename.endsWith(traceFilename + ".gz") || filename.endsWith(devtoolsFilename + ".gz") || filename === artifactsFilename || filename === artifactsFilename + ".gz"; + if (isPreviousFile) { + fs.unlinkSync(`${basePath}/${filename}`); + } + } + const { + DevtoolsLog: DevtoolsLog2, + Trace, + DevtoolsLogError, + TraceError, + ...restArtifacts + } = artifacts; + if (Trace) { + await saveTrace(Trace, `${basePath}/${traceFilename}`, options); + } + if (TraceError) { + await saveTrace(TraceError, `${basePath}/${errorPrefix}${traceFilename}`, options); + } + if (DevtoolsLog2) { + await saveDevtoolsLog( + DevtoolsLog2, + `${basePath}/${devtoolsFilename}`, + options + ); + } + if (DevtoolsLogError) { + await saveDevtoolsLog( + DevtoolsLogError, + `${basePath}/${errorPrefix}${devtoolsFilename}`, + options + ); + } + const restArtifactsString = JSON.stringify(restArtifacts, stringifyReplacer, 2); + await writeJson(function* () { + yield restArtifactsString; + yield "\n"; + }, `${basePath}/${artifactsFilename}`, !!options.gzip); + lighthouse_logger_default.log("Artifacts saved to disk in folder:", basePath); + lighthouse_logger_default.timeEnd(status); +} +function saveLhr(lhr, basePath) { + fs.writeFileSync(`${basePath}/lhr.report.json`, JSON.stringify(lhr, null, 2)); +} +function* arrayOfObjectsJsonGenerator(arrayOfObjects) { + const ITEMS_PER_ITERATION = 500; + yield "[\n"; + if (arrayOfObjects.length > 0) { + const itemsIterator = arrayOfObjects[Symbol.iterator](); + const firstItem = itemsIterator.next().value; + yield ` ${JSON.stringify(firstItem)}`; + let itemsRemaining = ITEMS_PER_ITERATION; + let itemsJSON = ""; + for (const item of itemsIterator) { + itemsJSON += `, + ${JSON.stringify(item)}`; + itemsRemaining--; + if (itemsRemaining === 0) { + yield itemsJSON; + itemsRemaining = ITEMS_PER_ITERATION; + itemsJSON = ""; + } + } + yield itemsJSON; + } + yield "\n]"; +} +function* traceJsonGenerator(traceData) { + const { traceEvents, ...rest } = traceData; + yield "{\n"; + yield '"traceEvents": '; + yield* arrayOfObjectsJsonGenerator(traceEvents); + for (const [key, value] of Object.entries(rest)) { + yield `, +"${key}": ${JSON.stringify(value, null, 2)}`; + } + yield "}\n"; +} +function saveTrace(traceData, traceFilename2, options = {}) { + const traceIter = traceJsonGenerator(traceData); + return writeJson(traceIter, traceFilename2, !!options.gzip); +} +function saveDevtoolsLog(devtoolsLog, devtoolLogFilename, options = {}) { + return writeJson(function* () { + yield* arrayOfObjectsJsonGenerator(devtoolsLog); + yield "\n"; + }, devtoolLogFilename, !!options.gzip); +} +var artifactsFilename, traceFilename, devtoolsFilename, errorPrefix; +var init_asset_saver = __esm({ + "core/lib/asset-saver.js"() { + "use strict"; + init_process_global(); + init_url(); + init_lighthouse_logger(); + init_lantern2(); + init_lantern_trace_saver(); + init_metric_trace_events(); + init_network_analysis(); + init_load_simulator(); + init_lh_error(); + init_root2(); + /** + * @license + * Copyright 2016 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + artifactsFilename = "artifacts.json"; + traceFilename = "trace.json"; + devtoolsFilename = "devtoolslog.json"; + errorPrefix = "pageLoadError."; + __name(writeJson, "writeJson"); + __name(readJson, "readJson"); + __name(endsWithSuffix, "endsWithSuffix"); + __name(loadArtifacts, "loadArtifacts"); + __name(stringifyReplacer, "stringifyReplacer"); + __name(saveArtifacts, "saveArtifacts"); + __name(saveLhr, "saveLhr"); + __name(arrayOfObjectsJsonGenerator, "arrayOfObjectsJsonGenerator"); + __name(traceJsonGenerator, "traceJsonGenerator"); + __name(saveTrace, "saveTrace"); + __name(saveDevtoolsLog, "saveDevtoolsLog"); + } +}); + +// core/config/constants.js +var constants_exports = {}; +__export(constants_exports, { + defaultSettings: () => defaultSettings, + nonSimulatedSettingsOverrides: () => nonSimulatedSettingsOverrides, + screenEmulationMetrics: () => screenEmulationMetrics, + throttling: () => throttling2, + userAgents: () => userAgents +}); +var throttling2, MOTOGPOWER_EMULATION_METRICS, DESKTOP_EMULATION_METRICS, screenEmulationMetrics, MOTOG4_USERAGENT, DESKTOP_USERAGENT, userAgents, defaultSettings, nonSimulatedSettingsOverrides; +var init_constants = __esm({ + "core/config/constants.js"() { + "use strict"; + init_process_global(); + init_lantern2(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + throttling2 = simulation_exports.Constants.throttling; + MOTOGPOWER_EMULATION_METRICS = { + mobile: true, + width: 412, + height: 823, + // This value has some interesting ramifications for image-size-responsive, see: + // https://github.com/GoogleChrome/lighthouse/issues/10741#issuecomment-626903508 + deviceScaleFactor: 1.75, + disabled: false + }; + DESKTOP_EMULATION_METRICS = { + mobile: false, + width: 1350, + height: 940, + deviceScaleFactor: 1, + disabled: false + }; + screenEmulationMetrics = { + mobile: MOTOGPOWER_EMULATION_METRICS, + desktop: DESKTOP_EMULATION_METRICS + }; + MOTOG4_USERAGENT = "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36"; + DESKTOP_USERAGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36"; + userAgents = { + mobile: MOTOG4_USERAGENT, + desktop: DESKTOP_USERAGENT + }; + defaultSettings = { + output: "json", + maxWaitForFcp: 30 * 1e3, + maxWaitForLoad: 45 * 1e3, + pauseAfterFcpMs: 1e3, + pauseAfterLoadMs: 1e3, + networkQuietThresholdMs: 1e3, + cpuQuietThresholdMs: 1e3, + formFactor: "mobile", + throttling: throttling2.mobileSlow4G, + throttlingMethod: "simulate", + screenEmulation: screenEmulationMetrics.mobile, + emulatedUserAgent: userAgents.mobile, + auditMode: false, + gatherMode: false, + clearStorageTypes: ["file_systems", "shader_cache", "service_workers", "cache_storage"], + disableStorageReset: false, + debugNavigation: false, + channel: "node", + usePassiveGathering: false, + disableFullPageScreenshot: false, + skipAboutBlank: false, + blankPage: "about:blank", + ignoreStatusCode: false, + // the following settings have no defaults but we still want ensure that `key in settings` + // in config will work in a typechecked way + locale: "en-US", + // actual default determined by Config using lib/i18n + blockedUrlPatterns: null, + additionalTraceCategories: null, + extraHeaders: null, + precomputedLanternData: null, + onlyAudits: null, + onlyCategories: null, + skipAudits: null + }; + nonSimulatedSettingsOverrides = { + pauseAfterFcpMs: 5250, + pauseAfterLoadMs: 5250, + networkQuietThresholdMs: 5250, + cpuQuietThresholdMs: 5250 + }; + } +}); + +// core/config/default-config.js +var UIStrings21, str_2, defaultConfig, default_config_default; +var init_default_config = __esm({ + "core/config/default-config.js"() { + "use strict"; + init_process_global(); + init_lh(); + init_constants(); + init_i18n(); + /** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + UIStrings21 = { + /** Title of the Performance category of audits. Equivalent to 'Web performance', this term is inclusive of all web page speed and loading optimization topics. Also used as a label of a score gauge; try to limit to 20 characters. */ + performanceCategoryTitle: "Performance", + /** Title of the speed metrics section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. */ + metricGroupTitle: "Metrics", + /** Title of the insights section of the Performance category. Within this section are various insights to give developers tips on how to improve the performance of their page. */ + insightsGroupTitle: "Insights", + /** Description of the insights section of the Performance category. Within this section are various insights to give developers tips on how to improve the performance of their page. */ + insightsGroupDescription: "These insights are also available in the Chrome DevTools Performance Panel - [record a trace](https://developer.chrome.com/docs/devtools/performance/reference) to view more detailed information.", + /** Title of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the time of the first initial render of the webpage. */ + firstPaintImprovementsGroupTitle: "First Paint Improvements", + /** Description of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the time of the first initial render of the webpage. */ + firstPaintImprovementsGroupDescription: "The most critical aspect of performance is how quickly pixels are rendered onscreen. Key metrics: First Contentful Paint, First Meaningful Paint", + /** Title of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the overall loading performance of their web page. */ + overallImprovementsGroupTitle: "Overall Improvements", + /** Description of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the overall loading performance of their web page. */ + overallImprovementsGroupDescription: "Enhance the overall loading experience, so the page is responsive and ready to use as soon as possible. Key metrics: Time to Interactive, Speed Index", + /** Title of the diagnostics section of the Performance category. Within this section are audits with non-imperative titles that provide more detail on the page's page load performance characteristics. Whereas the 'Opportunities' suggest an action along with expected time savings, diagnostics do not. Within this section, the user may read the details and deduce additional actions they could take. */ + diagnosticsGroupTitle: "Diagnostics", + /** Description of the diagnostics section of the Performance category. Within this section are audits with non-imperative titles that provide more detail on a web page's load performance characteristics. Within this section, the user may read the details and deduce additional actions they could take to improve performance. */ + diagnosticsGroupDescription: "More information about the performance of your application. These numbers don't [directly affect](https://developer.chrome.com/docs/lighthouse/performance/performance-scoring/) the Performance score.", + /** Title of the Accessibility category of audits. This section contains audits focused on making web content accessible to all users. Also used as a label of a score gauge; try to limit to 20 characters. */ + a11yCategoryTitle: "Accessibility", + /** Description of the Accessibility category. This is displayed at the top of a list of audits focused on making web content accessible to all users. No character length limits. 'improve the accessibility of your web app' and 'manual testing' become link texts to additional documentation. */ + a11yCategoryDescription: "These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/articles/how-to-review) is also encouraged.", + /** Description of the Accessibility manual checks category. This description is displayed above a list of accessibility audits that currently have no automated test and so must be verified manually by the user. No character length limits. 'conducting an accessibility review' becomes link text to additional documentation. */ + a11yCategoryManualDescription: "These items address areas which an automated testing tool cannot cover. Learn more in our guide on [conducting an accessibility review](https://web.dev/articles/how-to-review).", + /** Title of the best practices section of the Accessibility category. Within this section are audits with descriptive titles that highlight common accessibility best practices. */ + a11yBestPracticesGroupTitle: "Best practices", + /** Description of the best practices section within the Accessibility category. Within this section are audits with descriptive titles that highlight common accessibility best practices. */ + a11yBestPracticesGroupDescription: "These items highlight common accessibility best practices.", + /** Title of the color contrast section within the Accessibility category. Within this section are audits with descriptive titles that highlight the color and vision aspects of the page's accessibility that are passing or failing. */ + a11yColorContrastGroupTitle: "Contrast", + /** Description of the color contrast section within the Accessibility category. Within this section are audits with descriptive titles that highlight the color and vision aspects of the page's accessibility that are passing or failing. */ + a11yColorContrastGroupDescription: "These are opportunities to improve the legibility of your content.", + /** Title of the HTML element naming section within the Accessibility category. Within this section are audits with descriptive titles that highlight if the non-textual HTML elements on the page have names discernible by a screen reader. */ + a11yNamesLabelsGroupTitle: "Names and labels", + /** Description of the HTML element naming section within the Accessibility category. Within this section are audits with descriptive titles that highlight if the non-textual HTML elements on the page have names discernible by a screen reader. */ + a11yNamesLabelsGroupDescription: "These are opportunities to improve the semantics of the controls in your application. This may enhance the experience for users of assistive technology, like a screen reader.", + /** Title of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve keyboard navigation. */ + a11yNavigationGroupTitle: "Navigation", + /** Description of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve keyboard navigation. */ + a11yNavigationGroupDescription: "These are opportunities to improve keyboard navigation in your application.", + /** Title of the ARIA validity section within the Accessibility category. Within this section are audits with descriptive titles that highlight if whether all the aria-* HTML attributes have been used properly. */ + a11yAriaGroupTitle: "ARIA", + /** Description of the ARIA validity section within the Accessibility category. Within this section are audits with descriptive titles that highlight if whether all the aria-* HTML attributes have been used properly. */ + a11yAriaGroupDescription: "These are opportunities to improve the usage of ARIA in your application which may enhance the experience for users of assistive technology, like a screen reader.", + /** Title of the language section within the Accessibility category. Within this section are audits with descriptive titles that highlight if the language has been annotated in the correct HTML attributes on the page. */ + a11yLanguageGroupTitle: "Internationalization and localization", + /** Description of the language section within the Accessibility category. Within this section are audits with descriptive titles that highlight if the language has been annotated in the correct HTML attributes on the page. */ + a11yLanguageGroupDescription: "These are opportunities to improve the interpretation of your content by users in different locales.", + /** Title of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to provide alternative content for audio and video. */ + a11yAudioVideoGroupTitle: "Audio and video", + /** Description of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to provide alternative content for audio and video. */ + a11yAudioVideoGroupDescription: "These are opportunities to provide alternative content for audio and video. This may improve the experience for users with hearing or vision impairments.", + /** Title of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve the experience of reading tabular or list data using assistive technology. */ + a11yTablesListsVideoGroupTitle: "Tables and lists", + /** Description of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve the experience of reading tabular or list data using assistive technology. */ + a11yTablesListsVideoGroupDescription: "These are opportunities to improve the experience of reading tabular or list data using assistive technology, like a screen reader.", + /** Title of the Search Engine Optimization (SEO) category of audits. This is displayed at the top of a list of audits focused on topics related to optimizing a website for indexing by search engines. Also used as a label of a score gauge; try to limit to 20 characters. */ + seoCategoryTitle: "SEO", + /** Description of the Search Engine Optimization (SEO) category. This is displayed at the top of a list of audits focused on optimizing a website for indexing by search engines. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */ + seoCategoryDescription: "These checks ensure that your page is following basic search engine optimization advice. There are many additional factors Lighthouse does not score here that may affect your search ranking, including performance on [Core Web Vitals](https://web.dev/explore/vitals). [Learn more about Google Search Essentials](https://support.google.com/webmasters/answer/35769).", + /** Description of the Search Engine Optimization (SEO) manual checks category, the additional validators must be run by hand in order to check all SEO best practices. This is displayed at the top of a list of manually run audits focused on optimizing a website for indexing by search engines. No character length limits. */ + seoCategoryManualDescription: "Run these additional validators on your site to check additional SEO best practices.", + /** Title of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight opportunities to make a page more usable on mobile devices. */ + seoMobileGroupTitle: "Mobile Friendly", + /** Description of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight opportunities to make a page more usable on mobile devices. */ + seoMobileGroupDescription: "Make sure your pages are mobile friendly so users don’t have to pinch or zoom in order to read the content pages. [Learn how to make pages mobile-friendly](https://developers.google.com/search/mobile-sites/).", + /** Title of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight ways to make a website content more easily understood by search engine crawler bots. */ + seoContentGroupTitle: "Content Best Practices", + /** Description of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight ways to make a website content more easily understood by search engine crawler bots. */ + seoContentGroupDescription: "Format your HTML in a way that enables crawlers to better understand your app’s content.", + /** Title of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight ways to make a website accessible to search engine crawlers. */ + seoCrawlingGroupTitle: "Crawling and Indexing", + /** Description of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight ways to make a website accessible to search engine crawlers. */ + seoCrawlingGroupDescription: "To appear in search results, crawlers need access to your app.", + /** Title of the Best Practices category of audits. This is displayed at the top of a list of audits focused on topics related to following web development best practices and accepted guidelines. Also used as a label of a score gauge; try to limit to 20 characters. */ + bestPracticesCategoryTitle: "Best Practices", + /** Title of the Trust & Safety group of audits. This is displayed at the top of a list of audits focused on maintaining user trust and protecting security in web development. */ + bestPracticesTrustSafetyGroupTitle: "Trust and Safety", + /** Title of the User Experience group of the Best Practices category. Within this section are the audits related to the end user's experience of the webpage. */ + bestPracticesUXGroupTitle: "User Experience", + /** Title of the Browser Compatibility group of the Best Practices category. Within this section are the audits related to whether the page is interpreted consistently by browsers. */ + bestPracticesBrowserCompatGroupTitle: "Browser Compatibility", + /** Title of the General group of the Best Practices category. Within this section are the audits that don't belong to a specific group but are of general interest. */ + bestPracticesGeneralGroupTitle: "General" + }; + str_2 = createIcuMessageFn({ url: "core/config/default-config.js" }.url, UIStrings21); + defaultConfig = { + settings: defaultSettings, + artifacts: [ + // Artifacts which can be depended on come first. + { id: "DevtoolsLog", gatherer: "devtools-log" }, + { id: "Trace", gatherer: "trace" }, + { id: "Accessibility", gatherer: "accessibility" }, + { id: "AnchorElements", gatherer: "anchor-elements" }, + { id: "ConsoleMessages", gatherer: "console-messages" }, + { id: "CSSUsage", gatherer: "css-usage" }, + { id: "Doctype", gatherer: "dobetterweb/doctype" }, + { id: "Inputs", gatherer: "inputs" }, + { id: "IFrameElements", gatherer: "iframe-elements" }, + { id: "ImageElements", gatherer: "image-elements" }, + { id: "InspectorIssues", gatherer: "inspector-issues" }, + { id: "JsUsage", gatherer: "js-usage" }, + { id: "LinkElements", gatherer: "link-elements" }, + { id: "MainDocumentContent", gatherer: "main-document-content" }, + { id: "MetaElements", gatherer: "meta-elements" }, + { id: "NetworkUserAgent", gatherer: "network-user-agent" }, + { id: "RobotsTxt", gatherer: "seo/robots-txt" }, + { id: "Scripts", gatherer: "scripts" }, + { id: "SourceMaps", gatherer: "source-maps" }, + { id: "Stacks", gatherer: "stacks" }, + { id: "Stylesheets", gatherer: "stylesheets" }, + { id: "TraceElements", gatherer: "trace-elements" }, + { id: "ViewportDimensions", gatherer: "viewport-dimensions" }, + // FullPageScreenshot comes at the end so all other node analysis is captured. + { id: "FullPageScreenshot", gatherer: "full-page-screenshot" }, + // BFCacheFailures comes at the very end because it can perform a page navigation. + { id: "BFCacheFailures", gatherer: "bf-cache-failures" } + ], + audits: [ + "is-on-https", + "redirects-http", + "metrics/first-contentful-paint", + "metrics/largest-contentful-paint", + "metrics/speed-index", + "screenshot-thumbnails", + "final-screenshot", + "metrics/total-blocking-time", + "metrics/max-potential-fid", + "metrics/cumulative-layout-shift", + "metrics/interaction-to-next-paint", + "errors-in-console", + "server-response-time", + "metrics/interactive", + "user-timings", + "redirects", + "image-aspect-ratio", + "image-size-responsive", + "deprecations", + "third-party-cookies", + "mainthread-work-breakdown", + "bootup-time", + "diagnostics", + "network-requests", + "network-rtt", + "network-server-latency", + "main-thread-tasks", + "metrics", + "resource-summary", + "layout-shifts", + "long-tasks", + "non-composited-animations", + "unsized-images", + "valid-source-maps", + "csp-xss", + "has-hsts", + "origin-isolation", + "clickjacking-mitigation", + "trusted-types-xss", + "script-treemap-data", + "accessibility/accesskeys", + "accessibility/aria-allowed-attr", + "accessibility/aria-allowed-role", + "accessibility/aria-command-name", + "accessibility/aria-conditional-attr", + "accessibility/aria-deprecated-role", + "accessibility/aria-dialog-name", + "accessibility/aria-hidden-body", + "accessibility/aria-hidden-focus", + "accessibility/aria-input-field-name", + "accessibility/aria-meter-name", + "accessibility/aria-progressbar-name", + "accessibility/aria-prohibited-attr", + "accessibility/aria-required-attr", + "accessibility/aria-required-children", + "accessibility/aria-required-parent", + "accessibility/aria-roles", + "accessibility/aria-text", + "accessibility/aria-toggle-field-name", + "accessibility/aria-tooltip-name", + "accessibility/aria-treeitem-name", + "accessibility/aria-valid-attr-value", + "accessibility/aria-valid-attr", + "accessibility/button-name", + "accessibility/bypass", + "accessibility/color-contrast", + "accessibility/definition-list", + "accessibility/dlitem", + "accessibility/document-title", + "accessibility/duplicate-id-aria", + "accessibility/empty-heading", + "accessibility/form-field-multiple-labels", + "accessibility/frame-title", + "accessibility/heading-order", + "accessibility/html-has-lang", + "accessibility/html-lang-valid", + "accessibility/html-xml-lang-mismatch", + "accessibility/identical-links-same-purpose", + "accessibility/image-alt", + "accessibility/image-redundant-alt", + "accessibility/input-button-name", + "accessibility/input-image-alt", + "accessibility/label-content-name-mismatch", + "accessibility/label", + "accessibility/landmark-one-main", + "accessibility/link-name", + "accessibility/link-in-text-block", + "accessibility/list", + "accessibility/listitem", + "accessibility/meta-refresh", + "accessibility/meta-viewport", + "accessibility/object-alt", + "accessibility/select-name", + "accessibility/skip-link", + "accessibility/tabindex", + "accessibility/table-duplicate-name", + "accessibility/table-fake-caption", + "accessibility/target-size", + "accessibility/td-has-header", + "accessibility/td-headers-attr", + "accessibility/th-has-data-cells", + "accessibility/valid-lang", + "accessibility/video-caption", + "accessibility/manual/custom-controls-labels", + "accessibility/manual/custom-controls-roles", + "accessibility/manual/focus-traps", + "accessibility/manual/focusable-controls", + "accessibility/manual/interactive-element-affordance", + "accessibility/manual/logical-tab-order", + "accessibility/manual/managed-focus", + "accessibility/manual/offscreen-content-hidden", + "accessibility/manual/use-landmarks", + "accessibility/manual/visual-order-follows-dom", + "byte-efficiency/total-byte-weight", + "byte-efficiency/unminified-css", + "byte-efficiency/unminified-javascript", + "byte-efficiency/unused-css-rules", + "byte-efficiency/unused-javascript", + "dobetterweb/doctype", + "dobetterweb/charset", + "dobetterweb/geolocation-on-start", + "dobetterweb/inspector-issues", + "dobetterweb/js-libraries", + "dobetterweb/notification-on-start", + "dobetterweb/paste-preventing-inputs", + "seo/meta-description", + "seo/http-status-code", + "seo/link-text", + "seo/crawlable-anchors", + "seo/is-crawlable", + "seo/robots-txt", + "seo/hreflang", + "seo/canonical", + "seo/manual/structured-data", + "bf-cache", + "insights/cache-insight", + "insights/cls-culprits-insight", + "insights/document-latency-insight", + "insights/dom-size-insight", + "insights/duplicated-javascript-insight", + "insights/font-display-insight", + "insights/forced-reflow-insight", + "insights/image-delivery-insight", + "insights/inp-breakdown-insight", + "insights/lcp-breakdown-insight", + "insights/lcp-discovery-insight", + "insights/legacy-javascript-insight", + "insights/modern-http-insight", + "insights/network-dependency-tree-insight", + "insights/render-blocking-insight", + "insights/third-parties-insight", + "insights/viewport-insight" + ], + groups: { + "metrics": { + title: str_2(UIStrings21.metricGroupTitle) + }, + "insights": { + title: str_2(UIStrings21.insightsGroupTitle), + description: str_2(UIStrings21.insightsGroupDescription) + }, + "diagnostics": { + title: str_2(UIStrings21.diagnosticsGroupTitle), + description: str_2(UIStrings21.diagnosticsGroupDescription) + }, + "a11y-best-practices": { + title: str_2(UIStrings21.a11yBestPracticesGroupTitle), + description: str_2(UIStrings21.a11yBestPracticesGroupDescription) + }, + "a11y-color-contrast": { + title: str_2(UIStrings21.a11yColorContrastGroupTitle), + description: str_2(UIStrings21.a11yColorContrastGroupDescription) + }, + "a11y-names-labels": { + title: str_2(UIStrings21.a11yNamesLabelsGroupTitle), + description: str_2(UIStrings21.a11yNamesLabelsGroupDescription) + }, + "a11y-navigation": { + title: str_2(UIStrings21.a11yNavigationGroupTitle), + description: str_2(UIStrings21.a11yNavigationGroupDescription) + }, + "a11y-aria": { + title: str_2(UIStrings21.a11yAriaGroupTitle), + description: str_2(UIStrings21.a11yAriaGroupDescription) + }, + "a11y-language": { + title: str_2(UIStrings21.a11yLanguageGroupTitle), + description: str_2(UIStrings21.a11yLanguageGroupDescription) + }, + "a11y-audio-video": { + title: str_2(UIStrings21.a11yAudioVideoGroupTitle), + description: str_2(UIStrings21.a11yAudioVideoGroupDescription) + }, + "a11y-tables-lists": { + title: str_2(UIStrings21.a11yTablesListsVideoGroupTitle), + description: str_2(UIStrings21.a11yTablesListsVideoGroupDescription) + }, + "seo-mobile": { + title: str_2(UIStrings21.seoMobileGroupTitle), + description: str_2(UIStrings21.seoMobileGroupDescription) + }, + "seo-content": { + title: str_2(UIStrings21.seoContentGroupTitle), + description: str_2(UIStrings21.seoContentGroupDescription) + }, + "seo-crawl": { + title: str_2(UIStrings21.seoCrawlingGroupTitle), + description: str_2(UIStrings21.seoCrawlingGroupDescription) + }, + "best-practices-trust-safety": { + title: str_2(UIStrings21.bestPracticesTrustSafetyGroupTitle) + }, + "best-practices-ux": { + title: str_2(UIStrings21.bestPracticesUXGroupTitle) + }, + "best-practices-browser-compat": { + title: str_2(UIStrings21.bestPracticesBrowserCompatGroupTitle) + }, + "best-practices-general": { + title: str_2(UIStrings21.bestPracticesGeneralGroupTitle) + }, + // Group for audits that should not be displayed. + "hidden": { title: "" } + }, + categories: { + "performance": { + title: str_2(UIStrings21.performanceCategoryTitle), + supportedModes: ["navigation", "timespan", "snapshot"], + auditRefs: [ + { id: "first-contentful-paint", weight: 10, group: "metrics", acronym: "FCP" }, + { id: "largest-contentful-paint", weight: 25, group: "metrics", acronym: "LCP" }, + { id: "total-blocking-time", weight: 30, group: "metrics", acronym: "TBT" }, + { id: "cumulative-layout-shift", weight: 25, group: "metrics", acronym: "CLS" }, + { id: "speed-index", weight: 10, group: "metrics", acronym: "SI" }, + { id: "interaction-to-next-paint", weight: 0, group: "metrics", acronym: "INP" }, + // Insight audits. + { id: "cache-insight", weight: 0, group: "insights" }, + { id: "cls-culprits-insight", weight: 0, group: "insights" }, + { id: "document-latency-insight", weight: 0, group: "insights" }, + { id: "dom-size-insight", weight: 0, group: "insights" }, + { id: "duplicated-javascript-insight", weight: 0, group: "insights" }, + { id: "font-display-insight", weight: 0, group: "insights" }, + { id: "forced-reflow-insight", weight: 0, group: "insights" }, + { id: "image-delivery-insight", weight: 0, group: "insights" }, + { id: "inp-breakdown-insight", weight: 0, group: "insights" }, + { id: "lcp-breakdown-insight", weight: 0, group: "insights" }, + { id: "lcp-discovery-insight", weight: 0, group: "insights" }, + { id: "legacy-javascript-insight", weight: 0, group: "insights" }, + { id: "modern-http-insight", weight: 0, group: "insights" }, + { id: "network-dependency-tree-insight", weight: 0, group: "insights" }, + { id: "render-blocking-insight", weight: 0, group: "insights" }, + { id: "third-parties-insight", weight: 0, group: "insights" }, + { id: "viewport-insight", weight: 0, group: "insights" }, + // These are our "invisible" metrics. Not displayed, but still in the LHR. + { id: "interactive", weight: 0, group: "hidden", acronym: "TTI" }, + { id: "max-potential-fid", weight: 0, group: "hidden" }, + { id: "unminified-css", weight: 0, group: "diagnostics" }, + { id: "unminified-javascript", weight: 0, group: "diagnostics" }, + { id: "unused-css-rules", weight: 0, group: "diagnostics" }, + { id: "unused-javascript", weight: 0, group: "diagnostics" }, + { id: "total-byte-weight", weight: 0, group: "diagnostics" }, + { id: "user-timings", weight: 0, group: "diagnostics" }, + { id: "bootup-time", weight: 0, group: "diagnostics" }, + { id: "mainthread-work-breakdown", weight: 0, group: "diagnostics" }, + { id: "long-tasks", weight: 0, group: "diagnostics" }, + { id: "non-composited-animations", weight: 0, group: "diagnostics" }, + { id: "unsized-images", weight: 0, group: "diagnostics" }, + { id: "bf-cache", weight: 0, group: "diagnostics" }, + // Audits past this point contain useful data but are not displayed with other audits. + { id: "network-requests", weight: 0, group: "hidden" }, + { id: "network-rtt", weight: 0, group: "hidden" }, + { id: "network-server-latency", weight: 0, group: "hidden" }, + { id: "main-thread-tasks", weight: 0, group: "hidden" }, + { id: "diagnostics", weight: 0, group: "hidden" }, + { id: "metrics", weight: 0, group: "hidden" }, + { id: "screenshot-thumbnails", weight: 0, group: "hidden" }, + { id: "final-screenshot", weight: 0, group: "hidden" }, + { id: "script-treemap-data", weight: 0, group: "hidden" }, + { id: "resource-summary", weight: 0, group: "hidden" }, + { id: "redirects", weight: 0, group: "hidden" }, + { id: "server-response-time", weight: 0, group: "hidden" }, + { id: "layout-shifts", weight: 0, group: "hidden" } + ] + }, + "accessibility": { + title: str_2(UIStrings21.a11yCategoryTitle), + description: str_2(UIStrings21.a11yCategoryDescription), + manualDescription: str_2(UIStrings21.a11yCategoryManualDescription), + supportedModes: ["navigation", "snapshot"], + // Audit weights weights are derived from the axe-core "Impact", + // with adjustments based on axe-core "Tags": + // + // ┌────────────┬───────────────────────────────────────────────┐ + // │ Impact │ Weight Based on Tags │ + // │ ├──────────────┬─────────────────┬──────────────┤ + // │ │ wcag A+AA │ best-practice │ experimental │ + // │ │ (ex: wcag2aa)│ (w/o wcag tag) │ │ + // ├────────────┼──────────────┼─────────────────┼──────────────┤ + // │ Minor │ 1 │ 0 │ 0 │ + // │ Moderate │ 3 │ 3 │ 0 │ + // │ Serious │ 7 │ 7 │ 0 │ + // │ Critical │ 10 │ 10 │ 0 │ + // └────────────┴──────────────┴─────────────────┴──────────────┘ + // + // Notes: + // • Experimental rules always have weight 0 + // • Best practice rules only affect scores when tagged with wcagA+AA + // and are moderate, serious, or critical. + // + // To find the latest axe-core Impact and Tag values: + // 1. Browse to https://dequeuniversity.com/rules/axe/html. + // 2. Click on the latest rule set (ex: https://dequeuniversity.com/rules/axe/html/4.10) + // 3. Review the tables + auditRefs: [ + { id: "accesskeys", weight: 7, group: "a11y-navigation" }, + // Serious, best-practice + { id: "aria-allowed-attr", weight: 10, group: "a11y-aria" }, + // Critical, wcag2a + { id: "aria-command-name", weight: 7, group: "a11y-aria" }, + // Serious, wcag2a + { id: "aria-conditional-attr", weight: 7, group: "a11y-aria" }, + // Serious, wcag2a + { id: "aria-deprecated-role", weight: 1, group: "a11y-aria" }, + // Minor, wcag2a + { id: "aria-dialog-name", weight: 7, group: "a11y-aria" }, + // Serious, best-practice + { id: "aria-hidden-body", weight: 10, group: "a11y-aria" }, + // Critical, wcag2a + { id: "aria-hidden-focus", weight: 7, group: "a11y-aria" }, + // Serious, wcag2a + { id: "aria-input-field-name", weight: 7, group: "a11y-aria" }, + // Serious, wcag2a + { id: "aria-meter-name", weight: 7, group: "a11y-aria" }, + // Serious, wcag2a + { id: "aria-progressbar-name", weight: 7, group: "a11y-aria" }, + // Serious, wcag2a + { id: "aria-prohibited-attr", weight: 7, group: "a11y-aria" }, + // Serious, wcag2a + { id: "aria-required-attr", weight: 10, group: "a11y-aria" }, + // Critical, wcag2a + { id: "aria-required-children", weight: 10, group: "a11y-aria" }, + // Critical, wcag2a + { id: "aria-required-parent", weight: 10, group: "a11y-aria" }, + // Critical, wcag2a + { id: "aria-roles", weight: 10, group: "a11y-aria" }, + // Critical, wcag2a + { id: "aria-text", weight: 7, group: "a11y-aria" }, + // Serious, best-practice + { id: "aria-toggle-field-name", weight: 7, group: "a11y-aria" }, + // Serious, wcag2a + { id: "aria-tooltip-name", weight: 7, group: "a11y-aria" }, + // Serious, wcag2a + { id: "aria-treeitem-name", weight: 7, group: "a11y-aria" }, + // Serious, best-practice + { id: "aria-valid-attr-value", weight: 10, group: "a11y-aria" }, + // Critical, wcag2a + { id: "aria-valid-attr", weight: 10, group: "a11y-aria" }, + // Critical, wcag2a + { id: "button-name", weight: 10, group: "a11y-names-labels" }, + // Critical, wcag2a + { id: "bypass", weight: 7, group: "a11y-navigation" }, + // Serious, wcag2a + { id: "color-contrast", weight: 7, group: "a11y-color-contrast" }, + // Serious, wcag2aa + { id: "definition-list", weight: 7, group: "a11y-tables-lists" }, + // Serious, wcag2a + { id: "dlitem", weight: 7, group: "a11y-tables-lists" }, + // Serious, wcag2a + { id: "document-title", weight: 7, group: "a11y-names-labels" }, + // Serious, wcag2a + { id: "duplicate-id-aria", weight: 10, group: "a11y-aria" }, + // Critical, wcag2a + { id: "form-field-multiple-labels", weight: 3, group: "a11y-names-labels" }, + // Moderate, wcag2a + { id: "frame-title", weight: 7, group: "a11y-names-labels" }, + // Serious, wcag2a + { id: "heading-order", weight: 3, group: "a11y-navigation" }, + // Moderate, best-practice + { id: "html-has-lang", weight: 7, group: "a11y-language" }, + // Serious, wcag2a + { id: "html-lang-valid", weight: 7, group: "a11y-language" }, + // Serious, wcag2a + { id: "html-xml-lang-mismatch", weight: 3, group: "a11y-language" }, + // Moderate, wcag2a + { id: "image-alt", weight: 10, group: "a11y-names-labels" }, + // Critical, wcag2a + { id: "input-button-name", weight: 10, group: "a11y-names-labels" }, + // Critical, wcag2a + { id: "input-image-alt", weight: 10, group: "a11y-names-labels" }, + // Critical, wcag2a + { id: "label", weight: 10, group: "a11y-names-labels" }, + // Critical, wcag2a + { id: "link-in-text-block", weight: 7, group: "a11y-color-contrast" }, + // Serious, wcag2a + { id: "link-name", weight: 7, group: "a11y-names-labels" }, + // Serious, wcag2a + { id: "list", weight: 7, group: "a11y-tables-lists" }, + // Serious, wcag2a + { id: "listitem", weight: 7, group: "a11y-tables-lists" }, + // Serious, wcag2a + { id: "meta-refresh", weight: 10, group: "a11y-best-practices" }, + // Critical, wcag2a + { id: "meta-viewport", weight: 10, group: "a11y-best-practices" }, + // Critical, wcag2aa + { id: "object-alt", weight: 7, group: "a11y-names-labels" }, + // Serious, wcag2a + { id: "select-name", weight: 10, group: "a11y-names-labels" }, + // Critical, wcag2a + { id: "skip-link", weight: 3, group: "a11y-names-labels" }, + // Moderate, best-practice + { id: "tabindex", weight: 7, group: "a11y-navigation" }, + // Serious, best-practice + { id: "target-size", weight: 7, group: "a11y-best-practices" }, + // Serious, wcag22aa + { id: "td-headers-attr", weight: 7, group: "a11y-tables-lists" }, + // Serious, wcag2a + { id: "th-has-data-cells", weight: 7, group: "a11y-tables-lists" }, + // Serious, wcag2a + { id: "valid-lang", weight: 7, group: "a11y-language" }, + // Serious, wcag2aa + { id: "video-caption", weight: 10, group: "a11y-audio-video" }, + // Critical, wcag2a + { id: "landmark-one-main", weight: 3, group: "a11y-best-practices" }, + // Moderate, best-practice + // Manual audits + { id: "focusable-controls", weight: 0 }, + { id: "interactive-element-affordance", weight: 0 }, + { id: "logical-tab-order", weight: 0 }, + { id: "visual-order-follows-dom", weight: 0 }, + { id: "focus-traps", weight: 0 }, + { id: "managed-focus", weight: 0 }, + { id: "use-landmarks", weight: 0 }, + { id: "offscreen-content-hidden", weight: 0 }, + { id: "custom-controls-labels", weight: 0 }, + { id: "custom-controls-roles", weight: 0 }, + // Low-impact best-practices + { id: "table-duplicate-name", weight: 0, group: "a11y-best-practices" }, + // Minor, best-practice + { id: "empty-heading", weight: 0, group: "a11y-best-practices" }, + // Minor, best-practice + { id: "aria-allowed-role", weight: 0, group: "a11y-best-practices" }, + // Minor, best-practice + { id: "image-redundant-alt", weight: 0, group: "a11y-names-labels" }, + // Minor, best-practice + // WCAG AAA + { id: "identical-links-same-purpose", weight: 0, group: "a11y-best-practices" }, + // Minor, wcag2aaa + // Hidden audits (ie. experimental) + { id: "label-content-name-mismatch", weight: 0, group: "hidden" }, + // Serious, experimental + { id: "table-fake-caption", weight: 0, group: "hidden" }, + // Serious, experimental + { id: "td-has-header", weight: 0, group: "hidden" } + // Critical, experimental + ] + }, + "best-practices": { + title: str_2(UIStrings21.bestPracticesCategoryTitle), + supportedModes: ["navigation", "timespan", "snapshot"], + auditRefs: [ + // Trust & Safety + { id: "is-on-https", weight: 5, group: "best-practices-trust-safety" }, + { id: "redirects-http", weight: 1, group: "best-practices-trust-safety" }, + { id: "geolocation-on-start", weight: 1, group: "best-practices-trust-safety" }, + { id: "notification-on-start", weight: 1, group: "best-practices-trust-safety" }, + { id: "csp-xss", weight: 0, group: "best-practices-trust-safety" }, + { id: "has-hsts", weight: 0, group: "best-practices-trust-safety" }, + { id: "origin-isolation", weight: 0, group: "best-practices-trust-safety" }, + { id: "clickjacking-mitigation", weight: 0, group: "best-practices-trust-safety" }, + { id: "trusted-types-xss", weight: 0, group: "best-practices-trust-safety" }, + // User Experience + { id: "paste-preventing-inputs", weight: 3, group: "best-practices-ux" }, + { id: "image-aspect-ratio", weight: 1, group: "best-practices-ux" }, + { id: "image-size-responsive", weight: 1, group: "best-practices-ux" }, + // Browser Compatibility + { id: "doctype", weight: 1, group: "best-practices-browser-compat" }, + { id: "charset", weight: 1, group: "best-practices-browser-compat" }, + // General Group + { id: "js-libraries", weight: 0, group: "best-practices-general" }, + { id: "deprecations", weight: 5, group: "best-practices-general" }, + { id: "third-party-cookies", weight: 5, group: "best-practices-general" }, + { id: "errors-in-console", weight: 1, group: "best-practices-general" }, + { id: "valid-source-maps", weight: 0, group: "best-practices-general" }, + { id: "inspector-issues", weight: 1, group: "best-practices-general" } + ] + }, + "seo": { + title: str_2(UIStrings21.seoCategoryTitle), + description: str_2(UIStrings21.seoCategoryDescription), + manualDescription: str_2(UIStrings21.seoCategoryManualDescription), + supportedModes: ["navigation", "snapshot"], + auditRefs: [ + // Should be at least 31% of the score, such that this audit failing + // results in the SEO category failing. + // Solve for w: + // w / (w + T) >= 0.31 + // where T is the sum of all the other weights. + { id: "is-crawlable", weight: 93 / 23, group: "seo-crawl" }, + { id: "document-title", weight: 1, group: "seo-content" }, + { id: "meta-description", weight: 1, group: "seo-content" }, + { id: "http-status-code", weight: 1, group: "seo-crawl" }, + { id: "link-text", weight: 1, group: "seo-content" }, + { id: "crawlable-anchors", weight: 1, group: "seo-crawl" }, + { id: "robots-txt", weight: 1, group: "seo-crawl" }, + { id: "image-alt", weight: 1, group: "seo-content" }, + { id: "hreflang", weight: 1, group: "seo-content" }, + { id: "canonical", weight: 1, group: "seo-content" }, + // Manual audits + { id: "structured-data", weight: 0 } + ] + } + } + }; + Object.defineProperty(defaultConfig, "UIStrings", { + enumerable: false, + get: /* @__PURE__ */ __name(() => UIStrings21, "get") + }); + default_config_default = defaultConfig; + } +}); + +// core/config/validation.js +function isValidArtifactDependency(dependent, dependency) { + const levels = { timespan: 0, snapshot: 1, navigation: 2 }; + const dependentLevel = Math.min(...dependent.instance.meta.supportedModes.map((l) => levels[l])); + const dependencyLevel = Math.min(...dependency.instance.meta.supportedModes.map((l) => levels[l])); + if (dependentLevel === levels.timespan) return dependencyLevel === levels.timespan; + if (dependentLevel === levels.snapshot) return dependencyLevel === levels.snapshot; + return true; +} +function assertValidPluginName(config3, pluginName) { + const parts = pluginName.split("/"); + if (parts.length === 2) { + pluginName = parts[1]; + } + if (!pluginName.startsWith("lighthouse-plugin-")) { + throw new Error(`plugin name '${pluginName}' does not start with 'lighthouse-plugin-'`); + } + if (config3.categories?.[pluginName]) { + throw new Error(`plugin name '${pluginName}' not allowed because it is the id of a category already found in config`); + } +} +function assertValidArtifact(artifactDefn) { + const gatherer = artifactDefn.gatherer.instance; + if (typeof gatherer.meta !== "object") { + throw new Error(`Gatherer for ${artifactDefn.id} did not provide a meta object.`); + } + if (gatherer.meta.supportedModes.length === 0) { + throw new Error(`Gatherer for ${artifactDefn.id} did not support any gather modes.`); + } + if (typeof gatherer.getArtifact !== "function" || gatherer.getArtifact === base_gatherer_default.prototype.getArtifact) { + throw new Error(`Gatherer for ${artifactDefn.id} did not define a "getArtifact" method.`); + } +} +function assertValidAudit(auditDefinition) { + const { implementation, path: auditPath } = auditDefinition; + const auditName = auditPath || implementation?.meta?.id || "Unknown audit"; + if (typeof implementation.audit !== "function" || implementation.audit === Audit.audit) { + throw new Error(`${auditName} has no audit() method.`); + } + if (typeof implementation.meta.id !== "string") { + throw new Error(`${auditName} has no meta.id property, or the property is not a string.`); + } + if (!isStringOrIcuMessage(implementation.meta.title)) { + throw new Error(`${auditName} has no meta.title property, or the property is not a string.`); + } + const scoreDisplayMode = implementation.meta.scoreDisplayMode || Audit.SCORING_MODES.BINARY; + if (!isStringOrIcuMessage(implementation.meta.failureTitle) && scoreDisplayMode === Audit.SCORING_MODES.BINARY) { + throw new Error(`${auditName} has no meta.failureTitle and should.`); + } + if (!isStringOrIcuMessage(implementation.meta.description)) { + throw new Error( + `${auditName} has no meta.description property, or the property is not a string.` + ); + } else if (implementation.meta.description === "") { + throw new Error( + `${auditName} has an empty meta.description string. Please add a description for the UI.` + ); + } + if (!Array.isArray(implementation.meta.requiredArtifacts)) { + throw new Error( + `${auditName} has no meta.requiredArtifacts property, or the property is not an array.` + ); + } +} +function assertValidCategories(categories, audits, groups) { + if (!categories) { + return; + } + const auditsKeyedById = new Map((audits || []).map((audit) => { + return [audit.implementation.meta.id, audit]; + })); + Object.keys(categories).forEach((categoryId) => { + categories[categoryId].auditRefs.forEach((auditRef, index) => { + if (!auditRef.id) { + throw new Error(`missing an audit id at ${categoryId}[${index}]`); + } + const audit = auditsKeyedById.get(auditRef.id); + if (!audit) { + throw new Error(`could not find ${auditRef.id} audit for category ${categoryId}`); + } + const auditImpl = audit.implementation; + const isManual = auditImpl.meta.scoreDisplayMode === "manual"; + if (categoryId === "accessibility" && !auditRef.group && !isManual) { + throw new Error(`${auditRef.id} accessibility audit does not have a group`); + } + if (auditRef.weight > 0 && isManual) { + throw new Error(`${auditRef.id} is manual but has a positive weight`); + } + if (auditRef.group && (!groups || !groups[auditRef.group])) { + throw new Error(`${auditRef.id} references unknown group ${auditRef.group}`); + } + }); + }); +} +function assertValidSettings(settings) { + if (!settings.formFactor) { + throw new Error(`\`settings.formFactor\` must be defined as 'mobile' or 'desktop'. See https://github.com/GoogleChrome/lighthouse/blob/main/docs/emulation.md`); + } + if (!settings.screenEmulation.disabled) { + if (settings.screenEmulation.mobile !== (settings.formFactor === "mobile")) { + throw new Error(`Screen emulation mobile setting (${settings.screenEmulation.mobile}) does not match formFactor setting (${settings.formFactor}). See https://github.com/GoogleChrome/lighthouse/blob/main/docs/emulation.md`); + } + } + const skippedAndOnlyAuditId = settings.skipAudits?.find((auditId) => settings.onlyAudits?.includes(auditId)); + if (skippedAndOnlyAuditId) { + throw new Error(`${skippedAndOnlyAuditId} appears in both skipAudits and onlyAudits`); + } +} +function assertValidArtifacts(artifactDefns) { + const availableArtifacts = /* @__PURE__ */ new Set(); + for (const artifact of artifactDefns) { + assertValidArtifact(artifact); + if (availableArtifacts.has(artifact.id)) { + throw new Error(`Config defined multiple artifacts with id '${artifact.id}'`); + } + availableArtifacts.add(artifact.id); + if (!artifact.dependencies) continue; + for (const [dependencyKey, { id: dependencyId }] of Object.entries(artifact.dependencies)) { + if (availableArtifacts.has(dependencyId)) continue; + throwInvalidDependencyOrder(artifact.id, dependencyKey); + } + } +} +function assertValidConfig(resolvedConfig) { + assertValidArtifacts(resolvedConfig.artifacts || []); + for (const auditDefn of resolvedConfig.audits || []) { + assertValidAudit(auditDefn); + } + assertValidCategories(resolvedConfig.categories, resolvedConfig.audits, resolvedConfig.groups); + assertValidSettings(resolvedConfig.settings); +} +function throwInvalidDependencyOrder(artifactId, dependencyKey) { + throw new Error( + [ + `Failed to find dependency "${dependencyKey}" for "${artifactId}" artifact`, + `Check that...`, + ` 1. A gatherer exposes a matching Symbol that satisfies "${dependencyKey}".`, + ` 2. "${dependencyKey}" is configured to run before "${artifactId}"` + ].join("\n") + ); +} +function throwInvalidArtifactDependency(artifactId, dependencyKey) { + throw new Error( + [ + `Dependency "${dependencyKey}" for "${artifactId}" artifact is invalid.`, + `The dependency must be collected before the dependent.` + ].join("\n") + ); +} +var init_validation = __esm({ + "core/config/validation.js"() { + "use strict"; + init_process_global(); + init_audit(); + init_base_gatherer(); + init_i18n(); + /** + * @license + * Copyright 2021 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + __name(isValidArtifactDependency, "isValidArtifactDependency"); + __name(assertValidPluginName, "assertValidPluginName"); + __name(assertValidArtifact, "assertValidArtifact"); + __name(assertValidAudit, "assertValidAudit"); + __name(assertValidCategories, "assertValidCategories"); + __name(assertValidSettings, "assertValidSettings"); + __name(assertValidArtifacts, "assertValidArtifacts"); + __name(assertValidConfig, "assertValidConfig"); + __name(throwInvalidDependencyOrder, "throwInvalidDependencyOrder"); + __name(throwInvalidArtifactDependency, "throwInvalidArtifactDependency"); + } +}); + +// core/config/filters.js +function getAuditIdsInCategories(allCategories, onlyCategories) { + if (!allCategories) return /* @__PURE__ */ new Set(); + onlyCategories = onlyCategories || Object.keys(allCategories); + const categories = onlyCategories.map((categoryId) => allCategories[categoryId]); + const auditRefs = categories.flatMap((category) => category?.auditRefs || []); + return new Set(auditRefs.map((auditRef) => auditRef.id)); +} +function filterArtifactsByAvailableAudits(artifacts, audits) { + if (!artifacts) return null; + if (!audits) return artifacts; + const artifactsById = new Map(artifacts.map((artifact) => [artifact.id, artifact])); + const artifactIdsToKeep = /* @__PURE__ */ new Set([ + ...filterResistantArtifactIds, + ...audits.flatMap((audit) => audit.implementation.meta.requiredArtifacts) + ]); + let previousSize = 0; + while (previousSize !== artifactIdsToKeep.size) { + previousSize = artifactIdsToKeep.size; + for (const artifactId of artifactIdsToKeep) { + const artifact = artifactsById.get(artifactId); + if (!artifact) continue; + if (!artifact.dependencies) continue; + for (const dep of Object.values(artifact.dependencies)) { + artifactIdsToKeep.add(dep.id); + } + } + } + return artifacts.filter((artifact) => artifactIdsToKeep.has(artifact.id)); +} +function filterArtifactsByGatherMode(artifacts, mode) { + if (!artifacts) return null; + return artifacts.filter((artifact) => { + return artifact.gatherer.instance.meta.supportedModes.includes(mode); + }); +} +function filterAuditsByAvailableArtifacts(audits, availableArtifacts) { + if (!audits) return null; + const availableArtifactIds = new Set( + availableArtifacts.map((artifact) => artifact.id).concat(baseArtifactKeys) + ); + return audits.filter((audit) => { + const meta = audit.implementation.meta; + return meta.requiredArtifacts.every((id) => availableArtifactIds.has(id)); + }); +} +function filterAuditsByGatherMode(audits, mode) { + if (!audits) return null; + return audits.filter((audit) => { + const meta = audit.implementation.meta; + return !meta.supportedModes || meta.supportedModes.includes(mode); + }); +} +function filterCategoriesByGatherMode(categories, mode) { + if (!categories) return null; + const categoriesToKeep = Object.entries(categories).filter(([_, category]) => { + return !category.supportedModes || category.supportedModes.includes(mode); + }); + return Object.fromEntries(categoriesToKeep); +} +function filterCategoriesByExplicitFilters(categories, onlyCategories) { + if (!categories || !onlyCategories) return categories; + const categoriesToKeep = Object.entries(categories).filter(([categoryId]) => onlyCategories.includes(categoryId)); + return Object.fromEntries(categoriesToKeep); +} +function errorOnUnknownOnlyCategories(allCategories, onlyCategories) { + if (!onlyCategories) return; + const unknown = onlyCategories.filter((c) => !allCategories?.[c]); + if (unknown.length) { + throw new Error(`unrecognized category in 'onlyCategories': ${unknown.join(", ")}`); + } +} +function filterCategoriesByAvailableAudits(categories, availableAudits) { + if (!categories) return categories; + const availableAuditIdToMeta = new Map( + availableAudits.map((audit) => [audit.implementation.meta.id, audit.implementation.meta]) + ); + const categoryEntries = Object.entries(categories).map(([categoryId, category]) => { + const filteredCategory = { + ...category, + auditRefs: category.auditRefs.filter((ref) => availableAuditIdToMeta.has(ref.id)) + }; + const didFilter = filteredCategory.auditRefs.length < category.auditRefs.length; + const hasOnlyManualAudits = filteredCategory.auditRefs.every((ref) => { + const meta = availableAuditIdToMeta.get(ref.id); + if (!meta) return false; + return meta.scoreDisplayMode === Audit.SCORING_MODES.MANUAL; + }); + if (didFilter && hasOnlyManualAudits) filteredCategory.auditRefs = []; + return [categoryId, filteredCategory]; + }).filter((entry) => typeof entry[1] === "object" && entry[1].auditRefs.length); + return Object.fromEntries(categoryEntries); +} +function filterConfigByGatherMode(resolvedConfig, mode) { + const artifacts = filterArtifactsByGatherMode(resolvedConfig.artifacts, mode); + const supportedAudits = filterAuditsByGatherMode(resolvedConfig.audits, mode); + const audits = filterAuditsByAvailableArtifacts(supportedAudits, artifacts || []); + const supportedCategories = filterCategoriesByGatherMode(resolvedConfig.categories, mode); + const categories = filterCategoriesByAvailableAudits(supportedCategories, audits || []); + return { + ...resolvedConfig, + artifacts, + audits, + categories + }; +} +function filterConfigByExplicitFilters(resolvedConfig, filters) { + const { onlyAudits, onlyCategories, skipAudits } = filters; + if (onlyAudits && !onlyAudits.length) { + throw new Error(`onlyAudits cannot be an empty array.`); + } + if (onlyCategories && !onlyCategories.length) { + throw new Error(`onlyCategories cannot be an empty array.`); + } + errorOnUnknownOnlyCategories(resolvedConfig.categories, onlyCategories); + let baseAuditIds = getAuditIdsInCategories(resolvedConfig.categories, void 0); + if (onlyCategories) { + baseAuditIds = getAuditIdsInCategories(resolvedConfig.categories, onlyCategories); + } else if (onlyAudits) { + baseAuditIds = /* @__PURE__ */ new Set(); + } else if (!resolvedConfig.categories || !Object.keys(resolvedConfig.categories).length) { + baseAuditIds = new Set(resolvedConfig.audits?.map((audit) => audit.implementation.meta.id)); + } + const auditIdsToKeep = new Set( + [ + ...baseAuditIds, + // Start with our base audits. + ...onlyAudits || [], + // Additionally include the opt-in audits from `onlyAudits`. + ...filterResistantAuditIds + // Always include any filter-resistant audits. + ].filter((auditId) => !skipAudits || !skipAudits.includes(auditId)) + ); + const audits = auditIdsToKeep.size && resolvedConfig.audits ? resolvedConfig.audits.filter((audit) => auditIdsToKeep.has(audit.implementation.meta.id)) : resolvedConfig.audits; + const availableCategories = filterCategoriesByAvailableAudits(resolvedConfig.categories, audits || []); + const categories = filterCategoriesByExplicitFilters(availableCategories, onlyCategories); + let artifacts = filterArtifactsByAvailableAudits(resolvedConfig.artifacts, audits); + if (artifacts && resolvedConfig.settings.disableFullPageScreenshot) { + artifacts = artifacts.filter(({ id }) => id !== "FullPageScreenshot"); + } + return { + ...resolvedConfig, + artifacts, + audits, + categories + }; +} +var baseArtifactKeySource, baseArtifactKeys, filterResistantAuditIds, filterResistantArtifactIds; +var init_filters = __esm({ + "core/config/filters.js"() { + "use strict"; + init_process_global(); + init_audit(); + /** + * @license + * Copyright 2021 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + baseArtifactKeySource = { + fetchTime: "", + LighthouseRunWarnings: "", + BenchmarkIndex: "", + HostDPR: "", + settings: "", + Timing: "", + URL: "", + PageLoadError: "", + HostFormFactor: "", + HostUserAgent: "", + HostProduct: "", + GatherContext: "" + }; + baseArtifactKeys = Object.keys(baseArtifactKeySource); + filterResistantAuditIds = []; + filterResistantArtifactIds = ["Stacks", "NetworkUserAgent", "FullPageScreenshot"]; + __name(getAuditIdsInCategories, "getAuditIdsInCategories"); + __name(filterArtifactsByAvailableAudits, "filterArtifactsByAvailableAudits"); + __name(filterArtifactsByGatherMode, "filterArtifactsByGatherMode"); + __name(filterAuditsByAvailableArtifacts, "filterAuditsByAvailableArtifacts"); + __name(filterAuditsByGatherMode, "filterAuditsByGatherMode"); + __name(filterCategoriesByGatherMode, "filterCategoriesByGatherMode"); + __name(filterCategoriesByExplicitFilters, "filterCategoriesByExplicitFilters"); + __name(errorOnUnknownOnlyCategories, "errorOnUnknownOnlyCategories"); + __name(filterCategoriesByAvailableAudits, "filterCategoriesByAvailableAudits"); + __name(filterConfigByGatherMode, "filterConfigByGatherMode"); + __name(filterConfigByExplicitFilters, "filterConfigByExplicitFilters"); + } +}); + +// core/config/config-plugin.js +function isArrayOfUnknownObjects(arr) { + return Array.isArray(arr) && arr.every(isObjectOfUnknownProperties); +} +function isObjectOfUnknownProperties(val) { + return typeof val === "object" && val !== null && !Array.isArray(val); +} +function objectIsGatherMode(str) { + if (typeof str !== "string") return false; + return str === "navigation" || str === "timespan" || str === "snapshot"; +} +function isArrayOfGatherModes(arr) { + if (!Array.isArray(arr)) return false; + return arr.every(objectIsGatherMode); +} +function assertNoExcessProperties(obj, pluginName, objectName = "") { + if (objectName) { + objectName += " "; + } + const invalidKeys = Object.keys(obj); + if (invalidKeys.length > 0) { + const keys2 = invalidKeys.join(", "); + throw new Error(`${pluginName} has unrecognized ${objectName}properties: [${keys2}]`); + } +} +var ConfigPlugin, config_plugin_default; +var init_config_plugin = __esm({ + "core/config/config-plugin.js"() { + "use strict"; + init_process_global(); + init_i18n(); + /** + * @license + * Copyright 2019 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + __name(isArrayOfUnknownObjects, "isArrayOfUnknownObjects"); + __name(isObjectOfUnknownProperties, "isObjectOfUnknownProperties"); + __name(objectIsGatherMode, "objectIsGatherMode"); + __name(isArrayOfGatherModes, "isArrayOfGatherModes"); + __name(assertNoExcessProperties, "assertNoExcessProperties"); + ConfigPlugin = class _ConfigPlugin { + static { + __name(this, "ConfigPlugin"); + } + /** + * Extract and validate the list of AuditDefns added by the plugin (or undefined + * if no additional audits are being added by the plugin). + * @param {unknown} auditsJson + * @param {string} pluginName + * @return {Array<{path: string}>|undefined} + */ + static _parseAuditsList(auditsJson, pluginName) { + if (auditsJson === void 0) { + return void 0; + } else if (!isArrayOfUnknownObjects(auditsJson)) { + throw new Error(`${pluginName} has an invalid audits array.`); + } + return auditsJson.map((auditDefnJson) => { + const { path: path7, ...invalidRest } = auditDefnJson; + assertNoExcessProperties(invalidRest, pluginName, "audit"); + if (typeof path7 !== "string") { + throw new Error(`${pluginName} has a missing audit path.`); + } + return { + path: path7 + }; + }); + } + /** + * Extract and validate the list of category AuditRefs added by the plugin. + * @param {unknown} auditRefsJson + * @param {string} pluginName + * @return {Array} + */ + static _parseAuditRefsList(auditRefsJson, pluginName) { + if (!isArrayOfUnknownObjects(auditRefsJson)) { + throw new Error(`${pluginName} has no valid auditsRefs.`); + } + return auditRefsJson.map((auditRefJson) => { + const { id, weight, group, ...invalidRest } = auditRefJson; + assertNoExcessProperties(invalidRest, pluginName, "auditRef"); + if (typeof id !== "string") { + throw new Error(`${pluginName} has an invalid auditRef id.`); + } + if (typeof weight !== "number") { + throw new Error(`${pluginName} has an invalid auditRef weight.`); + } + if (typeof group !== "string" && typeof group !== "undefined") { + throw new Error(`${pluginName} has an invalid auditRef group.`); + } + const prependedGroup = group ? `${pluginName}-${group}` : group; + return { + id, + weight, + group: prependedGroup + }; + }); + } + /** + * Extract and validate the category added by the plugin. + * @param {unknown} categoryJson + * @param {string} pluginName + * @return {LH.Config.CategoryJson} + */ + static _parseCategory(categoryJson, pluginName) { + if (!isObjectOfUnknownProperties(categoryJson)) { + throw new Error(`${pluginName} has no valid category.`); + } + const { + title, + description, + manualDescription, + auditRefs: auditRefsJson, + supportedModes, + ...invalidRest + } = categoryJson; + assertNoExcessProperties(invalidRest, pluginName, "category"); + if (!isStringOrIcuMessage(title)) { + throw new Error(`${pluginName} has an invalid category tile.`); + } + if (!isStringOrIcuMessage(description) && description !== void 0) { + throw new Error(`${pluginName} has an invalid category description.`); + } + if (!isStringOrIcuMessage(manualDescription) && manualDescription !== void 0) { + throw new Error(`${pluginName} has an invalid category manualDescription.`); + } + if (!isArrayOfGatherModes(supportedModes) && supportedModes !== void 0) { + throw new Error( + `${pluginName} supportedModes must be an array, valid array values are "navigation", "timespan", and "snapshot".` + ); + } + const auditRefs = _ConfigPlugin._parseAuditRefsList(auditRefsJson, pluginName); + return { + title, + auditRefs, + description, + manualDescription, + supportedModes + }; + } + /** + * Extract and validate groups JSON added by the plugin. + * @param {unknown} groupsJson + * @param {string} pluginName + * @return {Record|undefined} + */ + static _parseGroups(groupsJson, pluginName) { + if (groupsJson === void 0) { + return void 0; + } + if (!isObjectOfUnknownProperties(groupsJson)) { + throw new Error(`${pluginName} groups json is not defined as an object.`); + } + const groups = Object.entries(groupsJson); + const parsedGroupsJson = {}; + groups.forEach(([groupId, groupJson]) => { + if (!isObjectOfUnknownProperties(groupJson)) { + throw new Error(`${pluginName} has a group not defined as an object.`); + } + const { title, description, ...invalidRest } = groupJson; + assertNoExcessProperties(invalidRest, pluginName, "group"); + if (!isStringOrIcuMessage(title)) { + throw new Error(`${pluginName} has an invalid group title.`); + } + if (!isStringOrIcuMessage(description) && description !== void 0) { + throw new Error(`${pluginName} has an invalid group description.`); + } + parsedGroupsJson[`${pluginName}-${groupId}`] = { + title, + description + }; + }); + return parsedGroupsJson; + } + /** + * Extracts and validates a config from the provided plugin input, throwing + * if it deviates from the expected object shape. + * @param {unknown} pluginJson + * @param {string} pluginName + * @return {LH.Config} + */ + static parsePlugin(pluginJson, pluginName) { + pluginJson = JSON.parse(JSON.stringify(pluginJson)); + if (!isObjectOfUnknownProperties(pluginJson)) { + throw new Error(`${pluginName} is not defined as an object.`); + } + const { + audits: pluginAuditsJson, + category: pluginCategoryJson, + groups: pluginGroupsJson, + ...invalidRest + } = pluginJson; + assertNoExcessProperties(invalidRest, pluginName); + return { + audits: _ConfigPlugin._parseAuditsList(pluginAuditsJson, pluginName), + categories: { + [pluginName]: _ConfigPlugin._parseCategory(pluginCategoryJson, pluginName) + }, + groups: _ConfigPlugin._parseGroups(pluginGroupsJson, pluginName) + }; + } + }; + config_plugin_default = ConfigPlugin; + } +}); + +// core/lib/axe.js +var require2, axeSource; +var init_axe = __esm({ + "core/lib/axe.js"() { + "use strict"; + init_process_global(); + init_module(); + /** + * @license + * Copyright 2020 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + require2 = /* @__PURE__ */ createRequire({ url: "core/lib/axe.js" }.url); + axeSource = `/*! axe v4.11.0 + * Copyright (c) 2015 - 2025 Deque Systems, Inc. + * + * Your use of this Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This entire copyright notice must appear in every copy of this file you + * distribute or in any file that contains substantial portions of this source + * code. + */ +!function e(t){var n=t,r=t.document;function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var o=o||{},i=(o.version="4.11.0","function"==typeof define&&define.amd&&define("axe-core",[],(function(){return o})),"object"===("undefined"==typeof module?"undefined":a(module))&&module.exports&&"function"==typeof e.toString&&(o.source="("+e.toString()+')(typeof window === "object" ? window : this);',module.exports=o),"function"==typeof t.getComputedStyle&&(t.axe=o),["precision","format","inGamut"]),l=["space"],u=["algorithm"],s=["method"],c=["maxDeltaE","deltaEMethod","steps","maxSteps"],d=["variant"],p=["matches"],f=["chromium"],m=["noImplicit"],h=["noPresentational"],g=["node"],v=["relatedNodes"],b=["node"],y=["node"],D=["environmentData"],w=["environmentData"],x=["environmentData"],E=["environmentData"],A=["environmentD\ +ata"];function F(e,t,n){return(t=Y(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function C(e,t,n){var r;return N()?Reflect.construct.apply(null,arguments):((r=[null]).push.apply(r,t),t=new(e.bind.apply(e,r)),n&&_(t,n.prototype),t)}function k(e,t){if(null==e)return{};var n,r=((e,t)=>{if(null==e)return{};var n,r={};for(n in e)!{}.hasOwnProperty.call(e,n)||-1!==t.indexOf(n)||(r[n]=e[n]);return r})(e,t);if(Object.getOwnPropertySymbols)for(var a=Object.getOwnPropertySymbols(e),o=0;o{if(Array.isArray(e))return Z(e)})(e)||P(e)||X(e)||(()=>{throw new TypeError("Invalid attempt to s\ +pread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")})()}function P(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function I(e,t,n){j(e,t),t.set(e,n)}function B(e,t){j(e,t),t.add(e)}function j(e,t){if(t.has(e))throw new TypeError("Cannot initialize the same private elements twice on an object")}function L(e,t){return e.get(z(e,t))}function q(e,t,n){e.set(z(e,t),n)}function z(e,t,n){if("function"==typeof e?e===t:e.has(t))return arguments.length<3?t:n;throw new TypeError("Private element is not present on this object")}function V(e,t){return $(e)||((e,t)=>{var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,o,i,l=[],u=!0,s=!1;try{if(o=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;u=!1}else for(;!(u=(r=o.call(n)).done)&&(l.push(r.value),l.length!==t);u=!0);}catch(e){s=!0,a=e}finally{try{if(!u&&null!=n.return&&(i=n.ret\ +urn(),Object(i)!==i))return}finally{if(s)throw a}}return l}})(e,t)||X(e,t)||G()}function G(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function $(e){if(Array.isArray(e))return e}function H(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function U(e,t){for(var n=0;n{if("object"!=a(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0===n)return String(e);if(n=n.call(e,"string"),"object"==a(n))throw new TypeError("@@toPrimitive must return a primitive value.");return n})(e),"symbol"==a(e)?e:e+""}function K(e,t){var n,r,a,o,i="undefined"!=typeof Symbol&&e[Symbol.\ +iterator]||e["@@iterator"];if(i)return a=!(r=!0),{s:function(){i=i.call(e)},n:function(){var e=i.next();return r=e.done,e},e:function(e){a=!0,n=e},f:function(){try{r||null==i.return||i.return()}finally{if(a)throw n}}};if(Array.isArray(e)||(i=X(e))||t&&e&&"number"==typeof e.length)return i&&(e=i),o=0,{s:t=function(){},n:function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function(e){throw e},f:t};throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function X(e,t){var n;if(e)return"string"==typeof e?Z(e,t):"Map"===(n="Object"===(n={}.toString.call(e).slice(8,-1))&&e.constructor?e.constructor.name:n)||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Z(e,t):void 0}function Z(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n{var a=r.value;ge.call(e,a)||"default"===a||me(e,a,{get:function(){return t[a]},enumerable:!(n=be(t,a))||n.enumerable})})()}catch(e){o.e(e)}finally{o.f()}}return e}((t=me(null!=e?fe(he(e)):{},"default",e&&e.__esModule&&"default"in e?{get:function(){return e.default},enumerable:!0}:{value:e,enumerable:!0}),me(t,"__esModule",{value:!0})),e);var t}function pe(e,t,n){(t="symbol"!==a(t)?t+"":t)in e?me(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n}var fe=Object.create,me=Object.defineProperty\ +,he=Object.getPrototypeOf,ge=Object.prototype.hasOwnProperty,ve=Object.getOwnPropertyNames,be=Object.getOwnPropertyDescriptor,ye=se((function(e,o){var i;i=function(){function e(e){return"function"==typeof e}var o=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},i=0,l=void 0,u=void 0,s=function(e,t){h[i]=e,h[i+1]=t,2===(i+=2)&&(u?u(g):D())},c=void 0!==t?t:void 0,d=(d=c||{}).MutationObserver||d.WebKitMutationObserver,p="undefined"==typeof self&&"undefined"!=typeof process&&"[object process]"==={}.toString.call(process),f="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function m(){var e=setTimeout;return function(){return e(g,1)}}var h=new Array(1e3);function g(){for(var e=0;e{try{e.call(t,n,r)}catch(e){return e}})(n,t,(function(n){r||(r=!0,(t!==n?N:S)(e,n))}),(function(t)\ +{r||(r=!0,_(e,t))}),e._label);!r&&a&&(r=!0,_(e,a))}),e)}(t,n,r):S(t,n)}function N(e,t){if(e===t)_(e,new TypeError("You cannot resolve a promise with itself"));else if(r=a(n=t),null===n||"object"!==r&&"function"!==r)S(e,t);else{n=void 0;try{n=t.then}catch(t){return void _(e,t)}R(e,t,n)}var n,r}function T(e){e._onerror&&e._onerror(e._result),M(e)}function S(e,t){e._state===F&&(e._result=t,e._state=C,0!==e._subscribers.length)&&s(M,e)}function _(e,t){e._state===F&&(e._state=k,e._result=t,s(T,e))}function O(e,t,n,r){var a=e._subscribers,o=a.length;e._onerror=null,a[o]=t,a[o+C]=n,a[o+k]=r,0===o&&e._state&&s(M,e)}function M(e){var t=e._subscribers,n=e._state;if(0!==t.length){for(var r,a=void 0,o=e._result,i=0;i>0},ToUint32:function(e){return e>>>0}}),i=Math.LN2,l=Math.abs,u=Math.floor,s=Math.log,c=Math.min,d=Math.pow,p=Math.round;function f(e,t,n){return er)throw new RangeError("Array too large for polyfill");for(var t=0;t{m(e,t,{get:funct\ +ion(){return e._getter(t)},set:function(n){e._setter(t,n)},enumerable:!0,configurable:!1})})(t)}}function R(e,t){return e<<(t=32-t)>>t}function N(e,t){return e<<(t=32-t)>>>t}function T(e){return N(e[0],8)}function S(e,t,n){var r,a,o,p,f,m,h,g=(1<=d(2,1-g)?(a=c(u(s(e)/i),1023),2<=(o=v(e/d(2,a)*d(2,n)))/d(2,n)&&(a+=1,o=1),g>=1;return s.reverse(),u=s.join(""),o=(1<this.buffer.byteLength)throw new RangeError("byteOffset out of \ +range");if(this.byteOffset%this.BYTES_PER_ELEMENT)throw new RangeError("ArrayBuffer length minus the byteOffset is not a multiple of the element size.");if(arguments.length<3){if(this.byteLength=this.buffer.byteLength-this.byteOffset,this.byteLength%this.BYTES_PER_ELEMENT)throw new RangeError("length of buffer minus byteOffset not a multiple of the element size");this.length=this.byteLength/this.BYTES_PER_ELEMENT}else this.length=o.ToUint32(n),this.byteLength=this.length*this.BYTES_PER_ELEMENT;if(this.byteOffset+this.byteLength>this.buffer.byteLength)throw new RangeError("byteOffset and length reference an area beyond the end of the buffer")}else for(this.length=o.ToUint32((l=e).length),this.byteLength=this.length*this.BYTES_PER_ELEMENT,this.buffer=new O(this.byteLength),u=this.byteOffset=0;u=this.length)){for(var t=[],n=0,r=this.byteOffset+e*this.BYTES_PER_ELEMENT;nthis.length)throw new RangeError("Offset plus length of array is out of range");if(d=this.byteOffset+i*this.BYTES_PER_ELEMENT,p=n.length*this.BYTES_PER_ELEMENT,n.buffer===this.buffer){for(f=[],u=0,s=n.byteOffset;uthis.length)throw new RangeError("Offset plus length of array is out of range");for(u=0;uthis.buffer.byteLength)throw new RangeError("byteOffset out of range");if(this.byteLength=arguments.length<3?this.buffer.byteLength-this.byteOffset:o.ToUint32(r),this.byteOffset+this.byteLength>this.buffer.byteLength)throw new RangeError("byteOffset and length reference an area beyond the end of the buffer");C(this)}function j(t){return function(n,r){if((n=o.ToUint32(n))+t.BYTES_PER_ELEMENT>this.byteLength)throw new RangeError("Array index out of range");n+=this.byteOffset;for(var a=new e.Uint8Array(this.buffer,n,t.BYTES_PER_ELEMENT),i=[],l=0;lthis.byteLength)throw new RangeError("Array index out of range");r=new t([r]);for(var i=new e.Uint8Array(r.buffer),l=[],u=0;u{try{return Object.defineProperty({},"x",{}),1}catch(e){}})()?Object.defineProperty:function(e,t,n){if(!e===Object(e))throw new TypeError("Object.defineProperty called on non-object");return o.HasProperty(n,"get")&&Object.prototype.__defineGetter__&&Object.prototype.__defineGetter__.call(e,t,n.get),o.HasProperty(n,"set")&&Object.prototype.__defineSetter__&&Object.prototype.__defineSetter__.call(e,t,n.set),o.HasProperty(n,"value")&&(e[t]=n.value),e},e.ArrayBuffer=e.ArrayBuffer||O,E=P(1,(function(e){return[255&e]}),(function(e){return R(e[0],8)})),h=P(1,(function(e){return[255&e]}),T),g=P(1,(function(e){return[(e=p(Number(e)))<0?0:255>8&255,255&e]}),(function(e){return R(e[0]<<8|e[1],16)})),b=P(2,(function(e){return[e>>8&255,255&e]}),(function(e){return N(e[0]<<8|e[1],16)})),y=P(4,(function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]}),(function(e){return R(e[0]<<24|e[1]<<16|e[2]<<8|e[3],32)})),D=P(4,(function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]}),(function(e){return N(e[0]<<24|e[1]<<16|e[2]<<8|e[3],32)})),w=P(4,(function(e){return S(e,8,23)}),(function(e){return _(e,8,23)})),x=P(8,(function(e){return S(e,11,52)}),(function(e){return _(e,11,52)})),e.Int8Array=e.Int8Array||E,e.Uint8Array=e.Uint8Array||h,e.Uint8ClampedArray=e.Uint8ClampedArray||g,e.Int16Array=e.Int16Array||v,e.Uint16Array=e.Uint16Array||b,e.Int32Array=e.Int32Array||y,e.Uint32Array=e.Uint32Array||D,e.Float32Array=e.Float32Array||w,e.Float64Array=e.Float64Array||x,E=new e.Uint16Array([4660]),A=18===I(new e.Uint8Array(E.buffer),0),B.prototype.getUint8=j(e.Uint8Array),B.prototype.getInt8=j(e.Int8Array),B.pr\ +ototype.getUint16=j(e.Uint16Array),B.prototype.getInt16=j(e.Int16Array),B.prototype.getUint32=j(e.Uint32Array),B.prototype.getInt32=j(e.Int32Array),B.prototype.getFloat32=j(e.Float32Array),B.prototype.getFloat64=j(e.Float64Array),B.prototype.setUint8=L(e.Uint8Array),B.prototype.setInt8=L(e.Int8Array),B.prototype.setUint16=L(e.Uint16Array),B.prototype.setInt16=L(e.Int16Array),B.prototype.setUint32=L(e.Uint32Array),B.prototype.setInt32=L(e.Int32Array),B.prototype.setFloat32=L(e.Float32Array),B.prototype.setFloat64=L(e.Float64Array),e.DataView=e.DataView||B})),we=se((function(e){function r(){if(void 0===this)throw new TypeError("Constructor WeakMap requires 'new'");if(c(this,"_id","_WeakMap_"+i()+"."+i()),0{try{return 1===Object.defineProperty({},"x",{value:1}).x}catch(e){}})(),e.WeakMap=((c=function(e,t,n){s?Object.defineProperty(e,t,{configurable:!0,writable:!0,value:n}):e[t]=n})(r.prototype,"delete",(function(e){var t;return o(this,"delete"),!!l(e)&&!(!(t=e[this._id])||t[0]!==e||(delete e[this._id],0))})),c(r.prototype,"get",(function(e){var t;return o(this,"get"),l(e)&&(t=e[this._id])&&t[0]===e?t[1]:void 0})),c(r.prototype,"has",(function(e){var t;return o(this,"has"),!!l(e)&&!(!(t=e[this._id])||t[0]!==e)})),c(r.prototype,"set",(function(e,t){var n;if(o(this,"set"),l(e))return(n=e[this._id])&&n[0]===e?n[1]=t:c(e,this._id,[e,t]),this;throw new TypeError("Invalid value used as weak map key")})),c(r,"_polyfill",!0),r))})),xe=se((function(e,r){function o(e){return e&&e.Math===Math&&e}r.exports=o("object"==("\ +undefined"==typeof globalThis?"undefined":a(globalThis))&&globalThis)||o("object"==(void 0===t?"undefined":a(t))&&t)||o("object"==("undefined"==typeof self?"undefined":a(self))&&self)||o("object"==(void 0===n?"undefined":a(n))&&n)||o("object"==a(e)&&e)||function(){return this}()||Function("return this")()})),Ee=se((function(e,t){t.exports=function(e){try{return!!e()}catch(e){return!0}}})),Ae=se((function(e,t){var n=Ee();t.exports=!n((function(){var e=function(){}.bind();return"function"!=typeof e||e.hasOwnProperty("prototype")}))})),Fe=se((function(e,t){var n=Ae(),r=Function.prototype,o=r.apply,i=r.call;t.exports="object"==("undefined"==typeof Reflect?"undefined":a(Reflect))&&Reflect.apply||(n?i.bind(o):function(){return i.apply(o,arguments)})})),Ce=se((function(e,t){var n=Ae(),r=(a=Function.prototype).call,a=n&&a.bind.bind(r,r);t.exports=n?a:function(e){return function(){return r.apply(e,arguments)}}})),ke=se((function(e,t){var n=Ce(),r=n({}.toString),a=n("".slice);t.exports=function(\ +e){return a(r(e),8,-1)}})),Re=se((function(e,t){var n=ke(),r=Ce();t.exports=function(e){if("Function"===n(e))return r(e)}})),Ne=se((function(e,t){var n="object"==(void 0===r?"undefined":a(r))&&r.all;t.exports=void 0===n&&void 0!==n?function(e){return"function"==typeof e||e===n}:function(e){return"function"==typeof e}})),Te=se((function(e,t){var n=Ee();t.exports=!n((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]}))})),Se=se((function(e,t){var n=Ae(),r=Function.prototype.call;t.exports=n?r.bind(r):function(){return r.apply(r,arguments)}})),_e=se((function(e){var t={}.propertyIsEnumerable,n=Object.getOwnPropertyDescriptor,r=n&&!t.call({1:2},1);e.f=r?function(e){return!!(e=n(this,e))&&e.enumerable}:t})),Oe=se((function(e,t){t.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}})),Me=se((function(e,t){var n=Ce(),r=Ee(),a=ke(),o=Object,i=n("".split);t.exports=r((function(){return!o("z").propertyIsEnumerable(0)}))?funct\ +ion(e){return"String"===a(e)?i(e,""):o(e)}:o})),Pe=se((function(e,t){t.exports=function(e){return null==e}})),Ie=se((function(e,t){var n=Pe(),r=TypeError;t.exports=function(e){if(n(e))throw new r("Can't call method on "+e);return e}})),Be=se((function(e,t){var n=Me(),r=Ie();t.exports=function(e){return n(r(e))}})),je=se((function(e,t){var n=Ne();t.exports=function(e){return"object"==a(e)?null!==e:n(e)}})),Le=se((function(e,t){t.exports={}})),qe=se((function(e,t){function n(e){return o(e)?e:void 0}var r=Le(),a=xe(),o=Ne();t.exports=function(e,t){return arguments.length<2?n(r[e])||n(a[e]):r[e]&&r[e][t]||a[e]&&a[e][t]}})),ze=se((function(e,t){var n=Ce();t.exports=n({}.isPrototypeOf)})),Ve=se((function(e,t){var n=(n=xe().navigator)&&n.userAgent;t.exports=n?String(n):""})),Ge=se((function(e,t){var n,r,a=xe(),o=Ve(),i=a.process;a=a.Deno;!(r=(a=(i=i&&i.versions||a&&a.version)&&i.v8)?0<(n=a.split("."))[0]&&n[0]<4?1:+(n[0]+n[1]):r)&&o&&(!(n=o.match(/Edge\\/(\\d+)/))||74<=n[1])&&(n=o.match(/Chrome\ +\\/(\\d+)/))&&(r=+n[1]),t.exports=r})),$e=se((function(e,t){var n=Ge(),r=Ee(),a=xe().String;t.exports=!!Object.getOwnPropertySymbols&&!r((function(){var e=Symbol("symbol detection");return!a(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&n&&n<41}))})),He=se((function(e,t){var n=$e();t.exports=n&&!Symbol.sham&&"symbol"==a(Symbol.iterator)})),Ue=se((function(e,t){var n=qe(),r=Ne(),o=ze(),i=He(),l=Object;t.exports=i?function(e){return"symbol"==a(e)}:function(e){var t=n("Symbol");return r(t)&&o(t.prototype,l(e))}})),We=se((function(e,t){var n=String;t.exports=function(e){try{return n(e)}catch(e){return"Object"}}})),Ye=se((function(e,t){var n=Ne(),r=We(),a=TypeError;t.exports=function(e){if(n(e))return e;throw new a(r(e)+" is not a function")}})),Ke=se((function(e,t){var n=Ye(),r=Pe();t.exports=function(e,t){return e=e[t],r(e)?void 0:n(e)}})),Xe=se((function(e,t){var n=Se(),r=Ne(),a=je(),o=TypeError;t.exports=function(e,t){var i,l;if("string"===t&&r(i=e.toString)&&!a(l=n(i,e)))return l;if(r\ +(i=e.valueOf)&&!a(l=n(i,e)))return l;if("string"!==t&&r(i=e.toString)&&!a(l=n(i,e)))return l;throw new o("Can't convert object to primitive value")}})),Ze=se((function(e,t){t.exports=!0})),Je=se((function(e,t){var n=xe(),r=Object.defineProperty;t.exports=function(e,t){try{r(n,e,{value:t,configurable:!0,writable:!0})}catch(r){n[e]=t}return t}})),Qe=se((function(e,t){var n=Ze(),r=xe(),a=Je(),o="__core-js_shared__";((t=t.exports=r[o]||a(o,{})).versions||(t.versions=[])).push({version:"3.44.0",mode:n?"pure":"global",copyright:"© 2014-2025 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.44.0/LICENSE",source:"https://github.com/zloirock/core-js"})})),et=se((function(e,t){var n=Qe();t.exports=function(e,t){return n[e]||(n[e]=t||{})}})),tt=se((function(e,t){var n=Ie(),r=Object;t.exports=function(e){return r(n(e))}})),nt=se((function(e,t){var n=Ce(),r=tt(),a=n({}.hasOwnProperty);t.exports=Object.hasOwn||function(e,t){return a(r(e),t)}})),rt=se((function(e,t){\ +var n=Ce(),r=0,a=Math.random(),o=n(1.1.toString);t.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+o(++r+a,36)}})),at=se((function(e,t){var n=xe(),r=et(),a=nt(),o=rt(),i=$e(),l=He(),u=n.Symbol,s=r("wks"),c=l?u.for||u:u&&u.withoutSetter||o;t.exports=function(e){return a(s,e)||(s[e]=i&&a(u,e)?u[e]:c("Symbol."+e)),s[e]}})),ot=se((function(e,t){var n=Se(),r=je(),a=Ue(),o=Ke(),i=Xe(),l=at(),u=TypeError,s=l("toPrimitive");t.exports=function(e,t){if(!r(e)||a(e))return e;var l=o(e,s);if(l){if(l=n(l,e,t=void 0===t?"default":t),!r(l)||a(l))return l;throw new u("Can't convert object to primitive value")}return i(e,t=void 0===t?"number":t)}})),it=se((function(e,t){var n=ot(),r=Ue();t.exports=function(e){return e=n(e,"string"),r(e)?e:e+""}})),lt=se((function(e,t){var n=xe(),r=je(),a=n.document,o=r(a)&&r(a.createElement);t.exports=function(e){return o?a.createElement(e):{}}})),ut=se((function(e,t){var n=Te(),r=Ee(),a=lt();t.exports=!n&&!r((function(){return 7!==Object.defineProperty(a("di\ +v"),"a",{get:function(){return 7}}).a}))})),st=se((function(e){var t=Te(),n=Se(),r=_e(),a=Oe(),o=Be(),i=it(),l=nt(),u=ut(),s=Object.getOwnPropertyDescriptor;e.f=t?s:function(e,t){if(e=o(e),t=i(t),u)try{return s(e,t)}catch(e){}if(l(e,t))return a(!n(r.f,e,t),e[t])}})),ct=se((function(e,t){function n(e,t){return(e=l[i(e)])===s||e!==u&&(a(t)?r(t):!!t)}var r=Ee(),a=Ne(),o=/#|\\.prototype\\./,i=n.normalize=function(e){return String(e).replace(o,".").toLowerCase()},l=n.data={},u=n.NATIVE="N",s=n.POLYFILL="P";t.exports=n})),dt=se((function(e,t){var n=Re(),r=Ye(),a=Ae(),o=n(n.bind);t.exports=function(e,t){return r(e),void 0===t?e:a?o(e,t):function(){return e.apply(t,arguments)}}})),pt=se((function(e,t){var n=Te(),r=Ee();t.exports=n&&r((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))})),ft=se((function(e,t){var n=je(),r=String,a=TypeError;t.exports=function(e){if(n(e))return e;throw new a(r(e)+" is not an object")}})),mt=se((function(e){\ +var t=Te(),n=ut(),r=pt(),a=ft(),o=it(),i=TypeError,l=Object.defineProperty,u=Object.getOwnPropertyDescriptor,s="enumerable",c="configurable",d="writable";e.f=t?r?function(e,t,n){var r;return a(e),t=o(t),a(n),"function"==typeof e&&"prototype"===t&&"value"in n&&d in n&&!n[d]&&(r=u(e,t))&&r[d]&&(e[t]=n.value,n={configurable:(c in n?n:r)[c],enumerable:(s in n?n:r)[s],writable:!1}),l(e,t,n)}:l:function(e,t,r){if(a(e),t=o(t),a(r),n)try{return l(e,t,r)}catch(e){}if("get"in r||"set"in r)throw new i("Accessors not supported");return"value"in r&&(e[t]=r.value),e}})),ht=se((function(e,t){var n=Te(),r=mt(),a=Oe();t.exports=n?function(e,t,n){return r.f(e,t,a(1,n))}:function(e,t,n){return e[t]=n,e}})),gt=se((function(e,t){function n(e){function t(n,r,a){if(this instanceof t){switch(arguments.length){case 0:return new e;case 1:return new e(n);case 2:return new e(n,r)}return new e(n,r,a)}return o(e,this,arguments)}return t.prototype=e.prototype,t}var r=xe(),o=Fe(),i=Re(),l=Ne(),u=st().f,s=ct(),c=Le(),\ +d=dt(),p=ht(),f=nt();Qe(),t.exports=function(e,t){var o,m,h,g,v,b,y=e.target,D=e.global,w=e.stat,x=e.proto,E=D?r:w?r[y]:r[y]&&r[y].prototype,A=D?c:c[y]||p(c,y,{})[y],F=A.prototype;for(m in t)v=!(o=s(D?m:y+(w?".":"#")+m,e.forced))&&E&&f(E,m),g=A[m],v&&(b=e.dontCallGetSet?(b=u(E,m))&&b.value:E[m]),h=v&&b?b:t[m],(o||x||a(g)!=a(h))&&(v=e.bind&&v?d(h,r):e.wrap&&v?n(h):x&&l(h)?i(h):h,(e.sham||h&&h.sham||g&&g.sham)&&p(v,"sham",!0),p(A,m,v),x)&&(f(c,g=y+"Prototype")||p(c,g,{}),p(c[g],m,h),e.real)&&F&&(o||!F[m])&&p(F,m,h)}})),vt=se((function(){gt()({target:"Object",stat:!0},{hasOwn:nt()})})),bt=se((function(e,t){vt();var n=Le();t.exports=n.Object.hasOwn})),yt=se((function(e,t){var n=bt();t.exports=n})),Dt=se((function(e,t){var n=yt();t.exports=n})),wt=se((function(e,t){var n=et(),r=rt(),a=n("keys");t.exports=function(e){return a[e]||(a[e]=r(e))}})),xt=se((function(e,t){var n=Ee();t.exports=!n((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototyp\ +e}))})),Et=se((function(e,t){var n=nt(),r=Ne(),a=tt(),o=wt(),i=xt(),l=o("IE_PROTO"),u=Object,s=u.prototype;t.exports=i?u.getPrototypeOf:function(e){var t;e=a(e);return n(e,l)?e[l]:(t=e.constructor,r(t)&&e instanceof t?t.prototype:e instanceof u?s:null)}})),At=se((function(e,t){var n=Math.ceil,r=Math.floor;t.exports=Math.trunc||function(e){return(0<(e=+e)?r:n)(e)}})),Ft=se((function(e,t){var n=At();t.exports=function(e){return(e=+e)!=e||0==e?0:n(e)}})),Ct=se((function(e,t){var n=Ft(),r=Math.max,a=Math.min;t.exports=function(e,t){return(e=n(e))<0?r(e+t,0):a(e,t)}})),kt=se((function(e,t){var n=Ft(),r=Math.min;t.exports=function(e){return 0<(e=n(e))?r(e,9007199254740991):0}})),Rt=se((function(e,t){var n=kt();t.exports=function(e){return n(e.length)}})),Nt=se((function(e,t){function n(e){return function(t,n,i){var l=r(t),u=o(l);if(0!==u){var s,c=a(i,u);if(e&&n!=n){for(;cs;)!r(u,n=t[s++])||~o(c,n)||l(c,n);return c}})),_t=se((function(e,t){t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]})),Ot=se((function(e,t){var n=St(),r=_t();t.exports=Object.keys||function(e){return n(e,r)}})),Mt=se((function(e,t){function n(e){return function(t){for(var n,a=u(t),o=l(a),p=d&&null===i(a),f=o.length,m=0,h=[];m{try{return e[t]}catch(e){}})(e=i(e),o))?t:l?a(e):"Object"===(t=a(e))&&r(e.callee)?"Arguments":t}})),zt=se((function(e,t){var n=qt(),r=String;t.exports=function(e){if("Symbol"===n(e))throw new TypeError("Cannot convert a Symbol value to a string");return r(e)}})),Vt=se((function(e,t){function n(e){return function(t,n){t=o(i(t)),n=a(n);var r,c=t.length;return n<0||c<=n?e?"":void 0:(r=u(t,n))<55296||56319"+e+""},g=function(){try{a=new ActiveXObject("htmlfile")}catch(e){}g=void 0===r||r.domain&&a?function(e){e.write(h("")),e.close();var t=e.parentWindow.Object;return e=null,t}(a):(e=c("iframe"),t="java"+f+":",e.style.display="none",s.appendChild(e),e.src=String(t),(t=e.contentWindow.document).open(),t.write(h("document.F=Object")),t.close(),t.F);for(var e,t,n=l.leng\ +th;n--;)delete g[p][l[n]];return g()};u[m]=!0,t.exports=Object.create||function(e,t){var r;return null!==e?(n[p]=o(e),r=new n,n[p]=null,r[m]=e):r=g(),void 0===t?r:i.f(r,t)}})),Kt=se((function(e,t){var n=ht();t.exports=function(e,t,r,a){return a&&a.enumerable?e[t]=r:n(e,t,r),e}})),Xt=se((function(e,t){var n,r,a=Ee(),o=Ne(),i=je(),l=Yt(),u=Et(),s=Kt(),c=at(),d=Ze(),p=c("iterator");c=!1;[].keys&&("next"in(r=[].keys())?(u=u(u(r)))!==Object.prototype&&(n=u):c=!0),!i(n)||a((function(){var e={};return n[p].call(e)!==e}))?n={}:d&&(n=l(n)),o(n[p])||s(n,p,(function(){return this})),t.exports={IteratorPrototype:n,BUGGY_SAFARI_ITERATORS:c}})),Zt=se((function(e,t){var n=Lt(),r=qt();t.exports=n?{}.toString:function(){return"[object "+r(this)+"]"}})),Jt=se((function(e,t){var n=Lt(),r=mt().f,a=ht(),o=nt(),i=Zt(),l=at()("toStringTag");t.exports=function(e,t,u,s){(u=u?e:e&&e.prototype)&&(o(u,l)||r(u,l,{configurable:!0,value:t}),s)&&!n&&a(u,"toString",i)}})),Qt=se((function(e,t){t.exports={}})),en=se((fu\ +nction(e,t){function n(){return this}var r=Xt().IteratorPrototype,a=Yt(),o=Oe(),i=Jt(),l=Qt();t.exports=function(e,t,u,s){return t+=" Iterator",e.prototype=a(r,{next:o(+!s,u)}),i(e,t,!1,!0),l[t]=n,e}})),tn=se((function(e,t){var n=Ce(),r=Ye();t.exports=function(e,t,a){try{return n(r(Object.getOwnPropertyDescriptor(e,t)[a]))}catch(e){}}})),nn=se((function(e,t){var n=je();t.exports=function(e){return n(e)||null===e}})),rn=se((function(e,t){var n=nn(),r=String,a=TypeError;t.exports=function(e){if(n(e))return e;throw new a("Can't set "+r(e)+" as a prototype")}})),an=se((function(e,t){var n=tn(),r=je(),a=Ie(),o=rn();t.exports=Object.setPrototypeOf||("__proto__"in{}?(()=>{var e,t=!1,i={};try{(e=n(Object.prototype,"__proto__","set"))(i,[]),t=i instanceof Array}catch(i){}return function(n,i){return a(n),o(i),r(n)&&(t?e(n,i):n.__proto__=i),n}})():void 0)})),on=se((function(e,t){function n(){return this}var r=gt(),a=Se(),o=Ze(),i=Ht(),l=Ne(),u=en(),s=Et(),c=an(),d=Jt(),p=ht(),f=Kt(),m=at(),h=Qt()\ +,g=Xt(),v=i.PROPER,b=i.CONFIGURABLE,y=g.IteratorPrototype,D=g.BUGGY_SAFARI_ITERATORS,w=m("iterator"),x="values",E="entries";t.exports=function(e,t,i,m,g,A,F){function C(e){if(e===g&&_)return _;if(!D&&e&&e in T)return T[e];switch(e){case"keys":case x:case E:return function(){return new i(this,e)}}return function(){return new i(this)}}u(i,t,m);m=t+" Iterator";var k,R,N=!1,T=e.prototype,S=T[w]||T["@@iterator"]||g&&T[g],_=!D&&S||C(g),O="Array"===t&&T.entries||S;if(O&&(O=s(O.call(new e)))!==Object.prototype&&O.next&&(o||s(O)===y||(c?c(O,y):l(O[w])||f(O,w,n)),d(O,m,!0,!0),o)&&(h[m]=n),v&&g===x&&S&&S.name!==x&&(!o&&b?p(T,"name",x):(N=!0,_=function(){return a(S,this)})),g)if(k={values:C(x),keys:A?_:C("keys"),entries:C(E)},F)for(R in k)!D&&!N&&R in T||f(T,R,k[R]);else r({target:t,proto:!0,forced:D||N},k);return o&&!F||T[w]===_||f(T,w,_,{name:g}),h[t]=_,k}})),ln=se((function(e,t){t.exports=function(e,t){return{value:e,done:t}}})),un=se((function(){var e=Vt().charAt,t=zt(),n=$t(),r=on(),a=ln(),o=\ +"String Iterator",i=n.set,l=n.getterFor(o);r(String,"String",(function(e){i(this,{type:o,string:t(e),index:0})}),(function(){var t=l(this),n=t.string,r=t.index;return r>=n.length?a(void 0,!0):(n=e(n,r),t.index+=n.length,a(n,!1))}))})),sn=se((function(e,t){var n=Se(),r=ft(),a=Ke();t.exports=function(e,t,o){var i,l;r(e);try{if(!(i=a(e,"return"))){if("throw"===t)throw o;return o}i=n(i,e)}catch(e){l=!0,i=e}if("throw"===t)throw o;if(l)throw i;return r(i),o}})),cn=se((function(e,t){var n=ft(),r=sn();t.exports=function(e,t,a,o){try{return o?t(n(a)[0],a[1]):t(a)}catch(t){r(e,"throw",t)}}})),dn=se((function(e,t){var n=at(),r=Qt(),a=n("iterator"),o=Array.prototype;t.exports=function(e){return void 0!==e&&(r.Array===e||o[a]===e)}})),pn=se((function(e,t){var n=Ce(),r=Ne(),a=Qe(),o=n(Function.toString);r(a.inspectSource)||(a.inspectSource=function(e){return o(e)}),t.exports=a.inspectSource})),fn=se((function(e,t){function n(){}function r(e){if(!l(e))return!1;try{return d(n,[],e),!0}catch(e){return!\ +1}}function a(e){if(!l(e))return!1;switch(u(e)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return m||!!f(p,c(e))}catch(e){return!0}}var o=Ce(),i=Ee(),l=Ne(),u=qt(),s=qe(),c=pn(),d=s("Reflect","construct"),p=/^\\s*(?:class|function)\\b/,f=o(p.exec),m=!p.test(n);a.sham=!0,t.exports=!d||i((function(){var e;return r(r.call)||!r(Object)||!r((function(){e=!0}))||e}))?a:r})),mn=se((function(e,t){var n=Te(),r=mt(),a=Oe();t.exports=function(e,t,o){n?r.f(e,t,a(0,o)):e[t]=o}})),hn=se((function(e,t){var n=qt(),r=Ke(),a=Pe(),o=Qt(),i=at()("iterator");t.exports=function(e){if(!a(e))return r(e,i)||r(e,"@@iterator")||o[n(e)]}})),gn=se((function(e,t){var n=Se(),r=Ye(),a=ft(),o=We(),i=hn(),l=TypeError;t.exports=function(e,t){if(t=arguments.length<2?i(e):t,r(t))return a(n(t,e));throw new l(o(e)+" is not iterable")}})),vn=se((function(e,t){var n=dt(),r=Se(),a=tt(),o=cn(),i=dn(),l=fn(),u=Rt(),s=mn(),c=gn(),d=hn(),p=Array;t.exports=function(e){var t,f,m,h,g,v,b,y=a(e\ +),D=(e=l(this),1<(b=arguments.length)?arguments[1]:void 0),w=void 0!==D,x=0;if(!(b=(w&&(D=n(D,2":!0,"?":!0,"@":!0,"[":!0,"\\\\":!0,"]":!0,"^":!0,"\`":!0,"{":!0,"|":!0,"}":!0,"~":!0},e.strReplacementsRev={"\\n":"\\\\n","\\r":"\\\\r","\\t":"\\\\t","\\f":"\\\\f","\\v":"\\\\v"},e.singleQuoteEscapeChars={n:"\\n",r:"\\r",t:"\\t",f:"\\f","\\\\":"\\\\","'":"'"},e.doubleQuotesEscapeChars={n:"\\n",r:"\\r",t:"\\t",f:"\\f","\\\\":"\\\\",'"':'"'}})),An=se((function(e){Object.defineProperty(e,"__esModule",{value:!0});var t=En();e.parseCssSelector=function(e,n,r,a,o,i){var l=e.length,u="";function s(r,a){var o="";for(n++,u=e.charAt(n);n":">",'"':""","'":"'","/":"/"},n=e?/[&<>"'\\/]/g:/&(?!#?\\w+;)|<|>|"|'|\\//g;return function(e){return \ +e?e.toString().replace(n,(function(e){return t[e]||e})):""}},void 0!==r&&r.exports?r.exports=o:"function"==typeof define&&define.amd?define((function(){return o})):globalThis.doT=o;var i={append:{start:"'+(",end:")+'",startencode:"'+encodeHTML("},split:{start:"';out+=(",end:");out+='",startencode:"';out+=encodeHTML("}},l=/$^/;function u(e){return e.replace(/\\\\('|\\\\)/g,"$1").replace(/[\\r\\t\\n]/g," ")}o.template=function(e,t,n){var r,a,s=(t=t||o.templateSettings).append?i.append:i.split,c=0;n=t.use||t.define?function e(t,n,r){return("string"==typeof n?n:n.toString()).replace(t.define||l,(function(e,n,a,o){return(n=0===n.indexOf("def.")?n.substring(4):n)in r||(":"===a?(t.defineParams&&o.replace(t.defineParams,(function(e,t,a){r[n]={arg:t,text:a}})),n in r||(r[n]=o)):new Function("def","def['"+n+"']="+o)(r)),""})).replace(t.use||l,(function(n,a){return t.useParams&&(a=a.replace(t.useParams,(function(e,t,n,a){var o;if(r[n]&&r[n].arg&&a)return o=(n+":"+a).replace(/'|\\\\/g,"_"),r.__exp=r.__exp|\ +|{},r.__exp[o]=r[n].text.replace(new RegExp("(^|[^\\\\w$])"+r[n].arg+"([^\\\\w$])","g"),"$1"+a+"$2"),t+"def.__exp['"+o+"']"}))),(a=new Function("def","return "+a)(r))&&e(t,a,r)}))}(t,e,n||{}):e,n=("var out='"+(t.strip?n.replace(/(^|\\r|\\n)\\t* +| +\\t*(\\r|\\n|$)/g," ").replace(/\\r|\\n|\\t|\\/\\*[\\s\\S]*?\\*\\//g,""):n).replace(/'|\\\\/g,"\\\\$&").replace(t.interpolate||l,(function(e,t){return s.start+u(t)+s.end})).replace(t.encode||l,(function(e,t){return r=!0,s.startencode+u(t)+s.end})).replace(t.conditional||l,(function(e,t,n){return t?n?"';}else if("+u(n)+"){out+='":"';}else{out+='":n?"';if("+u(n)+"){out+='":"';}out+='"})).replace(t.iterate||l,(function(e,t,n,r){return t?(c+=1,a=r||"i"+c,t=u(t),"';var arr"+c+"="+t+";if(arr"+c+"){var "+n+","+a+"=-1,l"+c+"=arr"+c+".length-1;while("+a+"{if("object"===("undefined"==typeof process?"undefined":a(process))&&process&&"function"==typeof process.nextTick)return process.nextTick;if("function"==typeof queueMicrotask)return function(e){queueMicrotask(n(e))};if("object"===(void 0===r?"undefined":a(r))&&r){if("function"==typeof MutationObserver)return o(MutationObserver);if("function"==typeof WebKitMutationObserver)return o(WebKitMutationObserver)}return"function"==typeof setImmediate?function(e){setImmediat\ +e(n(e))}:"function"==typeof setTimeout||"object"===("undefined"==typeof setTimeout?"undefined":a(setTimeout))?function(e){setTimeout(n(e),0)}:null})()})),zr=se((function(){var e=Ar(),t=Lr(),n=Xn(),r=Zn(),a=qr(),o=Array.prototype.slice,i=Function.prototype.apply,l=Object.create;zn().async=function(u,s){var c,d,p,f=l(null),m=l(null),h=s.memoized,g=s.original;s.memoized=r((function(e){var t=arguments,n=t[t.length-1];return"function"==typeof n&&(c=n,t=o.call(t,0,-1)),h.apply(d=this,p=t)}),h);try{n(s.memoized,h)}catch(u){}s.on("get",(function(e){var t,n,r;c&&(f[e]?("function"==typeof f[e]?f[e]=[f[e],c]:f[e].push(c),c=null):(t=c,n=d,r=p,c=d=p=null,a((function(){var a;hasOwnProperty.call(m,e)?(a=m[e],s.emit("getasync",e,r,n),i.call(t,a.context,a.args)):(c=t,d=n,p=r,h.apply(n,r))}))))})),s.original=function(){var t,n,r,o;return c?(t=e(arguments),r=c,c=d=p=null,t.push(n=function t(n){var r,l,u=t.id;if(null==u)a(i.bind(t,this,arguments));else if(delete t.id,r=f[u],delete f[u],r)return l=e(argume\ +nts),s.has(u)&&(n?s.delete(u):(m[u]={context:this,args:l},s.emit("setasync",u,"function"==typeof r?1:r.length))),"function"==typeof r?o=i.call(r,this,l):r.forEach((function(e){o=i.call(e,this,l)}),this),o}),o=i.call(g,this,t),n.cb=r,c=n,o):i.call(g,this,arguments)},s.on("set",(function(e){c?(f[e]?"function"==typeof f[e]?f[e]=[f[e],c.cb]:f[e].push(c.cb):f[e]=c.cb,delete c.cb,c.id=e,c=null):s.delete(e)})),s.on("delete",(function(e){var t;hasOwnProperty.call(f,e)||m[e]&&(t=m[e],delete m[e],s.emit("deleteasync",e,o.call(t.args,1)))})),s.on("clear",(function(){var e=m;m=l(null),s.emit("clearasync",t(e,(function(e){return o.call(e.args,1)})))}))}})),Vr=se((function(e,t){var n=Array.prototype.forEach,r=Object.create;t.exports=function(e){var t=r(null);return n.call(arguments,(function(e){t[e]=!0})),t}})),Gr=se((function(e,t){t.exports=function(e){return"function"==typeof e}})),$r=se((function(e,t){var n=Gr();t.exports=function(e){try{return e&&n(e.toString)?e.toString():String(e)}catch(e){thr\ +ow new TypeError("Passed argument cannot be stringifed")}}})),Hr=se((function(e,t){var n=jn(),r=$r();t.exports=function(e){return r(n(e))}})),Ur=se((function(e,t){var n=Gr();t.exports=function(e){try{return e&&n(e.toString)?e.toString():String(e)}catch(e){return""}}})),Wr=se((function(e,t){var n=Ur(),r=/[\\n\\r\\u2028\\u2029]/g;t.exports=function(e){return(e=100<(e=n(e)).length?e.slice(0,99)+"…":e).replace(r,(function(e){return JSON.stringify(e).slice(1,-1)}))}})),Yr=se((function(e,t){function n(e){return!!e&&("object"===a(e)||"function"==typeof e)&&"function"==typeof e.then}t.exports=n,t.exports.default=n})),Kr=se((function(){var e=Lr(),t=Vr(),n=Hr(),r=Wr(),a=Yr(),o=qr(),i=Object.create,l=t("then","then:finally","done","done:finally");zn().promise=function(t,u){var s=i(null),c=i(null),d=i(null);if(!0===t)t=null;else if(t=n(t),!l[t])throw new TypeError("'"+r(t)+"' is not valid promise mode");u.on("set",(function(e,n,r){var i=!1;if(a(r)){s[e]=1,d[e]=r;var l=fu\ +nction(t){var n=s[e];if(i)throw new Error("Memoizee error: Detected unordered then|done & finally resolution, which in turn makes proper detection of success/failure impossible (when in 'done:finally' mode)\\nConsider to rely on 'then' or 'done' mode instead.");n&&(delete s[e],c[e]=t,u.emit("setasync",e,n))},p=function(){i=!0,s[e]&&(delete s[e],delete d[e],u.delete(e))},f=t;if("then"===(f=f||"then")){var m=function(){o(p)};"function"==typeof(r=r.then((function(e){o(l.bind(this,e))}),m)).finally&&r.finally(m)}else if("done"===f){if("function"!=typeof r.done)throw new Error("Memoizee error: Retrieved promise does not implement 'done' in 'done' mode");r.done(l,p)}else if("done:finally"===f){if("function"!=typeof r.done)throw new Error("Memoizee error: Retrieved promise does not implement 'done' in 'done:finally' mode");if("function"!=typeof r.finally)throw new Error("Memoizee error: Retrieved promise does not implement 'finally' in 'done:finally' mode");r.done(l),r.finally(p)}}else c[e]=r,\ +u.emit("setasync",e,1)})),u.on("get",(function(e,t,n){var r,i;s[e]?++s[e]:(r=d[e],i=function(){u.emit("getasync",e,t,n)},a(r)?"function"==typeof r.done?r.done(i):r.then((function(){o(i)})):i())})),u.on("delete",(function(e){var t;delete d[e],s[e]?delete s[e]:hasOwnProperty.call(c,e)&&(t=c[e],delete c[e],u.emit("deleteasync",e,[t]))})),u.on("clear",(function(){var t=c;c=i(null),s=i(null),d=i(null),u.emit("clearasync",e(t,(function(e){return[e]})))}))}})),Xr=se((function(){var e=Bn(),t=qn(),n=zn(),r=Function.prototype.apply;n.dispose=function(a,o,i){var l;e(a),i.async&&n.async||i.promise&&n.promise?(o.on("deleteasync",l=function(e,t){r.call(a,null,t)}),o.on("clearasync",(function(e){t(e,(function(e,t){l(t,e)}))}))):(o.on("delete",l=function(e,t){a(t)}),o.on("clear",(function(e){t(e,(function(e,t){l(t,e)}))})))}})),Zr=se((function(e,t){t.exports=2147483647})),Jr=se((function(e,t){var n=Pn(),r=Zr();t.exports=function(e){if(e=n(e),r",sameOrigin:"",serializableErrorProps:Object.freeze(["message","stack","name","code","ruleId","method"])},oa=([{name:"NA",value:"inapplicable",priority:0,group:"inapplicable"},{name:"PASS",value:"passed",priority:1,group:"passes"},{name:"CANTTELL",value:"cantTell",priority:2,group:"incomplete"},{name:"FAIL",value:"failed",priority:3,group:"violations"}].forEach((function(e){var t=e.name,n=e.value,r=e.priority;e=e.group;aa[t]=n,aa[t+"_PRIO"]=r,aa[t+"_GROUP"]=e,aa.results[r]=n,aa.resultGroups[r]=e,aa.resultGroupMap[n]=e})),Object.freeze(aa.results),Object.freeze(aa.resultGroups),Object.freeze(aa.resultGroupMap),Object.freeze(aa),aa),ia=function(){"object"===("undefined"==typeof console?"undefined":a(console))&&console.log&&Function.prototype.apply.call(console.log,console,arguments)},la=/[\\t\\r\\n\\f]/g,ua=W((function e(){H(this,e),this.parent=void 0}),[{key:"props",get:function(){throw new Error('VirtualNode class must have \ +a "props" object consisting of "nodeType" and "nodeName" properties')}},{key:"attrNames",get:function(){throw new Error('VirtualNode class must have an "attrNames" property')}},{key:"attr",value:function(){throw new Error('VirtualNode class must have an "attr" function')}},{key:"hasAttr",value:function(){throw new Error('VirtualNode class must have a "hasAttr" function')}},{key:"hasClass",value:function(e){var t=this.attr("class");return!!t&&(e=" "+e+" ",0<=(" "+t+" ").replace(la," ").indexOf(e))}}]),sa={},ca=(ce(sa,{DqElement:function(){return Pd},RuleError:function(){return wm},aggregate:function(){return ca},aggregateChecks:function(){return ga},aggregateNodeResults:function(){return ba},aggregateResult:function(){return Da},areStylesSet:function(){return wa},assert:function(){return xa},checkHelper:function(){return Id},clone:function(){return Bd},closest:function(){return Wd},collectResultsFromFrames:function(){return zp},contains:function(){return Vp},convertSelector:function(){r\ +eturn Hd},cssParser:function(){return jd},deepMerge:function(){return $p},escapeSelector:function(){return Aa},extendMetaData:function(){return Hp},filterHtmlAttrs:function(){return gm},finalizeRuleResult:function(){return va},findBy:function(){return jp},getAllChecks:function(){return Bp},getAncestry:function(){return Rl},getBaseLang:function(){return of},getCheckMessage:function(){return hf},getCheckOption:function(){return gf},getEnvironmentData:function(){return vf},getFlattenedTree:function(){return tf},getFrameContexts:function(){return Ef},getFriendlyUriEnd:function(){return Ra},getNodeAttributes:function(){return Na},getNodeFromTree:function(){return _l},getPreloadConfig:function(){return cm},getRootNode:function(){return Ml},getRule:function(){return Af},getScroll:function(){return Cf},getScrollState:function(){return kf},getSelector:function(){return Fl},getSelectorData:function(){return wl},getShadowSelector:function(){return pl},getStandards:function(){return Rf},getStyleSh\ +eetFactory:function(){return Tf},getXpath:function(){return Nl},injectStyle:function(){return Sf},isArrayLike:function(){return _f},isContextObject:function(){return Pf},isContextProp:function(){return If},isContextSpec:function(){return Mf},isHidden:function(){return Lf},isHtmlElement:function(){return qf},isLabelledFramesSelector:function(){return Bf},isLabelledShadowDomSelector:function(){return jf},isNodeInContext:function(){return zf},isShadowRoot:function(){return Wp},isValidLang:function(){return Rm},isXHTML:function(){return dl},matchAncestry:function(){return Gf},matches:function(){return Ld},matchesExpression:function(){return Ud},matchesSelector:function(){return Ta},memoize:function(){return cl},mergeResults:function(){return qp},nodeLookup:function(){return Hf},nodeSerializer:function(){return Ip},nodeSorter:function(){return $f},objectHasOwn:function(){return Of},parseCrossOriginStylesheet:function(){return Xf},parseSameOriginStylesheet:function(){return Yf},parseStyleshe\ +et:function(){return Kf},parseTabindex:function(){return Zf},performanceTimer:function(){return Qf},pollyfillElementsFromPoint:function(){return em},preload:function(){return um},preloadCssom:function(){return am},preloadMedia:function(){return lm},processMessage:function(){return mf},publishMetaData:function(){return dm},querySelectorAll:function(){return fm},querySelectorAllFilter:function(){return rm},queue:function(){return Qd},respondable:function(){return Np},ruleShouldRun:function(){return hm},select:function(){return bm},sendCommandToFrame:function(){return Sp},serializeError:function(){return ym},setScrollState:function(){return xm},shadowSelect:function(){return Em},shadowSelectAll:function(){return Am},shouldPreload:function(){return sm},toArray:function(){return Ea},tokenList:function(){return Yp},uniqueArray:function(){return tm},uuid:function(){return pp},validInputTypes:function(){return Fm},validLangs:function(){return km}}),function(e,t,n){return t=t.slice(),n&&t.push(\ +n),n=t.map((function(t){return e.indexOf(t)})).sort(),e[n.pop()]}),da=oa.CANTTELL_PRIO,pa=oa.FAIL_PRIO,fa=[],ma=(fa[oa.PASS_PRIO]=!0,fa[oa.CANTTELL_PRIO]=null,fa[oa.FAIL_PRIO]=!1,["any","all","none"]);function ha(e,t){ma.reduce((function(n,r){return n[r]=(e[r]||[]).map((function(e){return t(e,r)})),n}),{})}var ga=function(e){var t=Object.assign({},e),n=(ha(t,(function(e,t){var n=void 0===e.result?-1:fa.indexOf(e.result);e.priority=-1!==n?n:oa.CANTTELL_PRIO,"none"===t&&(e.priority===oa.PASS_PRIO?e.priority=oa.FAIL_PRIO:e.priority===oa.FAIL_PRIO&&(e.priority=oa.PASS_PRIO))})),{all:t.all.reduce((function(e,t){return Math.max(e,t.priority)}),0),none:t.none.reduce((function(e,t){return Math.max(e,t.priority)}),0),any:t.any.reduce((function(e,t){return Math.min(e,t.priority)}),4)%4}),r=(t.priority=Math.max(n.all,n.none,n.any),[]);return ma.forEach((function(e){t[e]=t[e].filter((function(r){return r.priority===t.priority&&r.priority===n[e]})),t[e].forEach((function(e){return r.push(e.impact)}\ +))})),[da,pa].includes(t.priority)?t.impact=ca(oa.impact,r):t.impact=null,ha(t,(function(e){delete e.result,delete e.priority})),t.result=oa.results[t.priority],delete t.priority,t};function va(e){var t=o._audit.rules.find((function(t){return t.id===e.id}));return t&&t.impact&&e.nodes.forEach((function(e){["any","all","none"].forEach((function(n){(e[n]||[]).forEach((function(e){e.impact=t.impact}))}))})),Object.assign(e,ba(e.nodes)),delete e.nodes,e}var ba=function(e){var t={},n=((e=e.map((function(e){if(e.any&&e.all&&e.none)return ga(e);if(Array.isArray(e.node))return va(e);throw new TypeError("Invalid Result type")})))&&e.length?(n=e.map((function(e){return e.result})),t.result=ca(oa.results,n,t.result)):t.result="inapplicable",oa.resultGroups.forEach((function(e){return t[e]=[]})),e.forEach((function(e){var n=oa.resultGroupMap[e.result];t[n].push(e)})),oa.FAIL_GROUP);return 0===t[n].length&&(n=oa.CANTTELL_GROUP),0=e.length/2}(l)?Ca(l):void 0},Na=function(e){return(e.attributes instanceof t.NamedNodeMap?e:e.cloneNode(!1)).attributes},Ta=function(e,t){return!!e[ka=ka&&e[ka]?ka:(e=>{for(var t,n=["matches","matchesSelector","mozMatchesSelector","webkitMatchesSelector","msMatchesSelector"],r=n.length,a=0;a>>0,a=arguments[1],o=0;o>>0,o=0;o>>0,r=2<=arguments.length?arguments[1]:void 0,a=0;athis.length)&&-1!==this.indexOf(e,t)}),Array.prototype.flat||Object.defineProperty(Array.prototype,"flat",{configurable:!0,value:function e(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,(function(n,r){return Array.isArray(r)?n.push.apply(n,e.call(r,t-1)):n.push(r),n}),[]):Array.prototype.slice.call(this)},writable:!0}),!t.Node||"isConnected"in t.Node.prototype||Object.defineProperty(t.Node.prototype,"isConnected",{get:function(){return!(this.ownerDocument&&this.ownerDocument.compareDocumentPosition(this)&this.DOCUMENT_POSITION_DISCONNECTED)}}),de(Cn())),Oa=de(kn()),Ma=function(){return/[#*0-9]\\uFE0F?\\\ +u20E3|[\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23ED-\\u23EF\\u23F1\\u23F2\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB\\u25FC\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u265F\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267E\\u267F\\u2692\\u2694-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A7\\u26AA\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C8\\u26CF\\u26D1\\u26E9\\u26F0-\\u26F5\\u26F7\\u26F8\\u26FA\\u2702\\u2708\\u2709\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2733\\u2734\\u2744\\u2747\\u2757\\u2763\\u27A1\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B55\\u3030\\u303D\\u3297\\u3299]\\uFE0F?|[\\u261D\\u270C\\u270D](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?|[\\u270A\\u270B](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\u23E9-\\u23EC\\u23F0\\u23F3\\u25FD\\u2693\\u26A1\\u26AB\\u26C5\\u26CE\\u26D4\\u26EA\\u26FD\\u2705\\u2728\\u274C\\u274E\\u2753-\\u2755\\u2795-\\u2797\\u27B0\\u27BF\\u2B50]|\\u26D3\\uFE0F?(?:\\u200D\\uD83D\\uDCA5)?|\\u26F9(?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\ +\\u2642]\\uFE0F?)?|\\u2764\\uFE0F?(?:\\u200D(?:\\uD83D\\uDD25|\\uD83E\\uDE79))?|\\uD83C(?:[\\uDC04\\uDD70\\uDD71\\uDD7E\\uDD7F\\uDE02\\uDE37\\uDF21\\uDF24-\\uDF2C\\uDF36\\uDF7D\\uDF96\\uDF97\\uDF99-\\uDF9B\\uDF9E\\uDF9F\\uDFCD\\uDFCE\\uDFD4-\\uDFDF\\uDFF5\\uDFF7]\\uFE0F?|[\\uDF85\\uDFC2\\uDFC7](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDFC4\\uDFCA](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDFCB\\uDFCC](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDCCF\\uDD8E\\uDD91-\\uDD9A\\uDE01\\uDE1A\\uDE2F\\uDE32-\\uDE36\\uDE38-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF20\\uDF2D-\\uDF35\\uDF37-\\uDF43\\uDF45-\\uDF4A\\uDF4C-\\uDF7C\\uDF7E-\\uDF84\\uDF86-\\uDF93\\uDFA0-\\uDFC1\\uDFC5\\uDFC6\\uDFC8\\uDFC9\\uDFCF-\\uDFD3\\uDFE0-\\uDFF0\\uDFF8-\\uDFFF]|\\uDDE6\\uD83C[\\uDDE8-\\uDDEC\\uDDEE\\uDDF1\\uDDF2\\uDDF4\\uDDF6-\\uDDFA\\uDDFC\\uDDFD\\uDDFF]|\\uDDE7\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEF\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9\\uDDFB\\uDDFC\\uDDFE\\uDDFF]|\\uDDE8\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDEE\\uDDF0-\\uDDF7\\uDDFA-\\uDDFF]|\\uDDE9\\uD83C[\\uDDEA\\uDDEC\\uDDEF\\uDDF0\\uDDF2\\uDDF4\\uDDFF]|\\uDDEA\\uD8\ +3C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDED\\uDDF7-\\uDDFA]|\\uDDEB\\uD83C[\\uDDEE-\\uDDF0\\uDDF2\\uDDF4\\uDDF7]|\\uDDEC\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEE\\uDDF1-\\uDDF3\\uDDF5-\\uDDFA\\uDDFC\\uDDFE]|\\uDDED\\uD83C[\\uDDF0\\uDDF2\\uDDF3\\uDDF7\\uDDF9\\uDDFA]|\\uDDEE\\uD83C[\\uDDE8-\\uDDEA\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9]|\\uDDEF\\uD83C[\\uDDEA\\uDDF2\\uDDF4\\uDDF5]|\\uDDF0\\uD83C[\\uDDEA\\uDDEC-\\uDDEE\\uDDF2\\uDDF3\\uDDF5\\uDDF7\\uDDFC\\uDDFE\\uDDFF]|\\uDDF1\\uD83C[\\uDDE6-\\uDDE8\\uDDEE\\uDDF0\\uDDF7-\\uDDFB\\uDDFE]|\\uDDF2\\uD83C[\\uDDE6\\uDDE8-\\uDDED\\uDDF0-\\uDDFF]|\\uDDF3\\uD83C[\\uDDE6\\uDDE8\\uDDEA-\\uDDEC\\uDDEE\\uDDF1\\uDDF4\\uDDF5\\uDDF7\\uDDFA\\uDDFF]|\\uDDF4\\uD83C\\uDDF2|\\uDDF5\\uD83C[\\uDDE6\\uDDEA-\\uDDED\\uDDF0-\\uDDF3\\uDDF7-\\uDDF9\\uDDFC\\uDDFE]|\\uDDF6\\uD83C\\uDDE6|\\uDDF7\\uD83C[\\uDDEA\\uDDF4\\uDDF8\\uDDFA\\uDDFC]|\\uDDF8\\uD83C[\\uDDE6-\\uDDEA\\uDDEC-\\uDDF4\\uDDF7-\\uDDF9\\uDDFB\\uDDFD-\\uDDFF]|\\uDDF9\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDED\\uDDEF-\\uDDF4\\uDDF7\\uDDF9\\uDDFB\\uDDFC\\uDDFF]|\\uDDFA\\uD83C[\\uDDE6\\uDDEC\\uDDF2\\uDDF3\\uDDF8\\uDDFE\\uDDFF]|\\uDDFB\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDEE\\uD\ +DF3\\uDDFA]|\\uDDFC\\uD83C[\\uDDEB\\uDDF8]|\\uDDFD\\uD83C\\uDDF0|\\uDDFE\\uD83C[\\uDDEA\\uDDF9]|\\uDDFF\\uD83C[\\uDDE6\\uDDF2\\uDDFC]|\\uDF44(?:\\u200D\\uD83D\\uDFEB)?|\\uDF4B(?:\\u200D\\uD83D\\uDFE9)?|\\uDFC3(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?|\\uDFF3\\uFE0F?(?:\\u200D(?:\\u26A7\\uFE0F?|\\uD83C\\uDF08))?|\\uDFF4(?:\\u200D\\u2620\\uFE0F?|\\uDB40\\uDC67\\uDB40\\uDC62\\uDB40(?:\\uDC65\\uDB40\\uDC6E\\uDB40\\uDC67|\\uDC73\\uDB40\\uDC63\\uDB40\\uDC74|\\uDC77\\uDB40\\uDC6C\\uDB40\\uDC73)\\uDB40\\uDC7F)?)|\\uD83D(?:[\\uDC3F\\uDCFD\\uDD49\\uDD4A\\uDD6F\\uDD70\\uDD73\\uDD76-\\uDD79\\uDD87\\uDD8A-\\uDD8D\\uDDA5\\uDDA8\\uDDB1\\uDDB2\\uDDBC\\uDDC2-\\uDDC4\\uDDD1-\\uDDD3\\uDDDC-\\uDDDE\\uDDE1\\uDDE3\\uDDE8\\uDDEF\\uDDF3\\uDDFA\\uDECB\\uDECD-\\uDECF\\uDEE0-\\uDEE5\\uDEE9\\uDEF0\\uDEF3]\\uFE0F?|[\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66\\uDC67\\uDC6B-\\uDC6D\\uDC72\\uDC74-\\uDC76\\uDC78\\uDC7C\\uDC83\\uDC85\\uDC8F\\uDC91\\uDCAA\\uDD7A\\uDD95\\uDD96\\uDE4C\\uDE4F\\uDEC0\\uDECC](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDC6E-\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uD\ +E47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4\\uDEB5](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDD74\\uDD90](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?|[\\uDC00-\\uDC07\\uDC09-\\uDC14\\uDC16-\\uDC25\\uDC27-\\uDC3A\\uDC3C-\\uDC3E\\uDC40\\uDC44\\uDC45\\uDC51-\\uDC65\\uDC6A\\uDC79-\\uDC7B\\uDC7D-\\uDC80\\uDC84\\uDC88-\\uDC8E\\uDC90\\uDC92-\\uDCA9\\uDCAB-\\uDCFC\\uDCFF-\\uDD3D\\uDD4B-\\uDD4E\\uDD50-\\uDD67\\uDDA4\\uDDFB-\\uDE2D\\uDE2F-\\uDE34\\uDE37-\\uDE41\\uDE43\\uDE44\\uDE48-\\uDE4A\\uDE80-\\uDEA2\\uDEA4-\\uDEB3\\uDEB7-\\uDEBF\\uDEC1-\\uDEC5\\uDED0-\\uDED2\\uDED5-\\uDED8\\uDEDC-\\uDEDF\\uDEEB\\uDEEC\\uDEF4-\\uDEFC\\uDFE0-\\uDFEB\\uDFF0]|\\uDC08(?:\\u200D\\u2B1B)?|\\uDC15(?:\\u200D\\uD83E\\uDDBA)?|\\uDC26(?:\\u200D(?:\\u2B1B|\\uD83D\\uDD25))?|\\uDC3B(?:\\u200D\\u2744\\uFE0F?)?|\\uDC41\\uFE0F?(?:\\u200D\\uD83D\\uDDE8\\uFE0F?)?|\\uDC68(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDC68\\uDC69]\\u200D\\uD83D(?:\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uD\ +C67])?)|[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?)|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFC-\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0\ +-\\uDDB3])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\u\ +DF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFE]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?))?|\\uDC69(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?[\\uDC68\\uDC69]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?|\\uDC69\\u200D\\uD83D(?:\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?))|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFC-\\uD\ +FFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFC-\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFC-\\uDFFF])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uD\ +DBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\\ +uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB-\\uDFFE]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFE])))?))?|\\uDD75(?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|\\uDE2E(?:\\u200D\\uD83D\\uDCA8)?|\\uDE35(?:\\u200D\\uD83D\\uDCAB)?|\\uDE36(?:\\u200D\\uD83C\\uDF2B\\uFE0F?)?|\\uDE42(?:\\u200D[\\u2194\\u2195]\\uFE0F?)?|\\uDEB6(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?)|\\uD83E(?:[\\uDD0C\\uDD0F\\uDD18-\\uDD1F\\uDD30-\\uDD34\\uDD36\\uDD77\\uDDB5\\uDDB6\\uDDBB\\uDDD2\\uDDD3\\uDDD5\\uDEC3-\\uDEC5\\uDEF0\\uDEF2-\\uDEF8](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3C-\\uDD3E\\uDDB8\\uDDB9\\uDDCD\\uDDCF\\uDDD4\\uDDD6-\\uDDDD](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDDDE\\uDDDF](?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDD0D\\uDD0E\\uDD10-\\uDD17\\uDD20-\\uDD25\\uDD27-\\uDD2F\\uDD3A\\uDD3F-\\uDD45\\uDD47-\\uDD76\\uDD78-\\uDDB4\\uDDB7\\uDDBA\\uDDBC-\\uDDCC\\uDDD0\\uDDE0-\\uDDFF\\uDE70-\\uDE7C\\uDE80-\\uDE8A\\uDE8E-\\uDEC2\\uDEC6\\uDEC8\\uDECD-\\uDEDC\\u\ +DEDF-\\uDEEA\\uDEEF]|\\uDDCE(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?|\\uDDD1(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1|\\uDDD1\\u200D\\uD83E\\uDDD2(?:\\u200D\\uD83E\\uDDD2)?|\\uDDD2(?:\\u200D\\uD83E\\uDDD2)?))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC\ +8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uD\ +FFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE])))?))?|\\uDEF1(?:\\uD83C(?:\\uDFFB(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFC-\\uDFFF])?|\\uDFFC(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])?|\\uDFFD(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])?|\\uDFFE(?:\\\ +u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])?|\\uDFFF(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB-\\uDFFE])?))?)/g},Pa=de(ra());function Ia(e,t){var n=e.length,r=(Array.isArray(e[0])||(e=[e]),(t=Array.isArray(t[0])?t:t.map((function(e){return[e]})))[0].length),a=t[0].map((function(e,n){return t.map((function(e){return e[n]}))}));e=e.map((function(e){return a.map((function(t){var n=0;if(Array.isArray(e))for(var r=0;r)\\[(-?[.\\d]+),\\s*(-?[.\\d]+)\\]?$/);return n?((t=new String(n[1])).range=[+n[2],+n[3]],t):e}))}))}we=Object.freeze({__proto__:null,isString:Ba,type:ja,toPrecision:La,parseFunction:qa,last:za,interpolate:Va,interpolateInv:Ga,mapRange:$a,parseCoordGrammar:Ha,multiplyMatrices:Ia});var Ua=new(W((function e(){H(this,e)\ +}),[{key:"add",value:function(e,t,n){if("string"!=typeof arguments[0])for(var e in arguments[0])this.add(e,arguments[0][e],t);else(Array.isArray(e)?e:[e]).forEach((function(e){this[e]=this[e]||[],t&&this[e][n?"unshift":"push"](t)}),this)}},{key:"run",value:function(e,t){this[e]=this[e]||[],this[e].forEach((function(e){e.call(t&&t.context?t.context:t,t)}))}}])),Wa={gamut_mapping:"lch.c",precision:5,deltaE:"76"},Ya={D50:[.3457/.3585,1,.2958/.3585],D65:[.3127/.329,1,.3583/.329]};function Ka(e){return Array.isArray(e)?e:Ya[e]}function Xa(e,t,n,r){if(r=3"==n?(r=[0,100],a="%"):""==n&&(a="deg"),{fromRange:t,toRange:r,suffix:a}})),e.serializeCoords=function(e,n){return e.map((f\ +unction(e,r){var a=(r=t[r]).fromRange,o=r.toRange;r=r.suffix;return e=La(e=a&&o?$a(a,o,e):e,n),r&&(e+=r),e}))}),e}function Qa(){for(var e=[this],t=this;t=t.base;)e.push(t);return e}var eo=Za,to=(pe(eo,"registry",{}),pe(eo,"DEFAULT_FORMAT",{type:"functions",name:"color"}),new eo({id:"xyz-d65",name:"XYZ D65",coords:{x:{name:"X"},y:{name:"Y"},z:{name:"Z"}},white:"D65",formats:{color:{ids:["xyz-d65","xyz"]}},aliases:["xyz"]}));S(no,eo),Dt=W(no);function no(e){var t;return H(this,no),e.coords||(e.coords={r:{range:[0,1],name:"Red"},g:{range:[0,1],name:"Green"},b:{range:[0,1],name:"Blue"}}),e.base||(e.base=to),e.toXYZ_M&&e.fromXYZ_M&&(null==e.toBase&&(e.toBase=function(n){return n=Ia(e.toXYZ_M,n),t.white!==t.base.white?Xa(t.white,t.base.white,n):n}),null==e.fromBase)&&(e.fromBase=function(n){return n=Xa(t.base.white,t.white,n),Ia(e.fromXYZ_M,n)}),null==e.referred&&(e.referred="display"),t=R(this,no,[e])}function ro(e){var t={str:null==(s=String(e))?void 0:s.trim()};if(Ua.run("parse-start",t),\ +t.color)return t.color;if(t.parsed=qa(t.str),t.parsed){var n=t.parsed.name;if("color"===n){var r,a=t.parsed.args.shift(),o=0{var e,n=r.value,i=n.getFormat("color");if(i&&(a===i.id||null!=(i=i.ids)&&i.includes(a)))return i=Object.keys(n.coords).length,(e=Array(i).fill(0)).forEach((function(n,r){return e[r]=t.parsed.args[r]||0})),{v:{spaceId:n.id,coords:e,alpha:o}}})())return l.v}catch(e){i.e(e)}finally{i.f()}var u,s="";throw a in eo.registry&&(u=null==(u=eo.registry[a].formats)||null==(u=u.functions)||null==(u=u.color)?void 0:u.id)&&(s="Did you mean color(".concat(u,")?")),new TypeError("Cannot parse color(".concat(a,"). ")+(s||"Missing a plugin?"))}var c,d=K(eo.all);try{var p;for(d.s();!(c=d.n()).done;)if(p=(()=>{var e,r,a=c.value,o=a.getFormat(n);if(o&&"function"===o.type)return e=1,(o.lastAlpha||za(t.parsed.args).alpha)&&(e=t.parsed.args.pop()),r=t.parsed.args,o.coordGramma\ +r&&Object.entries(a.coords).forEach((function(e,t){var a=(e=V(e,2))[0],i=(e=e[1],o.coordGrammar[t]),l=null==(u=r[t])?void 0:u.type;if(!(i=i.find((function(e){return e==l}))))throw u=e.name||a,new TypeError("".concat(l," not allowed for ").concat(u," in ").concat(n,"()"));a=i.range;var u=e.range||e.refRange;(a=""===l?a||[0,1]:a)&&u&&(r[t]=$a(a,u,r[t]))})),{v:{spaceId:a.id,coords:r,alpha:e}}})())return p.v}catch(e){d.e(e)}finally{d.f()}}else{var f,m=K(eo.all);try{for(m.s();!(f=m.n()).done;){var h,g=f.value;for(h in g.formats){var v=g.formats[h];if("custom"===v.type&&(!v.test||v.test(t.str))){var b=v.parse(t.str);if(b)return null==b.alpha&&(b.alpha=1),b}}}}catch(e){m.e(e)}finally{m.f()}}throw new TypeError("Could not parse ".concat(e," as a color. Missing a plugin?"))}function ao(e){var t;if(e)return(t=(e=Ba(e)?ro(e):e).space||e.spaceId)instanceof eo||(e.space=eo.get(t)),void 0===e.alpha&&(e.alpha=1),e;throw new TypeError("Empty color reference")}function oo(e,t){return(t=eo.g\ +et(t)).from(e)}function io(e,t){var n=(t=eo.resolveCoord(t,e.space)).space;t=t.index;return oo(e,n)[t]}function lo(e,t,n){return t=eo.get(t),e.coords=t.to(e.space,n),e}function uo(e,t,n){if(e=ao(e),2===arguments.length&&"object"===ja(t)){var r,a=t;for(r in a)uo(e,r,a[r])}else{"function"==typeof n&&(n=n(io(e,t)));var o=(t=eo.resolveCoord(t,e.space)).space,i=(t=t.index,oo(e,o));i[t]=n,lo(e,o,i)}return e}ye=new eo({id:"xyz-d50",name:"XYZ D50",white:"D50",base:to,fromBase:function(e){return Xa(to.white,"D50",e)},toBase:function(e){return Xa("D50",to.white,e)},formats:{color:{}}});var so=24389/27,co=Ya.D50,po=new eo({id:"lab",name:"Lab",coords:{l:{refRange:[0,100],name:"L"},a:{refRange:[-125,125]},b:{refRange:[-125,125]}},white:co,base:ye,fromBase:function(e){return e=e.map((function(e,t){return e/co[t]})).map((function(e){return 216/24389 | ","",""]}}});function fo(e){return(e%360+360)%360}var mo=new eo({id:"lch",name:"LCH",coords:{l:{refRange:[0,100],name:"Lightness"},c:{refRange:[0,150],name:"Chroma"},h:{refRange:[0,360],type:"angle",name:"Hue"}},base:po,fromBase:function(e){var t=(e=V(e,3))[0],n=e[1],r=(e=e[2],Math.abs(n)<.02&&Math.abs(e)<.02?NaN:180*Math.atan2(e,n)/Math.PI);return[t,Math.sqrt(Math.pow(n,2)+Math.pow(e,2)),fo(r)]},toBase:function(e){var t=(e=V(e,3))[0],n=e[1];e=e[2];return n<0&&(n=0),isNaN(e)&&(e=0),[t,n*Math.cos(e*Math.PI/180),n*Math.sin(e*Math.PI/180)]},formats:{lch:{coords:[" | ",""," | "]}}}),ho=Math.pow(25,7),go=Math.PI,vo=180/go,bo=go/180;function yo(e,t){var n=void 0===(n=(a=2 | [0, 255]")},rgb_number:{name:"rgb",commas:!0,coords:No=Array(3).fill("[0, 255]"),noAlpha:!0},color:{},rgba:{coords:ra,commas:!0,lastAlpha:!0},rgba_number:{name:"rgba",commas:!0,coords:No},hex:{type:"custom",toGamut:!0,test:function(e){return/^#([a-f0-9]{3,4}){1,2}$/i.test(e)},parse:function(e){e.length<=5&&(e=e.replace(/[a-f0-9]/gi,"$&$&"));var t=[];return e.replace(/[a-f0-9]{2}/gi,(function(e){t.push(parseInt(e,16)/255)})),{spaceId:"srgb",coords:t.slice(0,3),alpha:t.slice(3)[0]}},serialize:function(e,t){var n=void 0===(n=(2 | ","",""]}}}),Vo=.5*Math.pow(5,.5)+.5,Go=Object.freeze({__proto__:null,contrastWCAG21:function(e,t){var n;return e=ao(e),t=ao(t),(e=Math.max(Po(e),0))<(t=Math.max(Po(t),0))&&(e=(n=[t,e])[0],t=n[1]),(e+.05)/(t+.05)},contrastAPCA:fun\ +ction(e,t){t=ao(t),e=ao(e);var n=(t=V((t=Ao(t,"srgb")).coords,3))[0],r=t[1],a=(t=t[2],.2126729*jo(n)+.7151522*jo(r)+.072175*jo(t));n=(e=V((e=Ao(e,"srgb")).coords,3))[0],r=e[1],t=e[2],e=.2126729*jo(n)+.7151522*jo(r)+.072175*jo(t),t=(n=Bo(a))<(r=Bo(e)),a=Math.abs(r-n)<5e-4?0:t?1.14*(Math.pow(r,.56)-Math.pow(n,.57)):1.14*(Math.pow(r,.65)-Math.pow(n,.62));return 100*(Math.abs(a)<.1?0:0 | ","",""]}}}),Di=Object.freeze({__proto__:null,deltaE76:function(e,t){return Mo(e,t,"lab")},deltaECMC:function(e,t){var n=void 0===(n=(r=2"}),e.defineFunction("steps",Ai,{returns:"array"})}}),Ri=new eo({id:"hsl",name:"HSL",coords:{h:{refRange:[0,360],type:"angle",name:"Hue"},s:{range:[0,100],name:"Saturation"},l:{range:[0,100],name:"Lightness"}},base:ra,fromBase:function(e){var t=Math.max.apply(Math,M(e)),n=Math.min.apply(Math,M(e)),r=(e=V(e,3))[0],a=e[1],o=e[2],i=NaN,l=(e=0,(n+t)/2),u=t-n;if(0!=u){switch(e=0==l||1==l?0:(t-l)/Math.min(l,1-l),t){case r:i=(a-o)/u+(a | ","",""]},hsla:{coords:[" | ","",""],commas:!0,lastAlpha:!0}}}),Ni=new eo({id:"hsv",name:"HSV",coords:{h:{refRange:[0,360],type:"angle",name:"Hue"},s:{range:[0,100],name:"Saturation"},v:{range:[0,100],name:"Value"}},base:Ri,fromBase:function(e){var t=(e=V(e,3))[0],n=e[1];e=e[2];return[t,0==(n=(e/=100)+(n/=100)*Math.min(e,1-e))?0:200*(1-e/n),100*n]},toBase:function(e){var t=(e=V(e,3))[0],n=e[1];e=e[2];return[t,0==(n=(e/=100)*(1-(n/=100)/2))||1==n?0:(e-n)/Math.min(n,1-n)*100,100*n]},formats:{color:{toGamut:!0}}}),Ti=new eo({id:"hwb",name:"HWB",coords:{h:{refRange:[0,360],type:"angle",name:"Hue"},w:{range:[0,100],name:"Whiteness"},b:{range:[0,100],name:"Blackness"}},base:Ni,fromBase:function(e){var t=(e=V(e,3))[0],n=e[2];return[t,n*(100-e[1])/100,100-n]},toBase:function(e){var t=(e=V(e,3))[0],n=e[1],r=(e=e[2]\ +,(n/=100)+(e/=100));return 1<=r?[t,0,n/r*100]:[t,100*(0==(r=1-e)?0:1-n/r),100*r]},formats:{hwb:{toGamut:!0,coords:[" | ","",""]}}}),Si=new Dt({id:"a98rgb-linear",name:"Linear Adobe® 98 RGB compatible",white:"D65",toXYZ_M:[[.5766690429101305,.1855582379065463,.1882286462349947],[.29734497525053605,.6273635662554661,.07529145849399788],[.02703136138641234,.07068885253582723,.9913375368376388]],fromXYZ_M:[[2.0415879038107465,-.5650069742788596,-.34473135077832956],[-.9692436362808795,1.8759675015077202,.04155505740717557],[.013444280632031142,-.11836239223101838,1.0151749943912054]]}),_i=new Dt({id:"a98rgb",name:"Adobe® 98 RGB compatible",base:Si,toBase:function(e){return e.map((function(e){return Math.pow(Math.abs(e),563/256)*Math.sign(e)}))},fromBase:function(e){return e.map((function(e){return Math.pow(Math.abs(e),256/563)*Math.sign(e)}))},formats:{color:{id:"a98-rgb"}}}),Oi=new Dt({id:"prophoto-linear",name:"Linear ProPhoto",white:"D50",base:ye,t\ +oXYZ_M:[[.7977604896723027,.13518583717574031,.0313493495815248],[.2880711282292934,.7118432178101014,8565396060525902e-20],[0,0,.8251046025104601]],fromXYZ_M:[[1.3457989731028281,-.25558010007997534,-.05110628506753401],[-.5446224939028347,1.5082327413132781,.02053603239147973],[0,0,1.2119675456389454]]}),Mi=new Dt({id:"prophoto",name:"ProPhoto",base:Oi,toBase:function(e){return e.map((function(e){return e<.03125?e/16:Math.pow(e,1.8)}))},fromBase:function(e){return e.map((function(e){return 1/512<=e?Math.pow(e,1/1.8):16*e}))},formats:{color:{id:"prophoto-rgb"}}}),Pi=new eo({id:"oklch",name:"OKLCh",coords:{l:{refRange:[0,1],name:"Lightness"},c:{refRange:[0,.4],name:"Chroma"},h:{refRange:[0,360],type:"angle",name:"Hue"}},white:"D65",base:yi,fromBase:function(e){var t=(e=V(e,3))[0],n=e[1],r=(e=e[2],Math.abs(n)<2e-4&&Math.abs(e)<2e-4?NaN:180*Math.atan2(e,n)/Math.PI);return[t,Math.sqrt(Math.pow(n,2)+Math.pow(e,2)),fo(r)]},toBase:function(e){var t,n=(e=V(e,3))[0],r=e[1];e=e[2],r=isNaN(e)?t=\ +0:(t=r*Math.cos(e*Math.PI/180),r*Math.sin(e*Math.PI/180));return[n,t,r]},formats:{oklch:{coords:[" | ",""," | "]}}}),Ii=2610/Math.pow(2,14),Bi=Math.pow(2,14)/2610,ji=2523/Math.pow(2,5),Li=Math.pow(2,5)/2523,qi=3424/Math.pow(2,12),zi=2413/Math.pow(2,7),Vi=2392/Math.pow(2,7),Gi=new Dt({id:"rec2100pq",name:"REC.2100-PQ",base:De,toBase:function(e){return e.map((function(e){return 1e4*Math.pow(Math.max(Math.pow(e,Li)-qi,0)/(zi-Vi*Math.pow(e,Li)),Bi)/203}))},fromBase:function(e){return e.map((function(e){e=Math.max(203*e/1e4,0);var t=qi+zi*Math.pow(e,Ii);e=1+Vi*Math.pow(e,Ii);return Math.pow(t/e,ji)}))},formats:{color:{id:"rec2100-pq"}}}),$i=.17883277,Hi=.28466892,Ui=.55991073,Wi=3.7743,Yi=new Dt({id:"rec2100hlg",cssid:"rec2100-hlg",name:"REC.2100-HLG",referred:"scene",base:De,toBase:function(e){return e.map((function(e){return e<=.5?Math.pow(e,2)/3*Wi:Math.exp((e-Ui)/$i+Hi)/12*Wi}))},fromBase:function(e){return e.map((function(e){return(e/=Wi)<=1/1\ +2?Math.sqrt(3*e):$i*Math.log(12*e-Hi)+Ui}))},formats:{color:{id:"rec2100-hlg"}}}),Ki={};function Xi(e){var t=e.id;Ki[t]=e}function Zi(e,t,n){var r=(e=V(Ia((n=Ki[2{Object.defineProperty(t,e,{get:function(){return t.get(e)},set:function(n){return t.set(e,n)}})})(s)}),[{key:"space",get:function(){return L(ee,this)}},{key:"spaceId",get:function(){return L(ee,this).id}},{key:"clone",value:function(){return new rl(this.space,this.coords,this.alpha)}},{key:"toJSON",value:function(){return{spaceId:this.spaceId,coords:this.coords,alpha:this.alpha}}},{key:"display",value:function(){for(var e=arguments.length,t=new Array(e),n=0\ +;n"===o?(e=n,n=function(){var t=e.apply(void 0,arguments);return rl.get(t)},Object.assign(n,e)):"array"===o&&(n=n.map((function(e){return rl.get(e)}))),n}var r=2{var e,a=n.pop(),o=a.actualNode;for(o.querySelectorAll&&(e=o.nodeName,t.tags[e]?t.tags[e]++:t.tags[e]=1,o.classList&&Array.from(o.classList).forEach((function(e){e=Aa(e),t.classes[e]?t.classes[e]++:t.classes[e]=1})),o.hasAttributes())&&Array.from(Na(o)).filter(Dl).forEach((function(e){(e=bl(o,e))&&(t.attributes[e]?t.attributes[e]++:t.\ +attributes[e]=1)})),a.children.length&&(r.push(n),n=a.children.slice());!n.length&&r.length;)n=r.pop()})();return t}function xl(e){var t=dl(r);return Aa(t?e.localName:e.nodeName.toLowerCase())}function El(e,t){var n,r,a,o,i,l,u,s,c,d="",p=(r=e,a=[],o=t.classes,i=t.tags,r.classList&&Array.from(r.classList).forEach((function(e){e=Aa(e),o[e]{var t;if(e.getAttribute("id"))return t=e.getRootNode&&e.getRootNode()||r,(e="#"+Aa(e.getAttribute("id")||"")).match(/player_uid_/)||1!==t.querySelectorAll(e).length?void 0:e})(e);u||(u=El(e,o._selectorData),u+=((e,t)=>{var n=e.parentNode&&Array.from(e.parentNode.children||"")||[];return n.find((function(n){return n!==e&&Ta(n,t)}))?":nth-child("+(1+n.indexOf(e))+")":""})(e,u)),a=a?u+" > "+a:u,i=!i||i.length>oa.selectorSimilarFilterLimit?Cl(n,a):i.filter((function(e){return Ta(e,a)})),e=e.parentElement}while((1 ")?":root"+a.substring(a.indexOf(" > ")):":root"}var Fl=cl((function(e,t){return pl(Al,e,t)})),Cl=cl((function(e,t){return Array.from(e.querySelectorAll(t))}));function kl(e){var t=e.nodeName.toLowerCase(),n=e.parentElement,r=e.pare\ +ntNode,a="";return"head"!==t&&"body"!==t&&1<(null==r?void 0:r.children.length)&&(r=Array.prototype.indexOf.call(r.children,e)+1,a=":nth-child(".concat(r,")")),n?kl(n)+" > "+t+a:t+a}function Rl(e,t){return pl(kl,e,t)}var Nl=function(e){return function e(t,n){var r,a,o,i;if(!t)return[];if(!n&&9===t.nodeType)return[{str:"html"}];if(n=n||[],t.parentNode&&t.parentNode!==t&&(n=e(t.parentNode,n)),t.previousSibling){for(a=1,r=t.previousSibling;1===r.nodeType&&r.nodeName===t.nodeName&&a++,r=r.previousSibling;);1===a&&(a=null)}else if(t.nextSibling)for(r=t.nextSibling;r=1===r.nodeType&&r.nodeName===t.nodeName?(a=1,null):(a=null,r.previousSibling););return 1===t.nodeType&&((o={}).str=t.nodeName.toLowerCase(),(i=t.getAttribute&&Aa(t.getAttribute("id")))&&1===t.ownerDocument.querySelectorAll("#"+i).length&&(o.id=t.getAttribute("id")),1(0|t.left)&&(0|e.top)<(0|t.bottom)&&(0|e.bottom)>(0|t.top)}var ql=cl((function(e){var t=[];return e?("hidden"===e.getComputedStylePropertyValue("overflow")&&t.push(e),t.concat(ql(e.parent))):t})),zl=ql,Vl=/rect\\s*\\(([0-9]+)px,?\\s*([0-9]+)px,?\\s*([0-9]+)px,?\\s*([0-9]+)px\\s*\\)/,Gl=/(\\w+)\\((\\d+)/;function $l(e){return["style","script","noscript","template"].includes(e.props.nodeName)}function Hl(e){return"area"!==e.props.nodeName&&"none"===e.getComputedStylePropertyValue("display")}function Ul(e){return!(1{for(var n=e.parent;n&&n!==t;){if(["relative","sticky"].includes(n.getComputedStylePropertyValue("position")))return 1;n=n.parent}})(e,n)&&"static"===n.getComputedStylePropertyValue("position"))&&((n=n.boundingClientRect).width<2||n.height<2||!Ll(r,n))})))}function Jl(e){var t=e.getComputedStylePropertyValue("clip").match(Vl),n=e.getComputedStylePropertyValue("clip-path").match(Gl);if(t&&5===t.length&&(e=e.getComputedStylePropertyValue("position"),["fixed","absolute"].includes(e)))return t[3]-t[1]<=0&&t[2]-t[4]<=0;if(n){e=n[1];var r=parseIn\ +t(n[2],10);switch(e){case"inset":return 50<=r;case"circle":return 0===r}}return!1}function Ql(e,t){var n,r=Wd(e,"map");return!r||!((r=r.attr("name"))&&(e=Ml(e.actualNode))&&9===e.nodeType&&(n=fm(o._tree,'img[usemap="#'.concat(Aa(r),'"]')))&&n.length)||n.some((function(e){return!t(e)}))}function eu(e){var t;return"details"===(null==(t=e.parent)?void 0:t.props.nodeName)&&(("summary"!==e.props.nodeName||e.parent.children.find((function(e){return"summary"===e.props.nodeName}))!==e)&&!e.parent.hasAttr("open"))}var tu=[Hl,Ul,Wl,eu];function nu(e){var t=(n=1{for(e=ou(e);e&&"html"!==e.nodeName.toLowerCase()\ +;){if(e.scrollTop&&0<=(t+=e.scrollTop))return;e=ou(e)}return 1})(e,i.bottom)||"absolute"===a.position))return!0;if(0!==i.left||0!==i.right)if("ltr"===o){if(i.right<=0)return!0}else if(e=Math.max(n.scrollWidth,uu(t).width),i.left>=e)return!0;return!1}},cu=[Kl,Xl,Zl,Jl,su];function du(e){return e=Hf(e).vNode,pu(e)}var pu=cl((function(e,t){return e.actualNode&&"area"===e.props.nodeName?!Ql(e,pu):!(nu(e,{skipAncestors:!0,isAncestor:t})||e.actualNode&&cu.some((function(n){return n(e,{isAncestor:t})})))&&(!e.parent||pu(e.parent,!0))}));function fu(e,n){var r=Math.min(e.top,n.top),a=Math.max(e.right,n.right),o=Math.max(e.bottom,n.bottom);e=Math.min(e.left,n.left);return new t.DOMRect(e,r,a-e,o-r)}function mu(e,t){var n=e.x;e=e.y;return t.top<=e&&n<=t.right&&e<=t.bottom&&t.left<=n}var hu={};function gu(e,n){var r=Math.max(e.left,n.left),a=Math.min(e.right,n.right),o=Math.max(e.top,n.top);e=Math.min(e.bottom,n.bottom);return a<=r||e<=o?null:new t.DOMRect(r,o,a-r,e-o)}function vu(e){var n=e.left\ +;return new t.DOMPoint(n+e.width/2,e.top+e.height/2)}ce(hu,{getBoundingRect:function(){return fu},getIntersectionRect:function(){return gu},getOffset:function(){return Du},getRectCenter:function(){return vu},hasVisualOverlap:function(){return xu},isPointInRect:function(){return mu},rectHasMinimumSize:function(){return yu},rectsOverlap:function(){return Ll},splitRects:function(){return Eu}});var bu=.05;function yu(e,t){return e<=t.width+bu&&e<=t.height+bu}function Du(e,t){var n=2({x:e.xt.right?t.right:e.x,y:t=e.yt.bottom?t.bottom:e.y}))(o,u));i=Math.min(i,s)}}catch(e){l.e(e)}finally{l.f()}return yu(2*n,is(t))?i:(e=wu(o,vu(r.reduce(fu)))-n,Math.max(0,Math.min(i,e)))}function wu(e,t){return Math.hypot(e.x-t.x,e.y-t.y)}funct\ +ion xu(e,t){var n=e.boundingClientRect,r=t.boundingClientRect;return!(n.left>=r.right||n.right<=r.left||n.top>=r.bottom||n.bottom<=r.top)&&0{var n=e.top,r=e.left,a=e.bottom,o=e.right,i=nt.top,l=rt.left,u=[];if(Au(t.top,n,a)&&l&&u.push({top:n,left:r,bottom:t.top,right:o}),Au(t.right,r,o)&&i&&u.push({top:n,left:t.right,bottom:a,right:o}),Au(t.bottom,n,a)&&l&&u.push({top:t.bottom,right:o,bottom:a,left:r}),Au(t.left,r,o)&&i&&u.push({top:n,left:r,bottom:a,right:t.left}),0===u.length){if(((e,t)=>e.top>=t.top&&e.left>=t.left&&e.bottom<=t.bottom&&e.right<=t.right)(e,t))return[];u.push(e)}return u.map(Fu)})(n,e))}),[])).length)throw new Error("splitRects: Too many rects")};for(a.s();!(n=a.n()).done;)o()}catch(e){a.e(e)}finally{a.f()}return r}var Au=function(e,t,n){return t{var r=t._stackingOrder.slice(),a=(_u(e,t)&&-1!==(a=r.findIndex((function(e){return e=e.stackLevel,[Cu,Ru,Nu].includes(e)})))&&r.splice(a,r.length-a),((e,t)=>{var n=((e,t)=>"static"!==e.getComputedStyleProp\ +ertyValue("position")||Ou(t)?e.getComputedStylePropertyValue("z-index"):"auto")(e,t);return["auto","0"].includes(n)?"static"!==e.getComputedStylePropertyValue("position")?Nu:"none"!==e.getComputedStylePropertyValue("float")?Ru:_u(e,t)?ku:null:parseInt(n)})(e,t));return null!==a&&r.push(Mu(a,n,e)),r})(c,a,Tu++),((e,t)=>{for(var n=null,r=[e];t;){if(Cf(t.actualNode)){n=t;break}if(t._scrollRegionParent){n=t._scrollRegionParent;break}r.push(t),t=_l(t.actualNode.parentElement||t.actualNode.parentNode)}return r.forEach((function(e){return e._scrollRegionParent=n})),n})(c,a)),p=(d=d?d._subGrid:n,Cf(c.actualNode)&&(p=new Iu(c),c._subGrid=p),c.boundingClientRect);0!==p.width&&0!==p.height&&du(s)&&Pu(d,c),Wp(s)&&Su(s.shadowRoot,d,c),s=u.nextNode()}}return oa.gridSize}function _u(e,t){var n=e.getComputedStylePropertyValue("position"),r=e.getComputedStylePropertyValue("z-index");return"fixed"===n||"sticky"===n||"auto"!==r&&"static"!==n||"1"!==e.getComputedStylePropertyValue("opacity")||"none"!==(e.\ +getComputedStylePropertyValue("-webkit-transform")||e.getComputedStylePropertyValue("-ms-transform")||e.getComputedStylePropertyValue("transform")||"none")||(n=e.getComputedStylePropertyValue("mix-blend-mode"))&&"normal"!==n||(n=e.getComputedStylePropertyValue("filter"))&&"none"!==n||(n=e.getComputedStylePropertyValue("perspective"))&&"none"!==n||(n=e.getComputedStylePropertyValue("clip-path"))&&"none"!==n||"none"!==(e.getComputedStylePropertyValue("-webkit-mask")||e.getComputedStylePropertyValue("mask")||"none")||"none"!==(e.getComputedStylePropertyValue("-webkit-mask-image")||e.getComputedStylePropertyValue("mask-image")||"none")||"none"!==(e.getComputedStylePropertyValue("-webkit-mask-border")||e.getComputedStylePropertyValue("mask-border")||"none")||"isolate"===e.getComputedStylePropertyValue("isolation")||"transform"===(n=e.getComputedStylePropertyValue("will-change"))||"opacity"===n||"touch"===e.getComputedStylePropertyValue("-webkit-overflow-scrolling")||(n=e.getComputedStylePro\ +pertyValue("contain"),["layout","paint","strict","content"].includes(n))||!("auto"===r||!Ou(t))}function Ou(e){if(e)return e=e.getComputedStylePropertyValue("display"),["flex","inline-flex","grid","inline-grid"].includes(e)}function Mu(e,t,n){return{stackLevel:e,treeOrder:t,vNode:n}}function Pu(e,t){var n=zl(t);t.clientRects.forEach((function(r){r=n.reduce((function(e,t){return e&&gu(e,t.boundingClientRect)}),r);r&&(null==t._grid&&(t._grid=e),r=e.getGridPositionOfRect(r),e.loopGridPosition(r,(function(e){e.includes(t)||e.push(t)})))}))}var Iu=W((function e(){var t=0{Su();var n=o._tree[0]._grid,r=new t.DOMRect(0,0,t.innerWidth,t.innerHeight);if(n)for(var a=0;ae._stackingOrder[a].stackLevel)return 1;if(n._stackingOrder[a].stackLevel=Math.floor(t)&&i=Math.floor(n)}))}));return(a=e.container)&&(t=Qu(a._grid,a.boundingClientRect,!0).concat(t)),n?t:t.sort(Zu).map((function(e){return e.actualNode})).concat(r.documentElement).filter((function(e,t,n){return n.indexOf(e)===t}))}var es=function(e){var t=ju(e);return t?Qu(t,_l(e).boundingClientRect):[]},ts=function(e){return fm(e,"*").filter((function(e){var t=e.isFocusable;return null!==(e=Zf(e.actualNode.getAttribute("tabindex")))?t&&0<=e:t}))},ns=function(e){var t=Hf(e).vNode;if(t&&!Uu(t))switch(t.props.nodeName){case"a":ca\ +se"area":if(t.hasAttr("href"))return!0;break;case"input":return"hidden"!==t.props.type;case"textarea":case"select":case"summary":case"button":return!0;case"details":return!fm(t,"summary").length}return!1};function rs(e){return 1===(e=Hf(e).vNode).props.nodeType&&!(Uu(e)||!ns(e)&&null===Zf(e.attr("tabindex")))}function as(e){return 1===(e=Hf(e).vNode).props.nodeType&&!(Zf(e.attr("tabindex"))<=-1)&&rs(e)}var os=cl((function(e){var t=e.boundingClientRect,n=Lu(e).filter((function(t){return xu(e,t)&&"none"!==t.getComputedStylePropertyValue("pointer-events")&&!(Vp(e,t)&&!as(t))}));return n.length?(n=n.map((function(e){return e.boundingClientRect})),Eu(t,n)):[t]})),is=cl((function(e,t){return((e,t)=>e.reduce((function(e,n){var r=yu(t,e);return r!==yu(t,n)?r?e:n:(r=e.width*e.height,n.width*n.height{if(!e.attr("id"))return[];if(e.actualNode)retu\ +rn Il({elm:"label",attr:"for",value:e.attr("id"),context:e.actualNode});throw new TypeError("Cannot resolve explicit label reference for non-DOM nodes")})(e);return(t=Wd(e,"label"))?(r=[].concat(M(n),[t.actualNode])).sort($f):r=n,r.map((function(e){return ss(e,a)})).filter((function(e){return""!==e})).join(" ")},Dc={submit:"Submit",image:"Submit",reset:"Reset",button:""};function wc(e,t){return t.attr(e)||""}function xc(e,t,n){t=t.actualNode;var r=[e=e.toLowerCase(),t.nodeName.toLowerCase()].join(",");return(t=t.querySelector(r))&&t.nodeName.toLowerCase()===e?ss(t,n):""}var Ec={valueText:function(e){return e.props.value||""},buttonDefaultText:function(e){return Dc[e.props.type]||""},tableCaptionText:xc.bind(null,"caption"),figureText:xc.bind(null,"figcaption"),svgTitleText:xc.bind(null,"title"),fieldsetLegendText:xc.bind(null,"legend"),altText:wc.bind(null,"alt"),tableSummaryText:wc.bind(null,"summary"),titleText:Js,subtreeText:bc,labelText:yc,singleSpace:function(){return" "},placehol\ +derText:wc.bind(null,"placeholder")};function Ac(e){var t,n=1?@\\[\\]^_\`{|}~\\xb1]/g.test(e):a};function Cc(e){var n=1=a){if(i.numLigatures/i.occurrences==1)return!0;if(0===i.numLigatures)return!1}i.occurrences++;var s="".concat(a=30,"px ").concat(e),c=(l.font=s,o.charAt(0)),d=l.measureText(c).width;if(0===d)return i.numLigatures++,!0;d<30&&(d*=p=30/d,s="".concat(a*=p,"px ").concat(e)),u.width=d,u.height=a,l.font=s,l.textAlign="\ +left",l.textBaseline="top",l.fillText(c,0,0);var p=new Uint32Array(l.getImageData(0,0,d,a).data.buffer);if(!p.some((function(e){return e})))return i.numLigatures++,!0;l.clearRect(0,0,d,a),l.fillText(o,0,0);var f=new Uint32Array(l.getImageData(0,0,d,a).data.buffer);e=p.reduce((function(e,t,n){return 0===t&&0===f[n]||0!==t&&0!==f[n]?e:++e}),0),u=o.split("").reduce((function(e,t){return e+l.measureText(t).width}),0),s=l.measureText(o).width;return n<=e/p.length&&n<=1-s/u&&(i.numLigatures++,!0)}function kc(e){var t,n,r,a,i,l=((e,t)=>(t.startNode||(t=O({startNode:e},t)),1===e.props.nodeType&&t.inLabelledByContext&&void 0===t.includeHidden?O({includeHidden:!nc(e)},t):t))(e,1e&&1===e.props.nodeType&&!t.includeHidden&&!nc(e))(e,l)||(t=e,n=(i=l).ignoreIconLigature,r=i.pixelThreshold,a=null!=(a=i.occurrenceThreshold)?a:i.occuranceThreshold,3===t.props.nodeType&&n&&Cc(t,r,a))?"":(i=[cs,ds,Ac,gc,bc,Rc,Js].reduce((function(t,n)\ +{return""!==(t=l.startNode===e?Ns(t):t)?t:n(e,l)}),""),l.debug&&o.log(i||"{empty-value}",e.actualNode,l),i)}function Rc(e){return 3!==e.props.nodeType?"":e.props.nodeValue}kc.alreadyProcessed=function(e,t){return t.processed=t.processed||[],!!t.processed.includes(e)||(t.processed.push(e),!1)};var Nc=function(e,t){var n=t.emoji,r=t.nonBmp;t=t.punctuations;return n&&(e=e.replace(Ma(),"")),r&&(e=e.replace(/[\\u1D00-\\u1D7F\\u1D80-\\u1DBF\\u1DC0-\\u1DFF\\u20A0-\\u20CF\\u20D0-\\u20FF\\u2100-\\u214F\\u2150-\\u218F\\u2190-\\u21FF\\u2200-\\u22FF\\u2300-\\u23FF\\u2400-\\u243F\\u2440-\\u245F\\u2460-\\u24FF\\u2500-\\u257F\\u2580-\\u259F\\u25A0-\\u25FF\\u2600-\\u26FF\\u2700-\\u27BF\\uE000-\\uF8FF]/g,"").replace(/[\\uDB80-\\uDBBF][\\uDC00-\\uDFFF]/g,"").replace(/[\\xAD\\u0600-\\u0605\\u061C\\u06DD\\u070F\\u08E2\\u180E\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\u2066-\\u206F\\uFEFF\\uFFF9-\\uFFFB]|\\uD804[\\uDCBD\\uDCCD]|\\uD80D[\\uDC30-\\uDC38]|\\uD82F[\\uDCA0-\\uDCA3]|\\uD834[\\uDD73-\\uDD7A]|\\uDB40[\\uDC01\\uDC20-\\uDC7F]/g,"")),t?e.replace(/[\\u2000-\\u206F\\u2E00-\\u2E7\ +F\\\\'!"#$%&\\xa3\\xa2\\xa5\\xa7\\u20ac()*+,\\-.\\/:;<=>?@\\[\\]^_\`{|}~\\xb1]/g,""):e},Tc=function(e){var t;return 0===Ns(e).length||1===(t=e).length&&t.match(/\\D/)||["aa","abc"].includes(e.toLowerCase())||(e=>(e=Nc(e,{emoji:!0,nonBmp:!0,punctuations:!0}),!Ns(e)))(e)?0:1},Sc={stateTerms:["on","off"],standaloneTerms:["name","honorific-prefix","given-name","additional-name","family-name","honorific-suffix","nickname","username","new-password","current-password","organization-title","organization","street-address","address-line1","address-line2","address-line3","address-level4","address-level3","address-level2","address-level1","country","country-name","postal-code","cc-name","cc-given-name","cc-additional-name","cc-family-name","cc-number","cc-exp","cc-exp-month","cc-exp-year","cc-csc","cc-type","transaction-currency","transaction-amount","language","bday","bday-day","bday-month","bday-year","sex","url","photo","one-time-code"],qualifiers:["home","work","mobile","fax","pager"],qualifiedTerms:["tel",\ +"tel-country-code","tel-national","tel-area-code","tel-local","tel-local-prefix","tel-local-suffix","tel-extension","email","impp"],locations:["billing","shipping"]},_c=function(e){var t=void 0!==(t=(l=1{for(var t=ou(e);t&&!nd(t);)t=ou(t);return _l(t)})(e),a=r="",o=0,function e(t,n){!1!==n(t.actualNode)&&t.children.forEach((function(t){return e(t,n)}))}(n,(function(t){if(2===o)return!1;if(3===t.nodeType&&(r+=t.nodeValue),1===t.nodeType){var n=(t.nodeName||"").toUpperCase();if(t===e&&(o=1),!["BR","HR"].includes(n))return!("none"===t.style.display||"hidden"===t.style.overflow||!["",null,"none"].includes(t.style.float)||!["",null,"relative"].includes(t.style.position))&&("widget"==\ +=ed(t)?(a+=t.textContent,!1):void 0);0===o?a=r="":o=2}})),r=Ns(r),null!=t&&t.noLengthCompare?0!==r.length:(a=Ns(a),r.length>a.length))},ad=function(e){if(e=(e=e||{}).modalPercent||.75,Sl.get("isModalOpen"))return Sl.get("isModalOpen");if(rm(o._tree[0],"dialog, [role=dialog], [aria-modal=true]",du).length)return Sl.set("isModalOpen",!0),!0;for(var n,a=uu(t),i=a.width*e,l=a.height*e,u=(e=(a.width-i)/2,(a.height-l)/2),s=[{x:e,y:u},{x:a.width-e,y:u},{x:a.width/2,y:a.height/2},{x:e,y:a.height-u},{x:a.width-e,y:a.height-u}].map((function(e){return Array.from(r.elementsFromPoint(e.x,e.y))})),c=0;c{var e=s[c].find((function(e){return e=t.getComputedStyle(e),parseInt(e.width,10)>=i&&parseInt(e.height,10)>=l&&"none"!==e.getPropertyValue("pointer-events")&&("absolute"===e.position||"fixed"===e.position)}));if(e&&s.every((function(t){return t.includes(e)})))return Sl.set("isModalOpen",!0),{v:!0}})())return n.v;Sl.set("isModalOpen",void 0)};function od(e){var t,n=1r.value?(a.value=(a.value-r.value)*e/(n.value-r.value),n.value=e):a.value=n.value=0,r.value=\ +0,t[n.name]=n.value,t[r.name]=r.value,t[a.name]=a.value,t}},{key:"clip",value:function(){var e=new pd(this),t=e.getLuminosity(),n=Math.min(e.r,e.g,e.b),r=Math.max(e.r,e.g,e.b);return n<0&&(e.r=t+(e.r-t)*t/(t-n),e.g=t+(e.g-t)*t/(t-n),e.b=t+(e.b-t)*t/(t-n)),1{var t=e.getPropertyValue("clip").match(Dd),n=e.getPropertyValue("clip-path").match(wd);if(t&&5===t.length&&(e=e.getPropertyValue("position"),["fixed","absolute"].includes(e)))return t[3]-t[1]<=0&&t[2]-t[4]<=0;if(n){e=n[1];var r=parseInt(n[2],10);switch(e){case"inset":return 50<=r;case"circle":return 0===r}}})(d)||"0"===d.getPropertyValue("opacity")||u||p||m)||!a&&("hidden"===d.getPropertyValue("visibility")||!r&&su(n))))&&(f=!1,(p=n.assignedSlot||n.parentNode)&&(f=e(p,r,!0)),s&&(s[c]=f),f)):(m=!0,(a=s.parent)&&(m=e(a,r,!0)),s&&(s[c]=m),m)))},Ed=function(e,n){for(var r=["fixed","sticky"],a=[],o=!1,i=0;iMath.ceil(l.left+l.width)||Math.floor(e.top+e.height)>Math.ceil(l.top+l.height))})))}while(e=c);return!1}function Fd(e){for(var t=_l(e).parent;t;){if(Cf(t.actualNode))return t.actualNode;t=t.parent}}var Cd=function e(t,n){var a=2{var t={};if(e&&e.length){var n=e.substring(1).split("&");if(n&&n.length)for(var r=0;ro&&e.left>r.right||e.top>a&&e.top>r.bottom||e.rightr.right||e.top>r.bottom)||"scroll"===o.overflow||"auto"===o.overflow||n instanceof t.HTMLBodyElement||n instanceof t.HTMLHtmlElement)},Nd=0;function Td(e,t,n){var r;return H(this,Td),(r=R(this,Td)).shadowId=n,r.children=[],r.actualNode=e,(r.parent=t)||(Nd=0),r.nodeIndex=Nd++,r._isHidden=null,r._cache={},r._isXHTML=dl(e.ownerDocument),"input"===e.nodeName.toLowerCase()&&(n=e.getAttribute("type"),n=r._isXHTML?n:(n||"").toLowerCase(),Fm().includes(n)||(n="text"),r._type=n),Sl.get("nodeMap")&&Sl.get("nodeMap").set(e,r),r}S(Td,ua);var Sd=W(Td,[{key:"props",get:function(){var e\ +,t,n,r;return this._cache.hasOwnProperty("props")||(e=(r=this.actualNode).nodeType,t=r.nodeName,n=r.id,r=r.nodeValue,this._cache.props={nodeType:e,nodeName:this._isXHTML?t:t.toLowerCase(),id:n,type:this._type,nodeValue:r},1===e&&(this._cache.props.multiple=this.actualNode.multiple,this._cache.props.value=this.actualNode.value,this._cache.props.selected=this.actualNode.selected,this._cache.props.checked=this.actualNode.checked,this._cache.props.indeterminate=this.actualNode.indeterminate)),this._cache.props}},{key:"attr",value:function(e){return"function"!=typeof this.actualNode.getAttribute?null:this.actualNode.getAttribute(e)}},{key:"hasAttr",value:function(e){return"function"==typeof this.actualNode.hasAttribute&&this.actualNode.hasAttribute(e)}},{key:"attrNames",get:function(){var e;return this._cache.hasOwnProperty("attrNames")||(e=(this.actualNode.attributes instanceof t.NamedNodeMap?this.actualNode:this.actualNode.cloneNode(!1)).attributes,this._cache.attrNames=Array.from(e).map(\ +(function(e){return e.name}))),this._cache.attrNames}},{key:"getComputedStylePropertyValue",value:function(e){var n="computedStyle_"+e;return this._cache.hasOwnProperty(n)||(this._cache.hasOwnProperty("computedStyle")||(this._cache.computedStyle=t.getComputedStyle(this.actualNode)),this._cache[n]=this._cache.computedStyle.getPropertyValue(e)),this._cache[n]}},{key:"isFocusable",get:function(){return this._cache.hasOwnProperty("isFocusable")||(this._cache.isFocusable=rs(this.actualNode)),this._cache.isFocusable}},{key:"tabbableElements",get:function(){return this._cache.hasOwnProperty("tabbableElements")||(this._cache.tabbableElements=ts(this)),this._cache.tabbableElements}},{key:"clientRects",get:function(){return this._cache.hasOwnProperty("clientRects")||(this._cache.clientRects=Array.from(this.actualNode.getClientRects()).filter((function(e){return 0")}var s,c="<".concat(n,">").length,d=K(e);try{for(d.s();!(s=d.n()).done;){var p=s.value,f=p.name,m=p.value;if(300")).length?t=t.substring(0,300)+" ...>":r.length")}return t}return""}(this._element)),this})),Pd=(Md.prototype={get selector(){return this.spec.selector||[Fl(this.element,this._options)]},get ancestry(){return this.spec.ancestry||[Rl(this.element)]},get xpath(){return this.spec.xpath||[Nl(this.e\ +lement)]},get element(){return this._element},toJSON:function(){var e={selector:this.selector,source:this.source,xpath:this.xpath,ancestry:this.ancestry,nodeIndexes:this.nodeIndexes,fromFrame:this.fromFrame};return this._includeElementInJson&&(e.element=this._element),e}},Md.fromFrame=function(e,t,n){return e=Md.mergeSpecs(e,n),new Md(n.element,t,e)},Md.mergeSpecs=function(e,t){return O({},e,{selector:[].concat(M(t.selector),M(e.selector)),ancestry:[].concat(M(t.ancestry),M(e.ancestry)),xpath:[].concat(M(t.xpath),M(e.xpath)),nodeIndexes:[].concat(M(t.nodeIndexes),M(e.nodeIndexes)),fromFrame:!0})},Md.setRunOptions=function(e){var t=e.elementRef;Sl.set(_d,{elementRef:t,absolutePaths:e.absolutePaths})},Md),Id=function(e,n,r,a){return{isAsync:!1,async:function(){return this.isAsync=!0,function(t){t instanceof Error==0?(e.result=t,r(e)):a(t)}},data:function(t){e.data=t},relatedNodes:function(n){t.Node&&(n=n instanceof t.Node||n instanceof ua?[n]:Ea(n),e.relatedNodes=[],n.forEach((function(n\ +){(n=n instanceof ua?n.actualNode:n)instanceof t.Node&&(n=new Pd(n),e.relatedNodes.push(n))})))}}};function Bd(e){return function e(n,r){var o,i;if(null===n||"object"!==a(n))return n;if(null!=(o=t)&&o.Node&&n instanceof t.Node||null!=(o=t)&&o.HTMLCollection&&n instanceof t.HTMLCollection||"nodeName"in n&&"nodeType"in n&&"ownerDocument"in n)return n;if(r.has(n))return r.get(n);if(Array.isArray(n))return i=[],r.set(n,i),n.forEach((function(t){i.push(e(t,r))})),i;var l={};for(var u in r.set(n,l),n)l[u]=e(n[u],r);return l}(e,new Map)}(Yo=new _a.CssSelectorParser).registerSelectorPseudos("not"),Yo.registerSelectorPseudos("is"),Yo.registerNestingOperators(">"),Yo.registerAttrEqualityMods("^","$","*","~");var jd=Yo;function Ld(e,t){return Hd(t).some((function(t){return Ud(e,t)}))}function qd(e,t){return i=t,1===(o=e).props.nodeType&&("*"===i.tag||o.props.nodeName===i.tag)&&(a=e,!(o=t).classes||o.classes.every((function(e){return a.hasClass(e.value)})))&&(r=e,!(i=t).attributes||i.attributes.ev\ +ery((function(e){var t=r.attr(e.key);return null!==t&&e.test(t)})))&&(o=e,!(i=t).id||o.props.id===i.id)&&(n=e,!((o=t).pseudos&&!o.pseudos.every((function(e){if("not"===e.name)return!e.expressions.some((function(e){return Ud(n,e)}));if("is"===e.name)return e.expressions.some((function(e){return Ud(n,e)}));throw new Error("the pseudo selector "+e.name+" has not yet been implemented")}))));var n,r,a,o,i}zd=/(?=[\\-\\[\\]{}()*+?.\\\\\\^$|,#\\s])/g;var zd,Vd=function(e){return e.replace(zd,"\\\\")},Gd=/\\\\/g;function $d(e){return e.map((function(e){for(var t=[],n=e.rule;n;)t.push({tag:n.tagName?n.tagName.toLowerCase():"*",combinator:n.nestingOperator||" ",id:n.id,attributes:(e=>{if(e)return e.map((function(e){var t,n,r=e.name.replace(Gd,""),a=(e.value||"").replace(Gd,"");switch(e.operator){case"^=":n=new RegExp("^"+Vd(a));break;case"$=":n=new RegExp(Vd(a)+"$");break;case"~=":n=new RegExp("(^|\\\\s)"+Vd(a)+"(\\\\s|$)");break;case"|=":n=new RegExp("^"+Vd(a)+"(-|$)");break;case"=":t=function(e){return a===e\ +};break;case"*=":t=function(e){return e&&e.includes(a)};break;case"!=":t=function(e){return a!==e};break;default:t=function(e){return null!==e}}return""===a&&/^[*$^]=$/.test(e.operator)&&(t=function(){return!1}),{key:r,value:a,type:void 0===e.value?"attrExist":"attrValue",test:t=t||function(e){return e&&n.test(e)}}}))})(n.attrs),classes:(e=>{if(e)return e.map((function(e){return{value:e=e.replace(Gd,""),regexp:new RegExp("(^|\\\\s)"+Vd(e)+"(\\\\s|$)")}}))})(n.classNames),pseudos:(e=>{if(e)return e.map((function(e){var t;return["is","not"].includes(e.name)&&(t=$d(t=(t=e.value).selectors||[t])),{name:e.name,expressions:t,value:e.value}}))})(n.pseudos)}),n=n.rule;return t}))}function Hd(e){return $d((e=jd.parse(e)).selectors||[e])}function Ud(e,t,n){return function e(t,n,r,a){if(!t)return!1;for(var o=Array.isArray(n)?n[r]:n,i=qd(t,o);!i&&a&&t.parent;)i=qd(t=t.parent,o);if(0"].includes(o.combinator))throw new Error("axe.utils.matchesExpression does not support the combinator\ +: "+o.combinator);i=i&&e(t.parent,n,r-1," "===o.combinator)}return i}(e,t,t.length-1,n)}var Wd=function(e,t){for(;e;){if(Ld(e,t))return e;if(void 0===e.parent)throw new TypeError("Cannot resolve parent for non-DOM nodes");e=e.parent}return null};function Yd(){}function Kd(e){if("function"!=typeof e)throw new TypeError("Queue methods require functions as arguments")}for(var Xd,Zd,Jd,Qd=function(){function e(e){t=e,setTimeout((function(){null!=t&&ia("Uncaught error (of queue)",t)}),1)}var t,n=[],r=0,o=0,i=Yd,l=!1,u=e;function s(e){return i=Yd,u(e),n}function c(){for(var e=n.length;rfunction(t){n[e]=t,--o||i===Yd||(l=!0,i(n))})(r),s)}catch(e){s(e)}}}var d={defer:function(e){var r;if("object"===a(e)&&e.then&&e.catch&&(r=e,e=function(e,t){r.then(e).catch(t)}),Kd(e),void 0===t){if(l)throw new Error("Queue already completed");return n.push(e),++o,c(),d}},then:function(e){if(Kd(e),i!==Yd)throw new Error("queue \`then\` already set");return t||(i=e,o)||(l=!0\ +,i(n)),d},catch:function(n){if(Kd(n),u!==e)throw new Error("queue \`catch\` already set");return t?(n(t),t=null):u=n,d},abort:s};return d},ep=t.crypto||t.msCrypto,tp=(!Zd&&ep&&ep.getRandomValues&&(Xd=new Uint8Array(16),Zd=function(){return ep.getRandomValues(Xd),Xd}),Zd||(Jd=new Array(16),Zd=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),Jd[t]=e>>>((3&t)<<3)&255;return Jd}),"function"==typeof t.Buffer?t.Buffer:Array),np=[],rp={},ap=0;ap<256;ap++)np[ap]=(ap+256).toString(16).substr(1),rp[np[ap]]=ap;function op(e,t){return t=t||0,np[e[t++]]+np[e[t++]]+np[e[t++]]+np[e[t++]]+"-"+np[e[t++]]+np[e[t++]]+"-"+np[e[t++]]+np[e[t++]]+"-"+np[e[t++]]+np[e[t++]]+"-"+np[e[t++]]+np[e[t++]]+np[e[t++]]+np[e[t++]]+np[e[t++]]+np[e[+t]]}var ip=[1|(kn=Zd())[0],kn[1],kn[2],kn[3],kn[4],kn[5]],lp=16383&(kn[6]<<8|kn[7]),up=0,sp=0;function cp(e,t,n){var r=t&&n||0,a=t||[],o=(n=null!=(e=e||{}).clockseq?e.clockseq:lp,null!=e.msecs?e.msecs:(new Date).getTime()),i=null!=e.nsecs?e.nsecs:sp+1;if(\ +(l=o-up+(i-sp)/1e4)<0&&null==e.clockseq&&(n=n+1&16383),1e4<=(i=(l<0||up>>24&255,a[r++]=l>>>16&255,a[r++]=l>>>8&255,a[r++]=255&l,o/4294967296*1e4&268435455),a[r++]=i>>>8&255,a[r++]=255&i,a[r++]=i>>>24&15|16,a[r++]=i>>>16&255,a[r++]=n>>>8|128,a[r++]=255&n,e.node||ip),s=0;s<6;s++)a[r+s]=u[s];return t||op(a)}function dp(e,t,n){var r=t&&n||0,a=("string"==typeof e&&(t="binary"==e?new tp(16):null,e=null),(e=e||{}).random||(e.rng||Zd)());if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,t)for(var o=0;o<16;o++)t[r+o]=a[o];return t||op(a)}(ra=dp).v1=cp,ra.v4=dp,ra.parse=function(e,t,n){var r=t&&n||0,a=0;for(t=t||[],e.toLowerCase().replace(/[0-9a-f]{2}/g,(function(e){a<16&&(t[r+a++]=rp[e])}));a<16;)t[r+a++]=0;return t},ra.unparse=op,ra.BufferClass=tp,o._uuid=cp();var pp=dp,fp=Object.freeze(["EvalError","RangeError","ReferenceError","S\ +yntaxError","TypeError","URIError"]);function mp(){var e="axeAPI",t="";return(e=void 0!==o&&o._audit&&o._audit.application?o._audit.application:e)+"."+(void 0!==o?o.version:t)}function hp(e){vp(e),xa(t.parent===e,"Source of the response must be the parent window.")}function gp(e){vp(e),xa(e.parent===t,"Respondable target must be a frame in the current window")}function vp(e){xa(t!==e,"Messages can not be sent to the same window.")}var bp={},yp=[];function Dp(){var e="".concat(dp(),":").concat(dp());return yp.includes(e)?Dp():(yp.push(e),e)}function wp(e,t,n,r){var a,i,l,u;return(n?hp:gp)(e),t.message instanceof Error&&!n?(o.log(t.message),!1):(i=(u=O({messageId:Dp()},t)).topic,l=u.message,i={channelId:u.channelId,topic:i,messageId:u.messageId,keepalive:!!u.keepalive,source:mp()},l instanceof Error?i.error={name:l.name,message:l.message,stack:l.stack}:i.payload=l,a=JSON.stringify(i),!(!(u=o._audit.allowedOrigins)||!u.length||("function"==typeof r&&function(e,t,n){n=!(2{var n=e.message||"Unknown error occurred",r=fp.includes(e.name)?e.name:"Error";return r=t[r]||Error,e.stack&&(n+="\\n"+e.stack.replace(e.message,"")),new r(n)})(n.error):n.payload,messageId:i,channelId:o,keepalive:!!e}}(s)||{},d=c.c\ +hannelId,p=c.message,f=c.messageId;if(i=u,((l=o._audit.allowedOrigins)&&l.includes("*")||l.includes(i))&&(r=f,!yp.includes(r))&&(yp.push(r),1))if(p instanceof Error&&e.parent!==t)o.log(p);else try{if(c.topic){var m=xp(e,d);hp(e),n(c,m)}else{var h=e,g=(b=c).channelId,v=b.message,b=b.keepalive,y=(D=(e=>bp[e])(g)||{}).replyHandler,D=D.sendToParent;if(y){(D?hp:gp)(h),h=xp(h,g,D),!b&&g&&(e=>{delete bp[e]})(g);try{y(v,b,h)}catch(n){o.log(n),h(n,b)}}}}catch(n){var w=e,x=n,E=d;if(!w.parent!==t)o.log(x);else try{wp(w,{topic:null,channelId:E,message:x,messageId:Dp(),keepalive:!0},!0)}catch(n){return void o.log(n)}}}catch(n){o.log(n)}}var Ap,Fp,Cp={open:function(e){var n;if("function"==typeof t.addEventListener)return t.addEventListener("message",n=function(t){Ep(t,e)},!1),function(){t.removeEventListener("message",n,!1)}},post:function(e,n,r){return"function"==typeof t.addEventListener&&wp(e,n,!1,r)}};function kp(e){e.updateMessenger(Cp)}var Rp={};function Np(e,t,n,r,a){return t={topic:t,message\ +:n,channelId:"".concat(dp(),":").concat(dp()),keepalive:r},Fp(e,t,a)}function Tp(e,t){var n=e.topic,r=e.message;e=e.keepalive;if(n=Rp[n])try{n(r,e,t)}catch(n){o.log(n),t(n,e)}}function Sp(e,t,n,r){var a,o=e.contentWindow,i=null!=(i=null==(i=t.options)?void 0:i.pingWaitTime)?i:500;o?0===i?_p(e,t,n,r):(a=setTimeout((function(){a=setTimeout((function(){t.debug?r(Op("No response from frame",e)):n(null)}),0)}),i),Np(o,"axe.ping",null,void 0,(function(){clearTimeout(a),_p(e,t,n,r)}))):(ia("Frame does not have a content window",e),n(null))}function _p(e,t,n,r){var a=null!=(a=null==(a=t.options)?void 0:a.frameWaitTime)?a:6e4,o=e.contentWindow,i=setTimeout((function(){r(Op("Axe in frame timed out",e))}),a);Np(o,"axe.start",t,void 0,(function(e){clearTimeout(i),(e instanceof Error==0?n:r)(e)}))}function Op(e,t){var n;return o._tree&&(n=Fl(t)),new Error(e+": "+(n||t))}Np.updateMessenger=function(e){var t=e.open;e=e.post,xa("function"==typeof t,"open callback must be a function"),xa("function"==ty\ +peof e,"post callback must be a function"),Ap&&Ap(),t=t(Tp);Ap=t?(xa("function"==typeof t,"open callback must return a cleanup function"),t):null,Fp=e},Np.subscribe=function(e,t){xa("function"==typeof t,"Subscriber callback must be a function"),xa(!Rp[e],"Topic ".concat(e," is already registered to.")),Rp[e]=t},Np.isInFrame=function(){return!!(0e.frameElement?Ip.toSpec(e.frameElement):e.frameSpec||null)(e),r.forEach((function(e){e.nodes&&t&&(a=e.nodes,r=t,a.forEach((function(e){e.node=Ip.mergeSpecs(e.node,r),Bp(e).forEach((function(e){e.relatedNodes=e.relatedNodes.map((function(e){return Ip.mergeSpecs(e,r)}))}))})));var r,a=jp(n,"id",e.id);a?(e.nodes.length&&((e,t)=>{for(var n=t[0].node,r=0;r{var r=e[e.length-1],a=null,o=1{var t=[];for(e=e.firstChild;e;)t.push(e),e=e.nextSibling;return t})(e)),t.getComputedStyle(e),rf(i,a,n)):e.nodeType===r.ELEMENT_NODE?(o=nf(e,a,n),i=Array.from(e.childNodes),o.children=rf(i,o,n),[o]):e.nodeType===r.TEXT_NODE?[nf(e,a)]:void 0}var of=function(e){return e?e.trim().split("-")[0].toLowerCase():""},lf\ +=function(e){var t={};return t.none=e.none.concat(e.all),t.any=e.any,Object.keys(t).map((function(e){var n;return t[e].length&&(n=o._audit.data.failureSummaries[e])&&"function"==typeof n.failureMessage?n.failureMessage(t[e].map((function(e){return e.message||""}))):void 0})).filter((function(e){return void 0!==e})).join("\\n\\n")};function uf(){var e=o._audit.data.incompleteFallbackMessage;return"string"!=typeof(e="function"==typeof e?e():e)?"":e}var sf=oa.resultGroups;function cf(e,t){var n=o.utils.aggregateResult(e);return sf.forEach((function(e){t.resultTypes&&!t.resultTypes.includes(e)&&(n[e]||[]).forEach((function(e){Array.isArray(e.nodes)&&0(e=e.screen).orientation||e.msOrientation||e.mozOrientation)(l)||{},i=l.angle,l=l.type,{userAgent:e.userAgent,windowWidth:r,windowHeight:n,orientationAngle:i,orientationType:l}):{},timestamp:(new Date).toISOString(),url:null==(e=u.location)?void 0:e.href}}function bf(e,t){var n=t.focusable;t=t.page;return{node:e,include:[],exclude:[],initiator:!1,focusable:n&&(e=>null===(e=Zf(e.getAttribute("tabindex")))||0<=e)(e),size:(e=>{var t=parseInt(e.getAttribute("width"),10),n=parseInt(e.getAttribute("height"),10);return(isNaN(t)||isNaN(n))&&(e=e.getBoundingClientRect(),t=isNaN(t)?e.width:t,n=isNaN(n)?e.height:n),{width:t,height:n}})(e),page:t}}function yf(e){var n=0{if(e instanceof t.Node)return e;if("string"==typeof e)return[e];var n;if(Bf(e)?(n=e,Df(Array.isArray(n.fromFrames),"fromFrames property must be an array"),Df(n.fromFrames.every((function(e){return!Of(e,"fromFrames")})),"Invalid context; fromFrames selector must be appended, rather than nested"),Df(!Of(n,"fromShadowDom"),"fromFrames and fromShadowDom cannot be used on the same object"),e=e.fromFrames):jf(e)&&(e=[e]),Array.isArray(e)){var r,a=[],o=K(e);try{for(o.s();!(r=o.n()).done;){var i=r.value;if(jf(i)&&((e=>{Df(Array.isArray(e.fromShadowDom),"fromShadowDom property must be an array"),Df(e.fromShadowDom.every((function(e){return!Of(e,"fromFrames")})),"shadow selector must be inside fromFrame instead"),Df(e.fromShadowDom.every((function(e){return!Of(e,"fromShadowDom")})),"fromShadowDom selector must be appended, rather than nested")})(i),i=i.fromShadowDom),"string"!=typeof i&&!(e=>Array.isArray(e)&&e.every((function(e){return"string"==typeof e})))(i))return;a.pus\ +h(i)}}catch(e){o.e(e)}finally{o.f()}return a}})(n[a]);o&&r.push(o)}return r}function Df(e,t){xa(e,"Invalid context; ".concat(t,"\\nSee: https://github.com/dequelabs/axe-core/blob/master/doc/context.md"))}function wf(e,n){for(var r=[],a=0,o=e[n].length;a{e.frames=e.frames||[],Am(n.shift()).forEach((function(r){var a=e.frames.find((function(e){return e.node===r}));a||(a=bf(r,e),e.frames.push(a)),a[t].push(n)}))})(e,n,i):(i=Am(i[0]),r.push.apply(r,M(i.map((function(e){return _l(e)}))))))}return r.filter((function(e){return e}))}function xf(e,n){var o=this,i=(e=Bd(e),this.frames=[],this.page="boolean"==typeof(null==(i=e)?void 0:i.page)?e.page:void 0,this.initiator="boolean"!=typeof(null==(i=e)?void 0:i.initiator)||e.initiator,this.focusable="boolean"!=typeof(null==(i=e)?void 0:i.focusable)||e.focusable,this.size="object"===a(null==(i=e)?void 0:\ +i.size)?e.size:{},e=(e=>{if(Pf(e)){var t=" must be used inside include or exclude. It should not be on the same object.";Df(!Of(e,"fromFrames"),"fromFrames"+t),Df(!Of(e,"fromShadowDom"),"fromShadowDom"+t)}else{if(!If(e))return{include:[r],exclude:[]};e={include:e,exclude:[]}}return 0===(t=yf(e.include)).length&&t.push(r),{include:t,exclude:e=yf(e.exclude)}})(e),this.flatTree=null!=n?n:tf((e=>{for(var n=e.include,a=(e=e.exclude,Array.from(n).concat(Array.from(e))),o=0;o1===(e=e.include).length&&e[0].actualNode===r.documentElement)(this),th\ +is.frames.forEach((function(e){e.page=o.page}))),this);if(0===i.include.length&&0===i.frames.length)throw i=Np.isInFrame()?"frame":"page",new Error("No elements found for include in "+i+" Context");Array.isArray(this.include)||(this.include=Array.from(this.include)),this.include.sort($f)}function Ef(e){return!1===(1e.clientWidth+a;a=e.clientHeight+a{try{return!(!e.cssRules&&e.href)}catch(e){return!1}})(e)?Yf(e,t,n,r,a):Xf(e.href,t,n,r,!0)},Xf=function(e,n,r,a,o){return a.push(e),new Promise((function(n,r){var a=new t.XMLHttpReques\ +t;a.open("GET",e),a.timeout=oa.preload.timeout,a.addEventListener("error",r),a.addEventListener("timeout",r),a.addEventListener("loadend",(function(e){if(e.loaded&&a.responseText)return n(a.responseText);r(a.responseText)})),a.send()})).then((function(e){return e=n.convertDataToStylesheet({data:e,isCrossOrigin:o,priority:r,root:n.rootNode,shadowId:n.shadowId}),Kf(e.sheet,n,r,a,e.isCrossOrigin)}))},Zf=function(e){return"string"==typeof e&&(e=e.trim().match(/^([-+]?\\d+)/))?Number(e[1]):null};function Jf(){if(t.performance)return t.performance.now()}Uf=Jf(),Wf=!1;var Qf={start:function(){this.reset(),Wf=!0,this.mark("mark_axe_start")},end:function(){this.mark("mark_axe_end"),this.measure("axe","mark_axe_start","mark_axe_end",!0),this.logMeasures("axe"),this.clearMark("mark_axe_start","mark_axe_end"),Wf=!1},auditStart:function(){Wf||this.reset(),this.mark("mark_audit_start")},auditEnd:function(){this.mark("mark_audit_end"),this.measure("audit_start_to_end","mark_audit_start","mark_audit_en\ +d",!0),this.logMeasures(),this.clearMark("mark_audit_start","mark_audit_end")},mark:function(e){var n;null!=(n=t.performance)&&n.mark&&t.performance.mark(e)},measure:function(e,n,r){var a,o=3=i.startTime})),u=0;u"].includes(v[0].combinator))throw new Error("axe.utils.querySelectorAll does not support the combinator: "+g[1].combinator);(">"===v[0].combinator?d=d||[]:p=p||[]).push(v)}g[0].id&&c.shadowId!==l.parentShadowId||null==(v=l.anyLevel)||!v.includes(g)||(p=p||[]).push(g)}for(c.children&&c.children.length&&(i.push(l),l=nm(c.children,p,d,c.shadowId,o.pop()));l.vNodesIndex===l.vNodes.length&&i.length;)o.push(l),l=i.pop()}return u},am=function(e){var t,n,a,i;e=void 0===(e=e.treeRoot)?o._tree[0]:e;return t=[],e=rm(e,"*",(function(e){return!t.includes(e.shadowId)&&(t.push(e.shadowId),!0)})).map((function(e){return{shadowId:e.shadowId,rootNode:Ml(e.actualNode)}})),(e=tm(e,[])).length?(n=r.implementation.createHTMLDocument("Dynamic document for loading cssom"),n=Tf(n),a=n,i=[],e.forEach((function(e,t){var n=e.rootNode,r=((e,t,n)=>{t=11===e.nodeType&&t?((e,t)=>Array.from(e.children).filter(om).reduce((function(n,r){var a=r.nodeName.toUpperCase();r="STYLE"===a?r.textContent:r;ret\ +urn(r=t({data:r,isLink:"LINK"===a,root:e})).sheet&&n.push(r.sheet),n}),[]))(e,n):(e=>Array.from(e.styleSheets).filter((function(e){return!!e.media&&im(e.media.mediaText)})))(e);var r=[];return t.filter((function(e){if(e.href){if(r.includes(e.href))return!1;r.push(e.href)}return!0}))})(n,e=e.shadowId,a);if(!r)return Promise.all(i);var o=t+1,l={rootNode:n,shadowId:e,convertDataToStylesheet:a,rootIndex:o},u=[];t=Promise.all(r.map((function(e,t){return Kf(e,l,[o,t],u)})));i.push(t)})),Promise.all(i).then((function e(t){return t.reduce((function(t,n){return Array.isArray(n)?t.concat(e(n)):t.concat(n)}),[])}))):Promise.resolve()};function om(e){var t=e.nodeName.toUpperCase(),n=e.getAttribute("href"),r=e.getAttribute("rel");n="LINK"===t&&n&&r&&e.rel.toUpperCase().includes("STYLESHEET");return"STYLE"===t||n&&im(e.media)}function im(e){return!e||!e.toUpperCase().includes("PRINT")}var lm=function(e){return e=void 0===(e=e.treeRoot)?o._tree[0]:e,e=rm(e,"video[autoplay], audio[autoplay]",(function\ +(e){return("none"!==(e=e.actualNode).preload||0!==e.readyState||e.networkState===e.NETWORK_LOADING)&&!(e.hasAttribute("paused")||e.hasAttribute("muted")||(e.hasAttribute("src")?!e.getAttribute("src"):Array.from(e.getElementsByTagName("source")).filter((function(e){return!!e.getAttribute("src")})).length<=0))})),Promise.all(e.map((function(e){var t;e=e.actualNode;return t=e,new Promise((function(e){0{function n(e){return e.incomplete&&e.incomplete.default?e.incomplete.default:uf()}if(!e||!e.missingData)return e&&e.messageKey?t.incomplete[e.messageKey]:n(t);try{var r=t.incomplete[e.missingData[0].reason];if(r)return r;throw new Error}catch(r){return"string"==typeof e.missingData?t.incomplete[e.missingData]:n(t)}})(r.data,i)),o.message||(o.message=i.incomplete)),"function"!=typeof o.message&&(o.message=mf(o.message,r.data)),Hp(r,o)}}var fm=function(e,t){return rm(e,t)};function mm(e,t){var n,r=o._audit&&o._audit.tagExclude?o._audit.tagExclude:[],a=t.hasOwnProperty("include")||t.hasOwnProperty("exclude")?(n=t.include||[],n=Array.isArray(n)?n:[n],a=t.exclude||[],(a=Array.isArray(a)?a:[a]).concat(r.filter((function(e){return-1===n.indexOf(e)})))):(n=Array.isArray(t)?t:[t],r.filter((function(e){return-1===n.indexOf(e)})));return!!(n.some((function(t){return-1!==e.tags.indexOf(t)})\ +)||0===n.length&&!1!==e.enabled)&&a.every((function(t){return-1===e.tags.indexOf(t)}))}var hm=function(e,t,n){var r=n.runOnly||{};n=(n.rules||{})[e.id];return!(e.pageLevel&&!t.page)&&("rule"===r.type?-1!==r.values.indexOf(e.id):n&&"boolean"==typeof n.enabled?n.enabled:"tag"===r.type&&r.values?mm(e,r.values):mm(e,[]))};function gm(e,t){var n,r,a;return t?(a=e.cloneNode(!1),n=Na(a),a=1===a.nodeType?(r=a.outerHTML,Sl.get(r,(function(){return vm(a,n,e,t)}))):vm(a,n,e,t),Array.from(e.childNodes).forEach((function(e){a.appendChild(gm(e,t))})),a):e}function vm(e,t,n,a){return t&&(e=r.createElement(e.nodeName),Array.from(t).forEach((function(t){var r,o,i;r=n,o=t.name,void 0!==(i=a)[o]&&(!0===i[o]||Ta(r,i[o]))||e.setAttribute(t.name,t.value)}))),e}function bm(e,t){var n=[];if(o._selectCache)for(var r=0,a=o._selectCache.length;r{if(0===e.length)return t;var n;e.length{try{return-1!==Function.toString.call(e).indexOf("[native code]")}catch(t){return"function"==typeof e}})(e))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return C(e,arguments,T(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),_(n,e)}(e)}(Error));var wm=W(Dm),xm=function(e){e.forEach((function(e){var n=e.elm,r=e.top;e=e.left;if(n===t)return n.scroll(e,r);n.scrollTop=r,n.scrollLeft=e}))};function Em(e){return function e(t,n){var r=t.shift();return n=r?n.querySelector(r):null,0===t.length?n:null!=n&&n.shadowRoot?e(t,n.shadowRoot):null}(Array.isArray(e)?M(e):[e],r)}function Am(e){var t=1{var t=null!=(t=e.nodeName)?t:_m[e.nodeType],n=null!=(n=null!=(n=e.nodeType)?n:Sm[e.nodeName])?n:1,r=(xa("number"==typeof n,"nodeType has to be a number, got '".concat(n,"'")),xa("string"==typeof t,"nodeName has to be a string, got '".concat(t,"'")),t=t.toLowerCase(\ +),null);return"input"===t&&(r=(e.type||e.attributes&&e.attributes.type||"").toLowerCase(),Fm().includes(r)||(r="text")),e=O({},e,{nodeType:n,nodeName:t}),r&&(e.type=r),delete e.attributes,Object.freeze(e)})(e),t._attrs=(e=e.attributes,n=void 0===e?{}:e,r={htmlFor:"for",className:"class"},Object.keys(n).reduce((function(e,t){var o=n[t];return xa("object"!==a(o)||null===o,"expects attributes not to be an object, '".concat(t,"' was")),void 0!==o&&(e[r[t]||t]=null!==o?String(o):null),e}),{})),t}var Tm,Sm={"#cdata-section":2,"#text":3,"#comment":8,"#document":9,"#document-fragment":11},_m={},Om=(Object.keys(Sm).forEach((function(e){_m[Sm[e]]=e})),Ri),Mm=function(e,t){if(e=e||function(){},t=t||o.log,!o._audit)throw new Error("No audit configured");var n=o.utils.queue(),a=[],i=(Object.keys(o.plugins).forEach((function(e){n.defer((function(t){function n(e){a.push(e),t()}try{o.plugins[e].cleanup(t,n)}catch(e){n(e)}}))})),o.utils.getFlattenedTree(r.body));o.utils.querySelectorAll(i,"iframe, fram\ +e").forEach((function(e){n.defer((function(t,n){return o.utils.sendCommandToFrame(e.actualNode,{command:"cleanup-plugin"},t,n)}))})),n.then((function(n){0===a.length?e(n):t(a)})).catch(t)},Pm={};function Im(e){return Pm.hasOwnProperty(e)}function Bm(e){return"string"==typeof e&&Pm[e]?Pm[e]:"function"==typeof e?e:Tm}var jm={},Lm=(ce(jm,{getAllCells:function(){return Lm},getCellPosition:function(){return Es},getHeaders:function(){return zm},getScope:function(){return As},isColumnHeader:function(){return Fs},isDataCell:function(){return Vm},isDataTable:function(){return Gm},isHeader:function(){return $m},isRowHeader:function(){return Cs},toArray:function(){return xs},toGrid:function(){return xs},traverse:function(){return Hm}}),function(e){for(var t,n,r=[],a=0,o=e.rows.length;a.95*uu(t).width||u<10||e.querySelector("object, embed, iframe, applet"))},$m=function(e){return!(!Fs(e)&&!Cs(e))||!!e.getAttribute("id")&&(e=Aa(e.getAttribute("id")),!!r.querySelector('[headers~="'.concat(e,'"]')))},Hm=function(e,t,n,r){if(Array.isArray(t)&&(r=n,n=t,t={x:0,y:0}),"string"==typeof e)switch(e){case"left":e={x:-1,y:0};break;case"up":e={x:0,y:-1};break;case"right":e={x:1,y:0};break;case"down":e={x:0,y:1}}return function e(t,n,r,a){var o,i=r[n.y]?r[n.y][n.x]:void 0;return i?"function"==typeof a&&!0===(o=a(i,n,r))?[i]:((o=e(t,{x:n.x+t.x,y:n.y+t.y},r,a)).unshift(i),o):[]}(e,{x:t.x+e.x,y:t.y+e.y},n,r)},Um={},Wm=(ce(Um,{allowedAttr:function(){return Wm},arialabelText:function(){return ds},arialabelledbyText:function(){return cs},getAccessibleRefs:function(){return Km},getEleme\ +ntUnallowedRoles:function(){return Qm},getExplicitRole:function(){return ys},getImplicitRole:function(){return Ws},getOwnedVirtual:function(){return ec},getRole:function(){return Xs},getRoleType:function(){return ed},getRolesByType:function(){return th},getRolesWithNameFromContents:function(){return oh},implicitNodes:function(){return lh},implicitRole:function(){return Ws},isAccessibleRef:function(){return uh},isAriaRoleAllowedOnElement:function(){return Xm},isComboboxPopup:function(){return sh},isUnsupportedRole:function(){return vs},isValidRole:function(){return bs},label:function(){return dh},labelVirtual:function(){return Oc},lookupTable:function(){return ih},namedFromContents:function(){return Qs},requiredAttr:function(){return ph},requiredContext:function(){return fh},requiredOwned:function(){return mh},validateAttr:function(){return gh},validateAttrValue:function(){return hh}}),function(e){e=gs.ariaRoles[e];var t=M(ws());return e&&(e.allowedAttrs&&t.push.apply(t,M(e.allowedAttrs\ +)),e.requiredAttrs)&&t.push.apply(t,M(e.requiredAttrs)),t}),Ym=/^idrefs?$/,Km=function(e){e=e.actualNode||e;var t=(t=Pl(e)).documentElement||t,n=Sl.get("idRefsByRoot",(function(){return new Map})),r=n.get(t);return r||(r=new Map,n.set(t,r),function e(t,n,r){if(t.hasAttribute){var a;"LABEL"===t.nodeName.toUpperCase()&&t.hasAttribute("for")&&(a=t.getAttribute("for"),n.has(a)?n.get(a).push(t):n.set(a,[t]));for(var o=0;o option, datalist > option, optgroup > option")},SELECT:function(e){var t=e.node;return!t.multiple&&t.size<=1&&"menu"===e.role},SVG:function(e){var t=e.node;return!(!t.parentNode||"http://www.w3.org/2000/svg"!==t.parentNode.namespaceURI)||e.out}},Ti.rolesOfType={widget:["button","checkbox","dialog","gridcell","link","log","marquee","men\ +uitem","menuitemcheckbox","menuitemradio","option","progressbar","radio","scrollbar","searchbox","slider","spinbutton","status","switch","tab","tabpanel","textbox","timer","tooltip","tree","treeitem"]},Ti),lh=function(e){var t=null;return(e=ih.role[e])&&e.implicit?Bd(e.implicit):t},uh=function(e){return!!Km(e).length};function sh(e){var t=(1{for(;e=e.parent;)if(null!==Xs(e,{noPresentational:!0}))return e;return null})(e),ch(t))return!0;if(!(n=e.props.id))return!1;if(e.actualNode)return t=Ml(e.actualNode).querySelectorAll('[aria-owns~="'.concat(n,'"][role~="combobox"]:not(select),\\n [aria-controls~="').concat(n,'"][role~="combobox"]:not(select)')),Array.from(t).some(ch);throw new Error("Unable to determine combobox popup without an actualNode")}var ch=function(e){return e&&"combobox"===Xs(e)},dh=function(e){return e=_l(e),Oc(e)},ph=f\ +unction(e){return(e=gs.ariaRoles[e])&&Array.isArray(e.requiredAttrs)?M(e.requiredAttrs):[]},fh=function(e){return(e=gs.ariaRoles[e])&&Array.isArray(e.requiredContext)?M(e.requiredContext):null},mh=function(e){return(e=gs.ariaRoles[e])&&Array.isArray(e.requiredOwned)?M(e.requiredOwned):null},hh=function(e,t){var n,r=(e=e instanceof ua?e:_l(e)).attr(t),a=gs.ariaAttrs[t];if(!a)return!0;if(a.allowEmpty&&(!r||""===r.trim()))return!0;switch(a.type){case"boolean":return["true","false"].includes(r.toLowerCase());case"nmtoken":return"string"==typeof r&&a.values.includes(r.toLowerCase());case"nmtokens":return(n=Yp(r)).reduce((function(e,t){return e&&a.values.includes(t)}),0!==n.length);case"idref":try{var o=Pl(e.actualNode);return!(!r||!o.getElementById(r))}catch(e){throw new TypeError("Cannot resolve id references for partial DOM")}case"idrefs":return us(e,t).some((function(e){return!!e}));case"string":return""!==r.trim();case"decimal":return!(!(n=r.match(/^[-+]?([0-9]*)\\.?([0-9]*)$/))||!n[1]&&\ +!n[2]);case"int":return o=void 0!==a.minValue?a.minValue:-1/0,/^[-+]?[0-9]+$/.test(r)&&parseInt(r)>=o}},gh=function(e){return!!gs.ariaAttrs[e]};var vh=["cell-header-not-in-table","cell-header-not-th","header-refs-self","empty-hdrs"],bh=vh[0],yh=vh[1],Dh=vh[2],wh=vh[3];function xh(e){return"caption"===e.props.nodeName}var Eh={};ce(Eh,{getAriaRolesByType:function(){return eh},getAriaRolesSupportingNameFromContent:function(){return nh},getElementSpec:function(){return Us},getElementsByContentType:function(){return Ds},getGlobalAriaAttrs:function(){return ws},implicitHtmlRoles:function(){return Ss}}),Ni=du;var Ah=["alert","log","status"];function Fh(e){return e=t.getComputedStyle((e=>{for(var t=e,n=e.textContent.trim(),r=n;r===n&&void 0!==t;){var a=-1;if(0===(e=t).children.length)return e;for(;a++,""===(r=e.children[a].textContent.trim())&&a+1{switch(e){case"lighter":return 100;case"normal":return 400;case"bold":return 700\ +;case"bolder":return 900}return e=parseInt(e),isNaN(e)?400:e})(e.getPropertyValue("font-weight")),fontSize:parseInt(e.getPropertyValue("font-size")),isItalic:"italic"===e.getPropertyValue("font-style")}}function Ch(e,t,n){return n.reduce((function(n,r){return n||(!r.size||e.fontSize/r.size>t.fontSize)&&(!r.weight||e.fontWeight-r.weight>t.fontWeight)&&(!r.italic||e.isItalic&&!t.isItalic)}),!1)}var kh=/[;,\\s]/,Rh=/^[0-9.]+$/;ce(Cn={},{aria:function(){return Um},color:function(){return Nh},dom:function(){return Ol},forms:function(){return ig},matches:function(){return Hs},math:function(){return hu},standards:function(){return Eh},table:function(){return jm},text:function(){return ls},utils:function(){return sa}});var Nh={},Th=(ce(Nh,{Color:function(){return md},centerPointOfRect:function(){return Th},elementHasImage:function(){return sd},elementIsDistinct:function(){return _h},filteredRectStack:function(){return Mh},flattenColors:function(){return Bh},flattenShadowColors:function(){return\ + Lh},getBackgroundColor:function(){return eg},getBackgroundStack:function(){return qh},getContrast:function(){return rg},getForegroundColor:function(){return ag},getOwnBackgroundColor:function(){return gd},getRectStack:function(){return Oh},getStackingContext:function(){return Kh},getStrokeColorsFromShadows:function(){return Hh},getTextShadowColors:function(){return Yh},hasValidContrastRatio:function(){return og},incompleteData:function(){return ud},parseTextShadows:function(){return Wh},stackingContextToColor:function(){return Xh}}),function(e){if(!(e.left>t.innerWidth||t.innerHeight{var r;return Ph.includes(n)?Ih[n](e,t):(r=new md,["r","g","b"].forEach((function(a){r[a]=Ih[n](e[a],t[a])})),r)})(t,e,2{var n=e.indexOf(r.body),a=gd(t.getComputedStyle(r.documentElement));return 1{if(e!==t){if(null===e||null===t)return;if(e.length!==t.length)return;for(var n=0;n{var t,n={},r=K(e);try{for(r.s();!(t=r.n()).done;){var a=t.value,o=a.colorStr,i=a.pixels,l=(null!=n[o]||(n[o]={top:[],right:[],bottom:[],left:[]}),n[o]),u=V(i,2),s=u[0],c=u[1];Vh{var t=e.colorStr,n=e.offsetY,r=e.blurRadius,a=e.fontSize;return e.offsetX>r||r0===e?1:.185/(e/t+.4))(r,a),e)})({colorStr:f,offsetX:h,offsetY:g,blurRadius:b,fontSiz\ +e:s});i.push(D)}}}catch(e){d.e(e)}finally{d.f()}if(0{var o=qh(e);if(!o)return null;var i=Lc(e);(a=null!=(a=Yh(e,{minRatio:a,ignoreEdgeCount:!0}))?a:[]).length&&(a=[{color:a.reduce(Lh)}]);for(var l=0;l{var a,o,i,l,u=[];return n||(n=r.documentElement,l=r.body,n=t.getComputedStyle(n),a=t.getComputedStyle(l),o=gd(n),l=0!==(i=gd(a)).alpha&&tg(l,e.getBoundingClientRect()),(0!==i.alpha&&0===o.alpha||l&&1!==i.alpha)&&u.unshift({color:i,blendMode:ng(a.getPropertyValue("mix-blend-mode"))}),0===o.alpha)||l&&1===i.alpha||u.unshift({color:o,blendMode:ng(n.getPropertyValue("mix-blend-mode"))}),u})(e,o.includes(r.body)));return a.unshift.apply(a,M(d)),0===a.length?new md(255,255,255,1):(e=a.reduce((function(e,t){return Bh(t.color,e.color instanceof md?e.color:e,t.blendMode)})),Bh(e.color instanceof md?e.color:e,new md(255,255,255,1)))})(e,n,a),o._cache.getBackgroundColor={bgColor:i,bgElms:n,incompleteData:ud.get("bgColor")},i)}function tg(e,n){n=Array.isArray(n)?n:[n];var r=e.getBoundingClientRect(),a=r.right,o=r.bottom,i=t.getComputedStyle(e).getPropertyValue("overflow");return(["scroll","auto"].includes(i)\ +||e instanceof t.HTMLHtmlElement)&&(a=r.left+e.scrollWidth,o=r.top+e.scrollHeight),n.every((function(e){return e.top>=r.top&&e.bottom<=o&&e.left>=r.left&&e.right<=a}))}function ng(e){return e||void 0}var rg=function(e,t){return t&&e?(t.alpha<1&&(t=Bh(t,e)),e=e.getRelativeLuminance(),t=t.getRelativeLuminance(),(Math.max(t,e)+.05)/(Math.min(t,e)+.05)):null};function ag(e,n,r){for(var a=3{for(;t;){var r;1===t.opacity&&t.ancestor||(e.alpha*=t.opacity,r=(null==(r=t.ancestor)?void 0:r.descendants)||n,(r=(r=1!==t.opacity?r.slice(0,r.indexOf(t)):r).map(Xh)).length&&(r=r.reduce((function(e,t){return Bh(t.color,e.color instanceof md?e.color:e)}),{color:new md(0,0,0,0),blendMode:"normal"}),e=Bh(e,r))),t=t.ancestor}return e})(c,function e(t,n){var r,a=K(t);try{for(a.s();!(r=a.n()).done;){var o,i=r.value;if((null==(o=i.vNode)?void 0:o.actualNode)===n)return i;var l=e(i.descendants,n);if(l)return l}}catch(e){a.e(e)}finally{a.f()}}(r=Kh(e),e),r),new md(255,255,255,1))}var og=function(e,t,n,r){return e=rg(e,t),{isValid:(t=r&&Math.ceil(72*n)/96<14||!r&&Math.ceil(72*n)/96<18?4.5:3){for(;t.length;){var n=cg(e,t);if(-1!==n)return n;t=dg(t,1)}return-1})(e,r))?e.push.apply(e,M(t)):e.splice.apply(e,[n,0].concat(M(t)))),e}function cg(e,t){return e.findIndex((function(e){return Gf(e.ancestry,t)}))}function dg(e,t){return e.slice(0,e.length-t)}function pg(e,t){return e=e.boundingClientRect,t=t.boundingClientRect,e.top>=t.top&&e.left>=t.left&&e.bottom<=t.\ +bottom&&e.right<=t.right}function fg(e){return{width:Math.round(10*e.width)/10,height:Math.round(10*e.height)/10}}function mg(e,t){return Vp(e,t)&&!as(t)}function hg(e){return e.map((function(e){return e.actualNode}))}function gg(e,t){var n=1{if(e.parent)return Wd(e,'table:not([role]), [role~="treegrid"], [role~="table"], [role~="grid"]')})(a))&&Xs(t))||"treegrid"===t||(n="row".concat(1e?(e=e.toLowerCase(),["mixed","true"].includes(e)?e:"false"):"")(n.attr("aria-checked"));return"input"!==r||"checkbox"!==a||!o||o===(r=(e=>e.pro\ +ps.indeterminate?"mixed":e.props.checked?"true":"false")(n))||(this.data({messageKey:"checkbox",checkState:r}),!1)}var Mg={row:_g,checkbox:Og};var Pg=function(e,t){try{return"svg"===t.props.nodeName||!!Wd(t,"svg")}catch(e){return!1}},Ig=[function(e,t){return Bg(t)},function(e,t){return"area"!==t.props.nodeName},function(e,t){return!Pg(0,t)},function(e,t){return rs(t)},function(e,t){return as(t)||!jg(t)},function(e){return!rd(e,{noLengthCompare:!0})}];function Bg(e){return"widget"===ed(e)}var jg=cl((function e(t){return!(null==t||!t.parent)&&(!(!Bg(t.parent)||!as(t.parent))||e(t.parent))})),Lg=function(e,t){var n=ys(t);return!(n&&!["none","presentation"].includes(n)&&!(fs[n]||{}).accessibleNameRequired&&!rs(t))},qg=function(e,t,n){return n.initiator},zg={emoji:!0,nonBmp:!1,punctuations:!0},Vg={"abstractrole-evaluate":function(e,t,n){return 0<(n=Yp(n.attr("role")).filter((function(e){return"abstract"===ed(e)}))).length&&(this.data(n),!0)},"accesskeys-after":function(e){var t={};return e.\ +filter((function(e){if(e.data){var n=e.data.toUpperCase();if(!t[n])return(t[n]=e).relatedNodes=[],!0;t[n].relatedNodes.push(e.relatedNodes[0])}return!1})).map((function(e){return e.result=!!e.relatedNodes.length,e}))},"accesskeys-evaluate":function(e,t,n){return nu(n)||(this.data(n.attr("accesskey")),this.relatedNodes([e])),!0},"alt-space-value-evaluate":function(e,t,n){return"string"==typeof(n=n.attr("alt"))&&/^\\s+$/.test(n)},"aria-allowed-attr-evaluate":function(e,t,n){var r,a=[],o=Xs(n),i=Wm(o),l=(Array.isArray(t[o])&&(i=tm(t[o].concat(i))),K(n.attrNames));try{for(l.s();!(r=l.n()).done;){var u=r.value;!gh(u)||i.includes(u)||((e,t,n)=>"aria-required"===e&&"false"===t||!("aria-multiline"!==e||"false"!==t||!n.hasAttr("contenteditable")))(u,n.attr(u),n)||a.push(u)}}catch(e){l.e(e)}finally{l.f()}return!a.length||(this.data(a.map((function(e){return e+'="'+n.attr(e)+'"'}))),!(o||qf(n)||rs(n))&&void 0)},"aria-allowed-attr-matches":function(e,t){var n=/^aria-/,r=t.attrNames;if(r.length)for(\ +var a=0,o=r.length;a{var a=gs.ariaRoles[t];return a?a.prohibitedAttrs||[]:t||r.includes(n)||"widget"===Sg(e)?[]:["aria-label","aria-labelledby"]})(n,o,a,r).filter((function(e){return!!n.attrNames.includes(e)&&""!==Ns(n.attr(e))}))).length&&(t=null!==o?"hasRole":"noRole",this.data({role:o,nodeName:a,messageKey:t+=1{function n(){if(3===r.props.nodeType&&a.push({vNode:r,role:null}),1!==r.props.nodeType||!nc(r))return 1;var e,n=Xs(r,{noPresentational:!0}),i=(e=r,ws().find((function(t){return e.hasAttr(t)}))),l=!!i||rs(r);!n&&!l||["group","rowgroup"].includes(n)&&t.some((function(e){return e===n}))?o.push.apply(o,M(r.children)):(n||l)&&a.push({role:n,attr:i||"tabindex",vNode:r})}for(var r,a=[],o=ec(e);r=o.shift();)n();return a})(n,l)).filter((function(e){var t=e.role;return 1===e.vNode.props.nodeType&&!l.includes(t)}))).length?(this.relatedNodes(a.map((function(e){return e.vNode}))),this.data({messageKey:"unallowed",values:a.map((function(\ +e){var t=e.vNode,n=(e=e.attr,t.props),r=n.nodeName;return 3===n.nodeType?"#text":(n=ys(t,{dpub:!0}))?"[role=".concat(n,"]"):e?r+"[".concat(e,"]"):r})).filter((function(e,t,n){return n.indexOf(e)===t})).join(", ")}),!1):(o=l,!!r.some((function(e){return(e=e.role)&&o.includes(e)}))||("true"===n.attr("aria-busy")?(this.data({messageKey:"aria-busy"}),!0):(this.data(l),!(!t.includes(i)||r.some(Tg))&&void 0))))},"aria-required-children-matches":function(e,t){return t=ys(t,{dpub:!0}),!!mh(t)},"aria-required-parent-evaluate":function(e,t,n){var r=t&&Array.isArray(t.ownGroupRoles)?t.ownGroupRoles:[],a=Ng(n,r);if(!a)return!0;var o=(e=>{for(var t,n=[];e;)e.getAttribute("id")&&(t=Aa(e.getAttribute("id")),t=Pl(e).querySelector("[aria-owns~=".concat(t,"]")))&&n.push(t),e=e.parentElement;return n.length?n:null})(e);if(o)for(var i=0,l=o.length;i=l||"bold"===a,a=Math.ceil(72*h)/96,a=(u=l&&a{var n=void 0===(n=t.pseudoSizeThreshold)?.25:n;if(!(\ +t=void 0!==(t=t.ignorePseudo)&&t)){var r=(t=e.boundingClientRect).width*t.height*n;do{if(r{var t=e.selectorText;e=e.style;return!(!t||e.length<=0||!(t=e.transform||e.webkitTransform||e.msTransform||!1)&&!e.rotate||(t=(e=>e&&(e=e.match(/(rotate|rotateZ|rotate3d|matrix|matrix3d)\\(([^)]+)\\)(?!.*(rotate|rotateZ|rotate3d|matrix|matrix3d))/))?p((e=V(e,3))[1],e[2]):0)(t),e=p("rotate",e.rotate),!(t+=e))||(t=Math.abs(t),Math.abs(t-180)%180<=a))&&Math.abs(t-90)%90<=a})(e);n&&"HTML"!==e.selectorText.toUpperCase()&&(e=Array.from(t.querySelectorAll(e.selectorText))||[],i=i.concat(e)),o=o||n}))}))},s=0,c=Object.keys(l);s "),t[n]=e,!0):(n=e.node.ancestry.slice(0,e.node.ancestry.length-1).flat(1/0).join(" > "),t[n]&&(t[n].result=!0),!1)}))},"frame-tested-evaluate":function(e,t){return!t.isViolation&&void 0},"frame-title-has-text-matches":function(e){return e=e.getAttribute("title"),!!Ns(e)},"has-alt-evaluate":function(e,t,n){var r=n.props.nodeName;return!!["img","input","area"].includes(r)&&n.hasAttr("alt")},"has-descendant-after":function(e){return e.some((function(e){return!0===e.result}))&&e.forEach((function(e){e.result=!0})),e},"has-descendant-evaluate":\ +function(e,t,n){if(t&&t.selector&&"string"==typeof t.selector)return!(!t.passForModal||!ad())||(n=rm(n,t.selector,nc),this.relatedNodes(n.map((function(e){return e.actualNode}))),0{var n=null!=(n=null==(n=t[e=cg(t,e.node.ancestry)])?void 0:n.level)?n:-1;t=null!=(t=null==(t=t[e-1])?void 0:t.level)?t:-1;return 0===e||(-1!==n?n-t<=1:void 0)})(e,n)})),e},"heading-order-evaluate":function(){var e,t=Sl.get("headingOrder");return t||(t=(e=rm(o._tree[0],"h1, h2, h3, h4, h5, h6, [role=heading], iframe, frame",nc)).map((function(e){return{ancestry:[Rl(e.actualNode)],level:(t=(t=Xs(e))&&t.includes("heading"),n=e.attr("aria-level"),r=parseInt(n,10),e=V(e.props.nodeName.match(/h(\\d)/)||[],2)[1],t?e&&!n?parseInt(e,10):isNaN(r)||r<1?e?parseInt(e,10):2:r||-1:-1)};var t,n,r})),this.data({headingOrder:t}),Sl.set("headingOrder",e)),!0},"help-same-as-label-evaluate":function(e,t,n){n=P\ +c(n);var r=e.getAttribute("title");return!!n&&(r||(r="",e.getAttribute("aria-describedby")&&(r=us(e,"aria-describedby").map((function(e){return e?ss(e):""})).join(""))),Ns(r)===Ns(n))},"hidden-content-evaluate":function(e,n,r){if(!["SCRIPT","HEAD","TITLE","NOSCRIPT","STYLE","TEMPLATE"].includes(e.nodeName.toUpperCase())&&Uc(r)){if("none"===(r=t.getComputedStyle(e)).getPropertyValue("display"))return;if("hidden"===r.getPropertyValue("visibility")&&(!(e=(r=ou(e))&&t.getComputedStyle(r))||"hidden"!==e.getPropertyValue("visibility")))return}return!0},"hidden-explicit-label-evaluate":function(e,t,n){if(n.hasAttr("id")){if(!n.actualNode)return;var r,a=Pl(e);e=Aa(e.getAttribute("id"));if((a=a.querySelector('label[for="'.concat(e,'"]')))&&!nc(a)){try{r=kc(n).trim()}catch(e){return}return""===r}}return!1},"html-namespace-matches":function(e,t){return!Pg(0,t)},"html5-scope-evaluate":function(e){return!Qc(r)||"TH"===e.nodeName.toUpperCase()},"identical-links-same-purpose-after":function(e){if(e.l\ +ength<2)return e;for(var t=e.filter((function(e){return void 0!==e.result})),n=[],r={},o=function(e){var o=t[e],i=(u=o.data).name,l=u.urlProps;if(r[i])return 1;var u=t.filter((function(t,n){return t.data.name===i&&n!==e})),s=u.every((function(e){return function e(t,n){var r,o;return!(!t||!n)&&(r=Object.getOwnPropertyNames(t),o=Object.getOwnPropertyNames(n),r.length===o.length)&&r.every((function(r){var o=t[r];r=n[r];return a(o)===a(r)&&("object"===a(o)||"object"===a(r)?e(o,r):o===r)}))}(e.data.urlProps,l)}));u.length&&!s&&(o.result=void 0),o.relatedNodes=[],(s=o.relatedNodes).push.apply(s,M(u.map((function(e){return e.relatedNodes[0]})))),r[i]=u,n.push(o)},i=0;i{var r=n.cssProperty,a=n.absoluteValues;n=n.normalValue;return"normal"===(r=(e=t.getComputedStyle(e)).getPropertyValue(r))||(n=parseFloat(r),a)?n:(a=parseFloat(e.getPropertyValue("font-size")),e=Math.round(n/a*100)/100,isNaN(e)?r:e)})(e,{absoluteValues:a,cssProperty:\ +r,normalValue:l}),this.data(O({value:u},n)),"number"==typeof u?("number"!=typeof o||o<=u)&&("number"!=typeof i||u<=i):void 0))},"inserted-into-focus-order-matches":function(e){return Kc(e)},"internal-link-present-evaluate":function(e,t,n){return fm(n,"a[href]").some((function(e){return/^#[^/!]/.test(e.attr("href"))}))},"invalid-children-evaluate":function(e){var t=1{var r=void 0===(r=n.validRoles)?[]:r,a=(n=void 0===(n=n.validNodeNames)?[]:n,(i=e.props).nodeName),o=i.nodeType,i=i.nodeValue;t=t?"div > ":"";return 3===o&&""!==i.trim()?t+"#text":!(1!==o||!nc(e))&&((i=ys(e))?!r.includes(i)&&t+"[role=".concat(i,"]"):!n.includes(a)&&t+a)})(i,l,t),u&&(a.\ +includes(u)||a.push(u),1===(null==i||null==(l=i.actualNode)?void 0:l.nodeType))&&r.push(i.actualNode)}return 0!==a.length&&(this.data({values:a.join(", ")}),this.relatedNodes(r),!0)}},"invalidrole-evaluate":function(e,t,n){return!!(n=Yp(n.attr("role"))).every((function(e){return!bs(e.toLowerCase(),{allowAbstract:!0})}))&&(this.data(n),!0)},"is-element-focusable-evaluate":function(e,t,n){return rs(n)},"is-initiator-matches":qg,"is-on-screen-evaluate":Ni,"is-visible-matches":du,"is-visible-on-screen-matches":function(e,t){return du(t)},"label-content-name-mismatch-evaluate":function(e,t,n){var r=null==t?void 0:t.pixelThreshold,a=null!=(a=null==t?void 0:t.occurrenceThreshold)?a:null==t?void 0:t.occuranceThreshold;return t=ss(e).toLowerCase(),!(e=Ns(bc(n,{subtreeDescendant:!0,ignoreIconLigature:!0,pixelThreshold:r,occurrenceThreshold:a})).toLowerCase())||(Tc(t)<1||Tc(e)<1?void 0:(n=e,r=bg(r=t),n=bg(n),!(!r||!n)&&r.includes(n)))},"label-content-name-mismatch-matches":function(e,t){var n=Xs(\ +e);return!!(n&&eh("widget").includes(n)&&nh().includes(n)&&(Ns(ds(t))||Ns(cs(e)))&&Ns(ac(t)))},"label-matches":function(e,t){return"input"!==t.props.nodeName||!1===t.hasAttr("type")||(t=t.attr("type").toLowerCase(),!1===["hidden","image","button","submit","reset"].includes(t))},"landmark-has-body-context-matches":function(e,t){return e.hasAttribute("role")||!Bl(t,"article, aside, main, nav, section")},"landmark-is-top-level-evaluate":function(e){var t=eh("landmark"),n=ou(e),r=Xs(e);for(this.data({role:r});n;){var a=ys(n);if((a=a||"FORM"===n.nodeName.toUpperCase()?a:Ws(n))&&t.includes(a)&&("main"!==a||"complementary"!==r))return!1;n=ou(n)}return!0},"landmark-is-unique-after":function(e){var t=[];return e.filter((function(e){var n=t.find((function(t){return e.data.role===t.data.role&&e.data.accessibleText===t.data.accessibleText}));return n?(n.result=!1,n.relatedNodes.push(e.relatedNodes[0]),!1):(t.push(e),e.relatedNodes=[],!0)}))},"landmark-is-unique-evaluate":function(e,t,n){var r=Xs(e\ +);return n=(n=kc(n))?n.toLowerCase():null,this.data({role:r,accessibleText:n}),this.relatedNodes([e]),!0},"landmark-unique-matches":function(e,t){return n=t,a=eh("landmark"),!!(o=Xs(n))&&("section"!==(r=n.props.nodeName)&&"form"!==r?0<=a.indexOf(o)||"region"===o:!!kc(n))&&nc(t);var n,r,a,o},"layout-table-matches":function(e){return!Gm(e)&&!rs(e)},"link-in-text-block-evaluate":function(e,t){var n=t.requiredContrastRatio;if(t=t.allowSameColor,Ag(e))return!1;for(var r=ou(e);r&&1===r.nodeType&&!Ag(r);)r=ou(r);if(r){this.relatedNodes([r]);var a=ag(e),o=ag(r),i=(e=eg(e),eg(r)),l=a&&o?xg(a,o):void 0;if((l=l&&Math.floor(100*l)/100)&&n<=l)return!0;var u=e&&i?xg(e,i):void 0;if((u=u&&Math.floor(100*u)/100)&&n<=u)return!0;if(u){if(l)return!(!t||1!==l||1!==u)||(1===l&&1{for(var n=0,r=["before","after"];nt.maxDelay},"meta-viewport-scale-evaluate":function(e,t,n){var r,a=void 0===(a=(t=t||{}).scaleMinimum)?2:a;return t=void 0!==(t=t.lowerBound)&&t,!((n=n.attr("content")||"")&&(n=n.split(/[;,]/).reduce((function(e,t){var n;return(t=t.trim())&&(n=(t=V(t.split("="),2))[0],t=t[1],n)&&t&&(n=n.toLowerCase().trim(),t=t.toLowerCase().trim(),"maximum-scale"===n&&"yes"===t&&(t=1),"maximum-scale"===n&&parseFloat(t)<0||(e[n]=t)),e}),{}),!(t&&n["maximum-scale"]&&parseFloat(n["maximum-scale"]){if(e=e.match(/#t=(.*)/))return V(e,2)[1].split(",").map((function(e){if(/:/.test(e)){for(var t=e.split(":"),n=0,r=1;0{var n,r=[],a=[],o=K(t);try{for(o.s();!(n=o.n()).done;){var i=n.value;!mg(e,i)&&xu(e,i)&&"none"!==i.getComputedStylePropertyValue("pointer-events")&&(pg(e,i)?r:a).push(i)}}catch(e){o.e(e)}finally{o.f()}return{fullyObscuringElms:r,partialObscuringElms:a}})(n,i)).fullyObscuringElms,i=i.partialObscuringElms,!r.length||!o.length&&l(s)?o.length?(this.relatedNodes(hg(o)),this.data({messageKey:"obscured"}),!0):(o=!as(n)&&void 0,l(s)?(i=i.filter((function(e){return"widget"===ed(e)&&rs(e)}))).length?(n=((e,t)=>{var n;e=e.boundingClientRect,t=t.map((function(e){return e.boundingClientRect}));try{n=Eu(e,t)}catch(e){return null}var r=void 0;return n.reduce((function(e,t){var n=yu(r,e);return n!==yu(r,t)?n?e:t:(n=e\ +.width*e.height,t.width*t.height{var t;return e?(t=Bd(e)).commons=e.commons:t={},t.reporter=t.reporter||null,t.noHtml=t.noHtml||!1,t.allowedOrigins||(e=Qg(),t.allowedOrigins=e?[e]:[]),t.rules=t.rules||[],t.checks=t.checks||[],t.data=O({checks:{},rules:{}},t.data),t})(this.defaultConfig);this.lang=e.lang||"en",this.reporter=e.reporter,this.commands={},this.rules=[],this.checks={},this.brand="axe",this.application="axeAPI",this.tagExclude=["experimental","deprecated"],this.noHtml=e.noHtml,this.allowedOrigins=e.allowedOrigin\ +s,ev(e.rules,this,"addRule"),ev(e.checks,this,"addCheck"),this.data={},this.data.checks=e.data&&e.data.checks||{},this.data.rules=e.data&&e.data.rules||{},this.data.failureSummaries=e.data&&e.data.failureSummaries||{},this.data.incompleteFallbackMessage=e.data&&e.data.incompleteFallbackMessage||"",this._constructHelpUrls()}},{key:"registerCommand",value:function(e){this.commands[e.id]=e.callback}},{key:"addRule",value:function(e){e.metadata&&(this.data.rules[e.id]=e.metadata);var t=this.getRule(e.id);t?t.configure(e):this.rules.push(new Kg(e,this))}},{key:"addCheck",value:function(e){var t=e.metadata;"object"===a(t)&&(this.data.checks[e.id]=t,"object"===a(t.messages))&&Object.keys(t.messages).filter((function(e){return t.messages.hasOwnProperty(e)&&"string"==typeof t.messages[e]})).forEach((function(e){0===t.messages[e].indexOf("function")&&(t.messages[e]=new Function("return "+t.messages[e]+";")())})),this.checks[e.id]?this.checks[e.id].configure(e):this.checks[e.id]=new Wg(e)}},{key:\ +"run",value:function(e,t,n,r){this.normalizeOptions(t),Pd.setRunOptions(t),o._selectCache=[],l=this.rules,a=e,i=t;var a,i,l=l.reduce((function(e,t){return hm(t,a,i)&&(t.preload?e.later:e.now).push(t),e}),{now:[],later:[]}),u=l.now,s=l.later,c=Qd();u.forEach((function(n){c.defer(ov(n,e,t))})),l=Qd();(u=(s.length&&l.defer((function(e){um(t).then((function(t){return e(t)})).catch((function(t){console.warn("Couldn't load preload assets: ",t),e(void 0)}))})),Qd())).defer(c),u.defer(l),u.then((function(a){var i,l=a.pop(),u=(l&&l.length&&(l=l[0])&&(e=O({},e,l)),a[0]);s.length?(i=Qd(),s.forEach((function(n){n=ov(n,e,t),i.defer(n)})),i.then((function(e){o._selectCache=void 0,n(u.concat(e).filter((function(e){return!!e})))})).catch(r)):(o._selectCache=void 0,n(u.filter((function(e){return!!e}))))})).catch(r)}},{key:"after",value:function(e,t){var n=this.rules;return e.map((function(e){if(e.error)return e;var r=jp(n,"id",e.id);if(!r)throw new Error("Result for unknown rule. You may be running mis\ +match axe-core versions");try{return r.after(e,t)}catch(e){if(t.debug)throw e;return iv(r,e)}}))}},{key:"getRule",value:function(e){return this.rules.find((function(t){return t.id===e}))}},{key:"normalizeOptions",value:function(e){var t=[],n=[];if(this.rules.forEach((function(e){n.push(e.id),e.tags.forEach((function(e){t.includes(e)||t.push(e)}))})),["object","string"].includes(a(e.runOnly))){if("string"==typeof e.runOnly&&(e.runOnly=[e.runOnly]),Array.isArray(e.runOnly)){var r=e.runOnly.find((function(e){return t.includes(e)})),i=e.runOnly.find((function(e){return n.includes(e)}));if(r&&i)throw new Error("runOnly cannot be both rules and tags");e.runOnly=i?{type:"rule",values:e.runOnly}:{type:"tag",values:e.runOnly}}if((r=e.runOnly).value&&!r.values&&(r.values=r.value,delete r.value),!Array.isArray(r.values)||0===r.values.length)throw new Error("runOnly.values must be a non-empty array");if(["rule","rules"].includes(r.type))r.type="rule",r.values.forEach((function(e){if(!n.includes(e)\ +)throw new Error("unknown rule \`"+e+"\` in options.runOnly")}));else{if(!["tag","tags",void 0].includes(r.type))throw new Error("Unknown runOnly type '".concat(r.type,"'"));r.type="tag",i=r.values.filter((function(e){return!t.includes(e)&&!/wcag2[1-3]a{1,3}/.test(e)})),0!==i.length&&o.log("Could not find tags \`"+i.join("\`, \`")+"\`")}}return"object"===a(e.rules)&&Object.keys(e.rules).forEach((function(e){if(!n.includes(e))throw new Error("unknown rule \`"+e+"\` in options.rules")})),e}},{key:"setBranding",value:function(e){var t={brand:this.brand,application:this.application};"string"==typeof e&&(this.application=e),e&&e.hasOwnProperty("brand")&&e.brand&&"string"==typeof e.brand&&(this.brand=e.brand),e&&e.hasOwnProperty("application")&&e.application&&"string"==typeof e.application&&(this.application=e.application),this._constructHelpUrls(t)}},{key:"_constructHelpUrls",value:function(){var e=this,t=0{var t,n,r;return"function"==typeof Promise&&e===fv?t=new Promise((function(e,t){n=t,r=e})):(r=function(t){return e(null,t)},n=function(t){return e(t)}),{thenable:t,reject:n,resolve:r}})(i)).thenable,u=c.resolve,s=c.reject;try{xa(o._audit,"No audit configured"),xa(!o._running,"Axe is already running. Use \`await axe.run()\` to wait for the previous run to finish before starting a new run.")}catch(e){var c=e;if("function"!=typeof i||i===fv)throw c;return void i(c.message)}return o._running=!0,a.performanceTimer&&Qf.start(),o._runRules(r,a,(function(e,t){function n(e){o._running=!1,t();try{s(e)}catch(e){o.log(e)}}try{a.performanceTimer&&Qf.mark("reporterStart");var r=e,i=a,l=function(e){a.performanceTimer&&(Qf.mark("reporterEnd"),Qf.measure("reporter","reporterStart","reporterEnd"),Qf.logMeasures("reporter"),Qf.end()),o._running=!1,t();try{u(e)}catch(e){o.log(e)}},c=n;void 0!==(r=Bm(i.reporter)(r,i,l,c))&&l(r)}catch(e){n(e)}}\ +),(function(e){a.performanceTimer&&Qf.end(),o._running=!1,i(e),s(e)})),l},o.setup=function(e){if(o._tree)throw new Error("Axe is already setup. Call \`axe.teardown()\` before calling \`axe.setup\` again.");return uv(e=e&&"object"===a(e.documentElement)&&"object"===a(e.defaultView)?e.documentElement:e),o._tree=tf(e),o._selectorData=wl(o._tree),o._tree[0]},o.teardown=sv,o.runPartial=function(){for(var e=arguments.length,t=new Array(e),n=0;n{var t=e.frames,n=e.frameSpec;return n?t.map((function(e){return Ip.mergeSpecs(e,n)})):t})(u),a.unshift.apply(a,M(l)))}}catch(e){i.e(e)}finally{i.f()}var c,d,p=qp(e);return(p=o._audit.after(p,n)).forEach(dm),p=p.map(va),c=p,d=O({environmentData:r},n),new Promise((function(e,t){Bm(d.reporter)(c,d,e,t)}))},o.commons=Cn,o.utils=sa,o.addReporter("na",(function(e,t,n){console.warn('"na" reporter will be deprecated in axe v4.0. Use the "v2" reporter instead.'),"function"==typeof t&&(n=t,t={})\ +;var r=t.environmentData,a=k(a=t,D);n(O({},vf(r),{toolOptions:a},cf(e,t)))})),o.addReporter("no-passes",(function(e,t,n){"function"==typeof t&&(n=t,t={});var r=t.environmentData,a=k(a=t,w);t.resultTypes=["violations"],e=cf(e,t).violations,n(O({},vf(r),{toolOptions:a,violations:e}))})),o.addReporter("rawEnv",(function(e,t,n){"function"==typeof t&&(n=t,t={});var r=t.environmentData;t=k(t,x),mv(e,t,(function(e){var t=vf(r);n({raw:e,env:t})}))})),o.addReporter("raw",mv),o.addReporter("v1",(function(e,t,n){function r(e){e.nodes.forEach((function(e){e.failureSummary=lf(e)}))}"function"==typeof t&&(n=t,t={});var a=t.environmentData,o=k(o=t,E);(e=cf(e,t)).incomplete.forEach(r),e.violations.forEach(r),n(O({},vf(a),{toolOptions:o},e))})),o.addReporter("v2",(function(e,t,n){"function"==typeof t&&(n=t,t={});var r=t.environmentData,a=k(a=t,A);e=cf(e,t),n(O({},vf(r),{toolOptions:a},e))}),!0),o._load({lang:"en",data:{rules:{accesskeys:{description:"Ensure every accesskey attribute value is unique",he\ +lp:"accesskey attribute value should be unique"},"area-alt":{description:"Ensure elements of image maps have alternative text",help:"Active elements must have alternative text"},"aria-allowed-attr":{description:"Ensure an element's role supports its ARIA attributes",help:"Elements must only use supported ARIA attributes"},"aria-allowed-role":{description:"Ensure role attribute has an appropriate value for the element",help:"ARIA role should be appropriate for the element"},"aria-braille-equivalent":{description:"Ensure aria-braillelabel and aria-brailleroledescription have a non-braille equivalent",help:"aria-braille attributes must have a non-braille equivalent"},"aria-command-name":{description:"Ensure every ARIA button, link and menuitem has an accessible name",help:"ARIA commands must have an accessible name"},"aria-conditional-attr":{description:"Ensure ARIA attributes are used as described in the specification of the element's role",help:"ARIA attributes must be use\ +d as specified for the element's role"},"aria-deprecated-role":{description:"Ensure elements do not use deprecated roles",help:"Deprecated ARIA roles must not be used"},"aria-dialog-name":{description:"Ensure every ARIA dialog and alertdialog node has an accessible name",help:"ARIA dialog and alertdialog nodes should have an accessible name"},"aria-hidden-body":{description:'Ensure aria-hidden="true" is not present on the document body.',help:'aria-hidden="true" must not be present on the document body'},"aria-hidden-focus":{description:"Ensure aria-hidden elements are not focusable nor contain focusable elements",help:"ARIA hidden element must not be focusable or contain focusable elements"},"aria-input-field-name":{description:"Ensure every ARIA input field has an accessible name",help:"ARIA input fields must have an accessible name"},"aria-meter-name":{description:"Ensure every ARIA meter node has an accessible name",help:"ARIA meter nodes must have an accessible name"},"aria-progre\ +ssbar-name":{description:"Ensure every ARIA progressbar node has an accessible name",help:"ARIA progressbar nodes must have an accessible name"},"aria-prohibited-attr":{description:"Ensure ARIA attributes are not prohibited for an element's role",help:"Elements must only use permitted ARIA attributes"},"aria-required-attr":{description:"Ensure elements with ARIA roles have all required ARIA attributes",help:"Required ARIA attributes must be provided"},"aria-required-children":{description:"Ensure elements with an ARIA role that require child roles contain them",help:"Certain ARIA roles must contain particular children"},"aria-required-parent":{description:"Ensure elements with an ARIA role that require parent roles are contained by them",help:"Certain ARIA roles must be contained by particular parents"},"aria-roledescription":{description:"Ensure aria-roledescription is only used on elements with an implicit or explicit role",help:"aria-roledescription must be on elements with a semant\ +ic role"},"aria-roles":{description:"Ensure all elements with a role attribute use a valid value",help:"ARIA roles used must conform to valid values"},"aria-text":{description:'Ensure role="text" is used on elements with no focusable descendants',help:'"role=text" should have no focusable descendants'},"aria-toggle-field-name":{description:"Ensure every ARIA toggle field has an accessible name",help:"ARIA toggle fields must have an accessible name"},"aria-tooltip-name":{description:"Ensure every ARIA tooltip node has an accessible name",help:"ARIA tooltip nodes must have an accessible name"},"aria-treeitem-name":{description:"Ensure every ARIA treeitem node has an accessible name",help:"ARIA treeitem nodes should have an accessible name"},"aria-valid-attr-value":{description:"Ensure all ARIA attributes have valid values",help:"ARIA attributes must conform to valid values"},"aria-valid-attr":{description:"Ensure attributes that begin with aria- are valid ARIA attributes",help:"ARIA attr\ +ibutes must conform to valid names"},"audio-caption":{description:"Ensure