@paulirish/trace_engine 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/trace.mjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../front_end/models/trace/trace.ts", "../../../../front_end/models/trace/handlers/handlers.ts", "../../../../front_end/models/trace/handlers/Migration.ts", "../../../../front_end/models/trace/handlers/AnimationHandler.ts", "../../../../front_end/core/platform/array-utilities.ts", "../../../../front_end/core/platform/DevToolsPath.ts", "../../../../front_end/core/platform/map-utilities.ts", "../../../../front_end/core/platform/number-utilities.ts", "../../../../front_end/core/platform/string-utilities.ts", "../../../../front_end/core/platform/typescript-utilities.ts", "../../../../front_end/core/platform/platform.ts", "../../../../front_end/models/trace/types/types.ts", "../../../../front_end/models/trace/types/File.ts", "../../../../front_end/models/trace/types/Timing.ts", "../../../../front_end/models/trace/types/TraceEvents.ts", "../../../../front_end/models/trace/handlers/types.ts", "../../../../front_end/models/trace/handlers/GPUHandler.ts", "../../../../front_end/models/trace/handlers/MetaHandler.ts", "../../../../front_end/models/trace/helpers/helpers.ts", "../../../../front_end/models/trace/helpers/SamplesIntegrator.ts", "../../../../front_end/core/root/Runtime.ts", "../../../../front_end/core/common/Base64.ts", "../../../../front_end/core/common/CharacterIdMap.ts", "../../../../front_end/core/common/ColorConverter.ts", "../../../../front_end/core/common/ColorUtils.ts", "../../../../front_end/core/common/Color.ts", "../../../../front_end/core/common/Console.ts", "../../../../front_end/core/common/Object.ts", "../../../../front_end/core/i18n/DevToolsLocale.ts", "../../../../front_end/core/i18n/i18nImpl.ts", "../../../../front_end/third_party/i18n/i18n-impl.ts", "../../../../front_end/third_party/intl-messageformat/package/intl-messageformat.esm.js", "../../../../front_end/third_party/i18n/localized-string-set.ts", "../../../../front_end/core/i18n/time-utilities.ts", "../../../../front_end/core/common/Revealer.ts", "../../../../front_end/core/common/Lazy.ts", "../../../../front_end/core/common/Mutex.ts", "../../../../front_end/core/common/ParsedURL.ts", "../../../../front_end/core/common/Progress.ts", "../../../../front_end/core/common/ResolverBase.ts", "../../../../front_end/core/common/ResourceType.ts", "../../../../front_end/core/common/SegmentedRange.ts", "../../../../front_end/core/common/SettingRegistration.ts", "../../../../front_end/core/common/Settings.ts", "../../../../front_end/core/common/SimpleHistoryManager.ts", "../../../../front_end/core/common/StringOutputStream.ts", "../../../../front_end/core/common/Trie.ts", "../../../../front_end/core/common/Throttler.ts", "../../../../front_end/core/common/WasmDisassembly.ts", "../../../../front_end/core/common/Worker.ts", "../../../../front_end/models/trace/helpers/Timing.ts", "../../../../front_end/models/trace/helpers/Trace.ts", "../../../../front_end/models/trace/handlers/LayoutShiftsHandler.ts", "../../../../front_end/models/trace/handlers/PageLoadMetricsHandler.ts", "../../../../front_end/models/trace/handlers/ScreenshotsHandler.ts", "../../../../front_end/models/trace/handlers/MemoryHandler.ts", "../../../../front_end/models/trace/handlers/NetworkRequestsHandler.ts", "../../../../front_end/models/trace/handlers/UserInteractionsHandler.ts", "../../../../front_end/models/trace/handlers/UserTimingsHandler.ts", "../../../../front_end/models/trace/handlers/WarningsHandler.ts", "../../../../front_end/models/trace/handlers/WorkersHandler.ts", "../../../../front_end/models/trace/handlers/ModelHandlers.ts", "../../../../front_end/models/trace/handlers/LargestImagePaintHandler.ts", "../../../../front_end/models/trace/handlers/LargestTextPaintHandler.ts", "../../../../front_end/models/trace/handlers/RendererHandler.ts", "../../../../front_end/models/trace/handlers/SamplesHandler.ts", "../../../../front_end/models/cpu_profile/CPUProfileDataModel.ts", "../../../../front_end/models/cpu_profile/ProfileTreeModel.ts", "../../../../front_end/models/trace/LegacyTracingModel.ts", "../../../../front_end/models/trace/ModelImpl.ts", "../../../../front_end/models/trace/Processor.ts"],
4
- "sourcesContent": ["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Extras from './extras/extras.js';\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\n// Purposefully use a shorter name here so references to this are\n// Legacy.TracingModel.\nimport * as Legacy from './LegacyTracingModel.js';\nimport * as TraceModel from './ModelImpl.js';\nimport * as Processor from './Processor.js';\nimport * as TracingManager from './TracingManager.js';\nimport * as Types from './types/types.js';\n\nexport {\n Extras,\n Handlers,\n Helpers,\n Legacy,\n Processor,\n TraceModel,\n TracingManager,\n Types,\n};\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as Migration from './Migration.js';\nexport * as ModelHandlers from './ModelHandlers.js';\nexport * as Types from './types.js';\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Animations from './AnimationHandler.js';\nimport * as GPU from './GPUHandler.js';\nimport * as LayoutShifts from './LayoutShiftsHandler.js';\nimport * as Memory from './MemoryHandler.js';\nimport * as NetworkRequests from './NetworkRequestsHandler.js';\nimport * as PageLoadMetrics from './PageLoadMetricsHandler.js';\nimport * as Screenshots from './ScreenshotsHandler.js';\nimport type * as Renderer from './RendererHandler.js';\nimport type * as Samples from './SamplesHandler.js';\nimport * as UserInteractions from './UserInteractionsHandler.js';\nimport * as UserTimings from './UserTimingsHandler.js';\nimport * as Warnings from './WarningsHandler.js';\nimport * as Workers from './WorkersHandler.js';\n\nimport type * as Types from './types.js';\n\n// As we migrate the data engine we are incrementally enabling the new handlers\n// one by one, so we do not waste effort parsing data that we do not use. This\n// object should be updated when we add a new handler to enable it.\nexport const ENABLED_TRACE_HANDLERS = {\n Animations,\n UserTimings,\n PageLoadMetrics,\n UserInteractions,\n LayoutShifts,\n Screenshots,\n GPU,\n Memory,\n NetworkRequests,\n Warnings,\n Workers,\n};\n\nexport type EnabledHandlersDuringMigration = typeof ENABLED_TRACE_HANDLERS;\n\n// Renderer and Samples handler are only executed when the panel is run\n// from the component examples server. Thus we mark them as optional\n// properties during the migration.\nexport type PartialTraceData = Readonly<Types.EnabledHandlerDataWithMeta<EnabledHandlersDuringMigration>>&{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n readonly Renderer?: Readonly<ReturnType<typeof Renderer['data']>>,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n readonly Samples?: Readonly<ReturnType<typeof Samples['data']>>,\n};\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\nconst animations: Types.TraceEvents.TraceEventAnimation[] = [];\nconst animationsSyntheticEvents: Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[] = [];\n\nexport interface AnimationData {\n animations: readonly Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[];\n}\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n animations.length = 0;\n animationsSyntheticEvents.length = 0;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventAnimation(event)) {\n animations.push(event);\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n const matchedEvents = matchBeginningAndEndEvents();\n\n createSortedAnimationsSyntheticEvents(matchedEvents);\n\n handlerState = HandlerState.FINALIZED;\n}\n\nfunction matchBeginningAndEndEvents(): Map<string, {\n begin: Types.TraceEvents.TraceEventNestableAsyncBegin | null,\n end: Types.TraceEvents.TraceEventNestableAsyncEnd | null,\n}> {\n // map to store begin and end of the event\n const matchedEvents: Map<string, {\n begin: Types.TraceEvents.TraceEventNestableAsyncBegin | null,\n end: Types.TraceEvents.TraceEventNestableAsyncEnd | null,\n }> = new Map();\n\n // looking for start and end\n for (const event of animations) {\n const id = event.id2;\n\n if (id === undefined) {\n continue;\n }\n\n const syntheticId = `${event.cat}:${id.local}:${event.name}`;\n\n const otherEventsWithID = Platform.MapUtilities.getWithDefault(matchedEvents, syntheticId, () => {\n return {begin: null, end: null};\n });\n\n const isStartEvent = event.ph === Types.TraceEvents.Phase.ASYNC_NESTABLE_START;\n const isEndEvent = event.ph === Types.TraceEvents.Phase.ASYNC_NESTABLE_END;\n\n if (isStartEvent) {\n otherEventsWithID.begin = {\n ...event,\n ph: Types.TraceEvents.Phase.ASYNC_NESTABLE_START,\n id2: {\n local: event.id2?.local,\n },\n id: event.args?.id,\n };\n } else if (isEndEvent) {\n otherEventsWithID.end = {\n ...event,\n ph: Types.TraceEvents.Phase.ASYNC_NESTABLE_END,\n id2: {\n local: event.id2?.local,\n },\n id: event.args?.id,\n };\n }\n }\n\n return matchedEvents;\n}\n\nfunction createSortedAnimationsSyntheticEvents(matchedEvents: Map<string, {\n begin: Types.TraceEvents.TraceEventNestableAsyncBegin | null,\n end: Types.TraceEvents.TraceEventNestableAsyncEnd | null,\n}>): void {\n for (const [id, eventsPair] of matchedEvents.entries()) {\n if (!eventsPair.begin || !eventsPair.end) {\n continue;\n }\n\n const event: Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent = {\n cat: eventsPair.end.cat,\n ph: eventsPair.end.ph,\n pid: eventsPair.end.pid,\n tid: eventsPair.end.tid,\n id,\n name: eventsPair.begin.name,\n dur: Types.Timing.MicroSeconds(eventsPair.end.ts - eventsPair.begin.ts),\n ts: eventsPair.begin.ts,\n args: {\n data: {\n beginEvent: eventsPair.begin,\n endEvent: eventsPair.end,\n },\n },\n };\n\n if (event.dur < 0) {\n // We have seen in the backend that sometimes animation events get\n // generated with multiple begin entries, or multiple end entries, and this\n // can cause invalid data on the performance panel, so we drop them.\n // crbug.com/1472375\n continue;\n }\n animationsSyntheticEvents.push(event);\n }\n\n animationsSyntheticEvents.sort((a, b) => a.ts - b.ts);\n}\n\nexport function data(): AnimationData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Animation handler is not finalized');\n }\n\n return {\n animations: Array.from(animationsSyntheticEvents),\n };\n}\n", "// Copyright (c) 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport const removeElement = <T>(array: T[], element: T, firstOnly?: boolean): boolean => {\n let index = array.indexOf(element);\n if (index === -1) {\n return false;\n }\n if (firstOnly) {\n array.splice(index, 1);\n return true;\n }\n for (let i = index + 1, n = array.length; i < n; ++i) {\n if (array[i] !== element) {\n array[index++] = array[i];\n }\n }\n array.length = index;\n return true;\n};\n\ntype NumberComparator = (a: number, b: number) => number;\n\nfunction swap(array: number[], i1: number, i2: number): void {\n const temp = array[i1];\n array[i1] = array[i2];\n array[i2] = temp;\n}\n\nfunction partition(\n array: number[], comparator: NumberComparator, left: number, right: number, pivotIndex: number): number {\n const pivotValue = array[pivotIndex];\n swap(array, right, pivotIndex);\n let storeIndex = left;\n for (let i = left; i < right; ++i) {\n if (comparator(array[i], pivotValue) < 0) {\n swap(array, storeIndex, i);\n ++storeIndex;\n }\n }\n swap(array, right, storeIndex);\n return storeIndex;\n}\n\nfunction quickSortRange(\n array: number[], comparator: NumberComparator, left: number, right: number, sortWindowLeft: number,\n sortWindowRight: number): void {\n if (right <= left) {\n return;\n }\n const pivotIndex = Math.floor(Math.random() * (right - left)) + left;\n const pivotNewIndex = partition(array, comparator, left, right, pivotIndex);\n if (sortWindowLeft < pivotNewIndex) {\n quickSortRange(array, comparator, left, pivotNewIndex - 1, sortWindowLeft, sortWindowRight);\n }\n if (pivotNewIndex < sortWindowRight) {\n quickSortRange(array, comparator, pivotNewIndex + 1, right, sortWindowLeft, sortWindowRight);\n }\n}\n\nexport function sortRange(\n array: number[], comparator: NumberComparator, leftBound: number, rightBound: number, sortWindowLeft: number,\n sortWindowRight: number): number[] {\n if (leftBound === 0 && rightBound === (array.length - 1) && sortWindowLeft === 0 && sortWindowRight >= rightBound) {\n array.sort(comparator);\n } else {\n quickSortRange(array, comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight);\n }\n return array;\n}\nexport const binaryIndexOf = <T, S>(array: T[], value: S, comparator: (a: S, b: T) => number): number => {\n const index = lowerBound(array, value, comparator);\n return index < array.length && comparator(value, array[index]) === 0 ? index : -1;\n};\n\nfunction mergeOrIntersect<T>(\n array1: T[], array2: T[], comparator: (a: T, b: T) => number, mergeNotIntersect: boolean): T[] {\n const result = [];\n let i = 0;\n let j = 0;\n while (i < array1.length && j < array2.length) {\n const compareValue = comparator(array1[i], array2[j]);\n if (mergeNotIntersect || !compareValue) {\n result.push(compareValue <= 0 ? array1[i] : array2[j]);\n }\n if (compareValue <= 0) {\n i++;\n }\n if (compareValue >= 0) {\n j++;\n }\n }\n if (mergeNotIntersect) {\n while (i < array1.length) {\n result.push(array1[i++]);\n }\n while (j < array2.length) {\n result.push(array2[j++]);\n }\n }\n return result;\n}\n\nexport const intersectOrdered = <T>(array1: T[], array2: T[], comparator: (a: T, b: T) => number): T[] => {\n return mergeOrIntersect(array1, array2, comparator, false);\n};\n\nexport const mergeOrdered = <T>(array1: T[], array2: T[], comparator: (a: T, b: T) => number): T[] => {\n return mergeOrIntersect(array1, array2, comparator, true);\n};\n\nexport const DEFAULT_COMPARATOR = (a: string|number, b: string|number): -1|0|1 => {\n return a < b ? -1 : (a > b ? 1 : 0);\n};\n\n/**\n * Returns the index of the element closest to the needle that is equal to or\n * greater than it. Assumes that the provided array is sorted.\n *\n * If no element is found, the right bound is returned.\n *\n * Uses the provided comparator function to determine if two items are equal or\n * if one is greater than the other. If you are working with strings or\n * numbers, you can use ArrayUtilities.DEFAULT_COMPARATOR. Otherwise, you\n * should define one that takes the needle element and an element from the\n * array and returns a positive or negative number to indicate which is greater\n * than the other.\n *\n * When specified, |left| (inclusive) and |right| (exclusive) indices\n * define the search window.\n */\nexport function lowerBound<T>(\n array: Uint32Array|Int32Array, needle: T, comparator: (needle: T, b: number) => number, left?: number,\n right?: number): number;\nexport function lowerBound<S, T>(\n array: S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function lowerBound<S, T, A extends S[]>(\n array: A, needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number {\n let l = left || 0;\n let r = right !== undefined ? right : array.length;\n while (l < r) {\n const m = (l + r) >> 1;\n if (comparator(needle, array[m]) > 0) {\n l = m + 1;\n } else {\n r = m;\n }\n }\n return r;\n}\n\n/**\n * Returns the index of the element closest to the needle that is greater than\n * it. Assumes that the provided array is sorted.\n *\n * If no element is found, the right bound is returned.\n *\n * Uses the provided comparator function to determine if two items are equal or\n * if one is greater than the other. If you are working with strings or\n * numbers, you can use ArrayUtilities.DEFAULT_COMPARATOR. Otherwise, you\n * should define one that takes the needle element and an element from the\n * array and returns a positive or negative number to indicate which is greater\n * than the other.\n *\n * When specified, |left| (inclusive) and |right| (exclusive) indices\n * define the search window.\n */\nexport function upperBound<T>(\n array: Uint32Array, needle: T, comparator: (needle: T, b: number) => number, left?: number, right?: number): number;\nexport function upperBound<S, T>(\n array: S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function upperBound<S, T, A extends S[]>(\n array: A, needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number {\n let l = left || 0;\n let r = right !== undefined ? right : array.length;\n while (l < r) {\n const m = (l + r) >> 1;\n if (comparator(needle, array[m]) >= 0) {\n l = m + 1;\n } else {\n r = m;\n }\n }\n return r;\n}\n\nconst enum NearestSearchStart {\n BEGINNING = 'BEGINNING',\n END = 'END',\n}\n/**\n * Obtains the first or last item in the array that satisfies the predicate function.\n * So, for example, if the array were arr = [2, 4, 6, 8, 10], and you are looking for\n * the last item arr[i] such that arr[i] < 5 you would be returned 1, because\n * array[1] is 4, the last item in the array that satisfies the\n * predicate function.\n *\n * If instead you were looking for the first item in the same array that satisfies\n * arr[i] > 5 you would be returned 2 because array[2] = 6.\n *\n * Please note: this presupposes that the array is already ordered.\n */\nfunction nearestIndex<T>(\n arr: readonly T[], predicate: (arrayItem: T) => boolean, searchStart: NearestSearchStart): number|null {\n const searchFromEnd = searchStart === NearestSearchStart.END;\n if (arr.length === 0) {\n return null;\n }\n\n let left = 0;\n let right = arr.length - 1;\n let pivot = 0;\n let matchesPredicate = false;\n let moveToTheRight = false;\n let middle = 0;\n do {\n middle = left + (right - left) / 2;\n pivot = searchFromEnd ? Math.ceil(middle) : Math.floor(middle);\n matchesPredicate = predicate(arr[pivot]);\n moveToTheRight = matchesPredicate === searchFromEnd;\n if (moveToTheRight) {\n left = Math.min(right, pivot + (left === pivot ? 1 : 0));\n } else {\n right = Math.max(left, pivot + (right === pivot ? -1 : 0));\n }\n } while (right !== left);\n\n // Special-case: the indexed item doesn't pass the predicate. This\n // occurs when none of the items in the array are a match for the\n // predicate.\n if (!predicate(arr[left])) {\n return null;\n }\n return left;\n}\n\n/**\n * Obtains the first item in the array that satisfies the predicate function.\n * So, for example, if the array was arr = [2, 4, 6, 8, 10], and you are looking for\n * the first item arr[i] such that arr[i] > 5 you would be returned 2, because\n * array[2] is 6, the first item in the array that satisfies the\n * predicate function.\n *\n * Please note: this presupposes that the array is already ordered.\n */\nexport function nearestIndexFromBeginning<T>(arr: T[], predicate: (arrayItem: T) => boolean): number|null {\n return nearestIndex(arr, predicate, NearestSearchStart.BEGINNING);\n}\n\n/**\n * Obtains the last item in the array that satisfies the predicate function.\n * So, for example, if the array was arr = [2, 4, 6, 8, 10], and you are looking for\n * the last item arr[i] such that arr[i] < 5 you would be returned 1, because\n * arr[1] is 4, the last item in the array that satisfies the\n * predicate function.\n *\n * Please note: this presupposes that the array is already ordered.\n */\n\nexport function nearestIndexFromEnd<T>(arr: readonly T[], predicate: (arrayItem: T) => boolean): number|null {\n return nearestIndex(arr, predicate, NearestSearchStart.END);\n}\n\n// Type guard for ensuring that `arr` does not contain null or undefined\nexport function arrayDoesNotContainNullOrUndefined<T>(arr: (T|null|undefined)[]): arr is T[] {\n return !arr.includes(null) && !arr.includes(undefined);\n}\n", "// Copyright 2021 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {type Brand} from './brand.js';\n\n/**\n * File paths in DevTools that are represented as URLs\n * @example\n * \u201Cfile:///Hello%20World/file/js\u201D\n */\nexport type UrlString = Brand<string, 'UrlString'>;\nexport const EmptyUrlString = '' as UrlString;\n\n/**\n * File paths in DevTools that are represented as unencoded absolute\n * or relative paths\n * @example\n * \u201C/Hello World/file.js\u201D\n */\nexport type RawPathString = Brand<string, 'RawPathString'>;\nexport const EmptyRawPathString = '' as RawPathString;\n\n/**\n * File paths in DevTools that are represented as encoded paths\n * @example\n * \u201C/Hello%20World/file.js\u201D\n */\nexport type EncodedPathString = Brand<string, 'EncodedPathString'>;\nexport const EmptyEncodedPathString = '' as EncodedPathString;\n", "// Copyright (c) 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport const inverse = function<K, V>(map: Map<K, V>): Multimap<V, K> {\n const result = new Multimap<V, K>();\n for (const [key, value] of map.entries()) {\n result.set(value, key);\n }\n return result;\n};\n\nexport class Multimap<K, V> {\n private map = new Map<K, Set<V>>();\n\n set(key: K, value: V): void {\n let set = this.map.get(key);\n if (!set) {\n set = new Set();\n this.map.set(key, set);\n }\n set.add(value);\n }\n\n get(key: K): Set<V> {\n return this.map.get(key) || new Set();\n }\n\n has(key: K): boolean {\n return this.map.has(key);\n }\n\n hasValue(key: K, value: V): boolean {\n const set = this.map.get(key);\n if (!set) {\n return false;\n }\n return set.has(value);\n }\n\n get size(): number {\n return this.map.size;\n }\n\n delete(key: K, value: V): boolean {\n const values = this.get(key);\n if (!values) {\n return false;\n }\n const result = values.delete(value);\n if (!values.size) {\n this.map.delete(key);\n }\n return result;\n }\n\n deleteAll(key: K): void {\n this.map.delete(key);\n }\n\n keysArray(): K[] {\n return [...this.map.keys()];\n }\n\n valuesArray(): V[] {\n const result = [];\n for (const set of this.map.values()) {\n result.push(...set.values());\n }\n return result;\n }\n\n clear(): void {\n this.map.clear();\n }\n}\n\n/**\n * Gets value for key, assigning a default if value is falsy.\n */\nexport function getWithDefault<K extends {}, V>(\n map: WeakMap<K, V>|Map<K, V>, key: K, defaultValueFactory: (key?: K) => V): V {\n let value = map.get(key);\n if (!value) {\n value = defaultValueFactory(key);\n map.set(key, value);\n }\n\n return value;\n}\n", "// Copyright (c) 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport const clamp = (num: number, min: number, max: number): number => {\n let clampedNumber = num;\n if (num < min) {\n clampedNumber = min;\n } else if (num > max) {\n clampedNumber = max;\n }\n return clampedNumber;\n};\n\nexport const mod = (m: number, n: number): number => {\n return ((m % n) + n) % n;\n};\n\nexport const bytesToString = (bytes: number): string => {\n if (bytes < 1000) {\n return `${bytes.toFixed(0)}\\xA0B`;\n }\n\n const kilobytes = bytes / 1000;\n if (kilobytes < 100) {\n return `${kilobytes.toFixed(1)}\\xA0kB`;\n }\n if (kilobytes < 1000) {\n return `${kilobytes.toFixed(0)}\\xA0kB`;\n }\n\n const megabytes = kilobytes / 1000;\n if (megabytes < 100) {\n return `${megabytes.toFixed(1)}\\xA0MB`;\n }\n return `${megabytes.toFixed(0)}\\xA0MB`;\n};\n\nexport const toFixedIfFloating = (value: string): string => {\n if (!value || Number.isNaN(Number(value))) {\n return value;\n }\n const number = Number(value);\n return number % 1 ? number.toFixed(3) : String(number);\n};\n\n/**\n * Rounds a number (including float) down.\n */\nexport const floor = (value: number, precision: number = 0): number => {\n const mult = Math.pow(10, precision);\n return Math.floor(value * mult) / mult;\n};\n\n/**\n * Computes the great common divisor for two numbers.\n * If the numbers are floats, they will be rounded to an integer.\n */\nexport const greatestCommonDivisor = (a: number, b: number): number => {\n a = Math.round(a);\n b = Math.round(b);\n while (b !== 0) {\n const t = b;\n b = a % b;\n a = t;\n }\n return a;\n};\n\nconst commonRatios = new Map([\n ['8\u22365', '16\u223610'],\n]);\n\nexport const aspectRatio = (width: number, height: number): string => {\n const divisor = greatestCommonDivisor(width, height);\n if (divisor !== 0) {\n width /= divisor;\n height /= divisor;\n }\n const result = `${width}\u2236${height}`;\n return commonRatios.get(result) || result;\n};\n\nexport const withThousandsSeparator = function(num: number): string {\n let str = String(num);\n const re = /(\\d+)(\\d{3})/;\n while (str.match(re)) {\n str = str.replace(re, '$1\\xA0$2');\n } // \\xa0 is a non-breaking space\n return str;\n};\n", "// Copyright (c) 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport const escapeCharacters = (inputString: string, charsToEscape: string): string => {\n let foundChar = false;\n for (let i = 0; i < charsToEscape.length; ++i) {\n if (inputString.indexOf(charsToEscape.charAt(i)) !== -1) {\n foundChar = true;\n break;\n }\n }\n\n if (!foundChar) {\n return String(inputString);\n }\n\n let result = '';\n for (let i = 0; i < inputString.length; ++i) {\n if (charsToEscape.indexOf(inputString.charAt(i)) !== -1) {\n result += '\\\\';\n }\n result += inputString.charAt(i);\n }\n\n return result;\n};\n\nconst toHexadecimal = (charCode: number, padToLength: number): string => {\n return charCode.toString(16).toUpperCase().padStart(padToLength, '0');\n};\n\n// Remember to update the third group in the regexps patternsToEscape and\n// patternsToEscapePlusSingleQuote when adding new entries in this map.\nconst escapedReplacements = new Map([\n ['\\b', '\\\\b'],\n ['\\f', '\\\\f'],\n ['\\n', '\\\\n'],\n ['\\r', '\\\\r'],\n ['\\t', '\\\\t'],\n ['\\v', '\\\\v'],\n ['\\'', '\\\\\\''],\n ['\\\\', '\\\\\\\\'],\n ['<!--', '\\\\x3C!--'],\n ['<script', '\\\\x3Cscript'],\n ['</script', '\\\\x3C/script'],\n]);\n\nexport const formatAsJSLiteral = (content: string): string => {\n const patternsToEscape = /(\\\\|<(?:!--|\\/?script))|(\\p{Control})|(\\p{Surrogate})/gu;\n const patternsToEscapePlusSingleQuote = /(\\\\|'|<(?:!--|\\/?script))|(\\p{Control})|(\\p{Surrogate})/gu;\n const escapePattern = (match: string, pattern: string, controlChar: string, loneSurrogate: string): string => {\n if (controlChar) {\n if (escapedReplacements.has(controlChar)) {\n // @ts-ignore https://github.com/microsoft/TypeScript/issues/13086\n return escapedReplacements.get(controlChar);\n }\n const twoDigitHex = toHexadecimal(controlChar.charCodeAt(0), 2);\n return '\\\\x' + twoDigitHex;\n }\n if (loneSurrogate) {\n const fourDigitHex = toHexadecimal(loneSurrogate.charCodeAt(0), 4);\n return '\\\\u' + fourDigitHex;\n }\n if (pattern) {\n return escapedReplacements.get(pattern) || '';\n }\n return match;\n };\n\n let escapedContent = '';\n let quote = '';\n if (!content.includes('\\'')) {\n quote = '\\'';\n escapedContent = content.replaceAll(patternsToEscape, escapePattern);\n } else if (!content.includes('\"')) {\n quote = '\"';\n escapedContent = content.replaceAll(patternsToEscape, escapePattern);\n } else if (!content.includes('`') && !content.includes('${')) {\n quote = '`';\n escapedContent = content.replaceAll(patternsToEscape, escapePattern);\n } else {\n quote = '\\'';\n escapedContent = content.replaceAll(patternsToEscapePlusSingleQuote, escapePattern);\n }\n return `${quote}${escapedContent}${quote}`;\n};\n\n/**\n * This implements a subset of the sprintf() function described in the Single UNIX\n * Specification. It supports the %s, %f, %d, and %% formatting specifiers, and\n * understands the %m$d notation to select the m-th parameter for this substitution,\n * as well as the optional precision for %s, %f, and %d.\n *\n * @param fmt format string.\n * @param args parameters to the format string.\n * @returns the formatted output string.\n */\nexport const sprintf = (fmt: string, ...args: unknown[]): string => {\n let argIndex = 0;\n const RE = /%(?:(\\d+)\\$)?(?:\\.(\\d*))?([%dfs])/g;\n return fmt.replaceAll(RE, (_: string, index?: string, precision?: string, specifier?: string): string => {\n if (specifier === '%') {\n return '%';\n }\n if (index !== undefined) {\n argIndex = parseInt(index, 10) - 1;\n if (argIndex < 0) {\n throw new RangeError(`Invalid parameter index ${argIndex + 1}`);\n }\n }\n if (argIndex >= args.length) {\n throw new RangeError(`Expected at least ${argIndex + 1} format parameters, but only ${args.length} where given.`);\n }\n if (specifier === 's') {\n const argValue = String(args[argIndex++]);\n if (precision !== undefined) {\n return argValue.substring(0, Number(precision));\n }\n return argValue;\n }\n let argValue = Number(args[argIndex++]);\n if (isNaN(argValue)) {\n argValue = 0;\n }\n if (specifier === 'd') {\n return String(Math.floor(argValue)).padStart(Number(precision), '0');\n }\n if (precision !== undefined) {\n return argValue.toFixed(Number(precision));\n }\n return String(argValue);\n });\n};\n\nexport const toBase64 = (inputString: string): string => {\n /* note to the reader: we can't use btoa here because we need to\n * support Unicode correctly. See the test cases for this function and\n * also\n * https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_Unicode_Problem\n */\n\n function encodeBits(b: number): number {\n return b < 26 ? b + 65 : b < 52 ? b + 71 : b < 62 ? b - 4 : b === 62 ? 43 : b === 63 ? 47 : 65;\n }\n const encoder = new TextEncoder();\n const data = encoder.encode(inputString.toString());\n const n = data.length;\n let encoded = '';\n if (n === 0) {\n return encoded;\n }\n let shift;\n let v = 0;\n for (let i = 0; i < n; i++) {\n shift = i % 3;\n v |= data[i] << (16 >>> shift & 24);\n if (shift === 2) {\n encoded += String.fromCharCode(\n encodeBits(v >>> 18 & 63), encodeBits(v >>> 12 & 63), encodeBits(v >>> 6 & 63), encodeBits(v & 63));\n v = 0;\n }\n }\n if (shift === 0) {\n encoded += String.fromCharCode(encodeBits(v >>> 18 & 63), encodeBits(v >>> 12 & 63), 61, 61);\n } else if (shift === 1) {\n encoded += String.fromCharCode(encodeBits(v >>> 18 & 63), encodeBits(v >>> 12 & 63), encodeBits(v >>> 6 & 63), 61);\n }\n return encoded;\n};\n\nexport const findIndexesOfSubString = (inputString: string, searchString: string): number[] => {\n const matches = [];\n let i = inputString.indexOf(searchString);\n while (i !== -1) {\n matches.push(i);\n i = inputString.indexOf(searchString, i + searchString.length);\n }\n return matches;\n};\n\nexport const findLineEndingIndexes = (inputString: string): number[] => {\n const endings = findIndexesOfSubString(inputString, '\\n');\n endings.push(inputString.length);\n return endings;\n};\n\nexport const isWhitespace = (inputString: string): boolean => {\n return /^\\s*$/.test(inputString);\n};\n\nexport const trimURL = (url: string, baseURLDomain?: string): string => {\n let result = url.replace(/^(https|http|file):\\/\\//i, '');\n if (baseURLDomain) {\n if (result.toLowerCase().startsWith(baseURLDomain.toLowerCase())) {\n result = result.substr(baseURLDomain.length);\n }\n }\n return result;\n};\n\nexport const collapseWhitespace = (inputString: string): string => {\n return inputString.replace(/[\\s\\xA0]+/g, ' ');\n};\n\nexport const reverse = (inputString: string): string => {\n return inputString.split('').reverse().join('');\n};\n\nexport const replaceControlCharacters = (inputString: string): string => {\n // Replace C0 and C1 control character sets with replacement character.\n // Do not replace '\\t', \\n' and '\\r'.\n return inputString.replace(/[\\0-\\x08\\x0B\\f\\x0E-\\x1F\\x80-\\x9F]/g, '\\uFFFD');\n};\n\nexport const countWtf8Bytes = (inputString: string): number => {\n let count = 0;\n for (let i = 0; i < inputString.length; i++) {\n const c = inputString.charCodeAt(i);\n if (c <= 0x7F) {\n count++;\n } else if (c <= 0x07FF) {\n count += 2;\n } else if (c < 0xD800 || 0xDFFF < c) {\n count += 3;\n } else {\n if (c <= 0xDBFF && i + 1 < inputString.length) {\n // The current character is a leading surrogate, and there is a\n // next character.\n const next = inputString.charCodeAt(i + 1);\n if (0xDC00 <= next && next <= 0xDFFF) {\n // The next character is a trailing surrogate, meaning this\n // is a surrogate pair.\n count += 4;\n i++;\n continue;\n }\n }\n count += 3;\n }\n }\n return count;\n};\n\nexport const stripLineBreaks = (inputStr: string): string => {\n return inputStr.replace(/(\\r)?\\n/g, '');\n};\n\nexport const toTitleCase = (inputStr: string): string => {\n return inputStr.substring(0, 1).toUpperCase() + inputStr.substring(1);\n};\n\nexport const removeURLFragment = (inputStr: string): string => {\n const url = new URL(inputStr);\n url.hash = '';\n return url.toString();\n};\n\nconst SPECIAL_REGEX_CHARACTERS = '^[]{}()\\\\.^$*+?|-,';\n\nexport const regexSpecialCharacters = function(): string {\n return SPECIAL_REGEX_CHARACTERS;\n};\n\nexport const filterRegex = function(query: string): RegExp {\n let regexString = '^(?:.*\\\\0)?'; // Start from beginning or after a \\0\n for (let i = 0; i < query.length; ++i) {\n let c = query.charAt(i);\n if (SPECIAL_REGEX_CHARACTERS.indexOf(c) !== -1) {\n c = '\\\\' + c;\n }\n regexString += '[^\\\\0' + c + ']*' + c;\n }\n return new RegExp(regexString, 'i');\n};\n\nexport const createSearchRegex = function(query: string, caseSensitive: boolean, isRegex: boolean): RegExp {\n const regexFlags = caseSensitive ? 'g' : 'gi';\n let regexObject;\n\n if (isRegex) {\n try {\n regexObject = new RegExp(query, regexFlags);\n } catch (e) {\n // Silent catch.\n }\n }\n\n if (!regexObject) {\n regexObject = createPlainTextSearchRegex(query, regexFlags);\n }\n\n return regexObject;\n};\n\nexport const caseInsensetiveComparator = function(a: string, b: string): number {\n a = a.toUpperCase();\n b = b.toUpperCase();\n if (a === b) {\n return 0;\n }\n return a > b ? 1 : -1;\n};\n\nexport const hashCode = function(string?: string): number {\n if (!string) {\n return 0;\n }\n // Hash algorithm for substrings is described in \"\u00DCber die Komplexit\u00E4t der Multiplikation in\n // eingeschr\u00E4nkten Branchingprogrammmodellen\" by Woelfe.\n // http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000\n const p = ((1 << 30) * 4 - 5); // prime: 2^32 - 5\n const z = 0x5033d967; // 32 bits from random.org\n const z2 = 0x59d2f15d; // random odd 32 bit number\n let s = 0;\n let zi = 1;\n for (let i = 0; i < string.length; i++) {\n const xi = string.charCodeAt(i) * z2;\n s = (s + zi * xi) % p;\n zi = (zi * z) % p;\n }\n s = (s + zi * (p - 1)) % p;\n return Math.abs(s | 0);\n};\n\nexport const compare = (a: string, b: string): number => {\n if (a > b) {\n return 1;\n }\n if (a < b) {\n return -1;\n }\n return 0;\n};\n\nexport const trimMiddle = (str: string, maxLength: number): string => {\n if (str.length <= maxLength) {\n return String(str);\n }\n let leftHalf = maxLength >> 1;\n let rightHalf = maxLength - leftHalf - 1;\n if ((str.codePointAt(str.length - rightHalf - 1) as number) >= 0x10000) {\n --rightHalf;\n ++leftHalf;\n }\n if (leftHalf > 0 && (str.codePointAt(leftHalf - 1) as number) >= 0x10000) {\n --leftHalf;\n }\n return str.substr(0, leftHalf) + '\u2026' + str.substr(str.length - rightHalf, rightHalf);\n};\n\nexport const trimEndWithMaxLength = (str: string, maxLength: number): string => {\n if (str.length <= maxLength) {\n return String(str);\n }\n return str.substr(0, maxLength - 1) + '\u2026';\n};\n\nexport const escapeForRegExp = (str: string): string => {\n return escapeCharacters(str, SPECIAL_REGEX_CHARACTERS);\n};\n\nexport const naturalOrderComparator = (a: string, b: string): number => {\n const chunk = /^\\d+|^\\D+/;\n let chunka, chunkb, anum, bnum;\n while (true) {\n if (a) {\n if (!b) {\n return 1;\n }\n } else {\n if (b) {\n return -1;\n }\n return 0;\n }\n chunka = (a.match(chunk) as string[])[0];\n chunkb = (b.match(chunk) as string[])[0];\n anum = !Number.isNaN(Number(chunka));\n bnum = !Number.isNaN(Number(chunkb));\n if (anum && !bnum) {\n return -1;\n }\n if (bnum && !anum) {\n return 1;\n }\n if (anum && bnum) {\n const diff = Number(chunka) - Number(chunkb);\n if (diff) {\n return diff;\n }\n if (chunka.length !== chunkb.length) {\n if (!Number(chunka) && !Number(chunkb)) { // chunks are strings of all 0s (special case)\n return chunka.length - chunkb.length;\n }\n return chunkb.length - chunka.length;\n }\n } else if (chunka !== chunkb) {\n return (chunka < chunkb) ? -1 : 1;\n }\n a = a.substring(chunka.length);\n b = b.substring(chunkb.length);\n }\n};\n\nexport const base64ToSize = function(content: string|null): number {\n if (!content) {\n return 0;\n }\n let size = content.length * 3 / 4;\n if (content[content.length - 1] === '=') {\n size--;\n }\n if (content.length > 1 && content[content.length - 2] === '=') {\n size--;\n }\n return size;\n};\n\nexport const SINGLE_QUOTE = '\\'';\nexport const DOUBLE_QUOTE = '\"';\nconst BACKSLASH = '\\\\';\n\nexport const findUnclosedCssQuote = function(str: string): string {\n let unmatchedQuote = '';\n for (let i = 0; i < str.length; ++i) {\n const char = str[i];\n if (char === BACKSLASH) {\n i++;\n continue;\n }\n if (char === SINGLE_QUOTE || char === DOUBLE_QUOTE) {\n if (unmatchedQuote === char) {\n unmatchedQuote = '';\n } else if (unmatchedQuote === '') {\n unmatchedQuote = char;\n }\n }\n }\n return unmatchedQuote;\n};\n\nexport const createPlainTextSearchRegex = function(query: string, flags?: string): RegExp {\n // This should be kept the same as the one in StringUtil.cpp.\n let regex = '';\n for (let i = 0; i < query.length; ++i) {\n const c = query.charAt(i);\n if (regexSpecialCharacters().indexOf(c) !== -1) {\n regex += '\\\\';\n }\n regex += c;\n }\n return new RegExp(regex, flags || '');\n};\n\nclass LowerCaseStringTag {\n private lowerCaseStringTag: (string|undefined);\n}\n\nexport type LowerCaseString = string&LowerCaseStringTag;\n\nexport const toLowerCaseString = function(input: string): LowerCaseString {\n return input.toLowerCase() as LowerCaseString;\n};\n\n// Replaces the last ocurrence of parameter `search` with parameter `replacement` in `input`\nexport const replaceLast = function(input: string, search: string, replacement: string): string {\n const replacementStartIndex = input.lastIndexOf(search);\n if (replacementStartIndex === -1) {\n return input;\n }\n\n return input.slice(0, replacementStartIndex) + input.slice(replacementStartIndex).replace(search, replacement);\n};\n\nexport const stringifyWithPrecision = function stringifyWithPrecision(s: number, precision = 2): string {\n if (precision === 0) {\n return s.toFixed(0);\n }\n const string = s.toFixed(precision).replace(/\\.?0*$/, '');\n return string === '-0' ? '0' : string;\n};\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/**\n * This is useful to keep TypeScript happy in a test - if you have a value\n * that's potentially `null` you can use this function to assert that it isn't,\n * and satisfy TypeScript that the value is present.\n */\nexport function assertNotNullOrUndefined<T>(val: T): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n throw new Error(`Expected given value to not be null/undefined but it was: ${val}`);\n }\n}\n\nexport function assertNever(type: never, message: string): never {\n throw new Error(message);\n}\n\n/**\n * This is useful to check on the type-level that the unhandled cases of\n * a switch are exactly `T` (where T is usually a union type of enum values).\n * @param caseVariable\n */\nexport function assertUnhandled<T>(_caseVariable: T): T {\n return _caseVariable;\n}\n\nexport type FieldsThatExtend<Type, Selector> = {\n [Key in keyof Type]: Type[Key] extends Selector ? Key : never;\n}[keyof Type];\n\nexport type PickFieldsThatExtend<Type, Selector> = Pick<Type, FieldsThatExtend<Type, Selector>>;\n\n/**\n * Turns a Union type (a | b) into an Intersection type (a & b).\n * This is a helper type to implement the \"NoUnion\" guard.\n *\n * Adapted from https://stackoverflow.com/a/50375286.\n *\n * The tautological `T extends any` is necessary to trigger distributivity for\n * plain unions, e.g. in IntersectionFromUnion<'a'|'b'> TypeScript expands it\n * to ('a' extends any ? (arg: 'a') => void : never)\n * | ('b' extends any ? (arg: 'b') => void : never)\n *\n * The second extends clause then asks TypeScript to find a type of the form\n * `(arg: infer U) => void` that upper-bounds the union, i.e., intuitively,\n * a type that converts to each of the union members. This forces U to be the\n * intersection of 'a' and 'b' in the example.\n *\n * Please note that some intersection types are simply impossible, e.g.\n * `string & number`. There is no type that fulfills both at the same time. A\n * union of this kind is reduced to `never`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype IntersectionFromUnion<T> = (T extends any ? (arg: T) => void : never) extends((arg: infer U) => void) ? U : never;\n\n/**\n * When writing generic code it may be desired to disallow Union types from\n * being passed. This type can be used in those cases.\n *\n * function foo<T>(argument: NoUnion<T>) {...}\n *\n * Would result in a compile error for foo<a|b>(...); invocations as `argument`\n * would be typed as `never`.\n *\n * Adapted from https://stackoverflow.com/a/50641073.\n *\n * Conditional types become distributive when receiving a union type. To\n * prevent this from happening, we use `[T] extends [IntersectionFromUnion<T>]`\n * instead of `T extends IntersectionFromUnion<T>`.\n * See: https://www.typescriptlang.org/docs/handbook/2/conditional-types.html\n */\nexport type NoUnion<T> = [T] extends [IntersectionFromUnion<T>] ? T : never;\n", "/*\n * Copyright (C) 2019 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nimport * as ArrayUtilities from './array-utilities.js';\nimport * as Brand from './brand.js';\nimport * as DateUtilities from './date-utilities.js';\nimport * as DevToolsPath from './DevToolsPath.js';\nimport * as DOMUtilities from './dom-utilities.js';\nimport * as KeyboardUtilities from './keyboard-utilities.js';\nimport * as MapUtilities from './map-utilities.js';\nimport * as NumberUtilities from './number-utilities.js';\nimport * as PromiseUtilities from './promise-utilities.js';\nimport * as SetUtilities from './set-utilities.js';\nimport * as StringUtilities from './string-utilities.js';\nimport * as Timing from './Timing.js';\nimport * as TypeScriptUtilities from './typescript-utilities.js';\nimport * as UIString from './UIString.js';\nimport * as UserVisibleError from './UserVisibleError.js';\n\n// export {DCHECK} from './dcheck.js';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function DCHECK(condition: () => boolean, message: string = 'DCHECK'): void {\n if (!condition()) {\n throw new Error(message + ':' + new Error().stack);\n }\n}\n\n/* `assertNotNull` also need to be exposed, as TypeScript does not\n * allow `asserts` functions to be used with qualified access\n * (e.g. `Platform.TypeScriptUtilities.assertNotNull` causes a\n * compiler error)\n */\nexport {assertNever, assertNotNullOrUndefined, assertUnhandled} from './typescript-utilities.js';\nexport {\n ArrayUtilities,\n Brand,\n DateUtilities,\n DevToolsPath,\n DOMUtilities,\n KeyboardUtilities,\n MapUtilities,\n NumberUtilities,\n PromiseUtilities,\n SetUtilities,\n StringUtilities,\n Timing,\n TypeScriptUtilities,\n UIString,\n UserVisibleError,\n};\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as File from './File.js';\nexport * as Timing from './Timing.js';\nexport * as TraceEvents from './TraceEvents.js';\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {type TraceEventData} from './TraceEvents.js';\nexport type TraceFile = {\n traceEvents: readonly TraceEventData[],\n metadata: MetaData,\n};\n\nexport const enum DataOrigin {\n CPUProfile = 'CPUProfile',\n TraceEvents = 'TraceEvents',\n}\n\n/**\n * Trace metadata that we persist to the file. This will allow us to\n * store specifics for the trace, e.g., which tracks should be visible\n * on load.\n */\nexport interface MetaData {\n source?: 'DevTools';\n startTime?: string;\n networkThrottling?: string;\n cpuThrottling?: number;\n hardwareConcurrency?: number;\n dataOrigin?: DataOrigin;\n}\n\nexport type Contents = TraceFile|TraceEventData[];\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/* eslint-disable no-unused-private-class-members */\n\nexport type MicroSeconds = number&{_tag: 'MicroSeconds'};\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function MicroSeconds(value: number): MicroSeconds {\n return value as MicroSeconds;\n}\n\nexport type MilliSeconds = number&{_tag: 'MilliSeconds'};\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function MilliSeconds(value: number): MilliSeconds {\n return value as MilliSeconds;\n}\nexport type Seconds = number&{_tag: 'Seconds'};\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function Seconds(value: number): Seconds {\n return value as Seconds;\n}\n\nexport const enum TimeUnit {\n MICROSECONDS = 0,\n MILLISECONDS = 1,\n SECONDS = 2,\n MINUTES = 3,\n}\n\n// Other types.\n\nexport interface TraceWindow {\n min: MicroSeconds;\n max: MicroSeconds;\n range: MicroSeconds;\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/* eslint-disable no-unused-private-class-members */\nimport type * as Protocol from '../../../generated/protocol.js';\nimport {type MicroSeconds, type MilliSeconds, type Seconds} from './Timing.js';\n\n// Trace Events.\nexport const enum Phase {\n // Standard\n BEGIN = 'B',\n END = 'E',\n COMPLETE = 'X',\n INSTANT = 'I',\n COUNTER = 'C',\n\n // Async\n ASYNC_NESTABLE_START = 'b',\n ASYNC_NESTABLE_INSTANT = 'n',\n ASYNC_NESTABLE_END = 'e',\n ASYNC_STEP_INTO = 'T',\n ASYNC_BEGIN = 'S',\n ASYNC_END = 'F',\n ASYNC_STEP_PAST = 'p',\n\n // Flow\n FLOW_START = 's',\n FLOW_STEP = 't',\n FLOW_END = 'f',\n\n // Sample\n SAMPLE = 'P',\n\n // Object\n OBJECT_CREATED = 'N',\n OBJECT_SNAPSHOT = 'O',\n OBJECT_DESTROYED = 'D',\n\n // Metadata\n METADATA = 'M',\n\n // Memory Dump\n MEMORY_DUMP_GLOBAL = 'V',\n MEMORY_DUMP_PROCESS = 'v',\n\n // Mark\n MARK = 'R',\n\n // Clock sync\n CLOCK_SYNC = 'c',\n}\n\nexport function isNestableAsyncPhase(phase: Phase): boolean {\n return phase === Phase.ASYNC_NESTABLE_START || phase === Phase.ASYNC_NESTABLE_END ||\n phase === Phase.ASYNC_NESTABLE_INSTANT;\n}\n\nexport function isAsyncPhase(phase: Phase): boolean {\n return isNestableAsyncPhase(phase) || phase === Phase.ASYNC_BEGIN || phase === Phase.ASYNC_STEP_INTO ||\n phase === Phase.ASYNC_END || phase === Phase.ASYNC_STEP_PAST;\n}\n\nexport function isFlowPhase(phase: Phase): boolean {\n return phase === Phase.FLOW_START || phase === Phase.FLOW_STEP || phase === Phase.FLOW_END;\n}\n\nexport const enum TraceEventScope {\n THREAD = 't',\n PROCESS = 'p',\n GLOBAL = 'g',\n}\n\nexport interface TraceEventData {\n args?: TraceEventArgs;\n cat: string;\n name: string;\n ph: Phase;\n pid: ProcessID;\n tid: ThreadID;\n tts?: MicroSeconds;\n ts: MicroSeconds;\n tdur?: MicroSeconds;\n dur?: MicroSeconds;\n}\n\nexport interface TraceEventArgs {\n data?: TraceEventArgsData;\n}\n\nexport interface TraceEventArgsData {\n stackTrace?: TraceEventCallFrame[];\n navigationId?: string;\n frame?: string;\n}\n\nexport interface TraceEventCallFrame {\n codeType?: string;\n functionName: string;\n scriptId: number;\n columnNumber?: number;\n lineNumber?: number;\n url?: string;\n}\n\nexport interface TraceFrame {\n frame: string;\n name: string;\n processId: ProcessID;\n url: string;\n parent?: string;\n}\n\n// Sample events.\n\nexport interface TraceEventSample extends TraceEventData {\n ph: Phase.SAMPLE;\n}\n\nexport interface TraceEventProfile extends TraceEventSample {\n name: 'Profile';\n id: ProfileID;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n startTime: MicroSeconds,\n },\n };\n}\n\nexport interface TraceEventProfileChunk extends TraceEventSample {\n name: 'ProfileChunk';\n id: ProfileID;\n args: TraceEventArgs&{\n // `data` is only missing in \"fake\" traces\n data?: TraceEventArgsData & {\n cpuProfile?: TraceEventPartialProfile,\n timeDeltas?: MicroSeconds[],\n lines?: MicroSeconds[],\n },\n };\n}\n\nexport interface TraceEventPartialProfile {\n nodes?: TraceEventPartialNode[];\n samples: CallFrameID[];\n}\n\nexport interface TraceEventPartialNode {\n callFrame: TraceEventCallFrame;\n id: CallFrameID;\n parent?: CallFrameID;\n}\n\n// Complete events.\n\nexport interface TraceEventComplete extends TraceEventData {\n ph: Phase.COMPLETE;\n dur: MicroSeconds;\n}\n\nexport interface TraceEventFireIdleCallback extends TraceEventComplete {\n name: 'FireIdleCallback';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n allottedMilliseconds: MilliSeconds,\n frame: string,\n id: number,\n timedOut: boolean,\n },\n };\n}\n\nexport interface TraceEventDispatch extends TraceEventComplete {\n name: 'EventDispatch';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n type: string,\n },\n };\n}\n\nexport interface TraceEventBegin extends TraceEventData {\n ph: Phase.BEGIN;\n}\n\nexport interface TraceEventEnd extends TraceEventData {\n ph: Phase.END;\n}\n\n/**\n * This denotes a complete event created from a pair of begin and end\n * events. For practicality, instead of always having to look for the\n * end event corresponding to a begin event, we create a synthetic\n * complete event that comprises the data of both from the beginning in\n * the RendererHandler.\n */\nexport type TraceEventSyntheticCompleteEvent = TraceEventComplete;\n\nexport interface TraceEventEventTiming extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_START|Phase.ASYNC_NESTABLE_END;\n name: KnownEventName.EventTiming;\n id: string;\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n cancelable: boolean,\n duration: MilliSeconds,\n processingEnd: MicroSeconds,\n processingStart: MicroSeconds,\n timeStamp: MicroSeconds,\n interactionId?: number, type: string,\n },\n };\n}\n\nexport interface TraceEventEventTimingBegin extends TraceEventEventTiming {\n ph: Phase.ASYNC_NESTABLE_START;\n}\nexport interface TraceEventEventTimingEnd extends TraceEventEventTiming {\n ph: Phase.ASYNC_NESTABLE_END;\n}\n\nexport interface TraceEventGPUTask extends TraceEventComplete {\n name: 'GPUTask';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n /* eslint-disable @typescript-eslint/naming-convention */\n renderer_pid: ProcessID,\n used_bytes: number,\n /* eslint-enable @typescript-eslint/naming-convention */\n },\n };\n}\n\nexport interface TraceEventSyntheticNetworkRedirect {\n url: string;\n priority: string;\n requestMethod?: string;\n ts: MicroSeconds;\n dur: MicroSeconds;\n}\n\n// TraceEventProcessedArgsData is used to store the processed data of a network\n// request. Which is used to distinguish from the date we extract from the\n// trace event directly.\ninterface TraceEventSyntheticArgsData {\n dnsLookup: MicroSeconds;\n download: MicroSeconds;\n downloadStart: MicroSeconds;\n finishTime: MicroSeconds;\n initialConnection: MicroSeconds;\n isDiskCached: boolean;\n isHttps: boolean;\n isMemoryCached: boolean;\n isPushedResource: boolean;\n networkDuration: MicroSeconds;\n processingDuration: MicroSeconds;\n proxyNegotiation: MicroSeconds;\n queueing: MicroSeconds;\n redirectionDuration: MicroSeconds;\n requestSent: MicroSeconds;\n sendStartTime: MicroSeconds;\n ssl: MicroSeconds;\n stalled: MicroSeconds;\n totalTime: MicroSeconds;\n waiting: MicroSeconds;\n}\n\nexport interface TraceEventSyntheticNetworkRequest extends TraceEventComplete {\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n syntheticData: TraceEventSyntheticArgsData,\n // All fields below are from TraceEventsForNetworkRequest,\n // Required fields\n decodedBodyLength: number,\n encodedDataLength: number,\n frame: string,\n fromServiceWorker: boolean,\n host: string,\n mimeType: string,\n pathname: string,\n search: string,\n priority: Priority,\n initialPriority: Priority,\n protocol: string,\n redirects: TraceEventSyntheticNetworkRedirect[],\n renderBlocking: RenderBlocking,\n requestId: string,\n requestingFrameUrl: string,\n statusCode: number,\n url: string,\n // Optional fields\n requestMethod?: string,\n timing?: TraceEventResourceReceiveResponseTimingData,\n },\n };\n cat: 'loading';\n name: 'SyntheticNetworkRequest';\n ph: Phase.COMPLETE;\n dur: MicroSeconds;\n tdur: MicroSeconds;\n ts: MicroSeconds;\n tts: MicroSeconds;\n pid: ProcessID;\n tid: ThreadID;\n}\n\n// Snapshot events.\n\nexport interface TraceEventSnapshot extends TraceEventData {\n args: TraceEventArgs&{\n snapshot: string,\n };\n name: 'Screenshot';\n cat: 'disabled-by-default-devtools.screenshot';\n ph: Phase.OBJECT_SNAPSHOT;\n}\n\n// Animation events.\n\nexport interface TraceEventAnimation extends TraceEventData {\n args: TraceEventArgs&{\n id?: string,\n name?: string,\n nodeId?: number,\n nodeName?: string,\n state?: string,\n compositeFailed?: number,\n unsupportedProperties?: string[],\n };\n name: 'Animation';\n id2?: {\n local?: string,\n };\n}\n\n// Metadata events.\n\nexport interface TraceEventMetadata extends TraceEventData {\n ph: Phase.METADATA;\n args: TraceEventArgs&{\n name?: string,\n uptime?: string,\n };\n}\n\nexport interface TraceEventThreadName extends TraceEventMetadata {\n name: 'thread_name';\n args: TraceEventArgs&{\n name?: string,\n };\n}\n\nexport interface TraceEventProcessName extends TraceEventMetadata {\n name: 'process_name';\n}\n\n// Mark events.\n\nexport interface TraceEventMark extends TraceEventData {\n ph: Phase.MARK;\n}\n\nexport interface TraceEventNavigationStart extends TraceEventMark {\n name: 'navigationStart';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n documentLoaderURL: string,\n isLoadingMainFrame: boolean,\n // isOutermostMainFrame was introduced in crrev.com/c/3625434 and exists\n // because of Fenced Frames\n // [github.com/WICG/fenced-frame/tree/master/explainer].\n // Fenced frames introduce a situation where isLoadingMainFrame could be\n // true for a navigation, but that navigation be within an embedded \"main\n // frame\", and therefore it wouldn't be on the top level main frame.\n // In situations where we need to distinguish that, we can rely on\n // isOutermostMainFrame, which will only be true for navigations on the\n // top level main frame.\n\n // This flag is optional as it was introduced in May 2022; so users\n // reasonably may import traces from before that date that do not have\n // this field present.\n isOutermostMainFrame?: boolean, navigationId: string,\n },\n frame: string,\n };\n}\n\nexport interface TraceEventFirstContentfulPaint extends TraceEventMark {\n name: 'firstContentfulPaint';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n navigationId: string,\n },\n };\n}\n\nexport interface TraceEventFirstPaint extends TraceEventMark {\n name: 'firstPaint';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n navigationId: string,\n },\n };\n}\n\nexport type PageLoadEvent = TraceEventFirstContentfulPaint|TraceEventMarkDOMContent|TraceEventInteractiveTime|\n TraceEventLargestContentfulPaintCandidate|TraceEventLayoutShift|TraceEventFirstPaint|TraceEventMarkLoad|\n TraceEventNavigationStart;\n\nexport interface TraceEventLargestContentfulPaintCandidate extends TraceEventMark {\n name: 'largestContentfulPaint::Candidate';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n candidateIndex: number,\n isOutermostMainFrame: boolean,\n isMainFrame: boolean,\n navigationId: string,\n nodeId: Protocol.DOM.BackendNodeId,\n type?: string,\n },\n };\n}\nexport interface TraceEventLargestImagePaintCandidate extends TraceEventMark {\n name: 'LargestImagePaint::Candidate';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n candidateIndex: number,\n imageUrl: string,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n DOMNodeId: Protocol.DOM.BackendNodeId,\n },\n };\n}\nexport interface TraceEventLargestTextPaintCandidate extends TraceEventMark {\n name: 'LargestTextPaint::Candidate';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n candidateIndex: number,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n DOMNodeId: Protocol.DOM.BackendNodeId,\n },\n };\n}\n\nexport interface TraceEventInteractiveTime extends TraceEventMark {\n name: 'InteractiveTime';\n args: TraceEventArgs&{\n args: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n total_blocking_time_ms: number,\n },\n frame: string,\n };\n}\n\n// Instant events.\n\nexport interface TraceEventInstant extends TraceEventData {\n ph: Phase.INSTANT;\n s: TraceEventScope;\n}\n\nexport interface TraceEventUpdateCounters extends TraceEventInstant {\n name: 'UpdateCounters';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n documents: number,\n jsEventListeners: number,\n jsHeapSizeUsed: number,\n nodes: number,\n },\n };\n}\n\nexport type TraceEventRendererEvent = TraceEventInstant|TraceEventComplete;\n\nexport interface TraceEventTracingStartedInBrowser extends TraceEventInstant {\n name: 'TracingStartedInBrowser';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n frameTreeNodeId: number,\n // Frames can only missing in \"fake\" traces\n frames?: TraceFrame[], persistentIds: boolean,\n },\n };\n}\n\nexport interface TraceEventTracingSessionIdForWorker extends TraceEventInstant {\n name: 'TracingSessionIdForWorker';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n url: string,\n workerId: string,\n workerThreadId: ThreadID,\n frame: string,\n },\n };\n}\nexport function isTraceEventTracingSessionIdForWorker(event: TraceEventData):\n event is TraceEventTracingSessionIdForWorker {\n return event.name === 'TracingSessionIdForWorker';\n}\n\nexport interface TraceEventFrameCommittedInBrowser extends TraceEventInstant {\n name: 'FrameCommittedInBrowser';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & TraceFrame,\n };\n}\n\nexport interface TraceEventMainFrameViewport extends TraceEventInstant {\n name: 'PaintTimingVisualizer::Viewport';\n args: {\n data: TraceEventArgsData&{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n viewport_rect: number[],\n },\n };\n}\n\nexport interface TraceEventCommitLoad extends TraceEventInstant {\n name: 'CommitLoad';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n frame: string,\n isMainFrame: boolean,\n name: string,\n nodeId: number,\n page: string,\n parent: string,\n url: string,\n },\n };\n}\n\nexport interface TraceEventMarkDOMContent extends TraceEventInstant {\n name: 'MarkDOMContent';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n frame: string,\n isMainFrame: boolean,\n page: string,\n },\n };\n}\n\nexport interface TraceEventMarkLoad extends TraceEventInstant {\n name: 'MarkLoad';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n frame: string,\n isMainFrame: boolean,\n page: string,\n },\n };\n}\n\nexport interface TraceEventAsync extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_START|Phase.ASYNC_NESTABLE_INSTANT|Phase.ASYNC_NESTABLE_END|Phase.ASYNC_STEP_INTO|\n Phase.ASYNC_BEGIN|Phase.ASYNC_END|Phase.ASYNC_STEP_PAST;\n}\n\nexport type TraceRect = [number, number, number, number];\nexport type TraceImpactedNode = {\n // These keys come from the trace data, so we have to use underscores.\n /* eslint-disable @typescript-eslint/naming-convention */\n new_rect: TraceRect,\n node_id: Protocol.DOM.BackendNodeId,\n old_rect: TraceRect,\n /* eslint-enable @typescript-eslint/naming-convention */\n};\n\ntype LayoutShiftData = TraceEventArgsData&{\n // These keys come from the trace data, so we have to use underscores.\n /* eslint-disable @typescript-eslint/naming-convention */\n cumulative_score: number,\n frame_max_distance: number,\n had_recent_input: boolean,\n impacted_nodes: TraceImpactedNode[] | undefined,\n is_main_frame: boolean,\n overall_max_distance: number,\n region_rects: TraceRect[],\n score: number,\n weighted_score_delta: number,\n /* eslint-enable @typescript-eslint/naming-convention */\n};\n// These keys come from the trace data, so we have to use underscores.\nexport interface TraceEventLayoutShift extends TraceEventInstant {\n name: 'LayoutShift';\n normalized?: boolean;\n args: TraceEventArgs&{\n frame: string,\n data?: LayoutShiftData,\n };\n}\n\ninterface LayoutShiftSessionWindowData {\n // The sum of the weighted score of all the shifts\n // that belong to a session window.\n cumulativeWindowScore: number;\n // A consecutive generated in the frontend to\n // to identify a session window.\n id: number;\n}\nexport interface LayoutShiftParsedData {\n screenshotSource?: string;\n timeFromNavigation?: MicroSeconds;\n // The sum of the weighted scores of the shifts that\n // belong to a session window up until this shift\n // (inclusive).\n cumulativeWeightedScoreInWindow: number;\n sessionWindowData: LayoutShiftSessionWindowData;\n}\nexport interface SyntheticLayoutShift extends TraceEventLayoutShift {\n args: TraceEventArgs&{\n frame: string,\n data?: LayoutShiftData&{\n rawEvent: TraceEventLayoutShift,\n },\n };\n parsedData: LayoutShiftParsedData;\n}\n\nexport type Priority = 'Low'|'High'|'Medium'|'VeryHigh'|'Highest';\nexport type RenderBlocking = 'blocking'|'non_blocking'|'in_body_parser_blocking'|'potentially_blocking';\nexport interface TraceEventResourceSendRequest extends TraceEventInstant {\n name: 'ResourceSendRequest';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n frame: string,\n requestId: string,\n url: string,\n priority: Priority,\n // TODO(crbug.com/1457985): change requestMethod to enum when confirm in the backend code.\n requestMethod?: string,\n renderBlocking?: RenderBlocking,\n },\n };\n}\n\nexport interface TraceEventResourceChangePriority extends TraceEventInstant {\n name: 'ResourceChangePriority';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n requestId: string,\n priority: Priority,\n },\n };\n}\n\nexport interface TraceEventResourceWillSendRequest extends TraceEventInstant {\n name: 'ResourceWillSendRequest';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n requestId: string,\n },\n };\n}\n\nexport interface TraceEventResourceFinish extends TraceEventInstant {\n name: 'ResourceFinish';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n decodedBodyLength: number,\n didFail: boolean,\n encodedDataLength: number,\n finishTime: Seconds,\n requestId: string,\n },\n };\n}\n\nexport interface TraceEventResourceReceivedData extends TraceEventInstant {\n name: 'ResourceReceivedData';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n encodedDataLength: number,\n frame: string,\n requestId: string,\n },\n };\n}\n\ninterface TraceEventResourceReceiveResponseTimingData {\n connectEnd: MilliSeconds;\n connectStart: MilliSeconds;\n dnsEnd: MilliSeconds;\n dnsStart: MilliSeconds;\n proxyEnd: MilliSeconds;\n proxyStart: MilliSeconds;\n pushEnd: MilliSeconds;\n pushStart: MilliSeconds;\n receiveHeadersEnd: MilliSeconds;\n requestTime: Seconds;\n sendEnd: MilliSeconds;\n sendStart: MilliSeconds;\n sslEnd: MilliSeconds;\n sslStart: MilliSeconds;\n workerReady: MilliSeconds;\n workerStart: MilliSeconds;\n}\n\nexport interface TraceEventResourceReceiveResponse extends TraceEventInstant {\n name: 'ResourceReceiveResponse';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n encodedDataLength: number,\n frame: string,\n fromCache: boolean,\n fromServiceWorker: boolean,\n mimeType: string,\n requestId: string,\n responseTime: MilliSeconds,\n statusCode: number,\n timing: TraceEventResourceReceiveResponseTimingData,\n },\n };\n}\n\nexport interface TraceEventResourceMarkAsCached extends TraceEventInstant {\n name: 'ResourceMarkAsCached';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n requestId: string,\n },\n };\n}\n\nexport const enum LayoutInvalidationReason {\n SIZE_CHANGED = 'Size changed',\n ATTRIBUTE = 'Attribute',\n ADDED_TO_LAYOUT = 'Added to layout',\n SCROLLBAR_CHANGED = 'Scrollbar changed',\n REMOVED_FROM_LAYOUT = 'Removed from layout',\n STYLE_CHANGED = 'Style changed',\n FONTS_CHANGED = 'Fonts changed',\n UNKNOWN = 'Unknown',\n}\n\nexport interface TraceEventLayoutInvalidation extends TraceEventInstant {\n name: 'LayoutInvalidationTracking'|'ScheduleStyleInvalidationTracking';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n frame: string,\n nodeId: Protocol.DOM.BackendNodeId,\n reason: LayoutInvalidationReason,\n nodeName?: string,\n },\n };\n}\n\nexport const enum StyleRecalcInvalidationReason {\n ANIMATION = 'Animation',\n}\n\nexport interface TraceEventStyleRecalcInvalidation extends TraceEventInstant {\n name: 'StyleRecalcInvalidationTracking';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n frame: string,\n nodeId: Protocol.DOM.BackendNodeId,\n reason: StyleRecalcInvalidationReason,\n subtree: boolean,\n nodeName?: string,\n extraData?: string,\n },\n };\n}\n\nexport interface TraceEventPrePaint extends TraceEventComplete {\n name: 'PrePaint';\n}\n\nexport type TraceEventNestableAsync = TraceEventNestableAsyncBegin|TraceEventNestableAsyncEnd;\nexport interface TraceEventNestableAsyncBegin extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_START;\n // The id2 field gives flexibility to explicitly specify if an event\n // id is global among processes or process local. However not all\n // events use it, so both kind of ids need to be marked as optional.\n id2?: {local?: string, global?: string};\n id?: string;\n}\n\nexport interface TraceEventNestableAsyncEnd extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_END;\n id2?: {local?: string, global?: string};\n id?: string;\n}\n\nexport type TraceEventAsyncPerformanceMeasure = TraceEventPerformanceMeasureBegin|TraceEventPerformanceMeasureEnd;\n\nexport interface TraceEventPerformanceMeasureBegin extends TraceEventNestableAsyncBegin {\n cat: 'blink.user_timing';\n id: string;\n}\n\nexport interface TraceEventPerformanceMeasureEnd extends TraceEventNestableAsyncEnd {\n cat: 'blink.user_timing';\n id: string;\n}\n\nexport interface TraceEventConsoleTimeBegin extends TraceEventNestableAsyncBegin {\n cat: 'blink.console';\n id2: {\n local: string,\n };\n}\n\nexport interface TraceEventConsoleTimeEnd extends TraceEventNestableAsyncEnd {\n cat: 'blink.console';\n id2: {\n local: string,\n };\n}\n\nexport interface TraceEventTimeStamp extends TraceEventData {\n cat: 'devtools.timeline';\n name: 'TimeStamp';\n ph: Phase.INSTANT;\n id: string;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n frame: string,\n message: string,\n },\n };\n}\n\nexport interface TraceEventPerformanceMark extends TraceEventData {\n cat: 'blink.user_timing';\n ph: Phase.INSTANT|Phase.MARK;\n id: string;\n}\n\n// Nestable async events with a duration are made up of two distinct\n// events: the begin, and the end. We need both of them to be able to\n// display the right information, so we create these synthetic events.\nexport interface TraceEventSyntheticNestableAsyncEvent extends TraceEventData {\n id?: string;\n id2?: {local?: string, global?: string};\n dur: MicroSeconds;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n beginEvent: TraceEventNestableAsyncBegin,\n endEvent: TraceEventNestableAsyncEnd,\n },\n };\n}\n\nexport interface TraceEventSyntheticUserTiming extends TraceEventSyntheticNestableAsyncEvent {\n id: string;\n dur: MicroSeconds;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n beginEvent: TraceEventPerformanceMeasureBegin,\n endEvent: TraceEventPerformanceMeasureEnd,\n },\n };\n}\n\nexport interface TraceEventSyntheticConsoleTiming extends TraceEventSyntheticNestableAsyncEvent {\n id2: {local: string};\n dur: MicroSeconds;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n beginEvent: TraceEventConsoleTimeBegin,\n endEvent: TraceEventConsoleTimeEnd,\n },\n };\n}\n\nexport interface SyntheticInteractionEvent extends TraceEventSyntheticNestableAsyncEvent {\n // InteractionID and type are available within the beginEvent's data, but we\n // put them on the top level for ease of access.\n interactionId: number;\n type: string;\n // This is equivalent to startEvent.ts;\n ts: MicroSeconds;\n // This duration can be calculated via endEvent.ts - startEvent.ts, but we do\n // that and put it here to make it easier. This also makes these events\n // consistent with real events that have a dur field.\n dur: MicroSeconds;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n beginEvent: TraceEventEventTimingBegin,\n endEvent: TraceEventEventTimingEnd,\n },\n };\n}\n\n/**\n * An event created synthetically in the frontend that has a self time\n * (the time spent running the task itself).\n */\nexport interface SyntheticEventWithSelfTime extends TraceEventData {\n selfTime?: MicroSeconds;\n}\n\n/**\n * A profile call created in the frontend from samples disguised as a\n * trace event.\n */\nexport interface TraceEventSyntheticProfileCall extends SyntheticEventWithSelfTime {\n callFrame: Protocol.Runtime.CallFrame;\n nodeId: Protocol.integer;\n children?: TraceEventSyntheticProfileCall[];\n}\n\n/**\n * A trace event augmented synthetically in the frontend to contain\n * its self time.\n */\nexport type SyntheticRendererEvent = TraceEventRendererEvent&SyntheticEventWithSelfTime;\n\nexport function isSyntheticInteractionEvent(event: TraceEventData): event is SyntheticInteractionEvent {\n return Boolean(\n 'interactionId' in event && event.args?.data && 'beginEvent' in event.args.data && 'endEvent' in event.args.data);\n}\n\nclass ProfileIdTag {\n readonly #profileIdTag: (symbol|undefined);\n}\nexport type ProfileID = string&ProfileIdTag;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function ProfileID(value: string): ProfileID {\n return value as ProfileID;\n}\n\nclass CallFrameIdTag {\n readonly #callFrameIdTag: (symbol|undefined);\n}\nexport type CallFrameID = number&CallFrameIdTag;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function CallFrameID(value: number): CallFrameID {\n return value as CallFrameID;\n}\n\nclass ProcessIdTag {\n readonly #processIdTag: (symbol|undefined);\n}\nexport type ProcessID = number&ProcessIdTag;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function ProcessID(value: number): ProcessID {\n return value as ProcessID;\n}\n\nclass ThreadIdTag {\n readonly #threadIdTag: (symbol|undefined);\n}\nexport type ThreadID = number&ThreadIdTag;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function ThreadID(value: number): ThreadID {\n return value as ThreadID;\n}\n\nexport function isTraceEventComplete(event: TraceEventData): event is TraceEventComplete {\n return event.ph === Phase.COMPLETE;\n}\n\nexport function isTraceEventBegin(event: TraceEventData): event is TraceEventBegin {\n return event.ph === Phase.BEGIN;\n}\n\nexport function isTraceEventEnd(event: TraceEventData): event is TraceEventEnd {\n return event.ph === Phase.END;\n}\n\nexport function isTraceEventDispatch(event: TraceEventData): event is TraceEventDispatch {\n return event.name === 'EventDispatch';\n}\n\nexport function isTraceEventInstant(event: TraceEventData): event is TraceEventInstant {\n return event.ph === Phase.INSTANT;\n}\n\nexport function isTraceEventRendererEvent(event: TraceEventData): event is TraceEventRendererEvent {\n return isTraceEventInstant(event) || isTraceEventComplete(event);\n}\n\nexport function isTraceEventFireIdleCallback(event: TraceEventData): event is TraceEventFireIdleCallback {\n return event.name === 'FireIdleCallback';\n}\n\nexport function isTraceEventUpdateCounters(event: TraceEventData): event is TraceEventUpdateCounters {\n return event.name === 'UpdateCounters';\n}\n\nexport function isThreadName(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventThreadName {\n return traceEventData.name === 'thread_name';\n}\n\nexport function isProcessName(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventProcessName {\n return traceEventData.name === 'process_name';\n}\n\nexport function isTraceEventTracingStartedInBrowser(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventTracingStartedInBrowser {\n return traceEventData.name === 'TracingStartedInBrowser';\n}\n\nexport function isTraceEventFrameCommittedInBrowser(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventFrameCommittedInBrowser {\n return traceEventData.name === 'FrameCommittedInBrowser';\n}\n\nexport function isTraceEventCommitLoad(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventCommitLoad {\n return traceEventData.name === 'CommitLoad';\n}\n\nexport function isTraceEventNavigationStart(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventNavigationStart {\n return traceEventData.name === 'navigationStart';\n}\n\nexport function isTraceEventAnimation(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventAnimation {\n return traceEventData.name === 'Animation';\n}\n\nexport function isTraceEventLayoutShift(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventLayoutShift {\n return traceEventData.name === 'LayoutShift';\n}\n\nexport function isTraceEventLayoutInvalidation(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventLayoutInvalidation {\n return traceEventData.name === 'LayoutInvalidationTracking' ||\n traceEventData.name === 'ScheduleStyleInvalidationTracking';\n}\n\nexport function isTraceEventStyleRecalcInvalidation(traceEventData: TraceEventData):\n traceEventData is TraceEventStyleRecalcInvalidation {\n return traceEventData.name === 'StyleRecalcInvalidationTracking';\n}\n\nexport function isTraceEventFirstContentfulPaint(traceEventData: TraceEventData):\n traceEventData is TraceEventFirstContentfulPaint {\n return traceEventData.name === 'firstContentfulPaint';\n}\n\nexport function isTraceEventLargestContentfulPaintCandidate(traceEventData: TraceEventData):\n traceEventData is TraceEventLargestContentfulPaintCandidate {\n return traceEventData.name === 'largestContentfulPaint::Candidate';\n}\nexport function isTraceEventLargestImagePaintCandidate(traceEventData: TraceEventData):\n traceEventData is TraceEventLargestImagePaintCandidate {\n return traceEventData.name === 'LargestImagePaint::Candidate';\n}\nexport function isTraceEventLargestTextPaintCandidate(traceEventData: TraceEventData):\n traceEventData is TraceEventLargestTextPaintCandidate {\n return traceEventData.name === 'LargestTextPaint::Candidate';\n}\n\nexport function isTraceEventMarkLoad(traceEventData: TraceEventData): traceEventData is TraceEventMarkLoad {\n return traceEventData.name === 'MarkLoad';\n}\n\nexport function isTraceEventFirstPaint(traceEventData: TraceEventData): traceEventData is TraceEventFirstPaint {\n return traceEventData.name === 'firstPaint';\n}\n\nexport function isTraceEventMarkDOMContent(traceEventData: TraceEventData): traceEventData is TraceEventMarkDOMContent {\n return traceEventData.name === 'MarkDOMContent';\n}\n\nexport function isTraceEventInteractiveTime(traceEventData: TraceEventData):\n traceEventData is TraceEventInteractiveTime {\n return traceEventData.name === 'InteractiveTime';\n}\n\nexport function isTraceEventEventTiming(traceEventData: TraceEventData): traceEventData is TraceEventEventTiming {\n return traceEventData.name === KnownEventName.EventTiming;\n}\n\nexport function isTraceEventEventTimingEnd(traceEventData: TraceEventData): traceEventData is TraceEventEventTimingEnd {\n return isTraceEventEventTiming(traceEventData) && traceEventData.ph === Phase.ASYNC_NESTABLE_END;\n}\nexport function isTraceEventEventTimingStart(traceEventData: TraceEventData):\n traceEventData is TraceEventEventTimingBegin {\n return isTraceEventEventTiming(traceEventData) && traceEventData.ph === Phase.ASYNC_NESTABLE_START;\n}\n\nexport function isTraceEventGPUTask(traceEventData: TraceEventData): traceEventData is TraceEventGPUTask {\n return traceEventData.name === 'GPUTask';\n}\n\nexport function isTraceEventProfile(traceEventData: TraceEventData): traceEventData is TraceEventProfile {\n return traceEventData.name === 'Profile';\n}\n\nexport function isTraceEventProfileChunk(traceEventData: TraceEventData): traceEventData is TraceEventProfileChunk {\n return traceEventData.name === 'ProfileChunk';\n}\n\nexport function isTraceEventResourceChangePriority(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceChangePriority {\n return traceEventData.name === 'ResourceChangePriority';\n}\n\nexport function isTraceEventResourceSendRequest(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceSendRequest {\n return traceEventData.name === 'ResourceSendRequest';\n}\n\nexport function isTraceEventResourceReceiveResponse(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceReceiveResponse {\n return traceEventData.name === 'ResourceReceiveResponse';\n}\n\nexport function isTraceEventResourceMarkAsCached(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceMarkAsCached {\n return traceEventData.name === 'ResourceMarkAsCached';\n}\n\nexport function isTraceEventResourceFinish(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceFinish {\n return traceEventData.name === 'ResourceFinish';\n}\n\nexport function isTraceEventResourceWillSendRequest(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceWillSendRequest {\n return traceEventData.name === 'ResourceWillSendRequest';\n}\n\nexport function isTraceEventResourceReceivedData(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceReceivedData {\n return traceEventData.name === 'ResourceReceivedData';\n}\n\nexport function isSyntheticNetworkRequestDetailsEvent(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventSyntheticNetworkRequest {\n return traceEventData.name === 'SyntheticNetworkRequest';\n}\n\nexport function isTraceEventPrePaint(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventPrePaint {\n return traceEventData.name === 'PrePaint';\n}\n\nexport function isTraceEventNavigationStartWithURL(event: TraceEventData): event is TraceEventNavigationStart {\n return Boolean(isTraceEventNavigationStart(event) && event.args.data && event.args.data.documentLoaderURL !== '');\n}\n\nexport function isTraceEventMainFrameViewport(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventMainFrameViewport {\n return traceEventData.name === 'PaintTimingVisualizer::Viewport';\n}\n\nexport function isSyntheticUserTimingTraceEvent(traceEventData: TraceEventData):\n traceEventData is TraceEventSyntheticUserTiming {\n if (traceEventData.cat !== 'blink.user_timing') {\n return false;\n }\n const data = traceEventData.args?.data;\n if (!data) {\n return false;\n }\n return 'beginEvent' in data && 'endEvent' in data;\n}\n\nexport function isSyntheticConsoleTimingTraceEvent(traceEventData: TraceEventData):\n traceEventData is TraceEventSyntheticConsoleTiming {\n if (traceEventData.cat !== 'blink.console') {\n return false;\n }\n const data = traceEventData.args?.data;\n if (!data) {\n return false;\n }\n return 'beginEvent' in data && 'endEvent' in data;\n}\n\nexport function isTraceEventPerformanceMeasure(traceEventData: TraceEventData):\n traceEventData is TraceEventPerformanceMeasureBegin|TraceEventPerformanceMeasureEnd {\n return traceEventData.cat === 'blink.user_timing' && isTraceEventAsyncPhase(traceEventData);\n}\n\nexport function isTraceEventPerformanceMark(traceEventData: TraceEventData):\n traceEventData is TraceEventPerformanceMark {\n return traceEventData.cat === 'blink.user_timing' &&\n (traceEventData.ph === Phase.MARK || traceEventData.ph === Phase.INSTANT);\n}\n\nexport function isTraceEventConsoleTime(traceEventData: TraceEventData): traceEventData is TraceEventConsoleTimeBegin|\n TraceEventConsoleTimeEnd {\n return traceEventData.cat === 'blink.console' && isTraceEventAsyncPhase(traceEventData);\n}\n\nexport function isTraceEventTimeStamp(traceEventData: TraceEventData): traceEventData is TraceEventTimeStamp {\n return traceEventData.ph === Phase.INSTANT && traceEventData.name === 'TimeStamp';\n}\n\nexport interface TraceEventAsync extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_START|Phase.ASYNC_NESTABLE_INSTANT|Phase.ASYNC_NESTABLE_END|Phase.ASYNC_STEP_INTO|\n Phase.ASYNC_BEGIN|Phase.ASYNC_END|Phase.ASYNC_STEP_PAST;\n}\n\nexport function isTraceEventAsyncPhase(traceEventData: TraceEventData): boolean {\n const asyncPhases = new Set([\n Phase.ASYNC_NESTABLE_START,\n Phase.ASYNC_NESTABLE_INSTANT,\n Phase.ASYNC_NESTABLE_END,\n Phase.ASYNC_STEP_INTO,\n Phase.ASYNC_BEGIN,\n Phase.ASYNC_END,\n Phase.ASYNC_STEP_PAST,\n ]);\n return asyncPhases.has(traceEventData.ph);\n}\n\nexport function isSyntheticLayoutShift(traceEventData: TraceEventData): traceEventData is SyntheticLayoutShift {\n if (!isTraceEventLayoutShift(traceEventData) || !traceEventData.args.data) {\n return false;\n }\n return 'rawEvent' in traceEventData.args.data;\n}\n\nexport function isProfileCall(event: TraceEventData): event is TraceEventSyntheticProfileCall {\n return 'callFrame' in event;\n}\n\n/**\n * This is an exhaustive list of events we track in the Performance\n * panel. Note not all of them are necessarliry shown in the flame\n * chart, some of them we only use for parsing.\n * TODO(crbug.com/1428024): Complete this enum.\n */\nexport const enum KnownEventName {\n /* Task */\n Program = 'Program',\n RunTask = 'RunTask',\n AsyncTask = 'AsyncTask',\n RunMicrotasks = 'RunMicrotasks',\n\n /* Load */\n XHRLoad = 'XHRLoad',\n XHRReadyStateChange = 'XHRReadyStateChange',\n /* Parse */\n ParseHTML = 'ParseHTML',\n ParseCSS = 'ParseAuthorStyleSheet',\n /* V8 */\n CompileScript = 'V8.CompileScript',\n CompileCode = 'V8.CompileCode',\n CompileModule = 'V8.CompileModule',\n Optimize = 'V8.OptimizeCode',\n WasmStreamFromResponseCallback = 'v8.wasm.streamFromResponseCallback',\n WasmCompiledModule = 'v8.wasm.compiledModule',\n WasmCachedModule = 'v8.wasm.cachedModule',\n WasmModuleCacheHit = 'v8.wasm.moduleCacheHit',\n WasmModuleCacheInvalid = 'v8.wasm.moduleCacheInvalid',\n /* Js */\n ProfileCall = 'ProfileCall',\n EvaluateScript = 'EvaluateScript',\n FunctionCall = 'FunctionCall',\n EventDispatch = 'EventDispatch',\n EvaluateModule = 'v8.evaluateModule',\n RequestMainThreadFrame = 'RequestMainThreadFrame',\n RequestAnimationFrame = 'RequestAnimationFrame',\n CancelAnimationFrame = 'CancelAnimationFrame',\n FireAnimationFrame = 'FireAnimationFrame',\n RequestIdleCallback = 'RequestIdleCallback',\n CancelIdleCallback = 'CancelIdleCallback',\n FireIdleCallback = 'FireIdleCallback',\n TimerInstall = 'TimerInstall',\n TimerRemove = 'TimerRemove',\n TimerFire = 'TimerFire',\n WebSocketCreate = 'WebSocketCreate',\n WebSocketSendHandshake = 'WebSocketSendHandshakeRequest',\n WebSocketReceiveHandshake = 'WebSocketReceiveHandshakeResponse',\n WebSocketDestroy = 'WebSocketDestroy',\n CryptoDoEncrypt = 'DoEncrypt',\n CryptoDoEncryptReply = 'DoEncryptReply',\n CryptoDoDecrypt = 'DoDecrypt',\n CryptoDoDecryptReply = 'DoDecryptReply',\n CryptoDoDigest = 'DoDigest',\n CryptoDoDigestReply = 'DoDigestReply',\n CryptoDoSign = 'DoSign',\n CryptoDoSignReply = 'DoSignReply',\n CryptoDoVerify = 'DoVerify',\n CryptoDoVerifyReply = 'DoVerifyReply',\n V8Execute = 'V8.Execute',\n\n /* Gc */\n GC = 'GCEvent',\n DOMGC = 'BlinkGC.AtomicPhase',\n IncrementalGCMarking = 'V8.GCIncrementalMarking',\n MajorGC = 'MajorGC',\n MinorGC = 'MinorGC',\n GCCollectGarbage = 'BlinkGC.AtomicPhase',\n\n /* Layout */\n ScheduleStyleRecalculation = 'ScheduleStyleRecalculation',\n RecalculateStyles = 'RecalculateStyles',\n Layout = 'Layout',\n UpdateLayoutTree = 'UpdateLayoutTree',\n InvalidateLayout = 'InvalidateLayout',\n LayoutInvalidationTracking = 'LayoutInvalidationTracking',\n ComputeIntersections = 'ComputeIntersections',\n HitTest = 'HitTest',\n PrePaint = 'PrePaint',\n Layerize = 'Layerize',\n LayoutShift = 'LayoutShift',\n UpdateLayerTree = 'UpdateLayerTree',\n ScheduleStyleInvalidationTracking = 'ScheduleStyleInvalidationTracking',\n StyleRecalcInvalidationTracking = 'StyleRecalcInvalidationTracking',\n StyleInvalidatorInvalidationTracking = 'StyleInvalidatorInvalidationTracking',\n\n /* Paint */\n ScrollLayer = 'ScrollLayer',\n UpdateLayer = 'UpdateLayer',\n PaintSetup = 'PaintSetup',\n Paint = 'Paint',\n PaintImage = 'PaintImage',\n Commit = 'Commit',\n CompositeLayers = 'CompositeLayers',\n RasterTask = 'RasterTask',\n ImageDecodeTask = 'ImageDecodeTask',\n ImageUploadTask = 'ImageUploadTask',\n DecodeImage = 'Decode Image',\n ResizeImage = 'Resize Image',\n DrawLazyPixelRef = 'Draw LazyPixelRef',\n DecodeLazyPixelRef = 'Decode LazyPixelRef',\n GPUTask = 'GPUTask',\n Rasterize = 'Rasterize',\n EventTiming = 'EventTiming',\n\n /* Compile */\n OptimizeCode = 'V8.OptimizeCode',\n CacheScript = 'v8.produceCache',\n CacheModule = 'v8.produceModuleCache',\n // V8Sample events are coming from tracing and contain raw stacks with function addresses.\n // After being processed with help of JitCodeAdded and JitCodeMoved events they\n // get translated into function infos and stored as stacks in JSSample events.\n V8Sample = 'V8Sample',\n JitCodeAdded = 'JitCodeAdded',\n JitCodeMoved = 'JitCodeMoved',\n StreamingCompileScript = 'v8.parseOnBackground',\n StreamingCompileScriptWaiting = 'v8.parseOnBackgroundWaiting',\n StreamingCompileScriptParsing = 'v8.parseOnBackgroundParsing',\n BackgroundDeserialize = 'v8.deserializeOnBackground',\n FinalizeDeserialization = 'V8.FinalizeDeserialization',\n\n /* Markers */\n CommitLoad = 'CommitLoad',\n MarkLoad = 'MarkLoad',\n MarkDOMContent = 'MarkDOMContent',\n MarkFirstPaint = 'firstPaint',\n MarkFCP = 'firstContentfulPaint',\n MarkLCPCandidate = 'largestContentfulPaint::Candidate',\n MarkLCPInvalidate = 'largestContentfulPaint::Invalidate',\n NavigationStart = 'navigationStart',\n TimeStamp = 'TimeStamp',\n ConsoleTime = 'ConsoleTime',\n UserTiming = 'UserTiming',\n InteractiveTime = 'InteractiveTime',\n\n /* Frames */\n BeginFrame = 'BeginFrame',\n NeedsBeginFrameChanged = 'NeedsBeginFrameChanged',\n BeginMainThreadFrame = 'BeginMainThreadFrame',\n ActivateLayerTree = 'ActivateLayerTree',\n DrawFrame = 'DrawFrame',\n DroppedFrame = 'DroppedFrame',\n FrameStartedLoading = 'FrameStartedLoading',\n\n /* Network request events */\n ResourceWillSendRequest = 'ResourceWillSendRequest',\n ResourceSendRequest = 'ResourceSendRequest',\n ResourceReceiveResponse = 'ResourceReceiveResponse',\n ResourceReceivedData = 'ResourceReceivedData',\n ResourceFinish = 'ResourceFinish',\n ResourceMarkAsCached = 'ResourceMarkAsCached',\n\n /* Web sockets */\n WebSocketSendHandshakeRequest = 'WebSocketSendHandshakeRequest',\n WebSocketReceiveHandshakeResponse = 'WebSocketReceiveHandshakeResponse',\n\n /* CPU Profiling */\n Profile = 'Profile',\n StartProfiling = 'CpuProfiler::StartProfiling',\n ProfileChunk = 'ProfileChunk',\n UpdateCounters = 'UpdateCounters',\n\n /* Other */\n Animation = 'Animation',\n ParseAuthorStyleSheet = 'ParseAuthorStyleSheet',\n EmbedderCallback = 'EmbedderCallback',\n SetLayerTreeId = 'SetLayerTreeId',\n TracingStartedInPage = 'TracingStartedInPage',\n TracingSessionIdForWorker = 'TracingSessionIdForWorker',\n LazyPixelRef = 'LazyPixelRef',\n LayerTreeHostImplSnapshot = 'cc::LayerTreeHostImpl',\n PictureSnapshot = 'cc::Picture',\n DisplayItemListSnapshot = 'cc::DisplayItemList',\n InputLatencyMouseMove = 'InputLatency::MouseMove',\n InputLatencyMouseWheel = 'InputLatency::MouseWheel',\n ImplSideFling = 'InputHandlerProxy::HandleGestureFling::started',\n}\n", "\n// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\nimport type * as ModelHandlers from './ModelHandlers.js';\n\nexport interface TraceEventHandler {\n reset(): void;\n initialize?(freshRecording?: boolean): void;\n handleEvent(data: {}): void;\n finalize?(): Promise<void>;\n data(): unknown;\n deps?(): TraceEventHandlerName[];\n}\nexport type TraceEventHandlerName = keyof typeof ModelHandlers;\n\n// This type maps TraceEventHandler names to the return type of their data\n// function. So, for example, if we are given an object with a key of 'foo'\n// and a value which is a TraceHandler containing a data() function that\n// returns a string, this type will be { foo: string }.\n//\n// This allows us to model the behavior of the TraceProcessor in the model,\n// which takes an object with TraceEventHandlers as part of its config, and\n// which ultimately returns an object keyed off the names of the\n// TraceEventHandlers, and with values that are derived from each\n// TraceEventHandler's data function.\n//\n// So, concretely, we provide a TraceEventHandler for calculating the #time\n// bounds of a trace called TraceBounds, whose data() function returns a\n// TraceWindow. The HandlerData, therefore, would determine that the\n// TraceProcessor would contain a key called 'TraceBounds' whose value is\n// a TraceWindow.\nexport type EnabledHandlerDataWithMeta<T extends {[key: string]: TraceEventHandler}> = {\n // We allow the user to configure which handlers are created by passing them\n // in when constructing a model instance. However, we then ensure that the\n // Meta handler is added to that, as the Model relies on some of the data\n // from the Meta handler when creating the file. Therefore, this type\n // explicitly defines that the Meta data is present, before then extending it\n // with the index type to represent all the other handlers.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Meta: Readonly<ReturnType<typeof ModelHandlers['Meta']['data']>>,\n}&{\n // For every key in the object, look up the TraceEventHandler's data function\n // and use its return type as the value for the object.\n [K in keyof T]: Readonly<ReturnType<T[K]['data']>>;\n};\n\nexport type HandlersWithMeta<T extends {[key: string]: TraceEventHandler}> = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Meta: typeof ModelHandlers.Meta,\n}&{\n [K in keyof T]: T[K];\n};\n\n// Represents the final parsed data from all of the handlers. Note that because\n// we are currently in the middle of the migration of data engines, not all the\n// handlers are enabled. Therefore for now you should use the type defined in\n// models/trace/handlers/Migration.ts, `PartialTraceData`, which\n// represents the final parsed data for only the enabled handlers.\nexport type TraceParseData = Readonly<EnabledHandlerDataWithMeta<typeof ModelHandlers>>;\n\nexport type Handlers = typeof ModelHandlers;\n\nexport const enum HandlerState {\n UNINITIALIZED = 1,\n INITIALIZED = 2,\n FINALIZED = 3,\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {data as metaHandlerData} from './MetaHandler.js';\n\nimport {type TraceEventHandlerName, HandlerState} from './types.js';\n\nimport * as Types from '../types/types.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nconst eventsInProcessThread =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventGPUTask[]>>();\n\nlet mainGPUThreadTasks: Types.TraceEvents.TraceEventGPUTask[] = [];\n\nexport function reset(): void {\n eventsInProcessThread.clear();\n mainGPUThreadTasks = [];\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('GPU Handler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('GPU Handler is not initialized');\n }\n\n if (!Types.TraceEvents.isTraceEventGPUTask(event)) {\n return;\n }\n\n Helpers.Trace.addEventToProcessThread(event, eventsInProcessThread);\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('GPU Handler is not initialized');\n }\n\n const {gpuProcessId, gpuThreadId} = metaHandlerData();\n const gpuThreadsForProcess = eventsInProcessThread.get(gpuProcessId);\n if (gpuThreadsForProcess && gpuThreadId) {\n mainGPUThreadTasks = gpuThreadsForProcess.get(gpuThreadId) || [];\n }\n handlerState = HandlerState.FINALIZED;\n}\n\nexport interface GPUHandlerReturnData {\n mainGPUThreadTasks: readonly Types.TraceEvents.TraceEventGPUTask[];\n}\n\nexport function data(): GPUHandlerReturnData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('GPU Handler is not finalized');\n }\n return {\n mainGPUThreadTasks: [...mainGPUThreadTasks],\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\n// We track the renderer processes we see in each frame on the way through the trace.\nconst rendererProcessesByFrameId = new Map<\n string,\n Map<Types.TraceEvents.ProcessID, {window: Types.Timing.TraceWindow, frame: Types.TraceEvents.TraceFrame}[]>>();\n\n// We will often want to key data by Frame IDs, and commonly we'll care most\n// about the main frame's ID, so we store and expose that.\nlet mainFrameId: string = '';\nlet mainFrameURL: string = '';\n\nconst framesByProcessId = new Map<Types.TraceEvents.ProcessID, Map<string, Types.TraceEvents.TraceFrame>>();\n\n// We will often want to key data by the browser process, GPU process and top\n// level renderer IDs, so keep a track on those.\nlet browserProcessId: Types.TraceEvents.ProcessID = Types.TraceEvents.ProcessID(-1);\nlet browserThreadId: Types.TraceEvents.ThreadID = Types.TraceEvents.ThreadID(-1);\nlet gpuProcessId: Types.TraceEvents.ProcessID = Types.TraceEvents.ProcessID(-1);\nlet gpuThreadId: Types.TraceEvents.ThreadID = Types.TraceEvents.ThreadID(-1);\nlet viewportRect: DOMRect|null = null;\n\nconst topLevelRendererIds = new Set<Types.TraceEvents.ProcessID>();\nconst traceBounds: Types.Timing.TraceWindow = {\n min: Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY),\n max: Types.Timing.MicroSeconds(Number.NEGATIVE_INFINITY),\n range: Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY),\n};\n\n/**\n * These represent the user navigating. Values such as First Contentful Paint,\n * etc, are relative to the navigation.\n *\n * We store navigation events both by the frame and navigation ID. This means\n * when we need to look them up, we can use whichever ID we have.\n *\n * Note that these Maps will have the same values in them; these are just keyed\n * differently to make look-ups easier.\n *\n * We also additionally maintain an array of only navigations that occured on\n * the main frame. In many places in the UI we only care about highlighting\n * main frame navigations, so calculating this list here is better than\n * filtering either of the below maps over and over again at the UI layer.\n */\nconst navigationsByFrameId = new Map<string, Types.TraceEvents.TraceEventNavigationStart[]>();\nconst navigationsByNavigationId = new Map<string, Types.TraceEvents.TraceEventNavigationStart>();\nconst mainFrameNavigations: Types.TraceEvents.TraceEventNavigationStart[] = [];\n\n// Represents all the threads in the trace, organized by process. This is mostly for internal\n// bookkeeping so that during the finalize pass we can obtain the main and browser thread IDs.\nconst threadsInProcess =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>();\n\nlet traceStartedTimeFromTracingStartedEvent = Types.Timing.MicroSeconds(-1);\nconst eventPhasesOfInterestForTraceBounds = new Set([\n Types.TraceEvents.Phase.BEGIN,\n Types.TraceEvents.Phase.END,\n Types.TraceEvents.Phase.COMPLETE,\n Types.TraceEvents.Phase.INSTANT,\n]);\n\nlet handlerState = HandlerState.UNINITIALIZED;\nexport function reset(): void {\n navigationsByFrameId.clear();\n navigationsByNavigationId.clear();\n mainFrameNavigations.length = 0;\n\n browserProcessId = Types.TraceEvents.ProcessID(-1);\n browserThreadId = Types.TraceEvents.ThreadID(-1);\n gpuProcessId = Types.TraceEvents.ProcessID(-1);\n gpuThreadId = Types.TraceEvents.ThreadID(-1);\n viewportRect = null;\n topLevelRendererIds.clear();\n threadsInProcess.clear();\n rendererProcessesByFrameId.clear();\n framesByProcessId.clear();\n\n traceBounds.min = Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY);\n traceBounds.max = Types.Timing.MicroSeconds(Number.NEGATIVE_INFINITY);\n traceBounds.range = Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY);\n traceStartedTimeFromTracingStartedEvent = Types.Timing.MicroSeconds(-1);\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Meta Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nfunction updateRendererProcessByFrame(\n event: Types.TraceEvents.TraceEventData, frame: Types.TraceEvents.TraceFrame): void {\n const framesInProcessById = Platform.MapUtilities.getWithDefault(framesByProcessId, frame.processId, () => new Map());\n framesInProcessById.set(frame.frame, frame);\n\n const rendererProcessInFrame = Platform.MapUtilities.getWithDefault(\n rendererProcessesByFrameId, frame.frame,\n () => new Map<\n Types.TraceEvents.ProcessID, {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindow}[]>());\n const rendererProcessInfo = Platform.MapUtilities.getWithDefault(rendererProcessInFrame, frame.processId, () => {\n return [];\n });\n const lastProcessData = rendererProcessInfo.at(-1);\n\n // Only store a new entry if the URL changed, otherwise it's just\n // redundant information.\n if (lastProcessData && lastProcessData.frame.url === frame.url) {\n return;\n }\n // For now we store the time of the event as the min. In the finalize we step\n // through each of these windows and update their max and range values.\n rendererProcessInfo.push({\n frame,\n window: {\n min: event.ts,\n max: Types.Timing.MicroSeconds(0),\n range: Types.Timing.MicroSeconds(0),\n },\n });\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Meta Handler is not initialized');\n }\n\n // If there is a timestamp (which meta events do not have), and the event does\n // not end with ::UMA then it, and the event is in the set of valid phases,\n // then it should be included for the purposes of calculating the trace bounds.\n // The UMA events in particular seem to be reported on page unloading, which\n // often extends the bounds of the trace unhelpfully.\n if (event.ts !== 0 && !event.name.endsWith('::UMA') && eventPhasesOfInterestForTraceBounds.has(event.ph)) {\n traceBounds.min = Types.Timing.MicroSeconds(Math.min(event.ts, traceBounds.min));\n const eventDuration = event.dur || Types.Timing.MicroSeconds(0);\n traceBounds.max = Types.Timing.MicroSeconds(Math.max(event.ts + eventDuration, traceBounds.max));\n }\n\n if (Types.TraceEvents.isProcessName(event) &&\n (event.args.name === 'Browser' || event.args.name === 'HeadlessBrowser')) {\n browserProcessId = event.pid;\n return;\n }\n\n if (Types.TraceEvents.isProcessName(event) && (event.args.name === 'Gpu' || event.args.name === 'GPU Process')) {\n gpuProcessId = event.pid;\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name === 'CrGpuMain') {\n gpuThreadId = event.tid;\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name === 'CrBrowserMain') {\n browserThreadId = event.tid;\n }\n\n if (Types.TraceEvents.isTraceEventMainFrameViewport(event) && viewportRect === null) {\n const rectAsArray = event.args.data.viewport_rect;\n const viewportX = rectAsArray[0];\n const viewportY = rectAsArray[1];\n const viewportWidth = rectAsArray[2];\n const viewportHeight = rectAsArray[5];\n viewportRect = new DOMRect(viewportX, viewportY, viewportWidth, viewportHeight);\n }\n\n // The TracingStartedInBrowser event includes the data on which frames are\n // in scope at the start of the trace. We use this to identify the frame with\n // no parent, i.e. the top level frame.\n if (Types.TraceEvents.isTraceEventTracingStartedInBrowser(event)) {\n traceStartedTimeFromTracingStartedEvent = event.ts;\n\n if (!event.args.data) {\n throw new Error('No frames found in trace data');\n }\n\n for (const frame of (event.args.data.frames ?? [])) {\n updateRendererProcessByFrame(event, frame);\n\n if (frame.parent) {\n continue;\n }\n\n mainFrameId = frame.frame;\n mainFrameURL = frame.url;\n topLevelRendererIds.add(frame.processId);\n }\n return;\n }\n\n // FrameCommittedInBrowser events tell us information about each frame\n // and we use these to track how long each individual renderer is active\n // for. We track all renderers here (top level and those in frames), but\n // for convenience we also populate a set of top level renderer IDs.\n if (Types.TraceEvents.isTraceEventFrameCommittedInBrowser(event)) {\n const frame = event.args.data;\n if (!frame) {\n return;\n }\n\n updateRendererProcessByFrame(event, frame);\n\n if (frame.parent) {\n return;\n }\n\n topLevelRendererIds.add(frame.processId);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventCommitLoad(event)) {\n const frameData = event.args.data;\n if (!frameData) {\n return;\n }\n\n const {frame, name, url} = frameData;\n updateRendererProcessByFrame(event, {processId: event.pid, frame, name, url});\n return;\n }\n\n // Track all threads based on the process & thread IDs.\n if (Types.TraceEvents.isThreadName(event)) {\n const threads = Platform.MapUtilities.getWithDefault(threadsInProcess, event.pid, () => new Map());\n threads.set(event.tid, event);\n return;\n }\n\n // Track all navigation events. Note that there can be navigation start events\n // but where the documentLoaderURL is empty. As far as the trace rendering is\n // concerned, these events are noise so we filter them out here.\n if (Types.TraceEvents.isTraceEventNavigationStartWithURL(event) && event.args.data) {\n const navigationId = event.args.data.navigationId;\n if (navigationsByNavigationId.has(navigationId)) {\n throw new Error('Found multiple navigation start events with the same navigation ID.');\n }\n navigationsByNavigationId.set(navigationId, event);\n\n const frameId = event.args.frame;\n const existingFrameNavigations = navigationsByFrameId.get(frameId) || [];\n existingFrameNavigations.push(event);\n navigationsByFrameId.set(frameId, existingFrameNavigations);\n if (frameId === mainFrameId) {\n mainFrameNavigations.push(event);\n }\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Handler is not initialized');\n }\n\n // We try to set the minimum time by finding the event with the smallest\n // timestamp. However, if we also got a timestamp from the\n // TracingStartedInBrowser event, we should always use that.\n // But in some traces (for example, CPU profiles) we do not get that event,\n // hence why we need to check we got a timestamp from it before setting it.\n if (traceStartedTimeFromTracingStartedEvent >= 0) {\n traceBounds.min = traceStartedTimeFromTracingStartedEvent;\n }\n traceBounds.range = Types.Timing.MicroSeconds(traceBounds.max - traceBounds.min);\n\n // If we go from foo.com to example.com we will get a new renderer, and\n // therefore the \"top level renderer\" will have a different PID as it has\n // changed. Here we step through each renderer process and updated its window\n // bounds, such that we end up with the time ranges in the trace for when\n // each particular renderer started and stopped being the main renderer\n // process.\n for (const [, processWindows] of rendererProcessesByFrameId) {\n const processWindowValues = [...processWindows.values()].flat();\n for (let i = 0; i < processWindowValues.length; i++) {\n const currentWindow = processWindowValues[i];\n const nextWindow = processWindowValues[i + 1];\n\n // For the last window we set its max to be positive infinity.\n // TODO: Move the trace bounds handler into meta so we can clamp first and last windows.\n if (!nextWindow) {\n currentWindow.window.max = Types.Timing.MicroSeconds(traceBounds.max);\n currentWindow.window.range = Types.Timing.MicroSeconds(traceBounds.max - currentWindow.window.min);\n } else {\n currentWindow.window.max = Types.Timing.MicroSeconds(nextWindow.window.min - 1);\n currentWindow.window.range = Types.Timing.MicroSeconds(currentWindow.window.max - currentWindow.window.min);\n }\n }\n }\n\n // Frame ids which we didn't register using either the TracingStartedInBrowser or\n // the FrameCommittedInBrowser events are considered noise, so we filter them out, as well\n // as the navigations that belong to such frames.\n for (const [frameId, navigations] of navigationsByFrameId) {\n // The frames in the rendererProcessesByFrameId map come only from the\n // TracingStartedInBrowser and FrameCommittedInBrowser events, so we can use it as point\n // of comparison to determine if a frameId should be discarded.\n if (rendererProcessesByFrameId.has(frameId)) {\n continue;\n }\n navigationsByFrameId.delete(frameId);\n for (const navigation of navigations) {\n if (!navigation.args.data) {\n continue;\n }\n navigationsByNavigationId.delete(navigation.args.data.navigationId);\n }\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\ntype MetaHandlerData = {\n traceBounds: Types.Timing.TraceWindow,\n browserProcessId: Types.TraceEvents.ProcessID,\n browserThreadId: Types.TraceEvents.ThreadID,\n gpuProcessId: Types.TraceEvents.ProcessID,\n gpuThreadId?: Types.TraceEvents.ThreadID,\n viewportRect?: DOMRect,\n navigationsByFrameId: Map<string, Types.TraceEvents.TraceEventNavigationStart[]>,\n navigationsByNavigationId: Map<string, Types.TraceEvents.TraceEventNavigationStart>,\n threadsInProcess:\n Map<Types.TraceEvents.ProcessID,\n Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>,\n mainFrameId: string,\n mainFrameURL: string,\n /**\n * A frame can have multiple renderer processes, at the same time,\n * a renderer process can have multiple URLs. This map tracks the\n * processes active on a given frame, with the time window in which\n * they were active. Because a renderer process might have multiple\n * URLs, each process in each frame has an array of windows, with an\n * entry for each URL it had.\n */\n rendererProcessesByFrame: FrameProcessData,\n topLevelRendererIds: Set<Types.TraceEvents.ProcessID>,\n frameByProcessId: Map<Types.TraceEvents.ProcessID, Map<string, Types.TraceEvents.TraceFrame>>,\n mainFrameNavigations: Types.TraceEvents.TraceEventNavigationStart[],\n};\n\nexport type FrameProcessData =\n Map<string,\n Map<Types.TraceEvents.ProcessID, {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindow}[]>>;\n\nexport function data(): MetaHandlerData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Meta Handler is not finalized');\n }\n\n return {\n traceBounds: {...traceBounds},\n browserProcessId,\n browserThreadId,\n gpuProcessId,\n gpuThreadId: gpuThreadId === Types.TraceEvents.ThreadID(-1) ? undefined : gpuThreadId,\n viewportRect: viewportRect || undefined,\n mainFrameId,\n mainFrameURL,\n navigationsByFrameId: new Map(navigationsByFrameId),\n navigationsByNavigationId: new Map(navigationsByNavigationId),\n threadsInProcess: new Map(threadsInProcess),\n rendererProcessesByFrame: new Map(rendererProcessesByFrameId),\n topLevelRendererIds: new Set(topLevelRendererIds),\n frameByProcessId: new Map(framesByProcessId),\n mainFrameNavigations: [...mainFrameNavigations],\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as SamplesIntegrator from './SamplesIntegrator.js';\nexport * as Timing from './Timing.js';\nexport * as Trace from './Trace.js';\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Root from '../../../core/root/root.js';\nimport type * as Protocol from '../../../generated/protocol.js';\nimport * as Common from '../../../core/common/common.js';\nimport type * as CPUProfile from '../../cpu_profile/cpu_profile.js';\nimport * as Types from '../types/types.js';\nimport {millisecondsToMicroseconds} from './Timing.js';\nimport {mergeEventsInOrder} from './Trace.js';\n\n/**\n * This is a helpers that integrates CPU profiling data coming in the\n * shape of samples, with trace events. Samples indicate what the JS\n * stack trace looked at a given point in time, but they don't have\n * duration. The SamplesIntegrator task is to make an approximation\n * of what the duration of each JS call was, given the sample data and\n * given the trace events profiled during that time. At the end of its\n * execution, the SamplesIntegrator returns an array of ProfileCalls\n * (under SamplesIntegrator::buildProfileCalls()), which\n * represent JS calls, with a call frame and duration. These calls have\n * the shape of a complete trace events and can be treated as flame\n * chart entries in the timeline.\n *\n * The approach to build the profile calls consists in tracking the\n * current stack as the following events happen (in order):\n * 1. A sample was done.\n * 2. A trace event started.\n * 3. A trace event ended.\n * Depending on the event and on the data that's coming with it the\n * stack is updated by adding or removing JS calls to it and updating\n * the duration of the calls in the tracking stack.\n *\n * note: Although this approach has been implemented since long ago, and\n * is relatively efficent (adds a complexity over the trace parsing of\n * O(n) where n is the number of samples) it has proven to be faulty.\n * It might be worthwhile experimenting with improvements or with a\n * completely different approach. Improving the approach is tracked in\n * crbug.com/1417439\n */\nexport class SamplesIntegrator {\n /**\n * The result of runing the samples integrator. Holds the JS calls\n * with their approximated duration after integrating samples into the\n * trace event tree.\n */\n #constructedProfileCalls: Types.TraceEvents.TraceEventSyntheticProfileCall[] = [];\n /**\n * tracks the state of the JS stack at each point in time to update\n * the profile call durations as new events arrive. This doesn't only\n * happen with new profile calls (in which case we would compare the\n * stack in them) but also with trace events (in which case we would\n * update the duration of the events we are tracking at the moment).\n */\n #currentJSStack: Types.TraceEvents.TraceEventSyntheticProfileCall[] = [];\n /**\n * Process holding the CPU profile and trace events.\n */\n #processId: Types.TraceEvents.ProcessID;\n /**\n * Thread holding the CPU profile and trace events.\n */\n #threadId: Types.TraceEvents.ThreadID;\n /**\n * Tracks the depth of the JS stack at the moment a trace event starts\n * or ends. It is assumed that for the duration of a trace event, the\n * JS stack's depth cannot decrease, since JS calls that started\n * before a trace event cannot end during the trace event. So as trace\n * events arrive, we store the \"locked\" amount of JS frames that were\n * in the stack before the event came.\n */\n #lockedJsStackDepth: number[] = [];\n /**\n * Used to keep track when samples should be integrated even if they\n * are not children of invocation trace events. This is useful in\n * cases where we can be missing the start of JS invocation events if\n * we start tracing half-way through.\n */\n #fakeJSInvocation = false;\n /**\n * The parsed CPU profile, holding the tree hierarchy of JS frames and\n * the sample data.\n */\n #profileModel: CPUProfile.CPUProfileDataModel.CPUProfileDataModel;\n /**\n * Because GC nodes don't have a stack, we artificially add a stack to\n * them which corresponds to that of the previous sample. This map\n * tracks which node is used for the stack of a GC call.\n */\n #nodeForGC = new Map<Types.TraceEvents.TraceEventSyntheticProfileCall, CPUProfile.ProfileTreeModel.ProfileNode>();\n constructor(\n profileModel: CPUProfile.CPUProfileDataModel.CPUProfileDataModel, pid: Types.TraceEvents.ProcessID,\n tid: Types.TraceEvents.ThreadID) {\n this.#profileModel = profileModel;\n this.#threadId = tid;\n this.#processId = pid;\n }\n\n buildProfileCalls(traceEvents: Types.TraceEvents.TraceEventData[]):\n Types.TraceEvents.TraceEventSyntheticProfileCall[] {\n const mergedEvents = mergeEventsInOrder(traceEvents, this.callsFromProfileSamples());\n const stack = [];\n for (let i = 0; i < mergedEvents.length; i++) {\n const event = mergedEvents[i];\n if (stack.length === 0) {\n if (Types.TraceEvents.isProfileCall(event)) {\n this.#onProfileCall(event);\n continue;\n }\n stack.push(event);\n this.#onTraceEventStart(event);\n continue;\n }\n\n const parentEvent = stack.at(-1);\n if (parentEvent === undefined) {\n continue;\n }\n const begin = event.ts;\n const parentBegin = parentEvent.ts;\n const parentDuration = parentEvent.dur || 0;\n const parentEnd = parentBegin + parentDuration;\n\n const startsAfterParent = begin >= parentEnd;\n if (startsAfterParent) {\n this.#onTraceEventEnd(parentEvent);\n stack.pop();\n i--;\n continue;\n }\n if (Types.TraceEvents.isProfileCall(event)) {\n this.#onProfileCall(event, parentEvent);\n continue;\n }\n this.#onTraceEventStart(event);\n stack.push(event);\n }\n while (stack.length) {\n const last = stack.pop();\n if (last) {\n this.#onTraceEventEnd(last);\n }\n }\n return this.#constructedProfileCalls;\n }\n\n #onTraceEventStart(event: Types.TraceEvents.TraceEventData): void {\n // Because instant trace events have no duration, they don't provide\n // useful information for possible changes in the duration of calls\n // in the JS stack.\n if (event.ph === Types.TraceEvents.Phase.INSTANT) {\n return;\n }\n // Top level events cannot be nested into JS frames so we reset\n // the stack when we find one.\n if (event.name === Types.TraceEvents.KnownEventName.RunMicrotasks ||\n event.name === Types.TraceEvents.KnownEventName.RunTask) {\n this.#lockedJsStackDepth = [];\n this.#truncateJSStack(0, event.ts);\n this.#fakeJSInvocation = false;\n }\n\n if (this.#fakeJSInvocation) {\n this.#truncateJSStack(this.#lockedJsStackDepth.pop() || 0, event.ts);\n this.#fakeJSInvocation = false;\n }\n this.#extractStackTrace(event);\n // Keep track of the call frames in the stack before the event\n // happened. For the duration of this event, these frames cannot\n // change (none can be terminated before this event finishes).\n //\n // Also, every frame that is opened after this event, is considered\n // to be a descendant of the event. So once the event finishes, the\n // frames that were opened after it, need to be closed (see\n // onEndEvent).\n //\n // TODO(crbug.com/1417439):\n // The assumption that every frame opened after an event is a\n // descendant of the event is incorrect. For example, a JS call that\n // parents a trace event might have been sampled after the event was\n // dispatched. In this case the JS call would be discarded if this\n // event isn't an invocation event, otherwise the call will be\n // considered a child of the event. In both cases, the result would\n // be incorrect.\n this.#lockedJsStackDepth.push(this.#currentJSStack.length);\n }\n\n #onProfileCall(event: Types.TraceEvents.TraceEventSyntheticProfileCall, parent?: Types.TraceEvents.TraceEventData):\n void {\n if ((parent && SamplesIntegrator.isJSInvocationEvent(parent)) || this.#fakeJSInvocation) {\n this.#extractStackTrace(event);\n } else if (Types.TraceEvents.isProfileCall(event) && this.#currentJSStack.length === 0) {\n // Force JS Samples to show up even if we are not inside a JS\n // invocation event, because we can be missing the start of JS\n // invocation events if we start tracing half-way through. Pretend\n // we have a top-level JS invocation event.\n this.#fakeJSInvocation = true;\n const stackDepthBefore = this.#currentJSStack.length;\n this.#extractStackTrace(event);\n this.#lockedJsStackDepth.push(stackDepthBefore);\n }\n }\n\n #onTraceEventEnd(event: Types.TraceEvents.TraceEventData): void {\n // Because the event has ended, any frames that happened after\n // this event are terminated. Frames that are ancestors to this\n // event are extended to cover its ending.\n const endTime = Types.Timing.MicroSeconds(event.ts + (event.dur || 0));\n this.#truncateJSStack(this.#lockedJsStackDepth.pop() || 0, endTime);\n }\n\n /**\n * Builds the initial calls with no duration from samples. Their\n * purpose is to be merged with the trace event array being parsed so\n * that they can be traversed in order with them and their duration\n * can be updated as the SampleIntegrator callbacks are invoked.\n */\n callsFromProfileSamples(): Types.TraceEvents.TraceEventSyntheticProfileCall[] {\n const samples = this.#profileModel.samples;\n const timestamps = this.#profileModel.timestamps;\n if (!samples) {\n return [];\n }\n const calls: Types.TraceEvents.TraceEventSyntheticProfileCall[] = [];\n let prevNode;\n for (let i = 0; i < samples.length; i++) {\n const node = this.#profileModel.nodeByIndex(i);\n const timestamp = millisecondsToMicroseconds(Types.Timing.MilliSeconds(timestamps[i]));\n if (!node) {\n continue;\n }\n const call = SamplesIntegrator.makeProfileCall(node, timestamp, this.#processId, this.#threadId);\n calls.push(call);\n if (node.id === this.#profileModel.gcNode?.id && prevNode) {\n // GC samples have no stack, so we just put GC node on top of the\n // last recorded sample. Cache the previous sample for future\n // reference.\n this.#nodeForGC.set(call, prevNode);\n continue;\n }\n prevNode = node;\n }\n return calls;\n }\n\n #getStackTraceFromProfileCall(profileCall: Types.TraceEvents.TraceEventSyntheticProfileCall):\n Types.TraceEvents.TraceEventSyntheticProfileCall[] {\n let node = this.#profileModel.nodeById(profileCall.nodeId);\n const isGarbageCollection = Boolean(node?.id === this.#profileModel.gcNode?.id);\n if (isGarbageCollection) {\n // Because GC don't have a stack, we use the stack of the previous\n // sample.\n node = this.#nodeForGC.get(profileCall) || null;\n }\n if (!node) {\n return [];\n }\n // `node.depth` is 0 based, so to set the size of the array we need\n // to add 1 to its value.\n const callFrames =\n new Array<Types.TraceEvents.TraceEventSyntheticProfileCall>(node.depth + 1 + Number(isGarbageCollection));\n // Add the stack trace in reverse order (bottom first).\n let i = callFrames.length - 1;\n if (isGarbageCollection) {\n callFrames[i--] = profileCall;\n }\n while (node) {\n callFrames[i--] = SamplesIntegrator.makeProfileCall(node, profileCall.ts, this.#processId, this.#threadId);\n node = node.parent;\n }\n return callFrames;\n }\n\n /**\n * Update tracked stack using this event's call stack.\n */\n #extractStackTrace(event: Types.TraceEvents.TraceEventData): void {\n const stackTrace =\n Types.TraceEvents.isProfileCall(event) ? this.#getStackTraceFromProfileCall(event) : this.#currentJSStack;\n SamplesIntegrator.filterStackFrames(stackTrace);\n\n const endTime = event.ts + (event.dur || 0);\n const minFrames = Math.min(stackTrace.length, this.#currentJSStack.length);\n let i;\n // Merge a sample's stack frames with the stack frames we have\n // so far if we detect they are equivalent.\n // Graphically\n // This:\n // Current stack trace Sample\n // [-------A------] [A]\n // [-------B------] [B]\n // [-------C------] [C]\n // ^ t = x1 ^ t = x2\n\n // Becomes this:\n // New stack trace after merge\n // [--------A-------]\n // [--------B-------]\n // [--------C-------]\n // ^ t = x2\n for (i = this.#lockedJsStackDepth.at(-1) || 0; i < minFrames; ++i) {\n const newFrame = stackTrace[i].callFrame;\n const oldFrame = this.#currentJSStack[i].callFrame;\n if (!SamplesIntegrator.framesAreEqual(newFrame, oldFrame)) {\n break;\n }\n // Scoot the right edge of this callFrame to the right\n this.#currentJSStack[i].dur =\n Types.Timing.MicroSeconds(Math.max(this.#currentJSStack[i].dur || 0, endTime - this.#currentJSStack[i].ts));\n }\n\n // If there are call frames in the sample that differ with the stack\n // we have, update the stack, but keeping the common frames in place\n // Graphically\n // This:\n // Current stack trace Sample\n // [-------A------] [A]\n // [-------B------] [B]\n // [-------C------] [C]\n // [-------D------] [E]\n // ^ t = x1 ^ t = x2\n // Becomes this:\n // New stack trace after merge\n // [--------A-------]\n // [--------B-------]\n // [--------C-------]\n // [E]\n // ^ t = x2\n this.#truncateJSStack(i, event.ts);\n\n for (; i < stackTrace.length; ++i) {\n const call = stackTrace[i];\n this.#currentJSStack.push(call);\n if (call.nodeId === this.#profileModel.programNode?.id || call.nodeId === this.#profileModel.root?.id ||\n call.nodeId === this.#profileModel.idleNode?.id) {\n // Skip (root), (program) and (idle) frames, since this are not\n // relevant for web profiling and we don't want to show them in\n // the timeline.\n continue;\n }\n this.#constructedProfileCalls.push(call);\n }\n }\n\n /**\n * When a call stack that differs from the one we are tracking has\n * been detected in the samples, the latter is \"truncated\" by\n * setting the ending time of its call frames and removing the top\n * call frames that aren't shared with the new call stack. This way,\n * we can update the tracked stack with the new call frames on top.\n * @param depth the amount of call frames from bottom to top that\n * should be kept in the tracking stack trace. AKA amount of shared\n * call frames between two stacks.\n * @param time the new end of the call frames in the stack.\n */\n #truncateJSStack(depth: number, time: Types.Timing.MicroSeconds): void {\n if (this.#lockedJsStackDepth.length) {\n const lockedDepth = this.#lockedJsStackDepth.at(-1);\n if (lockedDepth && depth < lockedDepth) {\n console.error(`Child stack is shallower (${depth}) than the parent stack (${lockedDepth}) at ${time}`);\n depth = lockedDepth;\n }\n }\n if (this.#currentJSStack.length < depth) {\n console.error(`Trying to truncate higher than the current stack size at ${time}`);\n depth = this.#currentJSStack.length;\n }\n for (let k = 0; k < this.#currentJSStack.length; ++k) {\n this.#currentJSStack[k].dur = Types.Timing.MicroSeconds(Math.max(time - this.#currentJSStack[k].ts, 0));\n }\n this.#currentJSStack.length = depth;\n }\n\n /**\n * Generally, before JS is executed, a trace event is dispatched that\n * parents the JS calls. These we call \"invocation\" events. This\n * function determines if an event is one of such.\n */\n static isJSInvocationEvent(event: Types.TraceEvents.TraceEventData): boolean {\n switch (event.name) {\n case Types.TraceEvents.KnownEventName.RunMicrotasks:\n case Types.TraceEvents.KnownEventName.FunctionCall:\n case Types.TraceEvents.KnownEventName.EvaluateScript:\n case Types.TraceEvents.KnownEventName.EvaluateModule:\n case Types.TraceEvents.KnownEventName.EventDispatch:\n case Types.TraceEvents.KnownEventName.V8Execute:\n return true;\n }\n // Also consider any new v8 trace events. (eg 'V8.RunMicrotasks' and 'v8.run')\n if (event.name.startsWith('v8') || event.name.startsWith('V8')) {\n return true;\n }\n return false;\n }\n\n static framesAreEqual(frame1: Protocol.Runtime.CallFrame, frame2: Protocol.Runtime.CallFrame): boolean {\n return frame1.scriptId === frame2.scriptId && frame1.functionName === frame2.functionName &&\n frame1.lineNumber === frame2.lineNumber;\n }\n\n static showNativeName(name: string): boolean {\n try {\n // Querying for unregistered experiments will error on debug\n // builds.\n const showRuntimeCallStats = Root.Runtime.experiments.isEnabled('timelineV8RuntimeCallStats');\n return showRuntimeCallStats && Boolean(SamplesIntegrator.nativeGroup(name));\n } catch (error) {\n return false;\n }\n }\n\n static nativeGroup(nativeName: string): 'Parse'|'Compile'|null {\n if (nativeName.startsWith('Parse')) {\n return 'Parse';\n }\n if (nativeName.startsWith('Compile') || nativeName.startsWith('Recompile')) {\n return 'Compile';\n }\n return null;\n }\n\n static isNativeRuntimeFrame(frame: Protocol.Runtime.CallFrame): boolean {\n return frame.url === 'native V8Runtime';\n }\n\n static filterStackFrames(stack: Types.TraceEvents.TraceEventSyntheticProfileCall[]): void {\n let showAllEvents = false;\n try {\n // Querying for unregistered experiments will error on debug\n // builds.\n showAllEvents = Root.Runtime.experiments.isEnabled('timelineShowAllEvents');\n } catch (_err) {\n }\n const showNativeFunctions = Common.Settings.Settings.hasInstance() &&\n Common.Settings.Settings.instance().moduleSetting('showNativeFunctionsInJSProfile').get();\n if (showAllEvents) {\n return;\n }\n let previousNativeFrameName: string|null = null;\n let j = 0;\n for (let i = 0; i < stack.length; ++i) {\n const frame = stack[i].callFrame;\n const url = frame.url;\n const isNativeFrame = url && url.startsWith('native ');\n if (!showNativeFunctions && isNativeFrame) {\n continue;\n }\n const nativeRuntimeFrame = SamplesIntegrator.isNativeRuntimeFrame(frame);\n if (nativeRuntimeFrame && !SamplesIntegrator.showNativeName(frame.functionName)) {\n continue;\n }\n const nativeFrameName = nativeRuntimeFrame ? SamplesIntegrator.nativeGroup(frame.functionName) : null;\n if (previousNativeFrameName && previousNativeFrameName === nativeFrameName) {\n continue;\n }\n previousNativeFrameName = nativeFrameName;\n stack[j++] = stack[i];\n }\n stack.length = j;\n }\n\n static makeProfileCall(\n node: CPUProfile.ProfileTreeModel.ProfileNode, ts: Types.Timing.MicroSeconds, pid: Types.TraceEvents.ProcessID,\n tid: Types.TraceEvents.ThreadID): Types.TraceEvents.TraceEventSyntheticProfileCall {\n return {\n cat: '',\n name: 'ProfileCall',\n nodeId: node.id,\n ph: Types.TraceEvents.Phase.COMPLETE,\n pid,\n tid,\n ts,\n dur: Types.Timing.MicroSeconds(0),\n selfTime: Types.Timing.MicroSeconds(0),\n callFrame: node.callFrame,\n };\n }\n}\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../platform/platform.js';\n\nconst queryParamsObject = new URLSearchParams(location.search);\n\nlet runtimePlatform = '';\n\nlet runtimeInstance: Runtime|undefined;\n\nexport function getRemoteBase(location: string = self.location.toString()): {\n base: string,\n version: string,\n}|null {\n const url = new URL(location);\n const remoteBase = url.searchParams.get('remoteBase');\n if (!remoteBase) {\n return null;\n }\n\n const version = /\\/serve_file\\/(@[0-9a-zA-Z]+)\\/?$/.exec(remoteBase);\n if (!version) {\n return null;\n }\n\n return {base: `devtools://devtools/remote/serve_file/${version[1]}/`, version: version[1]};\n}\n\nexport class Runtime {\n private constructor() {\n }\n\n static instance(opts: {\n forceNew: boolean|null,\n }|undefined = {forceNew: null}): Runtime {\n const {forceNew} = opts;\n if (!runtimeInstance || forceNew) {\n runtimeInstance = new Runtime();\n }\n\n return runtimeInstance;\n }\n\n static removeInstance(): void {\n runtimeInstance = undefined;\n }\n\n static queryParam(name: string): string|null {\n return queryParamsObject.get(name);\n }\n\n static setQueryParamForTesting(name: string, value: string): void {\n queryParamsObject.set(name, value);\n }\n\n static experimentsSetting(): {\n [x: string]: boolean,\n } {\n try {\n return JSON.parse(\n self.localStorage && self.localStorage['experiments'] ? self.localStorage['experiments'] : '{}') as {\n [x: string]: boolean,\n };\n } catch (e) {\n console.error('Failed to parse localStorage[\\'experiments\\']');\n return {};\n }\n }\n\n static setPlatform(platform: string): void {\n runtimePlatform = platform;\n }\n\n static platform(): string {\n return runtimePlatform;\n }\n\n static isDescriptorEnabled(descriptor: {\n experiment: ((string | undefined)|null),\n condition: ((string | undefined)|null),\n }): boolean {\n const activatorExperiment = descriptor['experiment'];\n if (activatorExperiment === '*') {\n return true;\n }\n if (activatorExperiment && activatorExperiment.startsWith('!') &&\n experiments.isEnabled(activatorExperiment.substring(1))) {\n return false;\n }\n if (activatorExperiment && !activatorExperiment.startsWith('!') && !experiments.isEnabled(activatorExperiment)) {\n return false;\n }\n const condition = descriptor['condition'];\n if (condition && !condition.startsWith('!') && !Runtime.queryParam(condition)) {\n return false;\n }\n if (condition && condition.startsWith('!') && Runtime.queryParam(condition.substring(1))) {\n return false;\n }\n return true;\n }\n\n loadLegacyModule(modulePath: string): Promise<void> {\n return import(`../../${modulePath}`);\n }\n}\n\nexport interface Option {\n title: string;\n value: string|boolean;\n raw?: boolean;\n text?: string;\n}\n\nexport class ExperimentsSupport {\n #experiments: Experiment[];\n #experimentNames: Set<string>;\n #enabledTransiently: Set<string>;\n readonly #enabledByDefault: Set<string>;\n readonly #serverEnabled: Set<string>;\n // Experiments in this set won't be shown to the user\n readonly #nonConfigurable: Set<string>;\n constructor() {\n this.#experiments = [];\n this.#experimentNames = new Set();\n this.#enabledTransiently = new Set();\n this.#enabledByDefault = new Set();\n this.#serverEnabled = new Set();\n this.#nonConfigurable = new Set();\n }\n\n allConfigurableExperiments(): Experiment[] {\n const result = [];\n for (const experiment of this.#experiments) {\n if (!this.#enabledTransiently.has(experiment.name) && !this.#nonConfigurable.has(experiment.name)) {\n result.push(experiment);\n }\n }\n return result;\n }\n\n private setExperimentsSetting(value: Object): void {\n if (!self.localStorage) {\n return;\n }\n self.localStorage['experiments'] = JSON.stringify(value);\n }\n\n register(\n experimentName: string, experimentTitle: string, unstable?: boolean, docLink?: string,\n feedbackLink?: string): void {\n Platform.DCHECK(\n () => !this.#experimentNames.has(experimentName), 'Duplicate registration of experiment ' + experimentName);\n this.#experimentNames.add(experimentName);\n this.#experiments.push(new Experiment(\n this, experimentName, experimentTitle, Boolean(unstable),\n docLink as Platform.DevToolsPath.UrlString ?? Platform.DevToolsPath.EmptyUrlString,\n feedbackLink as Platform.DevToolsPath.UrlString ?? Platform.DevToolsPath.EmptyUrlString));\n }\n\n isEnabled(experimentName: string): boolean {\n this.checkExperiment(experimentName);\n // Check for explicitly disabled #experiments first - the code could call setEnable(false) on the experiment enabled\n // by default and we should respect that.\n if (Runtime.experimentsSetting()[experimentName] === false) {\n return false;\n }\n if (this.#enabledTransiently.has(experimentName) || this.#enabledByDefault.has(experimentName)) {\n return true;\n }\n if (this.#serverEnabled.has(experimentName)) {\n return true;\n }\n\n return Boolean(Runtime.experimentsSetting()[experimentName]);\n }\n\n setEnabled(experimentName: string, enabled: boolean): void {\n this.checkExperiment(experimentName);\n const experimentsSetting = Runtime.experimentsSetting();\n experimentsSetting[experimentName] = enabled;\n this.setExperimentsSetting(experimentsSetting);\n }\n\n enableExperimentsTransiently(experimentNames: string[]): void {\n for (const experimentName of experimentNames) {\n this.checkExperiment(experimentName);\n this.#enabledTransiently.add(experimentName);\n }\n }\n\n enableExperimentsByDefault(experimentNames: string[]): void {\n for (const experimentName of experimentNames) {\n this.checkExperiment(experimentName);\n this.#enabledByDefault.add(experimentName);\n }\n }\n\n setServerEnabledExperiments(experimentNames: string[]): void {\n for (const experiment of experimentNames) {\n this.checkExperiment(experiment);\n this.#serverEnabled.add(experiment);\n }\n }\n\n setNonConfigurableExperiments(experimentNames: string[]): void {\n for (const experiment of experimentNames) {\n this.checkExperiment(experiment);\n this.#nonConfigurable.add(experiment);\n }\n }\n\n enableForTest(experimentName: string): void {\n this.checkExperiment(experimentName);\n this.#enabledTransiently.add(experimentName);\n }\n\n disableForTest(experimentName: string): void {\n this.checkExperiment(experimentName);\n this.#enabledTransiently.delete(experimentName);\n }\n\n clearForTest(): void {\n this.#experiments = [];\n this.#experimentNames.clear();\n this.#enabledTransiently.clear();\n this.#enabledByDefault.clear();\n this.#serverEnabled.clear();\n }\n\n cleanUpStaleExperiments(): void {\n const experimentsSetting = Runtime.experimentsSetting();\n const cleanedUpExperimentSetting: {\n [x: string]: boolean,\n } = {};\n for (const {name: experimentName} of this.#experiments) {\n if (experimentsSetting.hasOwnProperty(experimentName)) {\n const isEnabled = experimentsSetting[experimentName];\n if (isEnabled || this.#enabledByDefault.has(experimentName)) {\n cleanedUpExperimentSetting[experimentName] = isEnabled;\n }\n }\n }\n this.setExperimentsSetting(cleanedUpExperimentSetting);\n }\n\n private checkExperiment(experimentName: string): void {\n Platform.DCHECK(() => this.#experimentNames.has(experimentName), 'Unknown experiment ' + experimentName);\n }\n}\n\nexport class Experiment {\n name: string;\n title: string;\n unstable: boolean;\n docLink?: Platform.DevToolsPath.UrlString;\n readonly feedbackLink?: Platform.DevToolsPath.UrlString;\n readonly #experiments: ExperimentsSupport;\n constructor(\n experiments: ExperimentsSupport, name: string, title: string, unstable: boolean,\n docLink: Platform.DevToolsPath.UrlString, feedbackLink: Platform.DevToolsPath.UrlString) {\n this.name = name;\n this.title = title;\n this.unstable = unstable;\n this.docLink = docLink;\n this.feedbackLink = feedbackLink;\n this.#experiments = experiments;\n }\n\n isEnabled(): boolean {\n return this.#experiments.isEnabled(this.name);\n }\n\n setEnabled(enabled: boolean): void {\n this.#experiments.setEnabled(this.name, enabled);\n }\n}\n\n// This must be constructed after the query parameters have been parsed.\nexport const experiments = new ExperimentsSupport();\n\n// TODO(crbug.com/1167717): Make this a const enum again\n// eslint-disable-next-line rulesdir/const_enum\nexport enum ExperimentName {\n CAPTURE_NODE_CREATION_STACKS = 'captureNodeCreationStacks',\n CSS_OVERVIEW = 'cssOverview',\n LIVE_HEAP_PROFILE = 'liveHeapProfile',\n DEVELOPER_RESOURCES_VIEW = 'developerResourcesView',\n CSP_VIOLATIONS_VIEW = 'cspViolationsView',\n WASM_DWARF_DEBUGGING = 'wasmDWARFDebugging',\n ALL = '*',\n PROTOCOL_MONITOR = 'protocolMonitor',\n WEBAUTHN_PANE = 'webauthnPane',\n FULL_ACCESSIBILITY_TREE = 'fullAccessibilityTree',\n PRECISE_CHANGES = 'preciseChanges',\n STYLES_PANE_CSS_CHANGES = 'stylesPaneCSSChanges',\n HEADER_OVERRIDES = 'headerOverrides',\n EYEDROPPER_COLOR_PICKER = 'eyedropperColorPicker',\n INSTRUMENTATION_BREAKPOINTS = 'instrumentationBreakpoints',\n AUTHORED_DEPLOYED_GROUPING = 'authoredDeployedGrouping',\n IMPORTANT_DOM_PROPERTIES = 'importantDOMProperties',\n JUST_MY_CODE = 'justMyCode',\n PRELOADING_STATUS_PANEL = 'preloadingStatusPanel',\n DISABLE_COLOR_FORMAT_SETTING = 'disableColorFormatSetting',\n TIMELINE_AS_CONSOLE_PROFILE_RESULT_PANEL = 'timelineAsConsoleProfileResultPanel',\n OUTERMOST_TARGET_SELECTOR = 'outermostTargetSelector',\n JS_PROFILER_TEMP_ENABLE = 'jsProfilerTemporarilyEnable',\n HIGHLIGHT_ERRORS_ELEMENTS_PANEL = 'highlightErrorsElementsPanel',\n SET_ALL_BREAKPOINTS_EAGERLY = 'setAllBreakpointsEagerly',\n SELF_XSS_WARNING = 'selfXssWarning',\n USE_SOURCE_MAP_SCOPES = 'useSourceMapScopes',\n STORAGE_BUCKETS_TREE = 'storageBucketsTree',\n DELETE_OVERRIDES_TEMP_ENABLE = 'deleteOverridesTemporarilyEnable',\n}\n\n// TODO(crbug.com/1167717): Make this a const enum again\n// eslint-disable-next-line rulesdir/const_enum\nexport enum ConditionName {\n CAN_DOCK = 'can_dock',\n NOT_SOURCES_HIDE_ADD_FOLDER = '!sources.hide_add_folder',\n}\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nconst BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst BASE64_CODES = new Uint8Array(123);\nfor (let index = 0; index < BASE64_CHARS.length; ++index) {\n BASE64_CODES[BASE64_CHARS.charCodeAt(index)] = index;\n}\n\n/**\n * Decodes Base64-encoded data from a string without performing any kind of checking.\n */\nexport function decode(input: string): ArrayBuffer {\n let bytesLength = ((input.length * 3) / 4) >>> 0;\n if (input.charCodeAt(input.length - 2) === 0x3d /* '=' */) {\n bytesLength -= 2;\n } else if (input.charCodeAt(input.length - 1) === 0x3d /* '=' */) {\n bytesLength -= 1;\n }\n\n const bytes = new Uint8Array(bytesLength);\n for (let index = 0, offset = 0; index < input.length; index += 4) {\n const a = BASE64_CODES[input.charCodeAt(index + 0)];\n const b = BASE64_CODES[input.charCodeAt(index + 1)];\n const c = BASE64_CODES[input.charCodeAt(index + 2)];\n const d = BASE64_CODES[input.charCodeAt(index + 3)];\n bytes[offset++] = (a << 2) | (b >> 4);\n bytes[offset++] = ((b & 0x0f) << 4) | (c >> 2);\n bytes[offset++] = ((c & 0x03) << 6) | (d & 0x3f);\n }\n return bytes.buffer;\n}\n", "// Copyright 2016 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport class CharacterIdMap<T> {\n readonly #elementToCharacter: Map<T, string>;\n readonly #characterToElement: Map<string, T>;\n #charCode: number;\n\n constructor() {\n this.#elementToCharacter = new Map();\n this.#characterToElement = new Map();\n this.#charCode = 33;\n }\n\n toChar(object: T): string {\n let character = this.#elementToCharacter.get(object);\n if (!character) {\n if (this.#charCode >= 0xFFFF) {\n throw new Error('CharacterIdMap ran out of capacity!');\n }\n character = String.fromCharCode(this.#charCode++);\n this.#elementToCharacter.set(object, character);\n this.#characterToElement.set(character, object);\n }\n return character;\n }\n\n fromChar(character: string): T|null {\n const object = this.#characterToElement.get(character);\n if (object === undefined) {\n return null;\n }\n return object;\n }\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/**\n * Implementation of this module and all the tests are heavily influenced by\n * https://source.chromium.org/chromium/chromium/src/+/main:ui/gfx/color_conversions.cc\n */\n\n// https://en.wikipedia.org/wiki/CIELAB_color_space#Converting_between_CIELAB_and_CIEXYZ_coordinates\nconst D50_X = 0.9642;\nconst D50_Y = 1.0;\nconst D50_Z = 0.8251;\n\ntype Array3x3 = [\n [number, number, number],\n [number, number, number],\n [number, number, number],\n];\n\nclass Vector3 {\n values: [number, number, number] = [0, 0, 0];\n constructor(values?: [number, number, number]) {\n if (values) {\n this.values = values;\n }\n }\n}\n\nclass Matrix3x3 {\n values: Array3x3 = [\n [0, 0, 0],\n [0, 0, 0],\n [0, 0, 0],\n ];\n\n constructor(values?: Array3x3) {\n if (values) {\n this.values = values;\n }\n }\n\n multiply(other: Vector3): Vector3 {\n const dst = new Vector3();\n for (let row = 0; row < 3; ++row) {\n dst.values[row] = this.values[row][0] * other.values[0] + this.values[row][1] * other.values[1] +\n this.values[row][2] * other.values[2];\n }\n return dst;\n }\n}\n\n// A transfer function mapping encoded values to linear values,\n// represented by this 7-parameter piecewise function:\n//\n// linear = sign(encoded) * (c*|encoded| + f) , 0 <= |encoded| < d\n// = sign(encoded) * ((a*|encoded| + b)^g + e), d <= |encoded|\n//\n// (A simple gamma transfer function sets g to gamma and a to 1.)\nclass TransferFunction {\n g: number;\n a: number;\n b: number;\n c: number;\n d: number;\n e: number;\n f: number;\n\n constructor(g: number, a: number, b: number = 0, c: number = 0, d: number = 0, e: number = 0, f: number = 0) {\n this.g = g;\n this.a = a;\n this.b = b;\n this.c = c;\n this.d = d;\n this.e = e;\n this.f = f;\n }\n\n eval(val: number): number {\n const sign = val < 0 ? -1.0 : 1.0;\n const abs = val * sign;\n\n // 0 <= |encoded| < d path\n if (abs < this.d) {\n return sign * (this.c * abs + this.f);\n }\n\n // d <= |encoded| path\n return sign * (Math.pow(this.a * abs + this.b, this.g) + this.e);\n }\n}\n\nconst NAMED_TRANSFER_FN = {\n sRGB: new TransferFunction(2.4, (1 / 1.055), (0.055 / 1.055), (1 / 12.92), 0.04045, 0.0, 0.0),\n sRGB_INVERSE: new TransferFunction(0.416667, 1.13728, -0, 12.92, 0.0031308, -0.0549698, -0),\n\n proPhotoRGB: new TransferFunction(1.8, 1),\n proPhotoRGB_INVERSE: new TransferFunction(0.555556, 1, -0, 0, 0, 0, 0),\n\n k2Dot2: new TransferFunction(2.2, 1.0),\n k2Dot2_INVERSE: new TransferFunction(0.454545, 1),\n\n rec2020: new TransferFunction(2.22222, 0.909672, 0.0903276, 0.222222, 0.0812429, 0, 0),\n rec2020_INVERSE: new TransferFunction(0.45, 1.23439, -0, 4.5, 0.018054, -0.0993195, -0),\n};\n\nconst NAMED_GAMUTS = {\n sRGB: new Matrix3x3([\n [0.436065674, 0.385147095, 0.143066406],\n [0.222488403, 0.716873169, 0.060607910],\n [0.013916016, 0.097076416, 0.714096069],\n ]),\n sRGB_INVERSE: new Matrix3x3([\n [3.134112151374599, -1.6173924597114966, -0.4906334036481285],\n [-0.9787872938826594, 1.9162795854799963, 0.0334547139520088],\n [0.07198304248352326, -0.2289858493321844, 1.4053851325241447],\n ]),\n displayP3: new Matrix3x3([\n [0.515102, 0.291965, 0.157153],\n [0.241182, 0.692236, 0.0665819],\n [-0.00104941, 0.0418818, 0.784378],\n ]),\n displayP3_INVERSE: new Matrix3x3([\n [2.404045155982687, -0.9898986932663839, -0.3976317191366333],\n [-0.8422283799266768, 1.7988505115115485, 0.016048170293157416],\n [0.04818705979712955, -0.09737385156228891, 1.2735066448052303],\n ]),\n adobeRGB: new Matrix3x3([\n [0.60974, 0.20528, 0.14919],\n [0.31111, 0.62567, 0.06322],\n [0.01947, 0.06087, 0.74457],\n ]),\n adobeRGB_INVERSE: new Matrix3x3([\n [1.9625385510109137, -0.6106892546501431, -0.3413827467482388],\n [-0.9787580455521, 1.9161624707082339, 0.03341676594241408],\n [0.028696263137883395, -0.1406807819331586, 1.349252109991369],\n ]),\n rec2020: new Matrix3x3([\n [0.673459, 0.165661, 0.125100],\n [0.279033, 0.675338, 0.0456288],\n [-0.00193139, 0.0299794, 0.797162],\n ]),\n rec2020_INVERSE: new Matrix3x3([\n [1.647275201661012, -0.3936024771460771, -0.23598028884792507],\n [-0.6826176165196962, 1.647617775014935, 0.01281626807852422],\n [0.029662725298529837, -0.06291668721366285, 1.2533964313435522],\n ]),\n xyz: new Matrix3x3([\n [1.0, 0.0, 0.0],\n [0.0, 1.0, 0.0],\n [0.0, 0.0, 1.0],\n ]),\n\n};\n\nfunction degToRad(deg: number): number {\n return deg * (Math.PI / 180);\n}\n\nfunction radToDeg(rad: number): number {\n return rad * (180 / Math.PI);\n}\n\nfunction applyTransferFns(fn: TransferFunction, r: number, g: number, b: number): [number, number, number] {\n return [fn.eval(r), fn.eval(g), fn.eval(b)];\n}\n\nconst OKLAB_TO_LMS_MATRIX = new Matrix3x3([\n [0.99999999845051981432, 0.39633779217376785678, 0.21580375806075880339],\n [1.0000000088817607767, -0.1055613423236563494, -0.063854174771705903402],\n [1.0000000546724109177, -0.089484182094965759684, -1.2914855378640917399],\n]);\n\n// Inverse of the OKLAB_TO_LMS_MATRIX\nconst LMS_TO_OKLAB_MATRIX = new Matrix3x3([\n [0.2104542553, 0.7936177849999999, -0.0040720468],\n [1.9779984951000003, -2.4285922049999997, 0.4505937099000001],\n [0.025904037099999982, 0.7827717662, -0.8086757660000001],\n]);\n\nconst XYZ_TO_LMS_MATRIX = new Matrix3x3([\n [0.8190224432164319, 0.3619062562801221, -0.12887378261216414],\n [0.0329836671980271, 0.9292868468965546, 0.03614466816999844],\n [0.048177199566046255, 0.26423952494422764, 0.6335478258136937],\n]);\n// Inverse of XYZ_TO_LMS_MATRIX\nconst LMS_TO_XYZ_MATRIX = new Matrix3x3([\n [1.226879873374156, -0.5578149965554814, 0.2813910501772159],\n [-0.040575762624313734, 1.1122868293970596, -0.07171106666151703],\n [-0.07637294974672144, -0.4214933239627915, 1.586924024427242],\n]);\n\nconst PRO_PHOTO_TO_XYZD50_MATRIX = new Matrix3x3([\n [0.7976700747153241, 0.13519395152800417, 0.03135596341127167],\n [0.28803902352472205, 0.7118744007923554, 0.00008661179538844252],\n [2.739876695467402e-7, -0.0000014405226518969991, 0.825211112593861],\n]);\n// Inverse of PRO_PHOTO_TO_XYZD50_MATRIX\nconst XYZD50_TO_PRO_PHOTO_MATRIX = new Matrix3x3([\n [1.3459533710138858, -0.25561367037652133, -0.051116041522131374],\n [-0.544600415668951, 1.5081687311475767, 0.020535163968720935],\n [-0.0000013975622054109725, 0.000002717590904589903, 1.2118111696814942],\n]);\n\nconst XYZD65_TO_XYZD50_MATRIX = new Matrix3x3([\n [1.0478573189120088, 0.022907374491829943, -0.050162247377152525],\n [0.029570500050499514, 0.9904755577034089, -0.017061518194840468],\n [-0.00924047197558879, 0.015052921526981566, 0.7519708530777581],\n]);\n// Inverse of XYZD65_TO_XYZD50_MATRIX\nconst XYZD50_TO_XYZD65_MATRIX = new Matrix3x3([\n [0.9555366447632887, -0.02306009252137888, 0.06321844147263304],\n [-0.028315378228764922, 1.009951351591575, 0.021026001591792402],\n [0.012308773293784308, -0.02050053471777469, 1.3301947294775631],\n]);\n\nconst XYZD65_TO_SRGB_MATRIX = new Matrix3x3([\n [3.2408089365140573, -1.5375788839307314, -0.4985609572551541],\n [-0.9692732213205414, 1.876110235238969, 0.041560501141251774],\n [0.05567030990267439, -0.2040007921971802, 1.0571046720577026],\n]);\n\nexport class ColorConverter {\n static labToXyzd50(l: number, a: number, b: number): [number, number, number] {\n let y = (l + 16.0) / 116.0;\n let x = y + a / 500.0;\n let z = y - b / 200.0;\n\n function labInverseTransferFunction(t: number): number {\n const delta = (24.0 / 116.0);\n\n if (t <= delta) {\n return (108.0 / 841.0) * (t - (16.0 / 116.0));\n }\n\n return t * t * t;\n }\n\n x = labInverseTransferFunction(x) * D50_X;\n y = labInverseTransferFunction(y) * D50_Y;\n z = labInverseTransferFunction(z) * D50_Z;\n\n return [x, y, z];\n }\n\n static xyzd50ToLab(x: number, y: number, z: number): [number, number, number] {\n function labTransferFunction(t: number): number {\n const deltaLimit: number = (24.0 / 116.0) * (24.0 / 116.0) * (24.0 / 116.0);\n\n if (t <= deltaLimit) {\n return (841.0 / 108.0) * t + (16.0 / 116.0);\n }\n return Math.pow(t, 1.0 / 3.0);\n }\n\n x = labTransferFunction(x / D50_X);\n y = labTransferFunction(y / D50_Y);\n z = labTransferFunction(z / D50_Z);\n\n const l = 116.0 * y - 16.0;\n const a = 500.0 * (x - y);\n const b = 200.0 * (y - z);\n\n return [l, a, b];\n }\n\n static oklabToXyzd65(l: number, a: number, b: number): [number, number, number] {\n const labInput = new Vector3([l, a, b]);\n const lmsIntermediate = OKLAB_TO_LMS_MATRIX.multiply(labInput);\n lmsIntermediate.values[0] = lmsIntermediate.values[0] * lmsIntermediate.values[0] * lmsIntermediate.values[0];\n lmsIntermediate.values[1] = lmsIntermediate.values[1] * lmsIntermediate.values[1] * lmsIntermediate.values[1];\n lmsIntermediate.values[2] = lmsIntermediate.values[2] * lmsIntermediate.values[2] * lmsIntermediate.values[2];\n const xyzOutput = LMS_TO_XYZ_MATRIX.multiply(lmsIntermediate);\n return xyzOutput.values;\n }\n\n static xyzd65ToOklab(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const lmsIntermediate = XYZ_TO_LMS_MATRIX.multiply(xyzInput);\n\n lmsIntermediate.values[0] = Math.pow(lmsIntermediate.values[0], 1.0 / 3.0);\n lmsIntermediate.values[1] = Math.pow(lmsIntermediate.values[1], 1.0 / 3.0);\n lmsIntermediate.values[2] = Math.pow(lmsIntermediate.values[2], 1.0 / 3.0);\n\n const labOutput = LMS_TO_OKLAB_MATRIX.multiply(lmsIntermediate);\n return [labOutput.values[0], labOutput.values[1], labOutput.values[2]];\n }\n\n static lchToLab(l: number, c: number, h: number|undefined): [number, number, number] {\n if (h === undefined) {\n return [l, 0, 0];\n }\n\n return [l, c * Math.cos(degToRad(h)), c * Math.sin(degToRad(h))];\n }\n\n static labToLch(l: number, a: number, b: number): [number, number, number] {\n return [l, Math.sqrt(a * a + b * b), radToDeg(Math.atan2(b, a))];\n }\n\n static displayP3ToXyzd50(r: number, g: number, b: number): [number, number, number] {\n const [mappedR, mappedG, mappedB] = applyTransferFns(NAMED_TRANSFER_FN.sRGB, r, g, b);\n const rgbInput = new Vector3([mappedR, mappedG, mappedB]);\n const xyzOutput = NAMED_GAMUTS.displayP3.multiply(rgbInput);\n return xyzOutput.values;\n }\n\n static xyzd50ToDisplayP3(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const rgbOutput = NAMED_GAMUTS.displayP3_INVERSE.multiply(xyzInput);\n return applyTransferFns(\n NAMED_TRANSFER_FN.sRGB_INVERSE, rgbOutput.values[0], rgbOutput.values[1], rgbOutput.values[2]);\n }\n\n static proPhotoToXyzd50(r: number, g: number, b: number): [number, number, number] {\n const [mappedR, mappedG, mappedB] = applyTransferFns(NAMED_TRANSFER_FN.proPhotoRGB, r, g, b);\n const rgbInput = new Vector3([mappedR, mappedG, mappedB]);\n const xyzOutput = PRO_PHOTO_TO_XYZD50_MATRIX.multiply(rgbInput);\n return xyzOutput.values;\n }\n\n static xyzd50ToProPhoto(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const rgbOutput = XYZD50_TO_PRO_PHOTO_MATRIX.multiply(xyzInput);\n return applyTransferFns(\n NAMED_TRANSFER_FN.proPhotoRGB_INVERSE, rgbOutput.values[0], rgbOutput.values[1], rgbOutput.values[2]);\n }\n\n static adobeRGBToXyzd50(r: number, g: number, b: number): [number, number, number] {\n const [mappedR, mappedG, mappedB] = applyTransferFns(NAMED_TRANSFER_FN.k2Dot2, r, g, b);\n const rgbInput = new Vector3([mappedR, mappedG, mappedB]);\n const xyzOutput = NAMED_GAMUTS.adobeRGB.multiply(rgbInput);\n return xyzOutput.values;\n }\n\n static xyzd50ToAdobeRGB(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const rgbOutput = NAMED_GAMUTS.adobeRGB_INVERSE.multiply(xyzInput);\n return applyTransferFns(\n NAMED_TRANSFER_FN.k2Dot2_INVERSE, rgbOutput.values[0], rgbOutput.values[1], rgbOutput.values[2]);\n }\n\n static rec2020ToXyzd50(r: number, g: number, b: number): [number, number, number] {\n const [mappedR, mappedG, mappedB] = applyTransferFns(NAMED_TRANSFER_FN.rec2020, r, g, b);\n const rgbInput = new Vector3([mappedR, mappedG, mappedB]);\n const xyzOutput = NAMED_GAMUTS.rec2020.multiply(rgbInput);\n return xyzOutput.values;\n }\n\n static xyzd50ToRec2020(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const rgbOutput = NAMED_GAMUTS.rec2020_INVERSE.multiply(xyzInput);\n return applyTransferFns(\n NAMED_TRANSFER_FN.rec2020_INVERSE, rgbOutput.values[0], rgbOutput.values[1], rgbOutput.values[2]);\n }\n\n static xyzd50ToD65(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const xyzOutput = XYZD50_TO_XYZD65_MATRIX.multiply(xyzInput);\n return xyzOutput.values;\n }\n\n static xyzd65ToD50(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const xyzOutput = XYZD65_TO_XYZD50_MATRIX.multiply(xyzInput);\n return xyzOutput.values;\n }\n\n static xyzd65TosRGBLinear(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const rgbResult = XYZD65_TO_SRGB_MATRIX.multiply(xyzInput);\n return rgbResult.values;\n }\n\n static xyzd50TosRGBLinear(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const rgbResult = NAMED_GAMUTS.sRGB_INVERSE.multiply(xyzInput);\n return rgbResult.values;\n }\n\n static srgbLinearToXyzd50(r: number, g: number, b: number): [number, number, number] {\n const rgbInput = new Vector3([r, g, b]);\n const xyzOutput = NAMED_GAMUTS.sRGB.multiply(rgbInput);\n return xyzOutput.values;\n }\n\n static srgbToXyzd50(r: number, g: number, b: number): [number, number, number] {\n const [mappedR, mappedG, mappedB] = applyTransferFns(NAMED_TRANSFER_FN.sRGB, r, g, b);\n const rgbInput = new Vector3([mappedR, mappedG, mappedB]);\n const xyzOutput = NAMED_GAMUTS.sRGB.multiply(rgbInput);\n return xyzOutput.values;\n }\n\n static xyzd50ToSrgb(x: number, y: number, z: number): [number, number, number] {\n const xyzInput = new Vector3([x, y, z]);\n const rgbOutput = NAMED_GAMUTS.sRGB_INVERSE.multiply(xyzInput);\n return applyTransferFns(\n NAMED_TRANSFER_FN.sRGB_INVERSE, rgbOutput.values[0], rgbOutput.values[1], rgbOutput.values[2]);\n }\n\n static oklchToXyzd50(lInput: number, c: number, h: number): [number, number, number] {\n const [l, a, b] = ColorConverter.lchToLab(lInput, c, h);\n const [x65, y65, z65] = ColorConverter.oklabToXyzd65(l, a, b);\n return ColorConverter.xyzd65ToD50(x65, y65, z65);\n }\n\n static xyzd50ToOklch(x: number, y: number, z: number): [number, number, number] {\n const [x65, y65, z65] = ColorConverter.xyzd50ToD65(x, y, z);\n const [l, a, b] = ColorConverter.xyzd65ToOklab(x65, y65, z65);\n return ColorConverter.labToLch(l, a, b);\n }\n}\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/**\n * Combine the two given colors according to alpha blending.\n */\nexport type Color4D = [number, number, number, number];\nexport type Color3D = [number, number, number];\nexport type Color4DOr3D = [number, number, number, number | undefined];\nexport function blendColors(fgRGBA: Color4D, bgRGBA: Color4D): Color4D {\n const alpha = fgRGBA[3];\n return [\n ((1 - alpha) * bgRGBA[0]) + (alpha * fgRGBA[0]),\n ((1 - alpha) * bgRGBA[1]) + (alpha * fgRGBA[1]),\n ((1 - alpha) * bgRGBA[2]) + (alpha * fgRGBA[2]),\n alpha + (bgRGBA[3] * (1 - alpha)),\n ];\n}\n\nfunction rgbToHue([r, g, b]: number[]): number {\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const diff = max - min;\n\n let h;\n if (min === max) {\n h = 0;\n } else if (r === max) {\n h = ((1 / 6 * (g - b) / diff) + 1) % 1;\n } else if (g === max) {\n h = (1 / 6 * (b - r) / diff) + 1 / 3;\n } else {\n h = (1 / 6 * (r - g) / diff) + 2 / 3;\n }\n return h;\n}\n\nexport function rgbToHsl(rgb: Color3D): Color3D {\n const [h, s, l] = rgbaToHsla([...rgb, undefined]);\n return [h, s, l];\n}\nexport function rgbaToHsla([r, g, b, a]: Color4DOr3D): Color4DOr3D {\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const diff = max - min;\n const sum = max + min;\n\n const h = rgbToHue([r, g, b]);\n const l = 0.5 * sum;\n\n let s;\n if (l === 0) {\n s = 0;\n } else if (l === 1) {\n s = 0;\n } else if (l <= 0.5) {\n s = diff / sum;\n } else {\n s = diff / (2 - sum);\n }\n\n return [h, s, l, a];\n}\n\nexport function rgbToHwb(rgb: Color3D): Color3D {\n const [h, w, b] = rgbaToHwba([...rgb, undefined]);\n return [h, w, b];\n}\nexport function rgbaToHwba([r, g, b, a]: Color4DOr3D): Color4DOr3D {\n const h = rgbToHue([r, g, b]);\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n\n return [h, min, 1 - max, a];\n}\n\n/**\n * Calculate the luminance of this color using the WCAG algorithm.\n * See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef\n */\nexport function luminance([rSRGB, gSRGB, bSRGB]: number[]): number {\n const r = rSRGB <= 0.03928 ? rSRGB / 12.92 : Math.pow(((rSRGB + 0.055) / 1.055), 2.4);\n const g = gSRGB <= 0.03928 ? gSRGB / 12.92 : Math.pow(((gSRGB + 0.055) / 1.055), 2.4);\n const b = bSRGB <= 0.03928 ? bSRGB / 12.92 : Math.pow(((bSRGB + 0.055) / 1.055), 2.4);\n\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\n/**\n * Calculate the contrast ratio between a foreground and a background color.\n * Returns the ratio to 1, for example for two two colors with a contrast ratio of 21:1, this function will return 21.\n * See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef\n */\nexport function contrastRatio(fgRGBA: Color4D, bgRGBA: Color4D): number {\n const blendedFg = blendColors(fgRGBA, bgRGBA);\n const fgLuminance = luminance(blendedFg);\n const bgLuminance = luminance(bgRGBA);\n const contrastRatio = (Math.max(fgLuminance, bgLuminance) + 0.05) / (Math.min(fgLuminance, bgLuminance) + 0.05);\n return contrastRatio;\n}\n\n// Constants for basic APCA version.\n// See https://github.com/Myndex/SAPC-APCA\nconst mainTRC = 2.4;\nconst normBgExp = 0.56;\nconst normFgExp = 0.57;\nconst revBgExp = 0.65;\nconst revFgExp = 0.62;\nconst blkThrs = 0.022;\nconst blkClmp = 1.414;\nconst scaleBoW = 1.14;\nconst scaleWoB = 1.14;\nconst loConOffset = 0.027;\nconst loClip = 0.1;\nconst deltaLuminanceMin = 0.0005;\n\n/**\n * Calculate relative luminance of a color.\n * See https://github.com/Myndex/SAPC-APCA\n */\nexport function luminanceAPCA([rSRGB, gSRGB, bSRGB]: number[]): number {\n const r = Math.pow(rSRGB, mainTRC);\n const g = Math.pow(gSRGB, mainTRC);\n const b = Math.pow(bSRGB, mainTRC);\n\n return 0.2126729 * r + 0.7151522 * g + 0.0721750 * b;\n}\n\n/**\n * Calculate the contrast ratio between a foreground and a background color.\n * Returns the percentage of the predicted visual contrast.\n * See https://github.com/Myndex/SAPC-APCA\n */\nexport function contrastRatioAPCA(fgRGBA: Color4D, bgRGBA: Color4D): number {\n const blendedFg = blendColors(fgRGBA, bgRGBA);\n return contrastRatioByLuminanceAPCA(luminanceAPCA(blendedFg), luminanceAPCA(bgRGBA));\n}\n\nfunction clampLuminance(value: number): number {\n return value > blkThrs ? value : (value + Math.pow(blkThrs - value, blkClmp));\n}\n\nexport function contrastRatioByLuminanceAPCA(fgLuminance: number, bgLuminance: number): number {\n fgLuminance = clampLuminance(fgLuminance);\n bgLuminance = clampLuminance(bgLuminance);\n if (Math.abs(fgLuminance - bgLuminance) < deltaLuminanceMin) {\n return 0;\n }\n let result = 0;\n if (bgLuminance > fgLuminance) { // Black text on white.\n result = (Math.pow(bgLuminance, normBgExp) - Math.pow(fgLuminance, normFgExp)) * scaleBoW;\n result = result < loClip ? 0 : result - loConOffset;\n } else {\n // White text on black.\n result = (Math.pow(bgLuminance, revBgExp) - Math.pow(fgLuminance, revFgExp)) * scaleWoB;\n result = result > -loClip ? 0 : result + loConOffset;\n }\n return result * 100;\n}\n\n/**\n * Compute a desired luminance given a given luminance and a desired contrast\n * percentage according to APCA.\n */\nexport function desiredLuminanceAPCA(luminance: number, contrast: number, lighter: boolean): number {\n luminance = clampLuminance(luminance);\n contrast /= 100;\n function computeLuminance(): number {\n if (!lighter) { // Black text on white.\n return Math.pow(Math.abs(Math.pow(luminance, normBgExp) - (contrast + loConOffset) / scaleBoW), 1 / normFgExp);\n }\n // White text on black.\n return Math.pow(Math.abs(Math.pow(luminance, revBgExp) - (-contrast - loConOffset) / scaleWoB), 1 / revFgExp);\n }\n let desiredLuminance = computeLuminance();\n if (desiredLuminance < 0 || desiredLuminance > 1) {\n lighter = !lighter;\n desiredLuminance = computeLuminance();\n }\n return desiredLuminance;\n}\n\n// clang-format off\nconst contrastAPCALookupTable = [\n // See https://github.com/Myndex/SAPC-APCA\n // font size in px | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 weights\n [12, -1, -1, -1, -1, 100, 90, 80, -1, -1],\n [14, -1, -1, -1, 100, 90, 80, 60, 60, -1],\n [16, -1, -1, 100, 90, 80, 60, 55, 50, 50],\n [18, -1, -1, 90, 80, 60, 55, 50, 40, 40],\n [24, -1, 100, 80, 60, 55, 50, 40, 38, 35],\n [30, -1, 90, 70, 55, 50, 40, 38, 35, 40],\n [36, -1, 80, 60, 50, 40, 38, 35, 30, 25],\n [48, 100, 70, 55, 40, 38, 35, 30, 25, 20],\n [60, 90, 60, 50, 38, 35, 30, 25, 20, 20],\n [72, 80, 55, 40, 35, 30, 25, 20, 20, 20],\n [96, 70, 50, 35, 30, 25, 20, 20, 20, 20],\n [120, 60, 40, 30, 25, 20, 20, 20, 20, 20],\n];\n// clang-format on\n\ncontrastAPCALookupTable.reverse();\n\nexport function getAPCAThreshold(fontSize: string, fontWeight: string): number|null {\n const size = parseFloat(fontSize.replace('px', ''));\n const weight = parseFloat(fontWeight);\n\n // Go over the table backwards to find the first matching font size and then the weight.\n // Fonts larger than 96px, use the thresholds for 96px.\n // Fonts smaller than 12px, don't get any threshold meaning the font size needs to be increased.\n for (const [rowSize, ...rowWeights] of contrastAPCALookupTable) {\n if (size >= rowSize) {\n for (const [idx, keywordWeight] of [900, 800, 700, 600, 500, 400, 300, 200, 100].entries()) {\n if (weight >= keywordWeight) {\n const threshold = rowWeights[rowWeights.length - 1 - idx];\n return threshold === -1 ? null : threshold;\n }\n }\n }\n }\n\n return null;\n}\n\nexport function isLargeFont(fontSize: string, fontWeight: string): boolean {\n const boldWeights = ['bold', 'bolder'];\n\n const fontSizePx = parseFloat(fontSize.replace('px', ''));\n const isBold = isNaN(Number(fontWeight)) ? boldWeights.includes(fontWeight) : Number(fontWeight) >= 600;\n\n const fontSizePt = fontSizePx * 72 / 96;\n if (isBold) {\n return fontSizePt >= 14;\n }\n return fontSizePt >= 18;\n}\n\nconst contrastThresholds = {\n largeFont: {aa: 3.0, aaa: 4.5},\n normalFont: {aa: 4.5, aaa: 7.0},\n};\n\nexport function getContrastThreshold(fontSize: string, fontWeight: string): {\n aa: number,\n aaa: number,\n} {\n if (isLargeFont(fontSize, fontWeight)) {\n return contrastThresholds.largeFont;\n }\n return contrastThresholds.normalFont;\n}\n", "// Copyright 2021 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/*\n * Copyright (C) 2009 Apple Inc. All rights reserved.\n * Copyright (C) 2009 Joseph Pecoraro\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nimport * as Platform from '../platform/platform.js';\n\nimport {ColorConverter} from './ColorConverter.js';\n\nimport {\n blendColors,\n contrastRatioAPCA,\n desiredLuminanceAPCA,\n luminance,\n luminanceAPCA,\n rgbToHsl,\n rgbToHwb,\n type Color3D,\n type Color4D,\n type Color4DOr3D,\n} from './ColorUtils.js';\n\n// <hue> is defined as a <number> or <angle>\n// and we hold this in degrees. However, after\n// the conversions, these degrees can result in\n// negative values. That's why we normalize the hue to be\n// between [0 - 360].\nfunction normalizeHue(hue: number): number {\n // Even though it is highly unlikely, hue can be\n // very negative like -400. The initial modulo\n // operation makes sure that the if the number is\n // negative, it is between [-360, 0].\n return ((hue % 360) + 360) % 360;\n}\n\n// Parses angle in the form of\n// `<angle>deg`, `<angle>turn`, `<angle>grad and `<angle>rad`\n// and returns the canonicalized `degree`.\nfunction parseAngle(angleText: string): number|null {\n const angle = angleText.replace(/(deg|g?rad|turn)$/, '');\n // @ts-ignore: isNaN can accept strings\n if (isNaN(angle) || angleText.match(/\\s+(deg|g?rad|turn)/)) {\n return null;\n }\n\n const number = parseFloat(angle);\n if (angleText.includes('turn')) {\n // 1turn === 360deg\n return number * 360;\n }\n\n if (angleText.includes('grad')) {\n // 1grad === 0.9deg\n return number * 9 / 10;\n }\n\n if (angleText.includes('rad')) {\n // \u03C0rad === 180deg\n return number * 180 / Math.PI;\n }\n\n // 1deg === 1deg ^_^\n return number;\n}\n\n// Returns the `Format` equivalent from the format text\nexport function getFormat(formatText: string): Format|null {\n switch (formatText) {\n case Format.Nickname:\n return Format.Nickname;\n case Format.HEX:\n return Format.HEX;\n case Format.ShortHEX:\n return Format.ShortHEX;\n case Format.HEXA:\n return Format.HEXA;\n case Format.ShortHEXA:\n return Format.ShortHEXA;\n case Format.RGB:\n return Format.RGB;\n case Format.RGBA:\n return Format.RGBA;\n case Format.HSL:\n return Format.HSL;\n case Format.HSLA:\n return Format.HSLA;\n case Format.HWB:\n return Format.HWB;\n case Format.HWBA:\n return Format.HWBA;\n case Format.LCH:\n return Format.LCH;\n case Format.OKLCH:\n return Format.OKLCH;\n case Format.LAB:\n return Format.LAB;\n case Format.OKLAB:\n return Format.OKLAB;\n }\n\n return getColorSpace(formatText);\n}\n\n// Returns the `ColorSpace` equivalent from the color space text\ntype ColorSpace = Format.SRGB|Format.SRGB_LINEAR|Format.DISPLAY_P3|Format.A98_RGB|Format.PROPHOTO_RGB|\n Format.REC_2020|Format.XYZ|Format.XYZ_D50|Format.XYZ_D65;\nfunction getColorSpace(colorSpaceText: string): ColorSpace|null {\n switch (colorSpaceText) {\n case Format.SRGB:\n return Format.SRGB;\n case Format.SRGB_LINEAR:\n return Format.SRGB_LINEAR;\n case Format.DISPLAY_P3:\n return Format.DISPLAY_P3;\n case Format.A98_RGB:\n return Format.A98_RGB;\n case Format.PROPHOTO_RGB:\n return Format.PROPHOTO_RGB;\n case Format.REC_2020:\n return Format.REC_2020;\n case Format.XYZ:\n return Format.XYZ;\n case Format.XYZ_D50:\n return Format.XYZ_D50;\n case Format.XYZ_D65:\n return Format.XYZ_D65;\n }\n\n return null;\n}\n\n/**\n * Percents in color spaces are mapped to ranges.\n * These ranges change based on the syntax.\n * For example, for 'C' in lch() c: 0% = 0, 100% = 150.\n * See: https://www.w3.org/TR/css-color-4/#funcdef-lch\n * Some percentage values can be negative\n * though their ranges don't change depending on the sign\n * (for now, according to spec).\n * @param percent % value of the number. 42 for 42%.\n * @param range Range of [min, max]. Including `min` and `max`.\n */\nfunction mapPercentToRange(percent: number, range: [number, number]): number {\n const sign = Math.sign(percent);\n const absPercent = Math.abs(percent);\n const [outMin, outMax] = range;\n\n return sign * (absPercent * (outMax - outMin) / 100 + outMin);\n}\n\ninterface SplitColorFunctionParametersOptions {\n allowCommas: boolean;\n convertNoneToZero: boolean;\n}\n\nexport function parse(text: string): Color|null {\n // Simple - #hex, nickname\n const value = text.toLowerCase().replace(/\\s+/g, '');\n const simple = /^(?:#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})|(\\w+))$/i;\n let match = value.match(simple);\n if (match) {\n if (match[1]) {\n return Legacy.fromHex(match[1], text);\n }\n\n if (match[2]) {\n return Legacy.fromName(match[2], text);\n }\n\n return null;\n }\n\n // rgb/rgba(), hsl/hsla(), hwb/hwba(), lch(), oklch(), lab(), oklab() and color()\n match = text.toLowerCase().match(/^\\s*(?:(rgba?)|(hsla?)|(hwba?)|(lch)|(oklch)|(lab)|(oklab)|(color))\\((.*)\\)\\s*$/);\n if (match) {\n const isRgbaMatch = Boolean(match[1]); // rgb/rgba()\n const isHslaMatch = Boolean(match[2]); // hsl/hsla()\n const isHwbaMatch = Boolean(match[3]); // hwb/hwba()\n const isLchMatch = Boolean(match[4]); // lch()\n const isOklchMatch = Boolean(match[5]); // oklch()\n const isLabMatch = Boolean(match[6]); // lab()\n const isOklabMatch = Boolean(match[7]); // oklab()\n const isColorMatch = Boolean(match[8]); // color()\n const valuesText = match[9];\n\n // Parse color function first because extracting values for\n // this function is not the same as the other ones\n // so, we're not using any of the logic below.\n if (isColorMatch) {\n return ColorFunction.fromSpec(text, valuesText);\n }\n\n const isOldSyntax = isRgbaMatch || isHslaMatch || isHwbaMatch;\n const allowCommas = isRgbaMatch || isHslaMatch;\n const convertNoneToZero = !isOldSyntax; // Convert 'none' keyword to zero in new syntaxes\n\n const values = splitColorFunctionParameters(valuesText, {allowCommas, convertNoneToZero});\n if (!values) {\n return null;\n }\n const spec: ColorParameterSpec = [values[0], values[1], values[2], values[3]];\n if (isRgbaMatch) {\n return Legacy.fromRGBAFunction(values[0], values[1], values[2], values[3], text);\n }\n\n if (isHslaMatch) {\n return HSL.fromSpec(spec, text);\n }\n\n if (isHwbaMatch) {\n return HWB.fromSpec(spec, text);\n }\n\n if (isLchMatch) {\n return LCH.fromSpec(spec, text);\n }\n\n if (isOklchMatch) {\n return Oklch.fromSpec(spec, text);\n }\n\n if (isLabMatch) {\n return Lab.fromSpec(spec, text);\n }\n\n if (isOklabMatch) {\n return Oklab.fromSpec(spec, text);\n }\n }\n\n return null;\n}\n\n/**\n * Split the color parameters of (e.g.) rgb(a), hsl(a), hwb(a) functions.\n */\nfunction splitColorFunctionParameters(\n content: string, {allowCommas, convertNoneToZero}: SplitColorFunctionParametersOptions): string[]|null {\n const components = content.trim();\n let values: string[] = [];\n\n if (allowCommas) {\n values = components.split(/\\s*,\\s*/);\n }\n if (!allowCommas || values.length === 1) {\n values = components.split(/\\s+/);\n if (values[3] === '/') {\n values.splice(3, 1);\n if (values.length !== 4) {\n return null;\n }\n } else if (\n (values.length > 2 && values[2].indexOf('/') !== -1) || (values.length > 3 && values[3].indexOf('/') !== -1)) {\n const alpha = values.slice(2, 4).join('');\n values = values.slice(0, 2).concat(alpha.split(/\\//)).concat(values.slice(4));\n } else if (values.length >= 4) {\n return null;\n }\n }\n if (values.length !== 3 && values.length !== 4 || values.indexOf('') > -1) {\n return null;\n }\n\n // Question: what should we do with `alpha` being none?\n if (convertNoneToZero) {\n return values.map(value => value === 'none' ? '0' : value);\n }\n\n return values;\n}\n\nfunction clamp(value: number, {min, max}: {min?: number, max?: number}): number;\nfunction clamp(value: null, {min, max}: {min?: number, max?: number}): null;\nfunction clamp(value: number|null, {min, max}: {min?: number, max?: number}): number|null;\nfunction clamp(value: number|null, {min, max}: {min?: number, max?: number}): number|null {\n if (value === null) {\n return value;\n }\n if (min !== undefined) {\n value = Math.max(value, min);\n }\n if (max !== undefined) {\n value = Math.min(value, max);\n }\n return value;\n}\n\nfunction parsePercentage(value: string, range: [number, number]): number|null {\n if (!value.endsWith('%')) {\n return null;\n }\n const percentage = parseFloat(value.substr(0, value.length - 1));\n return isNaN(percentage) ? null : mapPercentToRange(percentage, range);\n}\n\nfunction parseNumber(value: string): number|null {\n const number = parseFloat(value);\n return isNaN(number) ? null : number;\n}\n\nfunction parseAlpha(value: string|undefined): number|null {\n if (value === undefined) {\n return null;\n }\n return clamp(parsePercentage(value, [0, 1]) ?? parseNumber(value), {min: 0, max: 1});\n}\n\n/**\n *\n * @param value Text value to be parsed in the form of 'number|percentage'.\n * @param range Range to map the percentage.\n * @returns If it is not percentage, returns number directly; otherwise,\n * maps the percentage to the range. For example:\n * - 30% in range [0, 100] is 30\n * - 20% in range [0, 1] is 0.5\n */\nfunction parsePercentOrNumber(value: string, range: [number, number] = [0, 1]): number|null {\n // @ts-ignore: isNaN can accept strings\n if (isNaN(value.replace('%', ''))) {\n return null;\n }\n const parsed = parseFloat(value);\n\n if (value.indexOf('%') !== -1) {\n if (value.indexOf('%') !== value.length - 1) {\n return null;\n }\n return mapPercentToRange(parsed, range);\n }\n return parsed;\n}\n\nfunction parseRgbNumeric(value: string): number|null {\n const parsed = parsePercentOrNumber(value);\n if (parsed === null) {\n return null;\n }\n\n if (value.indexOf('%') !== -1) {\n return parsed;\n }\n return parsed / 255;\n}\n\nfunction parseHueNumeric(value: string): number|null {\n const angle = value.replace(/(deg|g?rad|turn)$/, '');\n // @ts-ignore: isNaN can accept strings\n if (isNaN(angle) || value.match(/\\s+(deg|g?rad|turn)/)) {\n return null;\n }\n const number = parseFloat(angle);\n\n if (value.indexOf('turn') !== -1) {\n return number % 1;\n }\n if (value.indexOf('grad') !== -1) {\n return (number / 400) % 1;\n }\n if (value.indexOf('rad') !== -1) {\n return (number / (2 * Math.PI)) % 1;\n }\n return (number / 360) % 1;\n}\n\nfunction parseSatLightNumeric(value: string): number|null {\n // @ts-ignore: isNaN can accept strings\n if (value.indexOf('%') !== value.length - 1 || isNaN(value.replace('%', ''))) {\n return null;\n }\n const parsed = parseFloat(value);\n return parsed / 100;\n}\n\nfunction parseAlphaNumeric(value: string): number|null {\n return parsePercentOrNumber(value);\n}\n\n// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction hsva2hsla(hsva: Color4D, out_hsla: Color4D): void {\n const h = hsva[0];\n let s: 0|number = hsva[1];\n const v = hsva[2];\n\n const t = (2 - s) * v;\n if (v === 0 || s === 0) {\n s = 0;\n } else {\n s *= v / (t < 1 ? t : 2 - t);\n }\n\n out_hsla[0] = h;\n out_hsla[1] = s;\n out_hsla[2] = t / 2;\n out_hsla[3] = hsva[3];\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function hsl2rgb(hsl: Color4D, out_rgb: Color4D): void {\n const h = hsl[0];\n let s: 0|number = hsl[1];\n const l = hsl[2];\n\n function hue2rgb(p: number, q: number, h: number): number {\n if (h < 0) {\n h += 1;\n } else if (h > 1) {\n h -= 1;\n }\n\n if ((h * 6) < 1) {\n return p + (q - p) * h * 6;\n }\n if ((h * 2) < 1) {\n return q;\n }\n if ((h * 3) < 2) {\n return p + (q - p) * ((2 / 3) - h) * 6;\n }\n return p;\n }\n\n if (s < 0) {\n s = 0;\n }\n\n let q;\n if (l <= 0.5) {\n q = l * (1 + s);\n } else {\n q = l + s - (l * s);\n }\n\n const p = 2 * l - q;\n\n const tr = h + (1 / 3);\n const tg = h;\n const tb = h - (1 / 3);\n\n out_rgb[0] = hue2rgb(p, q, tr);\n out_rgb[1] = hue2rgb(p, q, tg);\n out_rgb[2] = hue2rgb(p, q, tb);\n out_rgb[3] = hsl[3];\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction hwb2rgb(hwb: Color4D, out_rgb: Color4D): void {\n const h = hwb[0];\n const w = hwb[1];\n const b = hwb[2];\n\n if (w + b >= 1) {\n out_rgb[0] = out_rgb[1] = out_rgb[2] = w / (w + b);\n out_rgb[3] = hwb[3];\n } else {\n hsl2rgb([h, 1, 0.5, hwb[3]], out_rgb);\n for (let i = 0; i < 3; ++i) {\n out_rgb[i] += w - (w + b) * out_rgb[i];\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function hsva2rgba(hsva: Color4D, out_rgba: Color4D): void {\n const tmpHSLA: Color4D = [0, 0, 0, 0];\n hsva2hsla(hsva, tmpHSLA);\n hsl2rgb(tmpHSLA, out_rgba);\n}\n\nexport function rgb2hsv(rgba: Color3D): Color3D {\n const hsla = rgbToHsl(rgba);\n const h = hsla[0];\n let s = hsla[1];\n const l = hsla[2];\n\n s *= l < 0.5 ? l : 1 - l;\n return [h, s !== 0 ? 2 * s / (l + s) : 0, (l + s)];\n}\n\n/**\n * Compute a desired luminance given a given luminance and a desired contrast\n * ratio.\n */\nexport function desiredLuminance(luminance: number, contrast: number, lighter: boolean): number {\n function computeLuminance(): number {\n if (lighter) {\n return (luminance + 0.05) * contrast - 0.05;\n }\n return (luminance + 0.05) / contrast - 0.05;\n }\n let desiredLuminance = computeLuminance();\n if (desiredLuminance < 0 || desiredLuminance > 1) {\n lighter = !lighter;\n desiredLuminance = computeLuminance();\n }\n return desiredLuminance;\n}\n\n/**\n * Approach a value of the given component of `candidateHSVA` such that the\n * calculated luminance of `candidateHSVA` approximates `desiredLuminance`.\n */\nexport function approachColorValue(\n candidateHSVA: Color4D, bgRGBA: Color4D, index: number, desiredLuminance: number,\n candidateLuminance: (arg0: Color4D) => number): number|null {\n const epsilon = 0.0002;\n\n let x = candidateHSVA[index];\n let multiplier = 1;\n let dLuminance: number = candidateLuminance(candidateHSVA) - desiredLuminance;\n let previousSign = Math.sign(dLuminance);\n\n for (let guard = 100; guard; guard--) {\n if (Math.abs(dLuminance) < epsilon) {\n candidateHSVA[index] = x;\n return x;\n }\n\n const sign = Math.sign(dLuminance);\n if (sign !== previousSign) {\n // If `x` overshoots the correct value, halve the step size.\n multiplier /= 2;\n previousSign = sign;\n } else if (x < 0 || x > 1) {\n // If there is no overshoot and `x` is out of bounds, there is no\n // acceptable value for `x`.\n return null;\n }\n\n // Adjust `x` by a multiple of `dLuminance` to decrease step size as\n // the computed luminance converges on `desiredLuminance`.\n x += multiplier * (index === 2 ? -dLuminance : dLuminance);\n\n candidateHSVA[index] = x;\n\n dLuminance = candidateLuminance(candidateHSVA) - desiredLuminance;\n }\n\n return null;\n}\n\nexport function findFgColorForContrast(fgColor: Legacy, bgColor: Legacy, requiredContrast: number): Legacy|null {\n const candidateHSVA = fgColor.as(Format.HSL).hsva();\n const bgRGBA = bgColor.rgba();\n\n const candidateLuminance = (candidateHSVA: Color4D): number => {\n return luminance(blendColors(Legacy.fromHSVA(candidateHSVA).rgba(), bgRGBA));\n };\n\n const bgLuminance = luminance(bgColor.rgba());\n const fgLuminance = candidateLuminance(candidateHSVA);\n const fgIsLighter = fgLuminance > bgLuminance;\n\n const desired = desiredLuminance(bgLuminance, requiredContrast, fgIsLighter);\n\n const saturationComponentIndex = 1;\n const valueComponentIndex = 2;\n\n if (approachColorValue(candidateHSVA, bgRGBA, valueComponentIndex, desired, candidateLuminance)) {\n return Legacy.fromHSVA(candidateHSVA);\n }\n\n candidateHSVA[valueComponentIndex] = 1;\n if (approachColorValue(candidateHSVA, bgRGBA, saturationComponentIndex, desired, candidateLuminance)) {\n return Legacy.fromHSVA(candidateHSVA);\n }\n\n return null;\n}\n\nexport function findFgColorForContrastAPCA(fgColor: Legacy, bgColor: Legacy, requiredContrast: number): Legacy|null {\n const candidateHSVA = fgColor.as(Format.HSL).hsva();\n const bgRGBA = bgColor.rgba();\n\n const candidateLuminance = (candidateHSVA: Color4D): number => {\n return luminanceAPCA(Legacy.fromHSVA(candidateHSVA).rgba());\n };\n\n const bgLuminance = luminanceAPCA(bgColor.rgba());\n const fgLuminance = candidateLuminance(candidateHSVA);\n const fgIsLighter = fgLuminance >= bgLuminance;\n const desiredLuminance = desiredLuminanceAPCA(bgLuminance, requiredContrast, fgIsLighter);\n\n const saturationComponentIndex = 1;\n const valueComponentIndex = 2;\n\n if (approachColorValue(candidateHSVA, bgRGBA, valueComponentIndex, desiredLuminance, candidateLuminance)) {\n const candidate = Legacy.fromHSVA(candidateHSVA);\n if (Math.abs(contrastRatioAPCA(bgColor.rgba(), candidate.rgba())) >= requiredContrast) {\n return candidate;\n }\n }\n\n candidateHSVA[valueComponentIndex] = 1;\n if (approachColorValue(candidateHSVA, bgRGBA, saturationComponentIndex, desiredLuminance, candidateLuminance)) {\n const candidate = Legacy.fromHSVA(candidateHSVA);\n if (Math.abs(contrastRatioAPCA(bgColor.rgba(), candidate.rgba())) >= requiredContrast) {\n return candidate;\n }\n }\n\n return null;\n}\n\ntype ColorParameterSpec = [string, string, string, string | undefined];\n\ninterface ColorConversions<T = void> {\n [Format.Nickname](self: T): Legacy;\n [Format.HEX](self: T): Legacy;\n [Format.ShortHEX](self: T): Legacy;\n [Format.HEXA](self: T): Legacy;\n [Format.ShortHEXA](self: T): Legacy;\n [Format.RGB](self: T): Legacy;\n [Format.RGBA](self: T): Legacy;\n [Format.HSL](self: T): HSL;\n [Format.HSLA](self: T): HSL;\n [Format.HWB](self: T): HWB;\n [Format.HWBA](self: T): HWB;\n [Format.LCH](self: T): LCH;\n [Format.OKLCH](self: T): Oklch;\n [Format.LAB](self: T): Lab;\n [Format.OKLAB](self: T): Oklab;\n\n [Format.SRGB](self: T): ColorFunction;\n [Format.SRGB_LINEAR](self: T): ColorFunction;\n [Format.DISPLAY_P3](self: T): ColorFunction;\n [Format.A98_RGB](self: T): ColorFunction;\n [Format.PROPHOTO_RGB](self: T): ColorFunction;\n [Format.REC_2020](self: T): ColorFunction;\n [Format.XYZ](self: T): ColorFunction;\n [Format.XYZ_D50](self: T): ColorFunction;\n [Format.XYZ_D65](self: T): ColorFunction;\n}\n\nexport interface Color {\n readonly alpha: number|null;\n\n equal(color: Color): boolean;\n asString(format?: Format): string|null;\n setAlpha(alpha: number): Color;\n format(): Format;\n as<T extends Format>(format: T): ReturnType<ColorConversions[T]>;\n asLegacyColor(): Legacy;\n getAuthoredText(): string|null;\n\n getRawParameters(): Color3D;\n getAsRawString(format?: Format): string|null;\n isGamutClipped(): boolean;\n}\n\nconst EPSILON = 0.01;\nconst WIDE_RANGE_EPSILON = 1; // For comparisons on channels with a wider range than [0,1]\nfunction equals(a: number[], b: number[], accuracy?: number): boolean;\nfunction equals(a: number|null, b: number|null, accuracy?: number): boolean;\nfunction equals(a: number|null|number[], b: number|null|number[], accuracy = EPSILON): boolean {\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false;\n }\n for (const i in a) {\n if (!equals(a[i], b[i])) {\n return false;\n }\n }\n return true;\n }\n if (Array.isArray(a) || Array.isArray(b)) {\n return false;\n }\n if (a === null || b === null) {\n return a === b;\n }\n return Math.abs(a - b) < accuracy;\n}\nfunction lessOrEquals(a: number, b: number, accuracy = EPSILON): boolean {\n return a - b <= accuracy;\n}\n\nexport const enum Format {\n Nickname = 'nickname',\n HEX = 'hex',\n ShortHEX = 'shorthex',\n HEXA = 'hexa',\n ShortHEXA = 'shorthexa',\n RGB = 'rgb',\n RGBA = 'rgba',\n HSL = 'hsl',\n HSLA = 'hsla',\n HWB = 'hwb',\n HWBA = 'hwba',\n LCH = 'lch',\n OKLCH = 'oklch',\n LAB = 'lab',\n OKLAB = 'oklab',\n SRGB = 'srgb',\n SRGB_LINEAR = 'srgb-linear',\n DISPLAY_P3 = 'display-p3',\n A98_RGB = 'a98-rgb',\n PROPHOTO_RGB = 'prophoto-rgb',\n REC_2020 = 'rec2020',\n XYZ = 'xyz',\n XYZ_D50 = 'xyz-d50',\n XYZ_D65 = 'xyz-d65',\n}\n\nexport class Lab implements Color {\n readonly l: number;\n readonly a: number;\n readonly b: number;\n readonly alpha: number|null;\n readonly #authoredText?: string;\n readonly #rawParams: Color3D;\n\n static readonly #conversions: ColorConversions<Lab> = {\n [Format.Nickname]: (self: Lab) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.Nickname),\n [Format.HEX]: (self: Lab) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.HEX),\n [Format.ShortHEX]: (self: Lab) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.ShortHEX),\n [Format.HEXA]: (self: Lab) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.HEXA),\n [Format.ShortHEXA]: (self: Lab) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.ShortHEXA),\n [Format.RGB]: (self: Lab) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.RGB),\n [Format.RGBA]: (self: Lab) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.RGBA),\n [Format.HSL]: (self: Lab) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HSLA]: (self: Lab) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWB]: (self: Lab) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWBA]: (self: Lab) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.LCH]: (self: Lab) => new LCH(...ColorConverter.labToLch(self.l, self.a, self.b), self.alpha),\n [Format.OKLCH]: (self: Lab) => new Oklch(...ColorConverter.xyzd50ToOklch(...self.#toXyzd50()), self.alpha),\n [Format.LAB]: (self: Lab) => self,\n [Format.OKLAB]: (self: Lab) =>\n new Oklab(...ColorConverter.xyzd65ToOklab(...ColorConverter.xyzd50ToD65(...self.#toXyzd50())), self.alpha),\n\n [Format.SRGB]: (self: Lab) =>\n new ColorFunction(Format.SRGB, ...ColorConverter.xyzd50ToSrgb(...self.#toXyzd50()), self.alpha),\n [Format.SRGB_LINEAR]: (self: Lab) =>\n new ColorFunction(Format.SRGB_LINEAR, ...ColorConverter.xyzd50TosRGBLinear(...self.#toXyzd50()), self.alpha),\n [Format.DISPLAY_P3]: (self: Lab) =>\n new ColorFunction(Format.DISPLAY_P3, ...ColorConverter.xyzd50ToDisplayP3(...self.#toXyzd50()), self.alpha),\n [Format.A98_RGB]: (self: Lab) =>\n new ColorFunction(Format.A98_RGB, ...ColorConverter.xyzd50ToAdobeRGB(...self.#toXyzd50()), self.alpha),\n [Format.PROPHOTO_RGB]: (self: Lab) =>\n new ColorFunction(Format.PROPHOTO_RGB, ...ColorConverter.xyzd50ToProPhoto(...self.#toXyzd50()), self.alpha),\n [Format.REC_2020]: (self: Lab) =>\n new ColorFunction(Format.REC_2020, ...ColorConverter.xyzd50ToRec2020(...self.#toXyzd50()), self.alpha),\n [Format.XYZ]: (self: Lab) =>\n new ColorFunction(Format.XYZ, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n [Format.XYZ_D50]: (self: Lab) => new ColorFunction(Format.XYZ_D50, ...self.#toXyzd50(), self.alpha),\n [Format.XYZ_D65]: (self: Lab) =>\n new ColorFunction(Format.XYZ_D65, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n };\n\n #toXyzd50(): Color3D {\n return ColorConverter.labToXyzd50(this.l, this.a, this.b);\n }\n\n #getRGBArray(withAlpha: true): Color4DOr3D;\n #getRGBArray(withAlpha: false): Color3D;\n #getRGBArray(withAlpha: boolean = true): Color3D|Color4DOr3D {\n const params = ColorConverter.xyzd50ToSrgb(...this.#toXyzd50());\n if (withAlpha) {\n return [...params, this.alpha ?? undefined];\n }\n return params;\n }\n\n constructor(l: number, a: number, b: number, alpha: number|null, authoredText?: string|undefined) {\n this.#rawParams = [l, a, b];\n this.l = clamp(l, {min: 0, max: 100});\n if (equals(this.l, 0, WIDE_RANGE_EPSILON) || equals(this.l, 100, WIDE_RANGE_EPSILON)) {\n a = b = 0;\n }\n this.a = a;\n this.b = b;\n this.alpha = clamp(alpha, {min: 0, max: 1});\n this.#authoredText = authoredText;\n }\n as<T extends Format>(format: T): ReturnType<ColorConversions[T]> {\n return Lab.#conversions[format](this) as ReturnType<ColorConversions[T]>;\n }\n asLegacyColor(): Legacy {\n return this.as(Format.RGBA);\n }\n equal(color: Color): boolean {\n const lab = color.as(Format.LAB);\n return equals(lab.l, this.l, WIDE_RANGE_EPSILON) && equals(lab.a, this.a) && equals(lab.b, this.b) &&\n equals(lab.alpha, this.alpha);\n }\n format(): Format {\n return Format.LAB;\n }\n setAlpha(alpha: number): Lab {\n return new Lab(this.l, this.a, this.b, alpha, undefined);\n }\n asString(format?: Format): string|null {\n if (format) {\n return this.as(format).asString();\n }\n return this.#stringify(this.l, this.a, this.b);\n }\n #stringify(l: number, a: number, b: number): string|null {\n const alpha = this.alpha === null || equals(this.alpha, 1) ?\n '' :\n ` / ${Platform.StringUtilities.stringifyWithPrecision(this.alpha)}`;\n return `lab(${Platform.StringUtilities.stringifyWithPrecision(l, 0)} ${\n Platform.StringUtilities.stringifyWithPrecision(\n a)} ${Platform.StringUtilities.stringifyWithPrecision(b)}${alpha})`;\n }\n getAuthoredText(): string|null {\n return this.#authoredText ?? null;\n }\n\n getRawParameters(): Color3D {\n return [...this.#rawParams];\n }\n getAsRawString(format?: Format): string|null {\n if (format) {\n return this.as(format).getAsRawString();\n }\n return this.#stringify(...this.#rawParams);\n }\n isGamutClipped(): boolean {\n return false;\n }\n\n static fromSpec(spec: ColorParameterSpec, text: string): Lab|null {\n const L = parsePercentage(spec[0], [0, 100]) ?? parseNumber(spec[0]);\n if (L === null) {\n return null;\n }\n const a = parsePercentage(spec[1], [0, 125]) ?? parseNumber(spec[1]);\n if (a === null) {\n return null;\n }\n const b = parsePercentage(spec[2], [0, 125]) ?? parseNumber(spec[2]);\n if (b === null) {\n return null;\n }\n const alpha = parseAlpha(spec[3]);\n\n return new Lab(L, a, b, alpha, text);\n }\n}\n\nexport class LCH implements Color {\n readonly #rawParams: Color3D;\n readonly l: number;\n readonly c: number;\n readonly h: number;\n readonly alpha: number|null;\n readonly #authoredText?: string;\n\n static readonly #conversions: ColorConversions<LCH> = {\n [Format.Nickname]: (self: LCH) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.Nickname),\n [Format.HEX]: (self: LCH) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.HEX),\n [Format.ShortHEX]: (self: LCH) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.ShortHEX),\n [Format.HEXA]: (self: LCH) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.HEXA),\n [Format.ShortHEXA]: (self: LCH) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.ShortHEXA),\n [Format.RGB]: (self: LCH) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.RGB),\n [Format.RGBA]: (self: LCH) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.RGBA),\n [Format.HSL]: (self: LCH) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HSLA]: (self: LCH) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWB]: (self: LCH) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWBA]: (self: LCH) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.LCH]: (self: LCH) => self,\n [Format.OKLCH]: (self: LCH) => new Oklch(...ColorConverter.xyzd50ToOklch(...self.#toXyzd50()), self.alpha),\n [Format.LAB]: (self: LCH) => new Lab(...ColorConverter.lchToLab(self.l, self.c, self.h), self.alpha),\n [Format.OKLAB]: (self: LCH) =>\n new Oklab(...ColorConverter.xyzd65ToOklab(...ColorConverter.xyzd50ToD65(...self.#toXyzd50())), self.alpha),\n\n [Format.SRGB]: (self: LCH) =>\n new ColorFunction(Format.SRGB, ...ColorConverter.xyzd50ToSrgb(...self.#toXyzd50()), self.alpha),\n [Format.SRGB_LINEAR]: (self: LCH) =>\n new ColorFunction(Format.SRGB_LINEAR, ...ColorConverter.xyzd50TosRGBLinear(...self.#toXyzd50()), self.alpha),\n [Format.DISPLAY_P3]: (self: LCH) =>\n new ColorFunction(Format.DISPLAY_P3, ...ColorConverter.xyzd50ToDisplayP3(...self.#toXyzd50()), self.alpha),\n [Format.A98_RGB]: (self: LCH) =>\n new ColorFunction(Format.A98_RGB, ...ColorConverter.xyzd50ToAdobeRGB(...self.#toXyzd50()), self.alpha),\n [Format.PROPHOTO_RGB]: (self: LCH) =>\n new ColorFunction(Format.PROPHOTO_RGB, ...ColorConverter.xyzd50ToProPhoto(...self.#toXyzd50()), self.alpha),\n [Format.REC_2020]: (self: LCH) =>\n new ColorFunction(Format.REC_2020, ...ColorConverter.xyzd50ToRec2020(...self.#toXyzd50()), self.alpha),\n [Format.XYZ]: (self: LCH) =>\n new ColorFunction(Format.XYZ, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n [Format.XYZ_D50]: (self: LCH) => new ColorFunction(Format.XYZ_D50, ...self.#toXyzd50(), self.alpha),\n [Format.XYZ_D65]: (self: LCH) =>\n new ColorFunction(Format.XYZ_D65, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n };\n\n #toXyzd50(): Color3D {\n return ColorConverter.labToXyzd50(...ColorConverter.lchToLab(this.l, this.c, this.h));\n }\n\n #getRGBArray(withAlpha: true): Color4DOr3D;\n #getRGBArray(withAlpha: false): Color3D;\n #getRGBArray(withAlpha: boolean = true): Color4DOr3D|Color3D {\n const params = ColorConverter.xyzd50ToSrgb(...this.#toXyzd50());\n if (withAlpha) {\n return [...params, this.alpha ?? undefined];\n }\n return params;\n }\n\n constructor(l: number, c: number, h: number, alpha: number|null, authoredText?: string|undefined) {\n this.#rawParams = [l, c, h];\n this.l = clamp(l, {min: 0, max: 100});\n c = equals(this.l, 0, WIDE_RANGE_EPSILON) || equals(this.l, 100, WIDE_RANGE_EPSILON) ? 0 : c;\n this.c = clamp(c, {min: 0});\n h = equals(c, 0) ? 0 : h;\n this.h = normalizeHue(h);\n this.alpha = clamp(alpha, {min: 0, max: 1});\n this.#authoredText = authoredText;\n }\n asLegacyColor(): Legacy {\n return this.as(Format.RGBA);\n }\n as<T extends Format>(format: T): ReturnType<ColorConversions[T]> {\n return LCH.#conversions[format](this) as ReturnType<ColorConversions[T]>;\n }\n equal(color: Color): boolean {\n const lch = color.as(Format.LCH);\n return equals(lch.l, this.l, WIDE_RANGE_EPSILON) && equals(lch.c, this.c) && equals(lch.h, this.h) &&\n equals(lch.alpha, this.alpha);\n }\n format(): Format {\n return Format.LCH;\n }\n setAlpha(alpha: number): Color {\n return new LCH(this.l, this.c, this.h, alpha);\n }\n asString(format?: Format): string|null {\n if (format) {\n return this.as(format).asString();\n }\n return this.#stringify(this.l, this.c, this.h);\n }\n #stringify(l: number, c: number, h: number): string|null {\n const alpha = this.alpha === null || equals(this.alpha, 1) ?\n '' :\n ` / ${Platform.StringUtilities.stringifyWithPrecision(this.alpha)}`;\n return `lch(${Platform.StringUtilities.stringifyWithPrecision(l, 0)} ${\n Platform.StringUtilities.stringifyWithPrecision(\n c)} ${Platform.StringUtilities.stringifyWithPrecision(h)}${alpha})`;\n }\n getAuthoredText(): string|null {\n return this.#authoredText ?? null;\n }\n\n getRawParameters(): Color3D {\n return [...this.#rawParams];\n }\n getAsRawString(format?: Format): string|null {\n if (format) {\n return this.as(format).getAsRawString();\n }\n return this.#stringify(...this.#rawParams);\n }\n isGamutClipped(): boolean {\n return false;\n }\n // See \"powerless\" component definitions in\n // https://www.w3.org/TR/css-color-4/#specifying-lab-lch\n isHuePowerless(): boolean {\n return equals(this.c, 0);\n }\n static fromSpec(spec: ColorParameterSpec, text: string): LCH|null {\n const L = parsePercentage(spec[0], [0, 100]) ?? parseNumber(spec[0]);\n if (L === null) {\n return null;\n }\n const c = parsePercentage(spec[1], [0, 150]) ?? parseNumber(spec[1]);\n if (c === null) {\n return null;\n }\n const h = parseAngle(spec[2]);\n if (h === null) {\n return null;\n }\n const alpha = parseAlpha(spec[3]);\n\n return new LCH(L, c, h, alpha, text);\n }\n}\n\nexport class Oklab implements Color {\n readonly #rawParams: Color3D;\n readonly l: number;\n readonly a: number;\n readonly b: number;\n readonly alpha: number|null;\n readonly #authoredText?: string;\n\n static readonly #conversions: ColorConversions<Oklab> = {\n [Format.Nickname]: (self: Oklab) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.Nickname),\n [Format.HEX]: (self: Oklab) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.HEX),\n [Format.ShortHEX]: (self: Oklab) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.ShortHEX),\n [Format.HEXA]: (self: Oklab) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.HEXA),\n [Format.ShortHEXA]: (self: Oklab) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.ShortHEXA),\n [Format.RGB]: (self: Oklab) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.RGB),\n [Format.RGBA]: (self: Oklab) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.RGBA),\n [Format.HSL]: (self: Oklab) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HSLA]: (self: Oklab) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWB]: (self: Oklab) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWBA]: (self: Oklab) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.LCH]: (self: Oklab) =>\n new LCH(...ColorConverter.labToLch(...ColorConverter.xyzd50ToLab(...self.#toXyzd50())), self.alpha),\n [Format.OKLCH]: (self: Oklab) => new Oklch(...ColorConverter.xyzd50ToOklch(...self.#toXyzd50()), self.alpha),\n [Format.LAB]: (self: Oklab) => new Lab(...ColorConverter.xyzd50ToLab(...self.#toXyzd50()), self.alpha),\n [Format.OKLAB]: (self: Oklab) => self,\n\n [Format.SRGB]: (self: Oklab) =>\n new ColorFunction(Format.SRGB, ...ColorConverter.xyzd50ToSrgb(...self.#toXyzd50()), self.alpha),\n [Format.SRGB_LINEAR]: (self: Oklab) =>\n new ColorFunction(Format.SRGB_LINEAR, ...ColorConverter.xyzd50TosRGBLinear(...self.#toXyzd50()), self.alpha),\n [Format.DISPLAY_P3]: (self: Oklab) =>\n new ColorFunction(Format.DISPLAY_P3, ...ColorConverter.xyzd50ToDisplayP3(...self.#toXyzd50()), self.alpha),\n [Format.A98_RGB]: (self: Oklab) =>\n new ColorFunction(Format.A98_RGB, ...ColorConverter.xyzd50ToAdobeRGB(...self.#toXyzd50()), self.alpha),\n [Format.PROPHOTO_RGB]: (self: Oklab) =>\n new ColorFunction(Format.PROPHOTO_RGB, ...ColorConverter.xyzd50ToProPhoto(...self.#toXyzd50()), self.alpha),\n [Format.REC_2020]: (self: Oklab) =>\n new ColorFunction(Format.REC_2020, ...ColorConverter.xyzd50ToRec2020(...self.#toXyzd50()), self.alpha),\n [Format.XYZ]: (self: Oklab) =>\n new ColorFunction(Format.XYZ, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n [Format.XYZ_D50]: (self: Oklab) => new ColorFunction(Format.XYZ_D50, ...self.#toXyzd50(), self.alpha),\n [Format.XYZ_D65]: (self: Oklab) =>\n new ColorFunction(Format.XYZ_D65, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n };\n\n #toXyzd50(): Color3D {\n return ColorConverter.xyzd65ToD50(...ColorConverter.oklabToXyzd65(this.l, this.a, this.b));\n }\n\n #getRGBArray(withAlpha: true): Color4DOr3D;\n #getRGBArray(withAlpha: false): Color3D;\n #getRGBArray(withAlpha: boolean = true): Color4DOr3D|Color3D {\n const params = ColorConverter.xyzd50ToSrgb(...this.#toXyzd50());\n if (withAlpha) {\n return [...params, this.alpha ?? undefined];\n }\n return params;\n }\n\n constructor(l: number, a: number, b: number, alpha: number|null, authoredText?: string|undefined) {\n this.#rawParams = [l, a, b];\n this.l = clamp(l, {min: 0, max: 1});\n if (equals(this.l, 0) || equals(this.l, 1)) {\n a = b = 0;\n }\n this.a = a;\n this.b = b;\n this.alpha = clamp(alpha, {min: 0, max: 1});\n this.#authoredText = authoredText;\n }\n asLegacyColor(): Legacy {\n return this.as(Format.RGBA);\n }\n as<T extends Format>(format: T): ReturnType<ColorConversions[T]> {\n return Oklab.#conversions[format](this) as ReturnType<ColorConversions[T]>;\n }\n equal(color: Color): boolean {\n const oklab = color.as(Format.OKLAB);\n return equals(oklab.l, this.l) && equals(oklab.a, this.a) && equals(oklab.b, this.b) &&\n equals(oklab.alpha, this.alpha);\n }\n format(): Format {\n return Format.OKLAB;\n }\n setAlpha(alpha: number): Color {\n return new Oklab(this.l, this.a, this.b, alpha);\n }\n asString(format?: Format): string|null {\n if (format) {\n return this.as(format).asString();\n }\n return this.#stringify(this.l, this.a, this.b);\n }\n #stringify(l: number, a: number, b: number): string|null {\n const alpha = this.alpha === null || equals(this.alpha, 1) ?\n '' :\n ` / ${Platform.StringUtilities.stringifyWithPrecision(this.alpha)}`;\n return `oklab(${Platform.StringUtilities.stringifyWithPrecision(l)} ${\n Platform.StringUtilities.stringifyWithPrecision(\n a)} ${Platform.StringUtilities.stringifyWithPrecision(b)}${alpha})`;\n }\n getAuthoredText(): string|null {\n return this.#authoredText ?? null;\n }\n\n getRawParameters(): Color3D {\n return [...this.#rawParams];\n }\n getAsRawString(format?: Format): string|null {\n if (format) {\n return this.as(format).getAsRawString();\n }\n return this.#stringify(...this.#rawParams);\n }\n isGamutClipped(): boolean {\n return false;\n }\n\n static fromSpec(spec: ColorParameterSpec, text: string): Oklab|null {\n const L = parsePercentage(spec[0], [0, 1]) ?? parseNumber(spec[0]);\n if (L === null) {\n return null;\n }\n const a = parsePercentage(spec[1], [0, 0.4]) ?? parseNumber(spec[1]);\n if (a === null) {\n return null;\n }\n const b = parsePercentage(spec[2], [0, 0.4]) ?? parseNumber(spec[2]);\n if (b === null) {\n return null;\n }\n const alpha = parseAlpha(spec[3]);\n\n return new Oklab(L, a, b, alpha, text);\n }\n}\n\nexport class Oklch implements Color {\n readonly #rawParams: Color3D;\n readonly l: number;\n readonly c: number;\n readonly h: number;\n readonly alpha: number|null;\n readonly #authoredText?: string;\n\n static readonly #conversions: ColorConversions<Oklch> = {\n [Format.Nickname]: (self: Oklch) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.Nickname),\n [Format.HEX]: (self: Oklch) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.HEX),\n [Format.ShortHEX]: (self: Oklch) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.ShortHEX),\n [Format.HEXA]: (self: Oklch) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.HEXA),\n [Format.ShortHEXA]: (self: Oklch) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.ShortHEXA),\n [Format.RGB]: (self: Oklch) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.RGB),\n [Format.RGBA]: (self: Oklch) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.RGBA),\n [Format.HSL]: (self: Oklch) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HSLA]: (self: Oklch) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWB]: (self: Oklch) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWBA]: (self: Oklch) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.LCH]: (self: Oklch) =>\n new LCH(...ColorConverter.labToLch(...ColorConverter.xyzd50ToLab(...self.#toXyzd50())), self.alpha),\n [Format.OKLCH]: (self: Oklch) => self,\n [Format.LAB]: (self: Oklch) => new Lab(...ColorConverter.xyzd50ToLab(...self.#toXyzd50()), self.alpha),\n [Format.OKLAB]: (self: Oklch) =>\n new Oklab(...ColorConverter.xyzd65ToOklab(...ColorConverter.xyzd50ToD65(...self.#toXyzd50())), self.alpha),\n [Format.SRGB]: (self: Oklch) =>\n new ColorFunction(Format.SRGB, ...ColorConverter.xyzd50ToSrgb(...self.#toXyzd50()), self.alpha),\n [Format.SRGB_LINEAR]: (self: Oklch) =>\n new ColorFunction(Format.SRGB_LINEAR, ...ColorConverter.xyzd50TosRGBLinear(...self.#toXyzd50()), self.alpha),\n [Format.DISPLAY_P3]: (self: Oklch) =>\n new ColorFunction(Format.DISPLAY_P3, ...ColorConverter.xyzd50ToDisplayP3(...self.#toXyzd50()), self.alpha),\n [Format.A98_RGB]: (self: Oklch) =>\n new ColorFunction(Format.A98_RGB, ...ColorConverter.xyzd50ToAdobeRGB(...self.#toXyzd50()), self.alpha),\n [Format.PROPHOTO_RGB]: (self: Oklch) =>\n new ColorFunction(Format.PROPHOTO_RGB, ...ColorConverter.xyzd50ToProPhoto(...self.#toXyzd50()), self.alpha),\n [Format.REC_2020]: (self: Oklch) =>\n new ColorFunction(Format.REC_2020, ...ColorConverter.xyzd50ToRec2020(...self.#toXyzd50()), self.alpha),\n [Format.XYZ]: (self: Oklch) =>\n new ColorFunction(Format.XYZ, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n [Format.XYZ_D50]: (self: Oklch) => new ColorFunction(Format.XYZ_D50, ...self.#toXyzd50(), self.alpha),\n [Format.XYZ_D65]: (self: Oklch) =>\n new ColorFunction(Format.XYZ_D65, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n };\n\n #toXyzd50(): Color3D {\n return ColorConverter.oklchToXyzd50(this.l, this.c, this.h);\n }\n\n #getRGBArray(withAlpha: true): Color4DOr3D;\n #getRGBArray(withAlpha: false): Color3D;\n #getRGBArray(withAlpha: boolean = true): Color4DOr3D|Color3D {\n const params = ColorConverter.xyzd50ToSrgb(...this.#toXyzd50());\n if (withAlpha) {\n return [...params, this.alpha ?? undefined];\n }\n return params;\n }\n\n constructor(l: number, c: number, h: number, alpha: number|null, authoredText?: string|undefined) {\n this.#rawParams = [l, c, h];\n this.l = clamp(l, {min: 0, max: 1});\n c = equals(this.l, 0) || equals(this.l, 1) ? 0 : c;\n this.c = clamp(c, {min: 0});\n h = equals(c, 0) ? 0 : h;\n this.h = normalizeHue(h);\n this.alpha = clamp(alpha, {min: 0, max: 1});\n this.#authoredText = authoredText;\n }\n asLegacyColor(): Legacy {\n return this.as(Format.RGBA);\n }\n as<T extends Format>(format: T): ReturnType<ColorConversions[T]> {\n return Oklch.#conversions[format](this) as ReturnType<ColorConversions[T]>;\n }\n equal(color: Color): boolean {\n const oklch = color.as(Format.OKLCH);\n return equals(oklch.l, this.l) && equals(oklch.c, this.c) && equals(oklch.h, this.h) &&\n equals(oklch.alpha, this.alpha);\n }\n format(): Format {\n return Format.OKLCH;\n }\n setAlpha(alpha: number): Color {\n return new Oklch(this.l, this.c, this.h, alpha);\n }\n asString(format?: Format): string|null {\n if (format) {\n return this.as(format).asString();\n }\n return this.#stringify(this.l, this.c, this.h);\n }\n #stringify(l: number, c: number, h: number): string|null {\n const alpha = this.alpha === null || equals(this.alpha, 1) ?\n '' :\n ` / ${Platform.StringUtilities.stringifyWithPrecision(this.alpha)}`;\n return `oklch(${Platform.StringUtilities.stringifyWithPrecision(l)} ${\n Platform.StringUtilities.stringifyWithPrecision(\n c)} ${Platform.StringUtilities.stringifyWithPrecision(h)}${alpha})`;\n }\n getAuthoredText(): string|null {\n return this.#authoredText ?? null;\n }\n\n getRawParameters(): Color3D {\n return [...this.#rawParams];\n }\n getAsRawString(format?: Format): string|null {\n if (format) {\n return this.as(format).getAsRawString();\n }\n return this.#stringify(...this.#rawParams);\n }\n isGamutClipped(): boolean {\n return false;\n }\n\n static fromSpec(spec: ColorParameterSpec, text: string): Oklch|null {\n const L = parsePercentage(spec[0], [0, 1]) ?? parseNumber(spec[0]);\n if (L === null) {\n return null;\n }\n const c = parsePercentage(spec[1], [0, 0.4]) ?? parseNumber(spec[1]);\n if (c === null) {\n return null;\n }\n const h = parseAngle(spec[2]);\n if (h === null) {\n return null;\n }\n const alpha = parseAlpha(spec[3]);\n\n return new Oklch(L, c, h, alpha, text);\n }\n}\n\nexport class ColorFunction implements Color {\n readonly #rawParams: Color3D;\n readonly p0: number;\n readonly p1: number;\n readonly p2: number;\n readonly alpha: number|null;\n readonly colorSpace: ColorSpace;\n readonly #authoredText?: string;\n\n static readonly #conversions: ColorConversions<ColorFunction> = {\n [Format.Nickname]: (self: ColorFunction) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.Nickname),\n [Format.HEX]: (self: ColorFunction) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.HEX),\n [Format.ShortHEX]: (self: ColorFunction) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.ShortHEX),\n [Format.HEXA]: (self: ColorFunction) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.HEXA),\n [Format.ShortHEXA]: (self: ColorFunction) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.ShortHEXA),\n [Format.RGB]: (self: ColorFunction) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.RGB),\n [Format.RGBA]: (self: ColorFunction) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.RGBA),\n [Format.HSL]: (self: ColorFunction) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HSLA]: (self: ColorFunction) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWB]: (self: ColorFunction) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWBA]: (self: ColorFunction) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.LCH]: (self: ColorFunction) =>\n new LCH(...ColorConverter.labToLch(...ColorConverter.xyzd50ToLab(...self.#toXyzd50())), self.alpha),\n [Format.OKLCH]: (self: ColorFunction) =>\n new Oklch(...ColorConverter.xyzd50ToOklch(...self.#toXyzd50()), self.alpha),\n [Format.LAB]: (self: ColorFunction) => new Lab(...ColorConverter.xyzd50ToLab(...self.#toXyzd50()), self.alpha),\n [Format.OKLAB]: (self: ColorFunction) =>\n new Oklab(...ColorConverter.xyzd65ToOklab(...ColorConverter.xyzd50ToD65(...self.#toXyzd50())), self.alpha),\n\n [Format.SRGB]: (self: ColorFunction) =>\n new ColorFunction(Format.SRGB, ...ColorConverter.xyzd50ToSrgb(...self.#toXyzd50()), self.alpha),\n [Format.SRGB_LINEAR]: (self: ColorFunction) =>\n new ColorFunction(Format.SRGB_LINEAR, ...ColorConverter.xyzd50TosRGBLinear(...self.#toXyzd50()), self.alpha),\n [Format.DISPLAY_P3]: (self: ColorFunction) =>\n new ColorFunction(Format.DISPLAY_P3, ...ColorConverter.xyzd50ToDisplayP3(...self.#toXyzd50()), self.alpha),\n [Format.A98_RGB]: (self: ColorFunction) =>\n new ColorFunction(Format.A98_RGB, ...ColorConverter.xyzd50ToAdobeRGB(...self.#toXyzd50()), self.alpha),\n [Format.PROPHOTO_RGB]: (self: ColorFunction) =>\n new ColorFunction(Format.PROPHOTO_RGB, ...ColorConverter.xyzd50ToProPhoto(...self.#toXyzd50()), self.alpha),\n [Format.REC_2020]: (self: ColorFunction) =>\n new ColorFunction(Format.REC_2020, ...ColorConverter.xyzd50ToRec2020(...self.#toXyzd50()), self.alpha),\n [Format.XYZ]: (self: ColorFunction) =>\n new ColorFunction(Format.XYZ, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n [Format.XYZ_D50]: (self: ColorFunction) => new ColorFunction(Format.XYZ_D50, ...self.#toXyzd50(), self.alpha),\n [Format.XYZ_D65]: (self: ColorFunction) =>\n new ColorFunction(Format.XYZ_D65, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n };\n\n #toXyzd50(): Color3D {\n // With color(), out-of-gamut inputs are to be used for intermediate computations\n const [p0, p1, p2] = this.#rawParams;\n switch (this.colorSpace) {\n case Format.SRGB:\n return ColorConverter.srgbToXyzd50(p0, p1, p2);\n case Format.SRGB_LINEAR:\n return ColorConverter.srgbLinearToXyzd50(p0, p1, p2);\n case Format.DISPLAY_P3:\n return ColorConverter.displayP3ToXyzd50(p0, p1, p2);\n case Format.A98_RGB:\n return ColorConverter.adobeRGBToXyzd50(p0, p1, p2);\n case Format.PROPHOTO_RGB:\n return ColorConverter.proPhotoToXyzd50(p0, p1, p2);\n case Format.REC_2020:\n return ColorConverter.rec2020ToXyzd50(p0, p1, p2);\n case Format.XYZ_D50:\n return [p0, p1, p2];\n case Format.XYZ:\n case Format.XYZ_D65:\n return ColorConverter.xyzd65ToD50(p0, p1, p2);\n }\n throw new Error('Invalid color space');\n }\n\n #getRGBArray(withAlpha: true): Color4DOr3D;\n #getRGBArray(withAlpha: false): Color3D;\n #getRGBArray(withAlpha: boolean = true): Color4DOr3D|Color3D {\n // With color(), out-of-gamut inputs are to be used for intermediate computations\n const [p0, p1, p2] = this.#rawParams;\n const params: Color3D =\n this.colorSpace === Format.SRGB ? [p0, p1, p2] : [...ColorConverter.xyzd50ToSrgb(...this.#toXyzd50())];\n if (withAlpha) {\n return [...params, this.alpha ?? undefined];\n }\n return params;\n }\n\n constructor(\n colorSpace: ColorSpace, p0: number, p1: number, p2: number, alpha: number|null, authoredText?: string|undefined) {\n this.#rawParams = [p0, p1, p2];\n this.colorSpace = colorSpace;\n this.#authoredText = authoredText;\n if (this.colorSpace !== Format.XYZ_D50 && this.colorSpace !== Format.XYZ_D65 && this.colorSpace !== Format.XYZ) {\n p0 = clamp(p0, {min: 0, max: 1});\n p1 = clamp(p1, {min: 0, max: 1});\n p2 = clamp(p2, {min: 0, max: 1});\n }\n\n this.p0 = p0;\n this.p1 = p1;\n this.p2 = p2;\n this.alpha = clamp(alpha, {min: 0, max: 1});\n }\n asLegacyColor(): Legacy {\n return this.as(Format.RGBA);\n }\n as<T extends Format>(format: T): ReturnType<ColorConversions[T]> {\n if (this.colorSpace === format) {\n return this as ReturnType<ColorConversions[T]>;\n }\n return ColorFunction.#conversions[format](this) as ReturnType<ColorConversions[T]>;\n }\n equal(color: Color): boolean {\n const space = color.as(this.colorSpace);\n return equals(this.p0, space.p0) && equals(this.p1, space.p1) && equals(this.p2, space.p2) &&\n equals(this.alpha, space.alpha);\n }\n format(): Format {\n return this.colorSpace;\n }\n setAlpha(alpha: number): Color {\n return new ColorFunction(this.colorSpace, this.p0, this.p1, this.p2, alpha);\n }\n asString(format?: Format): string|null {\n if (format) {\n return this.as(format).asString();\n }\n return this.#stringify(this.p0, this.p1, this.p2);\n }\n #stringify(p0: number, p1: number, p2: number): string|null {\n const alpha = this.alpha === null || equals(this.alpha, 1) ?\n '' :\n ` / ${Platform.StringUtilities.stringifyWithPrecision(this.alpha)}`;\n return `color(${this.colorSpace} ${Platform.StringUtilities.stringifyWithPrecision(p0)} ${\n Platform.StringUtilities.stringifyWithPrecision(\n p1)} ${Platform.StringUtilities.stringifyWithPrecision(p2)}${alpha})`;\n }\n getAuthoredText(): string|null {\n return this.#authoredText ?? null;\n }\n\n getRawParameters(): Color3D {\n return [...this.#rawParams];\n }\n getAsRawString(format?: Format): string|null {\n if (format) {\n return this.as(format).getAsRawString();\n }\n return this.#stringify(...this.#rawParams);\n }\n isGamutClipped(): boolean {\n if (this.colorSpace !== Format.XYZ_D50 && this.colorSpace !== Format.XYZ_D65 && this.colorSpace !== Format.XYZ) {\n return !equals(this.#rawParams, [this.p0, this.p1, this.p2]);\n }\n return false;\n }\n\n /**\n * Parses given `color()` function definition and returns the `Color` object.\n * We want to special case its parsing here because it's a bit different\n * than other color functions: rgb, lch etc. accepts 3 arguments with\n * optional alpha. This accepts 4 arguments with optional alpha.\n *\n * Instead of making `splitColorFunctionParameters` work for this case too\n * I've decided to implement it specifically.\n * @param authoredText Original definition of the color with `color`\n * @param parametersText Inside of the `color()` function. ex, `display-p3 0.1 0.2 0.3 / 0%`\n * @returns `Color` object\n */\n static fromSpec(authoredText: string, parametersWithAlphaText: string): ColorFunction|null {\n const [parametersText, alphaText] = parametersWithAlphaText.split('/', 2);\n const parameters = parametersText.trim().split(/\\s+/);\n const [colorSpaceText, ...remainingParams] = parameters;\n const colorSpace = getColorSpace(colorSpaceText);\n // Color space is not known to us, do not parse the Color.\n if (!colorSpace) {\n return null;\n }\n\n // `color(<color-space>)` is a valid syntax\n if (remainingParams.length === 0 && alphaText === undefined) {\n return new ColorFunction(colorSpace, 0, 0, 0, null, authoredText);\n }\n\n // Check if it contains `/ <alpha>` part, if so, it should be at the end\n if (remainingParams.length === 0 && alphaText !== undefined && alphaText.trim().split(/\\s+/).length > 1) {\n // Invalid syntax: like `color(<space> / <alpha> <number>)`\n return null;\n }\n\n // `color` cannot contain more than 3 parameters without alpha\n if (remainingParams.length > 3) {\n return null;\n }\n\n // Replace `none`s with 0s\n const nonesReplacedParams = remainingParams.map(param => param === 'none' ? '0' : param);\n\n // At this point, we know that all the values are there so we can\n // safely try to parse all the values as number or percentage\n const values = nonesReplacedParams.map(param => parsePercentOrNumber(param, [0, 1]));\n const containsNull = values.includes(null);\n // At least one value is malformatted (not a number or percentage)\n if (containsNull) {\n return null;\n }\n\n const alphaValue = alphaText ? parsePercentOrNumber(alphaText, [0, 1]) ?? 1 : 1;\n\n // Depending on the color space\n // this either reflects `rgb` parameters in that color space\n // or `xyz` parameters in the given `xyz` space.\n const rgbOrXyza: Color4D = [\n values[0] ?? 0,\n values[1] ?? 0,\n values[2] ?? 0,\n alphaValue,\n ];\n\n return new ColorFunction(colorSpace, ...rgbOrXyza, authoredText);\n }\n}\n\nexport class HSL implements Color {\n readonly h: number;\n readonly s: number;\n readonly l: number;\n readonly alpha: number|null;\n readonly #rawParams: Color3D;\n #authoredText: string|undefined;\n\n static readonly #conversions: ColorConversions<HSL> = {\n [Format.Nickname]: (self: HSL) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.Nickname),\n [Format.HEX]: (self: HSL) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.HEX),\n [Format.ShortHEX]: (self: HSL) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.ShortHEX),\n [Format.HEXA]: (self: HSL) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.HEXA),\n [Format.ShortHEXA]: (self: HSL) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.ShortHEXA),\n [Format.RGB]: (self: HSL) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.RGB),\n [Format.RGBA]: (self: HSL) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.RGBA),\n [Format.HSL]: (self: HSL) => self,\n [Format.HSLA]: (self: HSL) => self,\n [Format.HWB]: (self: HSL) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWBA]: (self: HSL) => new HWB(...rgbToHwb(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.LCH]: (self: HSL) =>\n new LCH(...ColorConverter.labToLch(...ColorConverter.xyzd50ToLab(...self.#toXyzd50())), self.alpha),\n [Format.OKLCH]: (self: HSL) => new Oklch(...ColorConverter.xyzd50ToOklch(...self.#toXyzd50()), self.alpha),\n [Format.LAB]: (self: HSL) => new Lab(...ColorConverter.xyzd50ToLab(...self.#toXyzd50()), self.alpha),\n [Format.OKLAB]: (self: HSL) =>\n new Oklab(...ColorConverter.xyzd65ToOklab(...ColorConverter.xyzd50ToD65(...self.#toXyzd50())), self.alpha),\n\n [Format.SRGB]: (self: HSL) =>\n new ColorFunction(Format.SRGB, ...ColorConverter.xyzd50ToSrgb(...self.#toXyzd50()), self.alpha),\n [Format.SRGB_LINEAR]: (self: HSL) =>\n new ColorFunction(Format.SRGB_LINEAR, ...ColorConverter.xyzd50TosRGBLinear(...self.#toXyzd50()), self.alpha),\n [Format.DISPLAY_P3]: (self: HSL) =>\n new ColorFunction(Format.DISPLAY_P3, ...ColorConverter.xyzd50ToDisplayP3(...self.#toXyzd50()), self.alpha),\n [Format.A98_RGB]: (self: HSL) =>\n new ColorFunction(Format.A98_RGB, ...ColorConverter.xyzd50ToAdobeRGB(...self.#toXyzd50()), self.alpha),\n [Format.PROPHOTO_RGB]: (self: HSL) =>\n new ColorFunction(Format.PROPHOTO_RGB, ...ColorConverter.xyzd50ToProPhoto(...self.#toXyzd50()), self.alpha),\n [Format.REC_2020]: (self: HSL) =>\n new ColorFunction(Format.REC_2020, ...ColorConverter.xyzd50ToRec2020(...self.#toXyzd50()), self.alpha),\n [Format.XYZ]: (self: HSL) =>\n new ColorFunction(Format.XYZ, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n [Format.XYZ_D50]: (self: HSL) => new ColorFunction(Format.XYZ_D50, ...self.#toXyzd50(), self.alpha),\n [Format.XYZ_D65]: (self: HSL) =>\n new ColorFunction(Format.XYZ_D65, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n };\n\n #getRGBArray(withAlpha: true): Color4DOr3D;\n #getRGBArray(withAlpha: false): Color3D;\n #getRGBArray(withAlpha: boolean = true): Color4DOr3D|Color3D {\n const rgb: Color4D = [0, 0, 0, 0];\n hsl2rgb([this.h, this.s, this.l, 0], rgb);\n if (withAlpha) {\n return [rgb[0], rgb[1], rgb[2], this.alpha ?? undefined];\n }\n return [rgb[0], rgb[1], rgb[2]];\n }\n\n #toXyzd50(): Color3D {\n const rgb = this.#getRGBArray(false);\n return ColorConverter.srgbToXyzd50(rgb[0], rgb[1], rgb[2]);\n }\n\n constructor(h: number, s: number, l: number, alpha: number|null|undefined, authoredText?: string) {\n this.#rawParams = [h, s, l];\n this.l = clamp(l, {min: 0, max: 1});\n s = equals(this.l, 0) || equals(this.l, 1) ? 0 : s;\n this.s = clamp(s, {min: 0, max: 1});\n h = equals(this.s, 0) ? 0 : h;\n this.h = normalizeHue(h * 360) / 360;\n this.alpha = clamp(alpha ?? null, {min: 0, max: 1});\n this.#authoredText = authoredText;\n }\n\n equal(color: Color): boolean {\n const hsl = color.as(Format.HSL);\n return equals(this.h, hsl.h) && equals(this.s, hsl.s) && equals(this.l, hsl.l) && equals(this.alpha, hsl.alpha);\n }\n asString(format?: Format|undefined): string|null {\n if (format) {\n return this.as(format).asString();\n }\n return this.#stringify(this.h, this.s, this.l);\n }\n #stringify(h: number, s: number, l: number): string {\n const start = Platform.StringUtilities.sprintf(\n 'hsl(%sdeg %s% %s%', Platform.StringUtilities.stringifyWithPrecision(h * 360),\n Platform.StringUtilities.stringifyWithPrecision(s * 100),\n Platform.StringUtilities.stringifyWithPrecision(l * 100));\n if (this.alpha !== null && this.alpha !== 1) {\n return start +\n Platform.StringUtilities.sprintf(\n ' / %s%)', Platform.StringUtilities.stringifyWithPrecision(this.alpha * 100));\n }\n return start + ')';\n }\n setAlpha(alpha: number): HSL {\n return new HSL(this.h, this.s, this.l, alpha);\n }\n format(): Format {\n return this.alpha === null || this.alpha === 1 ? Format.HSL : Format.HSLA;\n }\n as<T extends Format>(format: T): ReturnType<ColorConversions[T]> {\n if (format === this.format()) {\n return this as ReturnType<ColorConversions[T]>;\n }\n return HSL.#conversions[format](this) as ReturnType<ColorConversions[T]>;\n }\n asLegacyColor(): Legacy {\n return this.as(Format.RGBA);\n }\n getAuthoredText(): string|null {\n return this.#authoredText ?? null;\n }\n getRawParameters(): Color3D {\n return [...this.#rawParams];\n }\n getAsRawString(format?: Format): string|null {\n if (format) {\n return this.as(format).getAsRawString();\n }\n return this.#stringify(...this.#rawParams);\n }\n isGamutClipped(): boolean {\n return !lessOrEquals(this.#rawParams[1], 1) || !lessOrEquals(0, this.#rawParams[1]);\n }\n\n static fromSpec(spec: ColorParameterSpec, text: string): HSL|null {\n const h = parseHueNumeric(spec[0]);\n if (h === null) {\n return null;\n }\n const s = parseSatLightNumeric(spec[1]);\n if (s === null) {\n return null;\n }\n const l = parseSatLightNumeric(spec[2]);\n if (l === null) {\n return null;\n }\n const alpha = parseAlpha(spec[3]);\n\n return new HSL(h, s, l, alpha, text);\n }\n\n hsva(): Color4D {\n const s = this.s * (this.l < 0.5 ? this.l : 1 - this.l);\n return [this.h, s !== 0 ? 2 * s / (this.l + s) : 0, (this.l + s), this.alpha ?? 1];\n }\n canonicalHSLA(): number[] {\n return [Math.round(this.h * 360), Math.round(this.s * 100), Math.round(this.l * 100), this.alpha ?? 1];\n }\n}\nexport class HWB implements Color {\n readonly h: number;\n readonly w: number;\n readonly b: number;\n readonly alpha: number|null;\n readonly #rawParams: Color3D;\n #authoredText: string|undefined;\n\n static readonly #conversions: ColorConversions<HWB> = {\n [Format.Nickname]: (self: HWB) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.Nickname),\n [Format.HEX]: (self: HWB) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.HEX),\n [Format.ShortHEX]: (self: HWB) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.ShortHEX),\n [Format.HEXA]: (self: HWB) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.HEXA),\n [Format.ShortHEXA]: (self: HWB) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.ShortHEXA),\n [Format.RGB]: (self: HWB) => new Legacy(self.#getRGBArray(/* withAlpha= */ false), Format.RGB),\n [Format.RGBA]: (self: HWB) => new Legacy(self.#getRGBArray(/* withAlpha= */ true), Format.RGBA),\n [Format.HSL]: (self: HWB) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HSLA]: (self: HWB) => new HSL(...rgbToHsl(self.#getRGBArray(/* withAlpha= */ false)), self.alpha),\n [Format.HWB]: (self: HWB) => self,\n [Format.HWBA]: (self: HWB) => self,\n [Format.LCH]: (self: HWB) =>\n new LCH(...ColorConverter.labToLch(...ColorConverter.xyzd50ToLab(...self.#toXyzd50())), self.alpha),\n [Format.OKLCH]: (self: HWB) => new Oklch(...ColorConverter.xyzd50ToOklch(...self.#toXyzd50()), self.alpha),\n [Format.LAB]: (self: HWB) => new Lab(...ColorConverter.xyzd50ToLab(...self.#toXyzd50()), self.alpha),\n [Format.OKLAB]: (self: HWB) =>\n new Oklab(...ColorConverter.xyzd65ToOklab(...ColorConverter.xyzd50ToD65(...self.#toXyzd50())), self.alpha),\n\n [Format.SRGB]: (self: HWB) =>\n new ColorFunction(Format.SRGB, ...ColorConverter.xyzd50ToSrgb(...self.#toXyzd50()), self.alpha),\n [Format.SRGB_LINEAR]: (self: HWB) =>\n new ColorFunction(Format.SRGB_LINEAR, ...ColorConverter.xyzd50TosRGBLinear(...self.#toXyzd50()), self.alpha),\n [Format.DISPLAY_P3]: (self: HWB) =>\n new ColorFunction(Format.DISPLAY_P3, ...ColorConverter.xyzd50ToDisplayP3(...self.#toXyzd50()), self.alpha),\n [Format.A98_RGB]: (self: HWB) =>\n new ColorFunction(Format.A98_RGB, ...ColorConverter.xyzd50ToAdobeRGB(...self.#toXyzd50()), self.alpha),\n [Format.PROPHOTO_RGB]: (self: HWB) =>\n new ColorFunction(Format.PROPHOTO_RGB, ...ColorConverter.xyzd50ToProPhoto(...self.#toXyzd50()), self.alpha),\n [Format.REC_2020]: (self: HWB) =>\n new ColorFunction(Format.REC_2020, ...ColorConverter.xyzd50ToRec2020(...self.#toXyzd50()), self.alpha),\n [Format.XYZ]: (self: HWB) =>\n new ColorFunction(Format.XYZ, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n [Format.XYZ_D50]: (self: HWB) => new ColorFunction(Format.XYZ_D50, ...self.#toXyzd50(), self.alpha),\n [Format.XYZ_D65]: (self: HWB) =>\n new ColorFunction(Format.XYZ_D65, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n };\n\n #getRGBArray(withAlpha: true): Color4DOr3D;\n #getRGBArray(withAlpha: false): Color3D;\n #getRGBArray(withAlpha: boolean = true): Color4DOr3D|Color3D {\n const rgb: Color4D = [0, 0, 0, 0];\n hwb2rgb([this.h, this.w, this.b, 0], rgb);\n if (withAlpha) {\n return [rgb[0], rgb[1], rgb[2], this.alpha ?? undefined];\n }\n return [rgb[0], rgb[1], rgb[2]];\n }\n\n #toXyzd50(): Color3D {\n const rgb = this.#getRGBArray(false);\n return ColorConverter.srgbToXyzd50(rgb[0], rgb[1], rgb[2]);\n }\n constructor(h: number, w: number, b: number, alpha: number|null, authoredText?: string) {\n this.#rawParams = [h, w, b];\n this.w = clamp(w, {min: 0, max: 1});\n this.b = clamp(b, {min: 0, max: 1});\n h = lessOrEquals(1, this.w + this.b) ? 0 : h;\n this.h = normalizeHue(h * 360) / 360;\n this.alpha = clamp(alpha, {min: 0, max: 1});\n if (lessOrEquals(1, this.w + this.b)) {\n // normalize to a sum of 100% respecting the ratio, see https://www.w3.org/TR/css-color-4/#the-hwb-notation\n const ratio = this.w / this.b;\n this.b = 1 / (1 + ratio);\n this.w = 1 - this.b;\n }\n this.#authoredText = authoredText;\n }\n equal(color: Color): boolean {\n const hwb = color.as(Format.HWB);\n return equals(this.h, hwb.h) && equals(this.w, hwb.w) && equals(this.b, hwb.b) && equals(this.alpha, hwb.alpha);\n }\n asString(format?: Format|undefined): string|null {\n if (format) {\n return this.as(format).asString();\n }\n return this.#stringify(this.h, this.w, this.b);\n }\n #stringify(h: number, w: number, b: number): string {\n const start = Platform.StringUtilities.sprintf(\n 'hwb(%sdeg %s% %s%', Platform.StringUtilities.stringifyWithPrecision(h * 360),\n Platform.StringUtilities.stringifyWithPrecision(w * 100),\n Platform.StringUtilities.stringifyWithPrecision(b * 100));\n if (this.alpha !== null && this.alpha !== 1) {\n return start +\n Platform.StringUtilities.sprintf(\n ' / %s%)', Platform.StringUtilities.stringifyWithPrecision(this.alpha * 100));\n }\n return start + ')';\n }\n setAlpha(alpha: number): HWB {\n return new HWB(this.h, this.w, this.b, alpha, this.#authoredText);\n }\n format(): Format {\n return this.alpha !== null && !equals(this.alpha, 1) ? Format.HWBA : Format.HWB;\n }\n as<T extends Format>(format: T): ReturnType<ColorConversions[T]> {\n if (format === this.format()) {\n return this as ReturnType<ColorConversions[T]>;\n }\n return HWB.#conversions[format](this) as ReturnType<ColorConversions[T]>;\n }\n asLegacyColor(): Legacy {\n return this.as(Format.RGBA);\n }\n getAuthoredText(): string|null {\n return this.#authoredText ?? null;\n }\n\n canonicalHWBA(): number[] {\n return [\n Math.round(this.h * 360),\n Math.round(this.w * 100),\n Math.round(this.b * 100),\n this.alpha ?? 1,\n ];\n }\n getRawParameters(): Color3D {\n return [...this.#rawParams];\n }\n getAsRawString(format?: Format): string|null {\n if (format) {\n return this.as(format).getAsRawString();\n }\n return this.#stringify(...this.#rawParams);\n }\n isGamutClipped(): boolean {\n return !lessOrEquals(this.#rawParams[1], 1) || !lessOrEquals(0, this.#rawParams[1]) ||\n !lessOrEquals(this.#rawParams[2], 1) || !lessOrEquals(0, this.#rawParams[2]);\n }\n\n static fromSpec(spec: ColorParameterSpec, text: string): HWB|null {\n const h = parseHueNumeric(spec[0]);\n if (h === null) {\n return null;\n }\n const w = parseSatLightNumeric(spec[1]);\n if (w === null) {\n return null;\n }\n const b = parseSatLightNumeric(spec[2]);\n if (b === null) {\n return null;\n }\n const alpha = parseAlpha(spec[3]);\n return new HWB(h, w, b, alpha, text);\n }\n}\n\ntype LegacyColor = Format.Nickname|Format.HEX|Format.ShortHEX|Format.HEXA|Format.ShortHEXA|Format.RGB|Format.RGBA;\n\nfunction toRgbValue(value: number): number {\n return Math.round(value * 255);\n}\n\nexport class Legacy implements Color {\n readonly #rawParams: Color3D;\n #rgbaInternal: Color4D;\n readonly #authoredText: string|null;\n #formatInternal: LegacyColor;\n\n static readonly #conversions: ColorConversions<Legacy> = {\n [Format.Nickname]: (self: Legacy) => new Legacy(self.#rgbaInternal, Format.Nickname),\n [Format.HEX]: (self: Legacy) => new Legacy(self.#rgbaInternal, Format.HEX),\n [Format.ShortHEX]: (self: Legacy) => new Legacy(self.#rgbaInternal, Format.ShortHEX),\n [Format.HEXA]: (self: Legacy) => new Legacy(self.#rgbaInternal, Format.HEXA),\n [Format.ShortHEXA]: (self: Legacy) => new Legacy(self.#rgbaInternal, Format.ShortHEXA),\n [Format.RGB]: (self: Legacy) => new Legacy(self.#rgbaInternal, Format.RGB),\n [Format.RGBA]: (self: Legacy) => new Legacy(self.#rgbaInternal, Format.RGBA),\n [Format.HSL]: (self: Legacy) =>\n new HSL(...rgbToHsl([self.#rgbaInternal[0], self.#rgbaInternal[1], self.#rgbaInternal[2]]), self.alpha),\n [Format.HSLA]: (self: Legacy) =>\n new HSL(...rgbToHsl([self.#rgbaInternal[0], self.#rgbaInternal[1], self.#rgbaInternal[2]]), self.alpha),\n [Format.HWB]: (self: Legacy) =>\n new HWB(...rgbToHwb([self.#rgbaInternal[0], self.#rgbaInternal[1], self.#rgbaInternal[2]]), self.alpha),\n [Format.HWBA]: (self: Legacy) =>\n new HWB(...rgbToHwb([self.#rgbaInternal[0], self.#rgbaInternal[1], self.#rgbaInternal[2]]), self.alpha),\n [Format.LCH]: (self: Legacy) =>\n new LCH(...ColorConverter.labToLch(...ColorConverter.xyzd50ToLab(...self.#toXyzd50())), self.alpha),\n [Format.OKLCH]: (self: Legacy) => new Oklch(...ColorConverter.xyzd50ToOklch(...self.#toXyzd50()), self.alpha),\n [Format.LAB]: (self: Legacy) => new Lab(...ColorConverter.xyzd50ToLab(...self.#toXyzd50()), self.alpha),\n [Format.OKLAB]: (self: Legacy) =>\n new Oklab(...ColorConverter.xyzd65ToOklab(...ColorConverter.xyzd50ToD65(...self.#toXyzd50())), self.alpha),\n [Format.SRGB]: (self: Legacy) =>\n new ColorFunction(Format.SRGB, ...ColorConverter.xyzd50ToSrgb(...self.#toXyzd50()), self.alpha),\n [Format.SRGB_LINEAR]: (self: Legacy) =>\n new ColorFunction(Format.SRGB_LINEAR, ...ColorConverter.xyzd50TosRGBLinear(...self.#toXyzd50()), self.alpha),\n [Format.DISPLAY_P3]: (self: Legacy) =>\n new ColorFunction(Format.DISPLAY_P3, ...ColorConverter.xyzd50ToDisplayP3(...self.#toXyzd50()), self.alpha),\n [Format.A98_RGB]: (self: Legacy) =>\n new ColorFunction(Format.A98_RGB, ...ColorConverter.xyzd50ToAdobeRGB(...self.#toXyzd50()), self.alpha),\n [Format.PROPHOTO_RGB]: (self: Legacy) =>\n new ColorFunction(Format.PROPHOTO_RGB, ...ColorConverter.xyzd50ToProPhoto(...self.#toXyzd50()), self.alpha),\n [Format.REC_2020]: (self: Legacy) =>\n new ColorFunction(Format.REC_2020, ...ColorConverter.xyzd50ToRec2020(...self.#toXyzd50()), self.alpha),\n [Format.XYZ]: (self: Legacy) =>\n new ColorFunction(Format.XYZ, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n [Format.XYZ_D50]: (self: Legacy) => new ColorFunction(Format.XYZ_D50, ...self.#toXyzd50(), self.alpha),\n [Format.XYZ_D65]: (self: Legacy) =>\n new ColorFunction(Format.XYZ_D65, ...ColorConverter.xyzd50ToD65(...self.#toXyzd50()), self.alpha),\n };\n\n #toXyzd50(): Color3D {\n const [r, g, b] = this.#rgbaInternal;\n return ColorConverter.srgbToXyzd50(r, g, b);\n }\n\n get alpha(): number|null {\n switch (this.format()) {\n case Format.HEXA:\n case Format.ShortHEXA:\n case Format.RGBA:\n return this.#rgbaInternal[3];\n default:\n return null;\n }\n }\n\n asLegacyColor(): Legacy {\n return this;\n }\n\n constructor(rgba: Color3D|Color4DOr3D, format: LegacyColor, authoredText?: string) {\n this.#authoredText = authoredText || null;\n this.#formatInternal = format;\n this.#rawParams = [rgba[0], rgba[1], rgba[2]];\n\n this.#rgbaInternal = [\n clamp(rgba[0], {min: 0, max: 1}),\n clamp(rgba[1], {min: 0, max: 1}),\n clamp(rgba[2], {min: 0, max: 1}),\n clamp(rgba[3] ?? 1, {min: 0, max: 1}),\n ];\n }\n\n static fromHex(hex: string, text: string): Legacy {\n hex = hex.toLowerCase();\n let format: LegacyColor;\n if (hex.length === 3) {\n format = Format.ShortHEX;\n hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);\n } else if (hex.length === 4) {\n format = Format.ShortHEXA;\n hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2) +\n hex.charAt(3) + hex.charAt(3);\n } else if (hex.length === 6) {\n format = Format.HEX;\n } else {\n format = Format.HEXA;\n }\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n let a = 1;\n if (hex.length === 8) {\n a = parseInt(hex.substring(6, 8), 16) / 255;\n }\n return new Legacy([r / 255, g / 255, b / 255, a], format, text);\n }\n\n static fromName(name: string, text: string): Legacy|null {\n const nickname = name.toLowerCase();\n const rgba = Nicknames.get(nickname);\n if (rgba !== undefined) {\n const color = Legacy.fromRGBA(rgba, text);\n color.#formatInternal = Format.Nickname;\n return color;\n }\n return null;\n }\n\n static fromRGBAFunction(r: string, g: string, b: string, alpha: string|undefined, text: string): Legacy|null {\n const rgba = [\n parseRgbNumeric(r),\n parseRgbNumeric(g),\n parseRgbNumeric(b),\n alpha ? parseAlphaNumeric(alpha) : 1,\n ];\n\n if (!Platform.ArrayUtilities.arrayDoesNotContainNullOrUndefined(rgba)) {\n return null;\n }\n return new Legacy(rgba as Color4D, alpha ? Format.RGBA : Format.RGB, text);\n }\n\n static fromRGBA(rgba: number[], authoredText?: string): Legacy {\n return new Legacy([rgba[0] / 255, rgba[1] / 255, rgba[2] / 255, rgba[3]], Format.RGBA, authoredText);\n }\n\n static fromHSVA(hsva: Color4D): Legacy {\n const rgba: Color4D = [0, 0, 0, 0];\n hsva2rgba(hsva, rgba);\n return new Legacy(rgba, Format.RGBA);\n }\n\n as<T extends Format>(format: T): ReturnType<ColorConversions[T]> {\n if (format === this.format()) {\n return this as ReturnType<ColorConversions[T]>;\n }\n return Legacy.#conversions[format](this) as ReturnType<ColorConversions[T]>;\n }\n\n format(): LegacyColor {\n return this.#formatInternal;\n }\n\n hasAlpha(): boolean {\n return this.#rgbaInternal[3] !== 1;\n }\n\n detectHEXFormat(): Format {\n let canBeShort = true;\n for (let i = 0; i < 4; ++i) {\n const c = Math.round(this.#rgbaInternal[i] * 255);\n if (c % 17) {\n canBeShort = false;\n break;\n }\n }\n\n const hasAlpha = this.hasAlpha();\n if (canBeShort) {\n return hasAlpha ? Format.ShortHEXA : Format.ShortHEX;\n }\n return hasAlpha ? Format.HEXA : Format.HEX;\n }\n\n asString(format?: Format): string|null {\n if (format) {\n return this.as(format).asString();\n }\n return this.#stringify(format, this.#rgbaInternal[0], this.#rgbaInternal[1], this.#rgbaInternal[2]);\n }\n #stringify(format: Format|undefined, r: number, g: number, b: number): string|null {\n if (!format) {\n format = this.#formatInternal;\n }\n\n function toHexValue(value: number): string {\n const hex = Math.round(value * 255).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n }\n\n function toShortHexValue(value: number): string {\n return (Math.round(value * 255) / 17).toString(16);\n }\n\n switch (format) {\n case Format.RGB:\n case Format.RGBA: {\n const start = Platform.StringUtilities.sprintf('rgb(%d %d %d', toRgbValue(r), toRgbValue(g), toRgbValue(b));\n if (this.hasAlpha()) {\n return start + Platform.StringUtilities.sprintf(' / %d%)', Math.round(this.#rgbaInternal[3] * 100));\n }\n return start + ')';\n }\n case Format.HEXA: {\n return Platform.StringUtilities\n .sprintf('#%s%s%s%s', toHexValue(r), toHexValue(g), toHexValue(b), toHexValue(this.#rgbaInternal[3]))\n .toLowerCase();\n }\n case Format.HEX: {\n if (this.hasAlpha()) {\n return null;\n }\n return Platform.StringUtilities.sprintf('#%s%s%s', toHexValue(r), toHexValue(g), toHexValue(b)).toLowerCase();\n }\n case Format.ShortHEXA: {\n const hexFormat = this.detectHEXFormat();\n if (hexFormat !== Format.ShortHEXA && hexFormat !== Format.ShortHEX) {\n return null;\n }\n return Platform.StringUtilities\n .sprintf(\n '#%s%s%s%s', toShortHexValue(r), toShortHexValue(g), toShortHexValue(b),\n toShortHexValue(this.#rgbaInternal[3]))\n .toLowerCase();\n }\n case Format.ShortHEX: {\n if (this.hasAlpha()) {\n return null;\n }\n if (this.detectHEXFormat() !== Format.ShortHEX) {\n return null;\n }\n return Platform.StringUtilities.sprintf('#%s%s%s', toShortHexValue(r), toShortHexValue(g), toShortHexValue(b))\n .toLowerCase();\n }\n case Format.Nickname: {\n return this.nickname();\n }\n }\n\n return null; // Shouldn't get here.\n }\n getAuthoredText(): string|null {\n return this.#authoredText ?? null;\n }\n\n getRawParameters(): Color3D {\n return [...this.#rawParams];\n }\n getAsRawString(format?: Format): string|null {\n if (format) {\n return this.as(format).getAsRawString();\n }\n return this.#stringify(format, ...this.#rawParams);\n }\n isGamutClipped(): boolean {\n return !equals(\n this.#rawParams.map(toRgbValue),\n [this.#rgbaInternal[0], this.#rgbaInternal[1], this.#rgbaInternal[2]].map(toRgbValue), WIDE_RANGE_EPSILON);\n }\n\n rgba(): Color4D {\n return [...this.#rgbaInternal];\n }\n\n canonicalRGBA(): Color4D {\n const rgba = new Array(4);\n for (let i = 0; i < 3; ++i) {\n rgba[i] = Math.round(this.#rgbaInternal[i] * 255);\n }\n rgba[3] = this.#rgbaInternal[3];\n return rgba as Color4D;\n }\n\n /** nickname\n */\n nickname(): string|null {\n return RGBAToNickname.get(String(this.canonicalRGBA())) || null;\n }\n\n toProtocolRGBA(): {\n r: number,\n g: number,\n b: number,\n a: (number|undefined),\n } {\n const rgba = this.canonicalRGBA();\n const result: {\n r: number,\n g: number,\n b: number,\n a: number|undefined,\n } = {r: rgba[0], g: rgba[1], b: rgba[2], a: undefined};\n if (rgba[3] !== 1) {\n result.a = rgba[3];\n }\n return result;\n }\n\n invert(): Legacy {\n const rgba: Color4D = [0, 0, 0, 0];\n rgba[0] = 1 - this.#rgbaInternal[0];\n rgba[1] = 1 - this.#rgbaInternal[1];\n rgba[2] = 1 - this.#rgbaInternal[2];\n rgba[3] = this.#rgbaInternal[3];\n return new Legacy(rgba, Format.RGBA);\n }\n\n setAlpha(alpha: number): Legacy {\n const rgba: Color4D = [...this.#rgbaInternal];\n rgba[3] = alpha;\n return new Legacy(rgba, Format.RGBA);\n }\n\n blendWith(fgColor: Legacy): Legacy {\n const rgba: Color4D = blendColors(fgColor.#rgbaInternal, this.#rgbaInternal);\n return new Legacy(rgba, Format.RGBA);\n }\n\n blendWithAlpha(alpha: number): Legacy {\n const rgba: Color4D = [...this.#rgbaInternal];\n rgba[3] *= alpha;\n return new Legacy(rgba, Format.RGBA);\n }\n\n setFormat(format: LegacyColor): void {\n this.#formatInternal = format;\n }\n\n equal(other: Color): boolean {\n const legacy = other.as(this.#formatInternal);\n return equals(toRgbValue(this.#rgbaInternal[0]), toRgbValue(legacy.#rgbaInternal[0]), WIDE_RANGE_EPSILON) &&\n equals(toRgbValue(this.#rgbaInternal[1]), toRgbValue(legacy.#rgbaInternal[1]), WIDE_RANGE_EPSILON) &&\n equals(toRgbValue(this.#rgbaInternal[2]), toRgbValue(legacy.#rgbaInternal[2]), WIDE_RANGE_EPSILON) &&\n equals(this.#rgbaInternal[3], legacy.#rgbaInternal[3]);\n }\n}\n\nexport const Regex: RegExp =\n /((?:rgba?|hsla?|hwba?|lab|lch|oklab|oklch|color)\\([^)]+\\)|#[0-9a-fA-F]{8}|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3,4}|\\b[a-zA-Z]+\\b(?!-))/g;\nexport const ColorMixRegex: RegExp = /color-mix\\(.*,\\s*(?<firstColor>.+)\\s*,\\s*(?<secondColor>.+)\\s*\\)/g;\n\nconst COLOR_TO_RGBA_ENTRIES: Array<readonly[string, number[]]> = [\n ['aliceblue', [240, 248, 255]],\n ['antiquewhite', [250, 235, 215]],\n ['aqua', [0, 255, 255]],\n ['aquamarine', [127, 255, 212]],\n ['azure', [240, 255, 255]],\n ['beige', [245, 245, 220]],\n ['bisque', [255, 228, 196]],\n ['black', [0, 0, 0]],\n ['blanchedalmond', [255, 235, 205]],\n ['blue', [0, 0, 255]],\n ['blueviolet', [138, 43, 226]],\n ['brown', [165, 42, 42]],\n ['burlywood', [222, 184, 135]],\n ['cadetblue', [95, 158, 160]],\n ['chartreuse', [127, 255, 0]],\n ['chocolate', [210, 105, 30]],\n ['coral', [255, 127, 80]],\n ['cornflowerblue', [100, 149, 237]],\n ['cornsilk', [255, 248, 220]],\n ['crimson', [237, 20, 61]],\n ['cyan', [0, 255, 255]],\n ['darkblue', [0, 0, 139]],\n ['darkcyan', [0, 139, 139]],\n ['darkgoldenrod', [184, 134, 11]],\n ['darkgray', [169, 169, 169]],\n ['darkgrey', [169, 169, 169]],\n ['darkgreen', [0, 100, 0]],\n ['darkkhaki', [189, 183, 107]],\n ['darkmagenta', [139, 0, 139]],\n ['darkolivegreen', [85, 107, 47]],\n ['darkorange', [255, 140, 0]],\n ['darkorchid', [153, 50, 204]],\n ['darkred', [139, 0, 0]],\n ['darksalmon', [233, 150, 122]],\n ['darkseagreen', [143, 188, 143]],\n ['darkslateblue', [72, 61, 139]],\n ['darkslategray', [47, 79, 79]],\n ['darkslategrey', [47, 79, 79]],\n ['darkturquoise', [0, 206, 209]],\n ['darkviolet', [148, 0, 211]],\n ['deeppink', [255, 20, 147]],\n ['deepskyblue', [0, 191, 255]],\n ['dimgray', [105, 105, 105]],\n ['dimgrey', [105, 105, 105]],\n ['dodgerblue', [30, 144, 255]],\n ['firebrick', [178, 34, 34]],\n ['floralwhite', [255, 250, 240]],\n ['forestgreen', [34, 139, 34]],\n ['fuchsia', [255, 0, 255]],\n ['gainsboro', [220, 220, 220]],\n ['ghostwhite', [248, 248, 255]],\n ['gold', [255, 215, 0]],\n ['goldenrod', [218, 165, 32]],\n ['gray', [128, 128, 128]],\n ['grey', [128, 128, 128]],\n ['green', [0, 128, 0]],\n ['greenyellow', [173, 255, 47]],\n ['honeydew', [240, 255, 240]],\n ['hotpink', [255, 105, 180]],\n ['indianred', [205, 92, 92]],\n ['indigo', [75, 0, 130]],\n ['ivory', [255, 255, 240]],\n ['khaki', [240, 230, 140]],\n ['lavender', [230, 230, 250]],\n ['lavenderblush', [255, 240, 245]],\n ['lawngreen', [124, 252, 0]],\n ['lemonchiffon', [255, 250, 205]],\n ['lightblue', [173, 216, 230]],\n ['lightcoral', [240, 128, 128]],\n ['lightcyan', [224, 255, 255]],\n ['lightgoldenrodyellow', [250, 250, 210]],\n ['lightgreen', [144, 238, 144]],\n ['lightgray', [211, 211, 211]],\n ['lightgrey', [211, 211, 211]],\n ['lightpink', [255, 182, 193]],\n ['lightsalmon', [255, 160, 122]],\n ['lightseagreen', [32, 178, 170]],\n ['lightskyblue', [135, 206, 250]],\n ['lightslategray', [119, 136, 153]],\n ['lightslategrey', [119, 136, 153]],\n ['lightsteelblue', [176, 196, 222]],\n ['lightyellow', [255, 255, 224]],\n ['lime', [0, 255, 0]],\n ['limegreen', [50, 205, 50]],\n ['linen', [250, 240, 230]],\n ['magenta', [255, 0, 255]],\n ['maroon', [128, 0, 0]],\n ['mediumaquamarine', [102, 205, 170]],\n ['mediumblue', [0, 0, 205]],\n ['mediumorchid', [186, 85, 211]],\n ['mediumpurple', [147, 112, 219]],\n ['mediumseagreen', [60, 179, 113]],\n ['mediumslateblue', [123, 104, 238]],\n ['mediumspringgreen', [0, 250, 154]],\n ['mediumturquoise', [72, 209, 204]],\n ['mediumvioletred', [199, 21, 133]],\n ['midnightblue', [25, 25, 112]],\n ['mintcream', [245, 255, 250]],\n ['mistyrose', [255, 228, 225]],\n ['moccasin', [255, 228, 181]],\n ['navajowhite', [255, 222, 173]],\n ['navy', [0, 0, 128]],\n ['oldlace', [253, 245, 230]],\n ['olive', [128, 128, 0]],\n ['olivedrab', [107, 142, 35]],\n ['orange', [255, 165, 0]],\n ['orangered', [255, 69, 0]],\n ['orchid', [218, 112, 214]],\n ['palegoldenrod', [238, 232, 170]],\n ['palegreen', [152, 251, 152]],\n ['paleturquoise', [175, 238, 238]],\n ['palevioletred', [219, 112, 147]],\n ['papayawhip', [255, 239, 213]],\n ['peachpuff', [255, 218, 185]],\n ['peru', [205, 133, 63]],\n ['pink', [255, 192, 203]],\n ['plum', [221, 160, 221]],\n ['powderblue', [176, 224, 230]],\n ['purple', [128, 0, 128]],\n ['rebeccapurple', [102, 51, 153]],\n ['red', [255, 0, 0]],\n ['rosybrown', [188, 143, 143]],\n ['royalblue', [65, 105, 225]],\n ['saddlebrown', [139, 69, 19]],\n ['salmon', [250, 128, 114]],\n ['sandybrown', [244, 164, 96]],\n ['seagreen', [46, 139, 87]],\n ['seashell', [255, 245, 238]],\n ['sienna', [160, 82, 45]],\n ['silver', [192, 192, 192]],\n ['skyblue', [135, 206, 235]],\n ['slateblue', [106, 90, 205]],\n ['slategray', [112, 128, 144]],\n ['slategrey', [112, 128, 144]],\n ['snow', [255, 250, 250]],\n ['springgreen', [0, 255, 127]],\n ['steelblue', [70, 130, 180]],\n ['tan', [210, 180, 140]],\n ['teal', [0, 128, 128]],\n ['thistle', [216, 191, 216]],\n ['tomato', [255, 99, 71]],\n ['turquoise', [64, 224, 208]],\n ['violet', [238, 130, 238]],\n ['wheat', [245, 222, 179]],\n ['white', [255, 255, 255]],\n ['whitesmoke', [245, 245, 245]],\n ['yellow', [255, 255, 0]],\n ['yellowgreen', [154, 205, 50]],\n ['transparent', [0, 0, 0, 0]],\n];\n\nPlatform.DCHECK(() => {\n return COLOR_TO_RGBA_ENTRIES.every(([nickname]) => nickname.toLowerCase() === nickname);\n}, 'All color nicknames must be lowercase.');\n\nexport const Nicknames = new Map(COLOR_TO_RGBA_ENTRIES);\n\nconst RGBAToNickname = new Map(\n // Default opacity to 1 if the color only specified 3 channels\n COLOR_TO_RGBA_ENTRIES.map(([nickname, [r, g, b, a = 1]]) => {\n return [String([r, g, b, a]), nickname];\n }),\n);\n\nconst LAYOUT_LINES_HIGHLIGHT_COLOR = [127, 32, 210];\n\nexport const PageHighlight = {\n Content: Legacy.fromRGBA([111, 168, 220, .66]),\n ContentLight: Legacy.fromRGBA([111, 168, 220, .5]),\n ContentOutline: Legacy.fromRGBA([9, 83, 148]),\n Padding: Legacy.fromRGBA([147, 196, 125, .55]),\n PaddingLight: Legacy.fromRGBA([147, 196, 125, .4]),\n Border: Legacy.fromRGBA([255, 229, 153, .66]),\n BorderLight: Legacy.fromRGBA([255, 229, 153, .5]),\n Margin: Legacy.fromRGBA([246, 178, 107, .66]),\n MarginLight: Legacy.fromRGBA([246, 178, 107, .5]),\n EventTarget: Legacy.fromRGBA([255, 196, 196, .66]),\n Shape: Legacy.fromRGBA([96, 82, 177, 0.8]),\n ShapeMargin: Legacy.fromRGBA([96, 82, 127, .6]),\n CssGrid: Legacy.fromRGBA([0x4b, 0, 0x82, 1]),\n LayoutLine: Legacy.fromRGBA([...LAYOUT_LINES_HIGHLIGHT_COLOR, 1]),\n GridBorder: Legacy.fromRGBA([...LAYOUT_LINES_HIGHLIGHT_COLOR, 1]),\n GapBackground: Legacy.fromRGBA([...LAYOUT_LINES_HIGHLIGHT_COLOR, .3]),\n GapHatch: Legacy.fromRGBA([...LAYOUT_LINES_HIGHLIGHT_COLOR, .8]),\n GridAreaBorder: Legacy.fromRGBA([26, 115, 232, 1]),\n};\n\nexport const SourceOrderHighlight = {\n ParentOutline: Legacy.fromRGBA([224, 90, 183, 1]),\n ChildOutline: Legacy.fromRGBA([0, 120, 212, 1]),\n};\n\nexport const IsolationModeHighlight = {\n Resizer: Legacy.fromRGBA([222, 225, 230, 1]), // --color-background-elevation-2\n ResizerHandle: Legacy.fromRGBA([166, 166, 166, 1]),\n Mask: Legacy.fromRGBA([248, 249, 249, 1]),\n};\n\nexport class Generator {\n readonly #hueSpace: number|{\n min: number,\n max: number,\n count: (number|undefined),\n };\n readonly #satSpace: number|{\n min: number,\n max: number,\n count: (number|undefined),\n };\n readonly #lightnessSpace: number|{\n min: number,\n max: number,\n count: (number|undefined),\n };\n readonly #alphaSpace: number|{\n min: number,\n max: number,\n count: (number|undefined),\n };\n readonly #colors: Map<string, string>;\n constructor(\n hueSpace?: number|{\n min: number,\n max: number,\n count: (number|undefined),\n },\n satSpace?: number|{\n min: number,\n max: number,\n count: (number|undefined),\n },\n lightnessSpace?: number|{\n min: number,\n max: number,\n count: (number|undefined),\n },\n alphaSpace?: number|{\n min: number,\n max: number,\n count: (number|undefined),\n }) {\n this.#hueSpace = hueSpace || {min: 0, max: 360, count: undefined};\n this.#satSpace = satSpace || 67;\n this.#lightnessSpace = lightnessSpace || 80;\n this.#alphaSpace = alphaSpace || 1;\n this.#colors = new Map();\n }\n\n setColorForID(id: string, color: string): void {\n this.#colors.set(id, color);\n }\n\n colorForID(id: string): string {\n let color = this.#colors.get(id);\n if (!color) {\n color = this.generateColorForID(id);\n this.#colors.set(id, color);\n }\n return color;\n }\n\n private generateColorForID(id: string): string {\n const hash = Platform.StringUtilities.hashCode(id);\n const h = this.indexToValueInSpace(hash, this.#hueSpace);\n const s = this.indexToValueInSpace(hash >> 8, this.#satSpace);\n const l = this.indexToValueInSpace(hash >> 16, this.#lightnessSpace);\n const a = this.indexToValueInSpace(hash >> 24, this.#alphaSpace);\n const start = `hsl(${h}deg ${s}% ${l}%`;\n if (a !== 1) {\n return `${start} / ${Math.floor(a * 100)}%)`;\n }\n return `${start})`;\n }\n\n private indexToValueInSpace(index: number, space: number|{\n min: number,\n max: number,\n count: (number|undefined),\n }): number {\n if (typeof space === 'number') {\n return space;\n }\n const count = space.count || space.max - space.min;\n index %= count;\n return space.min + Math.floor(index / (count - 1) * (space.max - space.min));\n }\n}\n", "// Copyright 2014 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {ObjectWrapper} from './Object.js';\nimport {reveal} from './Revealer.js';\n\nlet consoleInstance: Console|undefined;\n\nexport class Console extends ObjectWrapper<EventTypes> {\n readonly #messagesInternal: Message[];\n /**\n * Instantiable via the instance() factory below.\n */\n private constructor() {\n super();\n this.#messagesInternal = [];\n }\n\n static instance(opts?: {forceNew: boolean}): Console {\n if (!consoleInstance || opts?.forceNew) {\n consoleInstance = new Console();\n }\n\n return consoleInstance;\n }\n\n static removeInstance(): void {\n consoleInstance = undefined;\n }\n\n addMessage(text: string, level: MessageLevel, show?: boolean): void {\n const message = new Message(text, level || MessageLevel.Info, Date.now(), show || false);\n this.#messagesInternal.push(message);\n this.dispatchEventToListeners(Events.MessageAdded, message);\n }\n\n log(text: string): void {\n this.addMessage(text, MessageLevel.Info);\n }\n\n warn(text: string): void {\n this.addMessage(text, MessageLevel.Warning);\n }\n\n error(text: string): void {\n this.addMessage(text, MessageLevel.Error, true);\n }\n\n messages(): Message[] {\n return this.#messagesInternal;\n }\n\n show(): void {\n void this.showPromise();\n }\n\n showPromise(): Promise<void> {\n return reveal(this);\n }\n}\n\n// TODO(crbug.com/1167717): Make this a const enum again\n// eslint-disable-next-line rulesdir/const_enum\nexport enum Events {\n MessageAdded = 'messageAdded',\n}\n\nexport type EventTypes = {\n [Events.MessageAdded]: Message,\n};\n\n// TODO(crbug.com/1167717): Make this a const enum again\n// eslint-disable-next-line rulesdir/const_enum\nexport enum MessageLevel {\n Info = 'info',\n Warning = 'warning',\n Error = 'error',\n}\n\nexport class Message {\n text: string;\n level: MessageLevel;\n timestamp: number;\n show: boolean;\n constructor(text: string, level: MessageLevel, timestamp: number, show: boolean) {\n this.text = text;\n this.level = level;\n this.timestamp = (typeof timestamp === 'number') ? timestamp : Date.now();\n this.show = show;\n }\n}\n", "// Copyright 2021 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/*\n * Copyright (C) 2008 Apple Inc. All Rights Reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR\n * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nimport type * as Platform from '../platform/platform.js';\nimport {\n type EventDescriptor,\n type EventListener,\n type EventTarget,\n type EventTargetEvent,\n type EventPayloadToRestParameters,\n} from './EventTarget.js';\n\nexport interface ListenerCallbackTuple<Events, T extends keyof Events> {\n thisObject?: Object;\n listener: EventListener<Events, T>;\n disposed?: boolean;\n}\n\nexport class ObjectWrapper<Events> implements EventTarget<Events> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n listeners?: Map<keyof Events, Set<ListenerCallbackTuple<Events, any>>>;\n\n addEventListener<T extends keyof Events>(eventType: T, listener: EventListener<Events, T>, thisObject?: Object):\n EventDescriptor<Events, T> {\n if (!this.listeners) {\n this.listeners = new Map();\n }\n\n let listenersForEventType = this.listeners.get(eventType);\n if (!listenersForEventType) {\n listenersForEventType = new Set();\n this.listeners.set(eventType, listenersForEventType);\n }\n listenersForEventType.add({thisObject, listener});\n return {eventTarget: this, eventType, thisObject, listener};\n }\n\n once<T extends keyof Events>(eventType: T): Promise<Events[T]> {\n return new Promise(resolve => {\n const descriptor = this.addEventListener(eventType, event => {\n this.removeEventListener(eventType, descriptor.listener);\n resolve(event.data);\n });\n });\n }\n\n removeEventListener<T extends keyof Events>(eventType: T, listener: EventListener<Events, T>, thisObject?: Object):\n void {\n const listeners = this.listeners?.get(eventType);\n if (!listeners) {\n return;\n }\n for (const listenerTuple of listeners) {\n if (listenerTuple.listener === listener && listenerTuple.thisObject === thisObject) {\n listenerTuple.disposed = true;\n listeners.delete(listenerTuple);\n }\n }\n\n if (!listeners.size) {\n this.listeners?.delete(eventType);\n }\n }\n\n hasEventListeners(eventType: keyof Events): boolean {\n return Boolean(this.listeners && this.listeners.has(eventType));\n }\n\n dispatchEventToListeners<T extends keyof Events>(\n eventType: Platform.TypeScriptUtilities.NoUnion<T>,\n ...[eventData]: EventPayloadToRestParameters<Events, T>): void {\n const listeners = this.listeners?.get(eventType);\n if (!listeners) {\n return;\n }\n // `eventData` is typed as `Events[T] | undefined`:\n // - `undefined` when `Events[T]` is void.\n // - `Events[T]` otherwise.\n // We cast it to `Events[T]` which is the correct type in all instances, as\n // `void` will be cast and used as `undefined`.\n const event = {data: eventData as Events[T], source: this};\n // Work on a snapshot of the current listeners, callbacks might remove/add\n // new listeners.\n for (const listener of [...listeners]) {\n if (!listener.disposed) {\n listener.listener.call(listener.thisObject, event);\n }\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Constructor = new (...args: any[]) => {};\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function eventMixin<Events, Base extends Constructor>(base: Base) {\n return class EventHandling extends base implements EventTarget<Events> {\n #events = new ObjectWrapper<Events>();\n\n addEventListener<T extends keyof Events>(\n eventType: T, listener: (arg0: EventTargetEvent<Events[T]>) => void,\n thisObject?: Object): EventDescriptor<Events, T> {\n return this.#events.addEventListener(eventType, listener, thisObject);\n }\n\n once<T extends keyof Events>(eventType: T): Promise<Events[T]> {\n return this.#events.once(eventType);\n }\n\n removeEventListener<T extends keyof Events>(\n eventType: T, listener: (arg0: EventTargetEvent<Events[T]>) => void, thisObject?: Object): void {\n this.#events.removeEventListener(eventType, listener, thisObject);\n }\n\n hasEventListeners(eventType: keyof Events): boolean {\n return this.#events.hasEventListeners(eventType);\n }\n\n dispatchEventToListeners<T extends keyof Events>(\n eventType: Platform.TypeScriptUtilities.NoUnion<T>,\n ...eventData: EventPayloadToRestParameters<Events, T>): void {\n this.#events.dispatchEventToListeners(eventType, ...eventData);\n }\n };\n}\n", "// Copyright 2021 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nlet devToolsLocaleInstance: DevToolsLocale|null = null;\n\nexport interface DevToolsLocaleData {\n settingLanguage: string;\n navigatorLanguage: string;\n lookupClosestDevToolsLocale: (locale: string) => string;\n}\n\nexport type DevToolsLocaleCreationOptions = {\n create: true,\n data: DevToolsLocaleData,\n}|{\n create: false,\n};\n\n/**\n * Simple class that determines the DevTools locale based on:\n * 1) navigator.language, which matches the Chrome UI\n * 2) the value of the \"language\" Setting the user choses\n * 3) available locales in DevTools.\n *\n * The DevTools locale is only determined once during startup and\n * guaranteed to never change. Use this class when using\n * `Intl` APIs.\n */\nexport class DevToolsLocale {\n readonly locale: string;\n readonly lookupClosestDevToolsLocale: (locale: string) => string;\n\n private constructor(data: DevToolsLocaleData) {\n this.lookupClosestDevToolsLocale = data.lookupClosestDevToolsLocale;\n\n // TODO(crbug.com/1163928): Use constant once setting actually exists.\n if (data.settingLanguage === 'browserLanguage') {\n this.locale = data.navigatorLanguage || 'en-US';\n } else {\n this.locale = data.settingLanguage;\n }\n\n this.locale = this.lookupClosestDevToolsLocale(this.locale);\n }\n\n static instance(opts: DevToolsLocaleCreationOptions = {create: false}): DevToolsLocale {\n if (!devToolsLocaleInstance && !opts.create) {\n throw new Error('No LanguageSelector instance exists yet.');\n }\n\n if (opts.create) {\n devToolsLocaleInstance = new DevToolsLocale(opts.data);\n }\n return devToolsLocaleInstance as DevToolsLocale;\n }\n\n static removeInstance(): void {\n devToolsLocaleInstance = null;\n }\n\n forceFallbackLocale(): void {\n // Locale is 'readonly', this is the only case where we want to forceably\n // overwrite the locale.\n (this.locale as DevToolsLocale['locale']) = 'en-US';\n }\n\n /**\n * Returns true iff DevTools supports the language of the passed locale.\n * Note that it doesn't have to be a one-to-one match, e.g. if DevTools supports\n * 'de', then passing 'de-AT' will return true.\n */\n languageIsSupportedByDevTools(localeString: string): boolean {\n return localeLanguagesMatch(localeString, this.lookupClosestDevToolsLocale(localeString));\n }\n}\n\n/**\n * Returns true iff the two locales have matching languages. This means the\n * passing 'de-AT' and 'de-DE' will return true, while 'de-DE' and 'en' will\n * return false.\n */\nexport function localeLanguagesMatch(localeString1: string, localeString2: string): boolean {\n const locale1 = new Intl.Locale(localeString1);\n const locale2 = new Intl.Locale(localeString2);\n return locale1.language === locale2.language;\n}\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as I18n from '../../third_party/i18n/i18n.js';\nimport * as Platform from '../platform/platform.js';\nimport * as Root from '../root/root.js';\n\nimport {DevToolsLocale} from './DevToolsLocale.js';\n\n// import {\n// BUNDLED_LOCALES as BUNDLED_LOCALES_GENERATED,\n// DEFAULT_LOCALE,\n// LOCAL_FETCH_PATTERN,\n// LOCALES,\n// REMOTE_FETCH_PATTERN,\n// } from './locales.js';\n\nconst LOCALES = ['en-GB'];\nconst BUNDLED_LOCALES_GENERATED = [\n 'en-US',\n 'zh',\n 'en-XL',\n];\n\nconst DEFAULT_LOCALE = 'en-US';\n\nconst REMOTE_FETCH_PATTERN = '@HOST@/remote/serve_file/@VERSION@/core/i18n/locales/@LOCALE@.json';\n\nconst LOCAL_FETCH_PATTERN = './locales/@LOCALE@.json';\n\n\nimport type * as i18nTypes from './i18nTypes.js';\n\nconst i18nInstance = new I18n.I18n.I18n(LOCALES, DEFAULT_LOCALE);\n\n// All the locales that are part of the DevTools bundle and should not be fetched\n// remotely.\nconst BUNDLED_LOCALES = new Set<string>([...BUNDLED_LOCALES_GENERATED]);\n\n/**\n * Look up the best available locale for the requested language through these fall backs:\n * - exact match\n * - progressively shorter prefixes (`de-CH-1996` -> `de-CH` -> `de`)\n * - the default locale ('en-US') if no match is found\n *\n * If `locale` isn't provided, the default is used.\n */\nexport function lookupClosestSupportedDevToolsLocale(locale: string): string {\n return i18nInstance.lookupClosestSupportedLocale(locale);\n}\n\n/**\n * Returns a list of all supported DevTools locales, including pseudo locales.\n */\nexport function getAllSupportedDevToolsLocales(): string[] {\n return [...i18nInstance.supportedLocales];\n}\n\n/**\n * Returns the Url from which a locale can be fetched. This depends on the\n * specific locale, as some are bundled with DevTools while others\n * have to be fetched remotely.\n */\nfunction getLocaleFetchUrl(locale: Intl.UnicodeBCP47LocaleIdentifier, location: string): string {\n const remoteBase = Root.Runtime.getRemoteBase(location);\n if (remoteBase && remoteBase.version && !BUNDLED_LOCALES.has(locale)) {\n return REMOTE_FETCH_PATTERN.replace('@HOST@', 'devtools://devtools')\n .replace('@VERSION@', remoteBase.version)\n .replace('@LOCALE@', locale);\n }\n const path = LOCAL_FETCH_PATTERN.replace('@LOCALE@', locale);\n return new URL(path, import.meta.url).toString();\n}\n\n/**\n * Fetches the locale data of the specified locale.\n * Callers have to ensure that `locale` is an officilly supported locale.\n * Depending whether a locale is present in `bundledLocales`, the data will be\n * fetched locally or remotely.\n */\nexport async function fetchAndRegisterLocaleData(\n locale: Intl.UnicodeBCP47LocaleIdentifier, location = self.location.toString()): Promise<void> {\n const localeDataTextPromise = fetch(getLocaleFetchUrl(locale, location)).then(result => result.json());\n const timeoutPromise =\n new Promise((resolve, reject) => window.setTimeout(() => reject(new Error('timed out fetching locale')), 5000));\n const localeData = await Promise.race([timeoutPromise, localeDataTextPromise]);\n i18nInstance.registerLocaleData(locale, localeData);\n}\n\n/**\n * Returns an anonymous function that wraps a call to retrieve a localized string.\n * This is introduced so that localized strings can be declared in environments where\n * the i18n system has not been configured and so, cannot be directly invoked. Instead,\n * strings are lazily localized when they are used. This is used for instance in the\n * meta files used to register module extensions.\n */\nexport function getLazilyComputedLocalizedString(\n registeredStrings: I18n.LocalizedStringSet.RegisteredFileStrings, id: string, values: i18nTypes.Values = {}): () =>\n Platform.UIString.LocalizedString {\n return (): Platform.UIString.LocalizedString => getLocalizedString(registeredStrings, id, values);\n}\n\n/**\n * Retrieve the localized string.\n */\nexport function getLocalizedString(\n registeredStrings: I18n.LocalizedStringSet.RegisteredFileStrings, id: string,\n values: i18nTypes.Values = {}): Platform.UIString.LocalizedString {\n return registeredStrings.getLocalizedStringSetFor(DevToolsLocale.instance().locale).getLocalizedString(id, values) as\n Platform.UIString.LocalizedString;\n}\n\n/**\n * Register a file's UIStrings with i18n, return function to generate the string ids.\n */\nexport function registerUIStrings(\n path: string, stringStructure: {[key: string]: string}): I18n.LocalizedStringSet.RegisteredFileStrings {\n return i18nInstance.registerFileStrings(path, stringStructure);\n}\n\n/**\n * Returns a span element that may contains other DOM element as placeholders\n */\nexport function getFormatLocalizedString(\n registeredStrings: I18n.LocalizedStringSet.RegisteredFileStrings, stringId: string,\n placeholders: Record<string, Object>): Element {\n const formatter =\n registeredStrings.getLocalizedStringSetFor(DevToolsLocale.instance().locale).getMessageFormatterFor(stringId);\n\n const element = document.createElement('span');\n for (const icuElement of formatter.getAst()) {\n if (icuElement.type === /* argumentElement */ 1) {\n const placeholderValue = placeholders[icuElement.value];\n if (placeholderValue) {\n element.append(placeholderValue as Node | string);\n }\n } else if ('value' in icuElement) {\n element.append(String(icuElement.value));\n }\n }\n return element;\n}\n\nexport function serializeUIString(string: string, values: Record<string, Object> = {}): string {\n const serializedMessage = {string, values};\n return JSON.stringify(serializedMessage);\n}\n\nexport function deserializeUIString(serializedMessage: string): i18nTypes.SerializedMessage {\n if (!serializedMessage) {\n return {string: '', values: {}} as i18nTypes.SerializedMessage;\n }\n\n return JSON.parse(serializedMessage) as i18nTypes.SerializedMessage;\n}\n\n/**\n * Use this function in places where a `LocalizedString` is expected but the\n * term/phrase you want to use does not require translation.\n */\nexport function lockedString(str: string): Platform.UIString.LocalizedString {\n return str as Platform.UIString.LocalizedString;\n}\n\n/**\n * Same as `lockedString` but for places where `i18nLazyString` would be used otherwise.\n */\nexport function lockedLazyString(str: string): () => Platform.UIString.LocalizedString {\n return (): Platform.UIString.LocalizedString => str as Platform.UIString.LocalizedString;\n}\n\n/**\n * Returns a string of the form:\n * \"German (Austria) - Deutsch (\u00D6sterreich)\"\n * where the former locale representation is written in the currently enabled DevTools\n * locale and the latter locale representation is written in the locale of `localeString`.\n *\n * Should the two locales match (i.e. have the same language) then the latter locale\n * representation is written in English.\n */\nexport function getLocalizedLanguageRegion(\n localeString: Intl.UnicodeBCP47LocaleIdentifier,\n devtoolsLocale: DevToolsLocale): Platform.UIString.LocalizedString {\n const locale = new Intl.Locale(localeString);\n Platform.DCHECK(() => locale.language !== undefined);\n Platform.DCHECK(() => locale.baseName !== undefined);\n const localLanguage = locale.language || 'en';\n const localBaseName = locale.baseName || 'en-US';\n const devtoolsLoc = new Intl.Locale(devtoolsLocale.locale);\n const targetLanguage = localLanguage === devtoolsLoc.language ? 'en' : localBaseName;\n const languageInCurrentLocale = new Intl.DisplayNames([devtoolsLocale.locale], {type: 'language'}).of(localLanguage);\n const languageInTargetLocale = new Intl.DisplayNames([targetLanguage], {type: 'language'}).of(localLanguage);\n\n let wrappedRegionInCurrentLocale = '';\n let wrappedRegionInTargetLocale = '';\n\n if (locale.region) {\n const regionInCurrentLocale =\n new Intl.DisplayNames([devtoolsLocale.locale], {type: 'region', style: 'short'}).of(locale.region);\n const regionInTargetLocale =\n new Intl.DisplayNames([targetLanguage], {type: 'region', style: 'short'}).of(locale.region);\n wrappedRegionInCurrentLocale = ` (${regionInCurrentLocale})`;\n wrappedRegionInTargetLocale = ` (${regionInTargetLocale})`;\n }\n\n return `${languageInCurrentLocale}${wrappedRegionInCurrentLocale} - ${languageInTargetLocale}${\n wrappedRegionInTargetLocale}` as Platform.UIString.LocalizedString;\n}\n", "// Copyright 2018 The Lighthouse Authors. All Rights Reserved.\n// 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\n// 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.\n\nimport {RegisteredFileStrings} from './localized-string-set.js';\n\nexport type UIStrings = Record<string, string>;\nexport type LocalizedMessages = Record<string, {message: string}>;\n\n/**\n * Encapsulates the global state of the i18n runtime.\n */\nexport class I18n {\n readonly supportedLocales: ReadonlySet<Intl.UnicodeBCP47LocaleIdentifier>;\n\n private localeData = new Map<Intl.UnicodeBCP47LocaleIdentifier, LocalizedMessages>();\n readonly defaultLocale;\n\n constructor(\n supportedLocales: readonly Intl.UnicodeBCP47LocaleIdentifier[], defaultLocale: Intl.UnicodeBCP47LocaleIdentifier) {\n this.defaultLocale = defaultLocale;\n\n this.supportedLocales = new Set(supportedLocales);\n }\n\n registerLocaleData(locale: Intl.UnicodeBCP47LocaleIdentifier, messages: LocalizedMessages): void {\n this.localeData.set(locale, messages);\n }\n\n registerFileStrings(filename: string, stringStructure: UIStrings): RegisteredFileStrings {\n return new RegisteredFileStrings(filename, stringStructure, this.localeData);\n }\n\n /**\n * Look up the best available locale for the requested language through these fall backs:\n * - exact match\n * - progressively shorter prefixes (`de-CH-1996` -> `de-CH` -> `de`)\n * - the default locale if no match is found\n */\n lookupClosestSupportedLocale(locale: Intl.UnicodeBCP47LocaleIdentifier): Intl.UnicodeBCP47LocaleIdentifier {\n // @ts-expect-error https://github.com/microsoft/TypeScript/issues/29129\n const canonicalLocale: string = Intl.getCanonicalLocales(locale)[0];\n\n const localeParts = canonicalLocale.split('-');\n while (localeParts.length) {\n const candidate = localeParts.join('-');\n if (this.supportedLocales.has(candidate)) {\n return candidate;\n }\n localeParts.pop();\n }\n return this.defaultLocale;\n }\n}\n", "// node_modules/tslib/tslib.es6.js\nvar __assign = function() {\n __assign = Object.assign || function __assign2(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s)\n if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\n\n// bazel-out/darwin-fastbuild/bin/packages/icu-messageformat-parser/lib/error.js\nvar ErrorKind;\n(function(ErrorKind2) {\n ErrorKind2[ErrorKind2[\"EXPECT_ARGUMENT_CLOSING_BRACE\"] = 1] = \"EXPECT_ARGUMENT_CLOSING_BRACE\";\n ErrorKind2[ErrorKind2[\"EMPTY_ARGUMENT\"] = 2] = \"EMPTY_ARGUMENT\";\n ErrorKind2[ErrorKind2[\"MALFORMED_ARGUMENT\"] = 3] = \"MALFORMED_ARGUMENT\";\n ErrorKind2[ErrorKind2[\"EXPECT_ARGUMENT_TYPE\"] = 4] = \"EXPECT_ARGUMENT_TYPE\";\n ErrorKind2[ErrorKind2[\"INVALID_ARGUMENT_TYPE\"] = 5] = \"INVALID_ARGUMENT_TYPE\";\n ErrorKind2[ErrorKind2[\"EXPECT_ARGUMENT_STYLE\"] = 6] = \"EXPECT_ARGUMENT_STYLE\";\n ErrorKind2[ErrorKind2[\"INVALID_NUMBER_SKELETON\"] = 7] = \"INVALID_NUMBER_SKELETON\";\n ErrorKind2[ErrorKind2[\"INVALID_DATE_TIME_SKELETON\"] = 8] = \"INVALID_DATE_TIME_SKELETON\";\n ErrorKind2[ErrorKind2[\"EXPECT_NUMBER_SKELETON\"] = 9] = \"EXPECT_NUMBER_SKELETON\";\n ErrorKind2[ErrorKind2[\"EXPECT_DATE_TIME_SKELETON\"] = 10] = \"EXPECT_DATE_TIME_SKELETON\";\n ErrorKind2[ErrorKind2[\"UNCLOSED_QUOTE_IN_ARGUMENT_STYLE\"] = 11] = \"UNCLOSED_QUOTE_IN_ARGUMENT_STYLE\";\n ErrorKind2[ErrorKind2[\"EXPECT_SELECT_ARGUMENT_OPTIONS\"] = 12] = \"EXPECT_SELECT_ARGUMENT_OPTIONS\";\n ErrorKind2[ErrorKind2[\"EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE\"] = 13] = \"EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE\";\n ErrorKind2[ErrorKind2[\"INVALID_PLURAL_ARGUMENT_OFFSET_VALUE\"] = 14] = \"INVALID_PLURAL_ARGUMENT_OFFSET_VALUE\";\n ErrorKind2[ErrorKind2[\"EXPECT_SELECT_ARGUMENT_SELECTOR\"] = 15] = \"EXPECT_SELECT_ARGUMENT_SELECTOR\";\n ErrorKind2[ErrorKind2[\"EXPECT_PLURAL_ARGUMENT_SELECTOR\"] = 16] = \"EXPECT_PLURAL_ARGUMENT_SELECTOR\";\n ErrorKind2[ErrorKind2[\"EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT\"] = 17] = \"EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT\";\n ErrorKind2[ErrorKind2[\"EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT\"] = 18] = \"EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT\";\n ErrorKind2[ErrorKind2[\"INVALID_PLURAL_ARGUMENT_SELECTOR\"] = 19] = \"INVALID_PLURAL_ARGUMENT_SELECTOR\";\n ErrorKind2[ErrorKind2[\"DUPLICATE_PLURAL_ARGUMENT_SELECTOR\"] = 20] = \"DUPLICATE_PLURAL_ARGUMENT_SELECTOR\";\n ErrorKind2[ErrorKind2[\"DUPLICATE_SELECT_ARGUMENT_SELECTOR\"] = 21] = \"DUPLICATE_SELECT_ARGUMENT_SELECTOR\";\n ErrorKind2[ErrorKind2[\"MISSING_OTHER_CLAUSE\"] = 22] = \"MISSING_OTHER_CLAUSE\";\n ErrorKind2[ErrorKind2[\"INVALID_TAG\"] = 23] = \"INVALID_TAG\";\n ErrorKind2[ErrorKind2[\"INVALID_TAG_NAME\"] = 25] = \"INVALID_TAG_NAME\";\n ErrorKind2[ErrorKind2[\"UNMATCHED_CLOSING_TAG\"] = 26] = \"UNMATCHED_CLOSING_TAG\";\n ErrorKind2[ErrorKind2[\"UNCLOSED_TAG\"] = 27] = \"UNCLOSED_TAG\";\n})(ErrorKind || (ErrorKind = {}));\n\n// bazel-out/darwin-fastbuild/bin/packages/icu-messageformat-parser/lib/types.js\nvar TYPE;\n(function(TYPE2) {\n TYPE2[TYPE2[\"literal\"] = 0] = \"literal\";\n TYPE2[TYPE2[\"argument\"] = 1] = \"argument\";\n TYPE2[TYPE2[\"number\"] = 2] = \"number\";\n TYPE2[TYPE2[\"date\"] = 3] = \"date\";\n TYPE2[TYPE2[\"time\"] = 4] = \"time\";\n TYPE2[TYPE2[\"select\"] = 5] = \"select\";\n TYPE2[TYPE2[\"plural\"] = 6] = \"plural\";\n TYPE2[TYPE2[\"pound\"] = 7] = \"pound\";\n TYPE2[TYPE2[\"tag\"] = 8] = \"tag\";\n})(TYPE || (TYPE = {}));\nvar SKELETON_TYPE;\n(function(SKELETON_TYPE2) {\n SKELETON_TYPE2[SKELETON_TYPE2[\"number\"] = 0] = \"number\";\n SKELETON_TYPE2[SKELETON_TYPE2[\"dateTime\"] = 1] = \"dateTime\";\n})(SKELETON_TYPE || (SKELETON_TYPE = {}));\nfunction isLiteralElement(el) {\n return el.type === TYPE.literal;\n}\nfunction isArgumentElement(el) {\n return el.type === TYPE.argument;\n}\nfunction isNumberElement(el) {\n return el.type === TYPE.number;\n}\nfunction isDateElement(el) {\n return el.type === TYPE.date;\n}\nfunction isTimeElement(el) {\n return el.type === TYPE.time;\n}\nfunction isSelectElement(el) {\n return el.type === TYPE.select;\n}\nfunction isPluralElement(el) {\n return el.type === TYPE.plural;\n}\nfunction isPoundElement(el) {\n return el.type === TYPE.pound;\n}\nfunction isTagElement(el) {\n return el.type === TYPE.tag;\n}\nfunction isNumberSkeleton(el) {\n return !!(el && typeof el === \"object\" && el.type === SKELETON_TYPE.number);\n}\nfunction isDateTimeSkeleton(el) {\n return !!(el && typeof el === \"object\" && el.type === SKELETON_TYPE.dateTime);\n}\n\n// bazel-out/darwin-fastbuild/bin/packages/icu-messageformat-parser/lib/regex.generated.js\nvar SPACE_SEPARATOR_REGEX = /[ \\xA0\\u1680\\u2000-\\u200A\\u202F\\u205F\\u3000]/;\n\n// bazel-out/darwin-fastbuild/bin/packages/icu-skeleton-parser/lib/date-time.js\nvar 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;\nfunction parseDateTimeSkeleton(skeleton) {\n var result = {};\n skeleton.replace(DATE_TIME_REGEX, function(match) {\n var len = match.length;\n switch (match[0]) {\n case \"G\":\n result.era = len === 4 ? \"long\" : len === 5 ? \"narrow\" : \"short\";\n break;\n case \"y\":\n result.year = len === 2 ? \"2-digit\" : \"numeric\";\n break;\n case \"Y\":\n case \"u\":\n case \"U\":\n case \"r\":\n throw new RangeError(\"`Y/u/U/r` (year) patterns are not supported, use `y` instead\");\n case \"q\":\n case \"Q\":\n throw new RangeError(\"`q/Q` (quarter) patterns are not supported\");\n case \"M\":\n case \"L\":\n result.month = [\"numeric\", \"2-digit\", \"short\", \"long\", \"narrow\"][len - 1];\n break;\n case \"w\":\n case \"W\":\n throw new RangeError(\"`w/W` (week) patterns are not supported\");\n case \"d\":\n result.day = [\"numeric\", \"2-digit\"][len - 1];\n break;\n case \"D\":\n case \"F\":\n case \"g\":\n throw new RangeError(\"`D/F/g` (day) patterns are not supported, use `d` instead\");\n case \"E\":\n result.weekday = len === 4 ? \"short\" : len === 5 ? \"narrow\" : \"short\";\n break;\n case \"e\":\n if (len < 4) {\n throw new RangeError(\"`e..eee` (weekday) patterns are not supported\");\n }\n result.weekday = [\"short\", \"long\", \"narrow\", \"short\"][len - 4];\n break;\n case \"c\":\n if (len < 4) {\n throw new RangeError(\"`c..ccc` (weekday) patterns are not supported\");\n }\n result.weekday = [\"short\", \"long\", \"narrow\", \"short\"][len - 4];\n break;\n case \"a\":\n result.hour12 = true;\n break;\n case \"b\":\n case \"B\":\n throw new RangeError(\"`b/B` (period) patterns are not supported, use `a` instead\");\n case \"h\":\n result.hourCycle = \"h12\";\n result.hour = [\"numeric\", \"2-digit\"][len - 1];\n break;\n case \"H\":\n result.hourCycle = \"h23\";\n result.hour = [\"numeric\", \"2-digit\"][len - 1];\n break;\n case \"K\":\n result.hourCycle = \"h11\";\n result.hour = [\"numeric\", \"2-digit\"][len - 1];\n break;\n case \"k\":\n result.hourCycle = \"h24\";\n result.hour = [\"numeric\", \"2-digit\"][len - 1];\n break;\n case \"j\":\n case \"J\":\n case \"C\":\n throw new RangeError(\"`j/J/C` (hour) patterns are not supported, use `h/H/K/k` instead\");\n case \"m\":\n result.minute = [\"numeric\", \"2-digit\"][len - 1];\n break;\n case \"s\":\n result.second = [\"numeric\", \"2-digit\"][len - 1];\n break;\n case \"S\":\n case \"A\":\n throw new RangeError(\"`S/A` (second) patterns are not supported, use `s` instead\");\n case \"z\":\n result.timeZoneName = len < 4 ? \"short\" : \"long\";\n break;\n case \"Z\":\n case \"O\":\n case \"v\":\n case \"V\":\n case \"X\":\n case \"x\":\n throw new RangeError(\"`Z/O/v/V/X/x` (timeZone) patterns are not supported, use `z` instead\");\n }\n return \"\";\n });\n return result;\n}\n\n// bazel-out/darwin-fastbuild/bin/packages/icu-skeleton-parser/lib/regex.generated.js\nvar WHITE_SPACE_REGEX = /[\\t-\\r \\x85\\u200E\\u200F\\u2028\\u2029]/i;\n\n// bazel-out/darwin-fastbuild/bin/packages/icu-skeleton-parser/lib/number.js\nfunction parseNumberSkeletonFromString(skeleton) {\n if (skeleton.length === 0) {\n throw new Error(\"Number skeleton cannot be empty\");\n }\n var stringTokens = skeleton.split(WHITE_SPACE_REGEX).filter(function(x) {\n return x.length > 0;\n });\n var tokens = [];\n for (var _i = 0, stringTokens_1 = stringTokens; _i < stringTokens_1.length; _i++) {\n var stringToken = stringTokens_1[_i];\n var stemAndOptions = stringToken.split(\"/\");\n if (stemAndOptions.length === 0) {\n throw new Error(\"Invalid number skeleton\");\n }\n var stem = stemAndOptions[0], options = stemAndOptions.slice(1);\n for (var _a2 = 0, options_1 = options; _a2 < options_1.length; _a2++) {\n var option = options_1[_a2];\n if (option.length === 0) {\n throw new Error(\"Invalid number skeleton\");\n }\n }\n tokens.push({stem, options});\n }\n return tokens;\n}\nfunction icuUnitToEcma(unit) {\n return unit.replace(/^(.*?)-/, \"\");\n}\nvar FRACTION_PRECISION_REGEX = /^\\.(?:(0+)(\\*)?|(#+)|(0+)(#+))$/g;\nvar SIGNIFICANT_PRECISION_REGEX = /^(@+)?(\\+|#+)?$/g;\nvar INTEGER_WIDTH_REGEX = /(\\*)(0+)|(#+)(0+)|(0+)/g;\nvar CONCISE_INTEGER_WIDTH_REGEX = /^(0+)$/;\nfunction parseSignificantPrecision(str) {\n var result = {};\n str.replace(SIGNIFICANT_PRECISION_REGEX, function(_, g1, g2) {\n if (typeof g2 !== \"string\") {\n result.minimumSignificantDigits = g1.length;\n result.maximumSignificantDigits = g1.length;\n } else if (g2 === \"+\") {\n result.minimumSignificantDigits = g1.length;\n } else if (g1[0] === \"#\") {\n result.maximumSignificantDigits = g1.length;\n } else {\n result.minimumSignificantDigits = g1.length;\n result.maximumSignificantDigits = g1.length + (typeof g2 === \"string\" ? g2.length : 0);\n }\n return \"\";\n });\n return result;\n}\nfunction parseSign(str) {\n switch (str) {\n case \"sign-auto\":\n return {\n signDisplay: \"auto\"\n };\n case \"sign-accounting\":\n case \"()\":\n return {\n currencySign: \"accounting\"\n };\n case \"sign-always\":\n case \"+!\":\n return {\n signDisplay: \"always\"\n };\n case \"sign-accounting-always\":\n case \"()!\":\n return {\n signDisplay: \"always\",\n currencySign: \"accounting\"\n };\n case \"sign-except-zero\":\n case \"+?\":\n return {\n signDisplay: \"exceptZero\"\n };\n case \"sign-accounting-except-zero\":\n case \"()?\":\n return {\n signDisplay: \"exceptZero\",\n currencySign: \"accounting\"\n };\n case \"sign-never\":\n case \"+_\":\n return {\n signDisplay: \"never\"\n };\n }\n}\nfunction parseConciseScientificAndEngineeringStem(stem) {\n var result;\n if (stem[0] === \"E\" && stem[1] === \"E\") {\n result = {\n notation: \"engineering\"\n };\n stem = stem.slice(2);\n } else if (stem[0] === \"E\") {\n result = {\n notation: \"scientific\"\n };\n stem = stem.slice(1);\n }\n if (result) {\n var signDisplay = stem.slice(0, 2);\n if (signDisplay === \"+!\") {\n result.signDisplay = \"always\";\n stem = stem.slice(2);\n } else if (signDisplay === \"+?\") {\n result.signDisplay = \"exceptZero\";\n stem = stem.slice(2);\n }\n if (!CONCISE_INTEGER_WIDTH_REGEX.test(stem)) {\n throw new Error(\"Malformed concise eng/scientific notation\");\n }\n result.minimumIntegerDigits = stem.length;\n }\n return result;\n}\nfunction parseNotationOptions(opt) {\n var result = {};\n var signOpts = parseSign(opt);\n if (signOpts) {\n return signOpts;\n }\n return result;\n}\nfunction parseNumberSkeleton(tokens) {\n var result = {};\n for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {\n var token = tokens_1[_i];\n switch (token.stem) {\n case \"percent\":\n case \"%\":\n result.style = \"percent\";\n continue;\n case \"%x100\":\n result.style = \"percent\";\n result.scale = 100;\n continue;\n case \"currency\":\n result.style = \"currency\";\n result.currency = token.options[0];\n continue;\n case \"group-off\":\n case \",_\":\n result.useGrouping = false;\n continue;\n case \"precision-integer\":\n case \".\":\n result.maximumFractionDigits = 0;\n continue;\n case \"measure-unit\":\n case \"unit\":\n result.style = \"unit\";\n result.unit = icuUnitToEcma(token.options[0]);\n continue;\n case \"compact-short\":\n case \"K\":\n result.notation = \"compact\";\n result.compactDisplay = \"short\";\n continue;\n case \"compact-long\":\n case \"KK\":\n result.notation = \"compact\";\n result.compactDisplay = \"long\";\n continue;\n case \"scientific\":\n result = __assign(__assign(__assign({}, result), {notation: \"scientific\"}), token.options.reduce(function(all, opt) {\n return __assign(__assign({}, all), parseNotationOptions(opt));\n }, {}));\n continue;\n case \"engineering\":\n result = __assign(__assign(__assign({}, result), {notation: \"engineering\"}), token.options.reduce(function(all, opt) {\n return __assign(__assign({}, all), parseNotationOptions(opt));\n }, {}));\n continue;\n case \"notation-simple\":\n result.notation = \"standard\";\n continue;\n case \"unit-width-narrow\":\n result.currencyDisplay = \"narrowSymbol\";\n result.unitDisplay = \"narrow\";\n continue;\n case \"unit-width-short\":\n result.currencyDisplay = \"code\";\n result.unitDisplay = \"short\";\n continue;\n case \"unit-width-full-name\":\n result.currencyDisplay = \"name\";\n result.unitDisplay = \"long\";\n continue;\n case \"unit-width-iso-code\":\n result.currencyDisplay = \"symbol\";\n continue;\n case \"scale\":\n result.scale = parseFloat(token.options[0]);\n continue;\n case \"integer-width\":\n if (token.options.length > 1) {\n throw new RangeError(\"integer-width stems only accept a single optional option\");\n }\n token.options[0].replace(INTEGER_WIDTH_REGEX, function(_, g1, g2, g3, g4, g5) {\n if (g1) {\n result.minimumIntegerDigits = g2.length;\n } else if (g3 && g4) {\n throw new Error(\"We currently do not support maximum integer digits\");\n } else if (g5) {\n throw new Error(\"We currently do not support exact integer digits\");\n }\n return \"\";\n });\n continue;\n }\n if (CONCISE_INTEGER_WIDTH_REGEX.test(token.stem)) {\n result.minimumIntegerDigits = token.stem.length;\n continue;\n }\n if (FRACTION_PRECISION_REGEX.test(token.stem)) {\n if (token.options.length > 1) {\n throw new RangeError(\"Fraction-precision stems only accept a single optional option\");\n }\n token.stem.replace(FRACTION_PRECISION_REGEX, function(_, g1, g2, g3, g4, g5) {\n if (g2 === \"*\") {\n result.minimumFractionDigits = g1.length;\n } else if (g3 && g3[0] === \"#\") {\n result.maximumFractionDigits = g3.length;\n } else if (g4 && g5) {\n result.minimumFractionDigits = g4.length;\n result.maximumFractionDigits = g4.length + g5.length;\n } else {\n result.minimumFractionDigits = g1.length;\n result.maximumFractionDigits = g1.length;\n }\n return \"\";\n });\n if (token.options.length) {\n result = __assign(__assign({}, result), parseSignificantPrecision(token.options[0]));\n }\n continue;\n }\n if (SIGNIFICANT_PRECISION_REGEX.test(token.stem)) {\n result = __assign(__assign({}, result), parseSignificantPrecision(token.stem));\n continue;\n }\n var signOpts = parseSign(token.stem);\n if (signOpts) {\n result = __assign(__assign({}, result), signOpts);\n }\n var conciseScientificAndEngineeringOpts = parseConciseScientificAndEngineeringStem(token.stem);\n if (conciseScientificAndEngineeringOpts) {\n result = __assign(__assign({}, result), conciseScientificAndEngineeringOpts);\n }\n }\n return result;\n}\n\n// bazel-out/darwin-fastbuild/bin/packages/icu-messageformat-parser/lib/parser.js\nvar _a;\nvar SPACE_SEPARATOR_START_REGEX = new RegExp(\"^\" + SPACE_SEPARATOR_REGEX.source + \"*\");\nvar SPACE_SEPARATOR_END_REGEX = new RegExp(SPACE_SEPARATOR_REGEX.source + \"*$\");\nfunction createLocation(start, end) {\n return {start, end};\n}\nvar hasNativeStartsWith = !!String.prototype.startsWith;\nvar hasNativeFromCodePoint = !!String.fromCodePoint;\nvar hasNativeFromEntries = !!Object.fromEntries;\nvar hasNativeCodePointAt = !!String.prototype.codePointAt;\nvar hasTrimStart = !!String.prototype.trimStart;\nvar hasTrimEnd = !!String.prototype.trimEnd;\nvar hasNativeIsSafeInteger = !!Number.isSafeInteger;\nvar isSafeInteger = hasNativeIsSafeInteger ? Number.isSafeInteger : function(n) {\n return typeof n === \"number\" && isFinite(n) && Math.floor(n) === n && Math.abs(n) <= 9007199254740991;\n};\nvar REGEX_SUPPORTS_U_AND_Y = true;\ntry {\n re = RE(\"([^\\\\p{White_Space}\\\\p{Pattern_Syntax}]*)\", \"yu\");\n REGEX_SUPPORTS_U_AND_Y = ((_a = re.exec(\"a\")) === null || _a === void 0 ? void 0 : _a[0]) === \"a\";\n} catch (_) {\n REGEX_SUPPORTS_U_AND_Y = false;\n}\nvar re;\nvar startsWith = hasNativeStartsWith ? function startsWith2(s, search, position) {\n return s.startsWith(search, position);\n} : function startsWith3(s, search, position) {\n return s.slice(position, position + search.length) === search;\n};\nvar fromCodePoint = hasNativeFromCodePoint ? String.fromCodePoint : function fromCodePoint2() {\n var codePoints = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n codePoints[_i] = arguments[_i];\n }\n var elements = \"\";\n var length = codePoints.length;\n var i = 0;\n var code;\n while (length > i) {\n code = codePoints[i++];\n if (code > 1114111)\n throw RangeError(code + \" is not a valid code point\");\n elements += code < 65536 ? String.fromCharCode(code) : String.fromCharCode(((code -= 65536) >> 10) + 55296, code % 1024 + 56320);\n }\n return elements;\n};\nvar fromEntries = hasNativeFromEntries ? Object.fromEntries : function fromEntries2(entries) {\n var obj = {};\n for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {\n var _a2 = entries_1[_i], k = _a2[0], v = _a2[1];\n obj[k] = v;\n }\n return obj;\n};\nvar codePointAt = hasNativeCodePointAt ? function codePointAt2(s, index) {\n return s.codePointAt(index);\n} : function codePointAt3(s, index) {\n var size = s.length;\n if (index < 0 || index >= size) {\n return void 0;\n }\n var first = s.charCodeAt(index);\n var second;\n return first < 55296 || first > 56319 || index + 1 === size || (second = s.charCodeAt(index + 1)) < 56320 || second > 57343 ? first : (first - 55296 << 10) + (second - 56320) + 65536;\n};\nvar trimStart = hasTrimStart ? function trimStart2(s) {\n return s.trimStart();\n} : function trimStart3(s) {\n return s.replace(SPACE_SEPARATOR_START_REGEX, \"\");\n};\nvar trimEnd = hasTrimEnd ? function trimEnd2(s) {\n return s.trimEnd();\n} : function trimEnd3(s) {\n return s.replace(SPACE_SEPARATOR_END_REGEX, \"\");\n};\nfunction RE(s, flag) {\n return new RegExp(s, flag);\n}\nvar matchIdentifierAtIndex;\nif (REGEX_SUPPORTS_U_AND_Y) {\n IDENTIFIER_PREFIX_RE_1 = RE(\"([^\\\\p{White_Space}\\\\p{Pattern_Syntax}]*)\", \"yu\");\n matchIdentifierAtIndex = function matchIdentifierAtIndex2(s, index) {\n var _a2;\n IDENTIFIER_PREFIX_RE_1.lastIndex = index;\n var match = IDENTIFIER_PREFIX_RE_1.exec(s);\n return (_a2 = match[1]) !== null && _a2 !== void 0 ? _a2 : \"\";\n };\n} else {\n matchIdentifierAtIndex = function matchIdentifierAtIndex2(s, index) {\n var match = [];\n while (true) {\n var c = codePointAt(s, index);\n if (c === void 0 || _isWhiteSpace(c) || _isPatternSyntax(c)) {\n break;\n }\n match.push(c);\n index += c >= 65536 ? 2 : 1;\n }\n return fromCodePoint.apply(void 0, match);\n };\n}\nvar IDENTIFIER_PREFIX_RE_1;\nvar Parser = function() {\n function Parser2(message, options) {\n if (options === void 0) {\n options = {};\n }\n this.message = message;\n this.position = {offset: 0, line: 1, column: 1};\n this.ignoreTag = !!options.ignoreTag;\n this.requiresOtherClause = !!options.requiresOtherClause;\n this.shouldParseSkeletons = !!options.shouldParseSkeletons;\n }\n Parser2.prototype.parse = function() {\n if (this.offset() !== 0) {\n throw Error(\"parser can only be used once\");\n }\n return this.parseMessage(0, \"\", false);\n };\n Parser2.prototype.parseMessage = function(nestingLevel, parentArgType, expectingCloseTag) {\n var elements = [];\n while (!this.isEOF()) {\n var char = this.char();\n if (char === 123) {\n var result = this.parseArgument(nestingLevel, expectingCloseTag);\n if (result.err) {\n return result;\n }\n elements.push(result.val);\n } else if (char === 125 && nestingLevel > 0) {\n break;\n } else if (char === 35 && (parentArgType === \"plural\" || parentArgType === \"selectordinal\")) {\n var position = this.clonePosition();\n this.bump();\n elements.push({\n type: TYPE.pound,\n location: createLocation(position, this.clonePosition())\n });\n } else if (char === 60 && !this.ignoreTag && this.peek() === 47) {\n if (expectingCloseTag) {\n break;\n } else {\n return this.error(ErrorKind.UNMATCHED_CLOSING_TAG, createLocation(this.clonePosition(), this.clonePosition()));\n }\n } else if (char === 60 && !this.ignoreTag && _isAlpha(this.peek() || 0)) {\n var result = this.parseTag(nestingLevel, parentArgType);\n if (result.err) {\n return result;\n }\n elements.push(result.val);\n } else {\n var result = this.parseLiteral(nestingLevel, parentArgType);\n if (result.err) {\n return result;\n }\n elements.push(result.val);\n }\n }\n return {val: elements, err: null};\n };\n Parser2.prototype.parseTag = function(nestingLevel, parentArgType) {\n var startPosition = this.clonePosition();\n this.bump();\n var tagName = this.parseTagName();\n this.bumpSpace();\n if (this.bumpIf(\"/>\")) {\n return {\n val: {\n type: TYPE.literal,\n value: \"<\" + tagName + \"/>\",\n location: createLocation(startPosition, this.clonePosition())\n },\n err: null\n };\n } else if (this.bumpIf(\">\")) {\n var childrenResult = this.parseMessage(nestingLevel + 1, parentArgType, true);\n if (childrenResult.err) {\n return childrenResult;\n }\n var children = childrenResult.val;\n var endTagStartPosition = this.clonePosition();\n if (this.bumpIf(\"</\")) {\n if (this.isEOF() || !_isAlpha(this.char())) {\n return this.error(ErrorKind.INVALID_TAG, createLocation(endTagStartPosition, this.clonePosition()));\n }\n var closingTagNameStartPosition = this.clonePosition();\n var closingTagName = this.parseTagName();\n if (tagName !== closingTagName) {\n return this.error(ErrorKind.UNMATCHED_CLOSING_TAG, createLocation(closingTagNameStartPosition, this.clonePosition()));\n }\n this.bumpSpace();\n if (!this.bumpIf(\">\")) {\n return this.error(ErrorKind.INVALID_TAG, createLocation(endTagStartPosition, this.clonePosition()));\n }\n return {\n val: {\n type: TYPE.tag,\n value: tagName,\n children,\n location: createLocation(startPosition, this.clonePosition())\n },\n err: null\n };\n } else {\n return this.error(ErrorKind.UNCLOSED_TAG, createLocation(startPosition, this.clonePosition()));\n }\n } else {\n return this.error(ErrorKind.INVALID_TAG, createLocation(startPosition, this.clonePosition()));\n }\n };\n Parser2.prototype.parseTagName = function() {\n var startOffset = this.offset();\n this.bump();\n while (!this.isEOF() && _isPotentialElementNameChar(this.char())) {\n this.bump();\n }\n return this.message.slice(startOffset, this.offset());\n };\n Parser2.prototype.parseLiteral = function(nestingLevel, parentArgType) {\n var start = this.clonePosition();\n var value = \"\";\n while (true) {\n var parseQuoteResult = this.tryParseQuote(parentArgType);\n if (parseQuoteResult) {\n value += parseQuoteResult;\n continue;\n }\n var parseUnquotedResult = this.tryParseUnquoted(nestingLevel, parentArgType);\n if (parseUnquotedResult) {\n value += parseUnquotedResult;\n continue;\n }\n var parseLeftAngleResult = this.tryParseLeftAngleBracket();\n if (parseLeftAngleResult) {\n value += parseLeftAngleResult;\n continue;\n }\n break;\n }\n var location = createLocation(start, this.clonePosition());\n return {\n val: {type: TYPE.literal, value, location},\n err: null\n };\n };\n Parser2.prototype.tryParseLeftAngleBracket = function() {\n if (!this.isEOF() && this.char() === 60 && (this.ignoreTag || !_isAlphaOrSlash(this.peek() || 0))) {\n this.bump();\n return \"<\";\n }\n return null;\n };\n Parser2.prototype.tryParseQuote = function(parentArgType) {\n if (this.isEOF() || this.char() !== 39) {\n return null;\n }\n switch (this.peek()) {\n case 39:\n this.bump();\n this.bump();\n return \"'\";\n case 123:\n case 60:\n case 62:\n case 125:\n break;\n case 35:\n if (parentArgType === \"plural\" || parentArgType === \"selectordinal\") {\n break;\n }\n return null;\n default:\n return null;\n }\n this.bump();\n var codePoints = [this.char()];\n this.bump();\n while (!this.isEOF()) {\n var ch = this.char();\n if (ch === 39) {\n if (this.peek() === 39) {\n codePoints.push(39);\n this.bump();\n } else {\n this.bump();\n break;\n }\n } else {\n codePoints.push(ch);\n }\n this.bump();\n }\n return fromCodePoint.apply(void 0, codePoints);\n };\n Parser2.prototype.tryParseUnquoted = function(nestingLevel, parentArgType) {\n if (this.isEOF()) {\n return null;\n }\n var ch = this.char();\n if (ch === 60 || ch === 123 || ch === 35 && (parentArgType === \"plural\" || parentArgType === \"selectordinal\") || ch === 125 && nestingLevel > 0) {\n return null;\n } else {\n this.bump();\n return fromCodePoint(ch);\n }\n };\n Parser2.prototype.parseArgument = function(nestingLevel, expectingCloseTag) {\n var openingBracePosition = this.clonePosition();\n this.bump();\n this.bumpSpace();\n if (this.isEOF()) {\n return this.error(ErrorKind.EXPECT_ARGUMENT_CLOSING_BRACE, createLocation(openingBracePosition, this.clonePosition()));\n }\n if (this.char() === 125) {\n this.bump();\n return this.error(ErrorKind.EMPTY_ARGUMENT, createLocation(openingBracePosition, this.clonePosition()));\n }\n var value = this.parseIdentifierIfPossible().value;\n if (!value) {\n return this.error(ErrorKind.MALFORMED_ARGUMENT, createLocation(openingBracePosition, this.clonePosition()));\n }\n this.bumpSpace();\n if (this.isEOF()) {\n return this.error(ErrorKind.EXPECT_ARGUMENT_CLOSING_BRACE, createLocation(openingBracePosition, this.clonePosition()));\n }\n switch (this.char()) {\n case 125: {\n this.bump();\n return {\n val: {\n type: TYPE.argument,\n value,\n location: createLocation(openingBracePosition, this.clonePosition())\n },\n err: null\n };\n }\n case 44: {\n this.bump();\n this.bumpSpace();\n if (this.isEOF()) {\n return this.error(ErrorKind.EXPECT_ARGUMENT_CLOSING_BRACE, createLocation(openingBracePosition, this.clonePosition()));\n }\n return this.parseArgumentOptions(nestingLevel, expectingCloseTag, value, openingBracePosition);\n }\n default:\n return this.error(ErrorKind.MALFORMED_ARGUMENT, createLocation(openingBracePosition, this.clonePosition()));\n }\n };\n Parser2.prototype.parseIdentifierIfPossible = function() {\n var startingPosition = this.clonePosition();\n var startOffset = this.offset();\n var value = matchIdentifierAtIndex(this.message, startOffset);\n var endOffset = startOffset + value.length;\n this.bumpTo(endOffset);\n var endPosition = this.clonePosition();\n var location = createLocation(startingPosition, endPosition);\n return {value, location};\n };\n Parser2.prototype.parseArgumentOptions = function(nestingLevel, expectingCloseTag, value, openingBracePosition) {\n var _a2;\n var typeStartPosition = this.clonePosition();\n var argType = this.parseIdentifierIfPossible().value;\n var typeEndPosition = this.clonePosition();\n switch (argType) {\n case \"\":\n return this.error(ErrorKind.EXPECT_ARGUMENT_TYPE, createLocation(typeStartPosition, typeEndPosition));\n case \"number\":\n case \"date\":\n case \"time\": {\n this.bumpSpace();\n var styleAndLocation = null;\n if (this.bumpIf(\",\")) {\n this.bumpSpace();\n var styleStartPosition = this.clonePosition();\n var result = this.parseSimpleArgStyleIfPossible();\n if (result.err) {\n return result;\n }\n var style = trimEnd(result.val);\n if (style.length === 0) {\n return this.error(ErrorKind.EXPECT_ARGUMENT_STYLE, createLocation(this.clonePosition(), this.clonePosition()));\n }\n var styleLocation = createLocation(styleStartPosition, this.clonePosition());\n styleAndLocation = {style, styleLocation};\n }\n var argCloseResult = this.tryParseArgumentClose(openingBracePosition);\n if (argCloseResult.err) {\n return argCloseResult;\n }\n var location_1 = createLocation(openingBracePosition, this.clonePosition());\n if (styleAndLocation && startsWith(styleAndLocation === null || styleAndLocation === void 0 ? void 0 : styleAndLocation.style, \"::\", 0)) {\n var skeleton = trimStart(styleAndLocation.style.slice(2));\n if (argType === \"number\") {\n var result = this.parseNumberSkeletonFromString(skeleton, styleAndLocation.styleLocation);\n if (result.err) {\n return result;\n }\n return {\n val: {type: TYPE.number, value, location: location_1, style: result.val},\n err: null\n };\n } else {\n if (skeleton.length === 0) {\n return this.error(ErrorKind.EXPECT_DATE_TIME_SKELETON, location_1);\n }\n var style = {\n type: SKELETON_TYPE.dateTime,\n pattern: skeleton,\n location: styleAndLocation.styleLocation,\n parsedOptions: this.shouldParseSkeletons ? parseDateTimeSkeleton(skeleton) : {}\n };\n var type = argType === \"date\" ? TYPE.date : TYPE.time;\n return {\n val: {type, value, location: location_1, style},\n err: null\n };\n }\n }\n return {\n val: {\n type: argType === \"number\" ? TYPE.number : argType === \"date\" ? TYPE.date : TYPE.time,\n value,\n location: location_1,\n style: (_a2 = styleAndLocation === null || styleAndLocation === void 0 ? void 0 : styleAndLocation.style) !== null && _a2 !== void 0 ? _a2 : null\n },\n err: null\n };\n }\n case \"plural\":\n case \"selectordinal\":\n case \"select\": {\n var typeEndPosition_1 = this.clonePosition();\n this.bumpSpace();\n if (!this.bumpIf(\",\")) {\n return this.error(ErrorKind.EXPECT_SELECT_ARGUMENT_OPTIONS, createLocation(typeEndPosition_1, __assign({}, typeEndPosition_1)));\n }\n this.bumpSpace();\n var identifierAndLocation = this.parseIdentifierIfPossible();\n var pluralOffset = 0;\n if (argType !== \"select\" && identifierAndLocation.value === \"offset\") {\n if (!this.bumpIf(\":\")) {\n return this.error(ErrorKind.EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE, createLocation(this.clonePosition(), this.clonePosition()));\n }\n this.bumpSpace();\n var result = this.tryParseDecimalInteger(ErrorKind.EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE, ErrorKind.INVALID_PLURAL_ARGUMENT_OFFSET_VALUE);\n if (result.err) {\n return result;\n }\n this.bumpSpace();\n identifierAndLocation = this.parseIdentifierIfPossible();\n pluralOffset = result.val;\n }\n var optionsResult = this.tryParsePluralOrSelectOptions(nestingLevel, argType, expectingCloseTag, identifierAndLocation);\n if (optionsResult.err) {\n return optionsResult;\n }\n var argCloseResult = this.tryParseArgumentClose(openingBracePosition);\n if (argCloseResult.err) {\n return argCloseResult;\n }\n var location_2 = createLocation(openingBracePosition, this.clonePosition());\n if (argType === \"select\") {\n return {\n val: {\n type: TYPE.select,\n value,\n options: fromEntries(optionsResult.val),\n location: location_2\n },\n err: null\n };\n } else {\n return {\n val: {\n type: TYPE.plural,\n value,\n options: fromEntries(optionsResult.val),\n offset: pluralOffset,\n pluralType: argType === \"plural\" ? \"cardinal\" : \"ordinal\",\n location: location_2\n },\n err: null\n };\n }\n }\n default:\n return this.error(ErrorKind.INVALID_ARGUMENT_TYPE, createLocation(typeStartPosition, typeEndPosition));\n }\n };\n Parser2.prototype.tryParseArgumentClose = function(openingBracePosition) {\n if (this.isEOF() || this.char() !== 125) {\n return this.error(ErrorKind.EXPECT_ARGUMENT_CLOSING_BRACE, createLocation(openingBracePosition, this.clonePosition()));\n }\n this.bump();\n return {val: true, err: null};\n };\n Parser2.prototype.parseSimpleArgStyleIfPossible = function() {\n var nestedBraces = 0;\n var startPosition = this.clonePosition();\n while (!this.isEOF()) {\n var ch = this.char();\n switch (ch) {\n case 39: {\n this.bump();\n var apostrophePosition = this.clonePosition();\n if (!this.bumpUntil(\"'\")) {\n return this.error(ErrorKind.UNCLOSED_QUOTE_IN_ARGUMENT_STYLE, createLocation(apostrophePosition, this.clonePosition()));\n }\n this.bump();\n break;\n }\n case 123: {\n nestedBraces += 1;\n this.bump();\n break;\n }\n case 125: {\n if (nestedBraces > 0) {\n nestedBraces -= 1;\n } else {\n return {\n val: this.message.slice(startPosition.offset, this.offset()),\n err: null\n };\n }\n break;\n }\n default:\n this.bump();\n break;\n }\n }\n return {\n val: this.message.slice(startPosition.offset, this.offset()),\n err: null\n };\n };\n Parser2.prototype.parseNumberSkeletonFromString = function(skeleton, location) {\n var tokens = [];\n try {\n tokens = parseNumberSkeletonFromString(skeleton);\n } catch (e) {\n return this.error(ErrorKind.INVALID_NUMBER_SKELETON, location);\n }\n return {\n val: {\n type: SKELETON_TYPE.number,\n tokens,\n location,\n parsedOptions: this.shouldParseSkeletons ? parseNumberSkeleton(tokens) : {}\n },\n err: null\n };\n };\n Parser2.prototype.tryParsePluralOrSelectOptions = function(nestingLevel, parentArgType, expectCloseTag, parsedFirstIdentifier) {\n var _a2;\n var hasOtherClause = false;\n var options = [];\n var parsedSelectors = new Set();\n var selector = parsedFirstIdentifier.value, selectorLocation = parsedFirstIdentifier.location;\n while (true) {\n if (selector.length === 0) {\n var startPosition = this.clonePosition();\n if (parentArgType !== \"select\" && this.bumpIf(\"=\")) {\n var result = this.tryParseDecimalInteger(ErrorKind.EXPECT_PLURAL_ARGUMENT_SELECTOR, ErrorKind.INVALID_PLURAL_ARGUMENT_SELECTOR);\n if (result.err) {\n return result;\n }\n selectorLocation = createLocation(startPosition, this.clonePosition());\n selector = this.message.slice(startPosition.offset, this.offset());\n } else {\n break;\n }\n }\n if (parsedSelectors.has(selector)) {\n return this.error(parentArgType === \"select\" ? ErrorKind.DUPLICATE_SELECT_ARGUMENT_SELECTOR : ErrorKind.DUPLICATE_PLURAL_ARGUMENT_SELECTOR, selectorLocation);\n }\n if (selector === \"other\") {\n hasOtherClause = true;\n }\n this.bumpSpace();\n var openingBracePosition = this.clonePosition();\n if (!this.bumpIf(\"{\")) {\n return this.error(parentArgType === \"select\" ? ErrorKind.EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT : ErrorKind.EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT, createLocation(this.clonePosition(), this.clonePosition()));\n }\n var fragmentResult = this.parseMessage(nestingLevel + 1, parentArgType, expectCloseTag);\n if (fragmentResult.err) {\n return fragmentResult;\n }\n var argCloseResult = this.tryParseArgumentClose(openingBracePosition);\n if (argCloseResult.err) {\n return argCloseResult;\n }\n options.push([\n selector,\n {\n value: fragmentResult.val,\n location: createLocation(openingBracePosition, this.clonePosition())\n }\n ]);\n parsedSelectors.add(selector);\n this.bumpSpace();\n _a2 = this.parseIdentifierIfPossible(), selector = _a2.value, selectorLocation = _a2.location;\n }\n if (options.length === 0) {\n return this.error(parentArgType === \"select\" ? ErrorKind.EXPECT_SELECT_ARGUMENT_SELECTOR : ErrorKind.EXPECT_PLURAL_ARGUMENT_SELECTOR, createLocation(this.clonePosition(), this.clonePosition()));\n }\n if (this.requiresOtherClause && !hasOtherClause) {\n return this.error(ErrorKind.MISSING_OTHER_CLAUSE, createLocation(this.clonePosition(), this.clonePosition()));\n }\n return {val: options, err: null};\n };\n Parser2.prototype.tryParseDecimalInteger = function(expectNumberError, invalidNumberError) {\n var sign = 1;\n var startingPosition = this.clonePosition();\n if (this.bumpIf(\"+\")) {\n } else if (this.bumpIf(\"-\")) {\n sign = -1;\n }\n var hasDigits = false;\n var decimal = 0;\n while (!this.isEOF()) {\n var ch = this.char();\n if (ch >= 48 && ch <= 57) {\n hasDigits = true;\n decimal = decimal * 10 + (ch - 48);\n this.bump();\n } else {\n break;\n }\n }\n var location = createLocation(startingPosition, this.clonePosition());\n if (!hasDigits) {\n return this.error(expectNumberError, location);\n }\n decimal *= sign;\n if (!isSafeInteger(decimal)) {\n return this.error(invalidNumberError, location);\n }\n return {val: decimal, err: null};\n };\n Parser2.prototype.offset = function() {\n return this.position.offset;\n };\n Parser2.prototype.isEOF = function() {\n return this.offset() === this.message.length;\n };\n Parser2.prototype.clonePosition = function() {\n return {\n offset: this.position.offset,\n line: this.position.line,\n column: this.position.column\n };\n };\n Parser2.prototype.char = function() {\n var offset = this.position.offset;\n if (offset >= this.message.length) {\n throw Error(\"out of bound\");\n }\n var code = codePointAt(this.message, offset);\n if (code === void 0) {\n throw Error(\"Offset \" + offset + \" is at invalid UTF-16 code unit boundary\");\n }\n return code;\n };\n Parser2.prototype.error = function(kind, location) {\n return {\n val: null,\n err: {\n kind,\n message: this.message,\n location\n }\n };\n };\n Parser2.prototype.bump = function() {\n if (this.isEOF()) {\n return;\n }\n var code = this.char();\n if (code === 10) {\n this.position.line += 1;\n this.position.column = 1;\n this.position.offset += 1;\n } else {\n this.position.column += 1;\n this.position.offset += code < 65536 ? 1 : 2;\n }\n };\n Parser2.prototype.bumpIf = function(prefix) {\n if (startsWith(this.message, prefix, this.offset())) {\n for (var i = 0; i < prefix.length; i++) {\n this.bump();\n }\n return true;\n }\n return false;\n };\n Parser2.prototype.bumpUntil = function(pattern) {\n var currentOffset = this.offset();\n var index = this.message.indexOf(pattern, currentOffset);\n if (index >= 0) {\n this.bumpTo(index);\n return true;\n } else {\n this.bumpTo(this.message.length);\n return false;\n }\n };\n Parser2.prototype.bumpTo = function(targetOffset) {\n if (this.offset() > targetOffset) {\n throw Error(\"targetOffset \" + targetOffset + \" must be greater than or equal to the current offset \" + this.offset());\n }\n targetOffset = Math.min(targetOffset, this.message.length);\n while (true) {\n var offset = this.offset();\n if (offset === targetOffset) {\n break;\n }\n if (offset > targetOffset) {\n throw Error(\"targetOffset \" + targetOffset + \" is at invalid UTF-16 code unit boundary\");\n }\n this.bump();\n if (this.isEOF()) {\n break;\n }\n }\n };\n Parser2.prototype.bumpSpace = function() {\n while (!this.isEOF() && _isWhiteSpace(this.char())) {\n this.bump();\n }\n };\n Parser2.prototype.peek = function() {\n if (this.isEOF()) {\n return null;\n }\n var code = this.char();\n var offset = this.offset();\n var nextCode = this.message.charCodeAt(offset + (code >= 65536 ? 2 : 1));\n return nextCode !== null && nextCode !== void 0 ? nextCode : null;\n };\n return Parser2;\n}();\nfunction _isAlpha(codepoint) {\n return codepoint >= 97 && codepoint <= 122 || codepoint >= 65 && codepoint <= 90;\n}\nfunction _isAlphaOrSlash(codepoint) {\n return _isAlpha(codepoint) || codepoint === 47;\n}\nfunction _isPotentialElementNameChar(c) {\n 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;\n}\nfunction _isWhiteSpace(c) {\n return c >= 9 && c <= 13 || c === 32 || c === 133 || c >= 8206 && c <= 8207 || c === 8232 || c === 8233;\n}\nfunction _isPatternSyntax(c) {\n 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;\n}\n\n// bazel-out/darwin-fastbuild/bin/packages/icu-messageformat-parser/lib/index.js\nfunction pruneLocation(els) {\n els.forEach(function(el) {\n delete el.location;\n if (isSelectElement(el) || isPluralElement(el)) {\n for (var k in el.options) {\n delete el.options[k].location;\n pruneLocation(el.options[k].value);\n }\n } else if (isNumberElement(el) && isNumberSkeleton(el.style)) {\n delete el.style.location;\n } else if ((isDateElement(el) || isTimeElement(el)) && isDateTimeSkeleton(el.style)) {\n delete el.style.location;\n } else if (isTagElement(el)) {\n pruneLocation(el.children);\n }\n });\n}\nfunction parse(message, opts) {\n if (opts === void 0) {\n opts = {};\n }\n opts = __assign({shouldParseSkeletons: true, requiresOtherClause: true}, opts);\n var result = new Parser(message, opts).parse();\n if (result.err) {\n var error = SyntaxError(ErrorKind[result.err.kind]);\n error.location = result.err.location;\n error.originalMessage = result.err.message;\n throw error;\n }\n if (!(opts === null || opts === void 0 ? void 0 : opts.captureLocation)) {\n pruneLocation(result.val);\n }\n return result.val;\n}\n\n// bazel-out/darwin-fastbuild/bin/packages/fast-memoize/lib/index.js\nfunction memoize(fn, options) {\n var cache = options && options.cache ? options.cache : cacheDefault;\n var serializer = options && options.serializer ? options.serializer : serializerDefault;\n var strategy = options && options.strategy ? options.strategy : strategyDefault;\n return strategy(fn, {\n cache,\n serializer\n });\n}\nfunction isPrimitive(value) {\n return value == null || typeof value === \"number\" || typeof value === \"boolean\";\n}\nfunction monadic(fn, cache, serializer, arg) {\n var cacheKey = isPrimitive(arg) ? arg : serializer(arg);\n var computedValue = cache.get(cacheKey);\n if (typeof computedValue === \"undefined\") {\n computedValue = fn.call(this, arg);\n cache.set(cacheKey, computedValue);\n }\n return computedValue;\n}\nfunction variadic(fn, cache, serializer) {\n var args = Array.prototype.slice.call(arguments, 3);\n var cacheKey = serializer(args);\n var computedValue = cache.get(cacheKey);\n if (typeof computedValue === \"undefined\") {\n computedValue = fn.apply(this, args);\n cache.set(cacheKey, computedValue);\n }\n return computedValue;\n}\nfunction assemble(fn, context, strategy, cache, serialize) {\n return strategy.bind(context, fn, cache, serialize);\n}\nfunction strategyDefault(fn, options) {\n var strategy = fn.length === 1 ? monadic : variadic;\n return assemble(fn, this, strategy, options.cache.create(), options.serializer);\n}\nfunction strategyVariadic(fn, options) {\n return assemble(fn, this, variadic, options.cache.create(), options.serializer);\n}\nfunction strategyMonadic(fn, options) {\n return assemble(fn, this, monadic, options.cache.create(), options.serializer);\n}\nvar serializerDefault = function() {\n return JSON.stringify(arguments);\n};\nfunction ObjectWithoutPrototypeCache() {\n this.cache = Object.create(null);\n}\nObjectWithoutPrototypeCache.prototype.has = function(key) {\n return key in this.cache;\n};\nObjectWithoutPrototypeCache.prototype.get = function(key) {\n return this.cache[key];\n};\nObjectWithoutPrototypeCache.prototype.set = function(key, value) {\n this.cache[key] = value;\n};\nvar cacheDefault = {\n create: function create() {\n return new ObjectWithoutPrototypeCache();\n }\n};\nvar strategies = {\n variadic: strategyVariadic,\n monadic: strategyMonadic\n};\n\n// bazel-out/darwin-fastbuild/bin/packages/intl-messageformat/lib_esnext/src/error.js\nvar ErrorCode;\n(function(ErrorCode2) {\n ErrorCode2[\"MISSING_VALUE\"] = \"MISSING_VALUE\";\n ErrorCode2[\"INVALID_VALUE\"] = \"INVALID_VALUE\";\n ErrorCode2[\"MISSING_INTL_API\"] = \"MISSING_INTL_API\";\n})(ErrorCode || (ErrorCode = {}));\nvar FormatError = class extends Error {\n constructor(msg, code, originalMessage) {\n super(msg);\n this.code = code;\n this.originalMessage = originalMessage;\n }\n toString() {\n return `[formatjs Error: ${this.code}] ${this.message}`;\n }\n};\nvar InvalidValueError = class extends FormatError {\n constructor(variableId, value, options, originalMessage) {\n super(`Invalid values for \"${variableId}\": \"${value}\". Options are \"${Object.keys(options).join('\", \"')}\"`, ErrorCode.INVALID_VALUE, originalMessage);\n }\n};\nvar InvalidValueTypeError = class extends FormatError {\n constructor(value, type, originalMessage) {\n super(`Value for \"${value}\" must be of type ${type}`, ErrorCode.INVALID_VALUE, originalMessage);\n }\n};\nvar MissingValueError = class extends FormatError {\n constructor(variableId, originalMessage) {\n super(`The intl string context variable \"${variableId}\" was not provided to the string \"${originalMessage}\"`, ErrorCode.MISSING_VALUE, originalMessage);\n }\n};\n\n// bazel-out/darwin-fastbuild/bin/packages/intl-messageformat/lib_esnext/src/formatters.js\nvar PART_TYPE;\n(function(PART_TYPE2) {\n PART_TYPE2[PART_TYPE2[\"literal\"] = 0] = \"literal\";\n PART_TYPE2[PART_TYPE2[\"object\"] = 1] = \"object\";\n})(PART_TYPE || (PART_TYPE = {}));\nfunction mergeLiteral(parts) {\n if (parts.length < 2) {\n return parts;\n }\n return parts.reduce((all, part) => {\n const lastPart = all[all.length - 1];\n if (!lastPart || lastPart.type !== PART_TYPE.literal || part.type !== PART_TYPE.literal) {\n all.push(part);\n } else {\n lastPart.value += part.value;\n }\n return all;\n }, []);\n}\nfunction isFormatXMLElementFn(el) {\n return typeof el === \"function\";\n}\nfunction formatToParts(els, locales, formatters, formats, values, currentPluralValue, originalMessage) {\n if (els.length === 1 && isLiteralElement(els[0])) {\n return [\n {\n type: PART_TYPE.literal,\n value: els[0].value\n }\n ];\n }\n const result = [];\n for (const el of els) {\n if (isLiteralElement(el)) {\n result.push({\n type: PART_TYPE.literal,\n value: el.value\n });\n continue;\n }\n if (isPoundElement(el)) {\n if (typeof currentPluralValue === \"number\") {\n result.push({\n type: PART_TYPE.literal,\n value: formatters.getNumberFormat(locales).format(currentPluralValue)\n });\n }\n continue;\n }\n const {value: varName} = el;\n if (!(values && varName in values)) {\n throw new MissingValueError(varName, originalMessage);\n }\n let value = values[varName];\n if (isArgumentElement(el)) {\n if (!value || typeof value === \"string\" || typeof value === \"number\") {\n value = typeof value === \"string\" || typeof value === \"number\" ? String(value) : \"\";\n }\n result.push({\n type: typeof value === \"string\" ? PART_TYPE.literal : PART_TYPE.object,\n value\n });\n continue;\n }\n if (isDateElement(el)) {\n const style = typeof el.style === \"string\" ? formats.date[el.style] : isDateTimeSkeleton(el.style) ? el.style.parsedOptions : void 0;\n result.push({\n type: PART_TYPE.literal,\n value: formatters.getDateTimeFormat(locales, style).format(value)\n });\n continue;\n }\n if (isTimeElement(el)) {\n const style = typeof el.style === \"string\" ? formats.time[el.style] : isDateTimeSkeleton(el.style) ? el.style.parsedOptions : void 0;\n result.push({\n type: PART_TYPE.literal,\n value: formatters.getDateTimeFormat(locales, style).format(value)\n });\n continue;\n }\n if (isNumberElement(el)) {\n const style = typeof el.style === \"string\" ? formats.number[el.style] : isNumberSkeleton(el.style) ? el.style.parsedOptions : void 0;\n if (style && style.scale) {\n value = value * (style.scale || 1);\n }\n result.push({\n type: PART_TYPE.literal,\n value: formatters.getNumberFormat(locales, style).format(value)\n });\n continue;\n }\n if (isTagElement(el)) {\n const {children, value: value2} = el;\n const formatFn = values[value2];\n if (!isFormatXMLElementFn(formatFn)) {\n throw new InvalidValueTypeError(value2, \"function\", originalMessage);\n }\n const parts = formatToParts(children, locales, formatters, formats, values, currentPluralValue);\n let chunks = formatFn(parts.map((p) => p.value));\n if (!Array.isArray(chunks)) {\n chunks = [chunks];\n }\n result.push(...chunks.map((c) => {\n return {\n type: typeof c === \"string\" ? PART_TYPE.literal : PART_TYPE.object,\n value: c\n };\n }));\n }\n if (isSelectElement(el)) {\n const opt = el.options[value] || el.options.other;\n if (!opt) {\n throw new InvalidValueError(el.value, value, Object.keys(el.options), originalMessage);\n }\n result.push(...formatToParts(opt.value, locales, formatters, formats, values));\n continue;\n }\n if (isPluralElement(el)) {\n let opt = el.options[`=${value}`];\n if (!opt) {\n if (!Intl.PluralRules) {\n throw new FormatError(`Intl.PluralRules is not available in this environment.\nTry polyfilling it using \"@formatjs/intl-pluralrules\"\n`, ErrorCode.MISSING_INTL_API, originalMessage);\n }\n const rule = formatters.getPluralRules(locales, {type: el.pluralType}).select(value - (el.offset || 0));\n opt = el.options[rule] || el.options.other;\n }\n if (!opt) {\n throw new InvalidValueError(el.value, value, Object.keys(el.options), originalMessage);\n }\n result.push(...formatToParts(opt.value, locales, formatters, formats, values, value - (el.offset || 0)));\n continue;\n }\n }\n return mergeLiteral(result);\n}\n\n// bazel-out/darwin-fastbuild/bin/packages/intl-messageformat/lib_esnext/src/core.js\nfunction mergeConfig(c1, c2) {\n if (!c2) {\n return c1;\n }\n return {\n ...c1 || {},\n ...c2 || {},\n ...Object.keys(c1).reduce((all, k) => {\n all[k] = {\n ...c1[k],\n ...c2[k] || {}\n };\n return all;\n }, {})\n };\n}\nfunction mergeConfigs(defaultConfig, configs) {\n if (!configs) {\n return defaultConfig;\n }\n return Object.keys(defaultConfig).reduce((all, k) => {\n all[k] = mergeConfig(defaultConfig[k], configs[k]);\n return all;\n }, {...defaultConfig});\n}\nfunction createFastMemoizeCache(store) {\n return {\n create() {\n return {\n has(key) {\n return key in store;\n },\n get(key) {\n return store[key];\n },\n set(key, value) {\n store[key] = value;\n }\n };\n }\n };\n}\nfunction createDefaultFormatters(cache = {\n number: {},\n dateTime: {},\n pluralRules: {}\n}) {\n return {\n getNumberFormat: memoize((...args) => new Intl.NumberFormat(...args), {\n cache: createFastMemoizeCache(cache.number),\n strategy: strategies.variadic\n }),\n getDateTimeFormat: memoize((...args) => new Intl.DateTimeFormat(...args), {\n cache: createFastMemoizeCache(cache.dateTime),\n strategy: strategies.variadic\n }),\n getPluralRules: memoize((...args) => new Intl.PluralRules(...args), {\n cache: createFastMemoizeCache(cache.pluralRules),\n strategy: strategies.variadic\n })\n };\n}\nvar IntlMessageFormat = class {\n constructor(message, locales = IntlMessageFormat.defaultLocale, overrideFormats, opts) {\n this.formatterCache = {\n number: {},\n dateTime: {},\n pluralRules: {}\n };\n this.format = (values) => {\n const parts = this.formatToParts(values);\n if (parts.length === 1) {\n return parts[0].value;\n }\n const result = parts.reduce((all, part) => {\n if (!all.length || part.type !== PART_TYPE.literal || typeof all[all.length - 1] !== \"string\") {\n all.push(part.value);\n } else {\n all[all.length - 1] += part.value;\n }\n return all;\n }, []);\n if (result.length <= 1) {\n return result[0] || \"\";\n }\n return result;\n };\n this.formatToParts = (values) => formatToParts(this.ast, this.locales, this.formatters, this.formats, values, void 0, this.message);\n this.resolvedOptions = () => ({\n locale: Intl.NumberFormat.supportedLocalesOf(this.locales)[0]\n });\n this.getAst = () => this.ast;\n if (typeof message === \"string\") {\n this.message = message;\n if (!IntlMessageFormat.__parse) {\n throw new TypeError(\"IntlMessageFormat.__parse must be set to process `message` of type `string`\");\n }\n this.ast = IntlMessageFormat.__parse(message, {\n ignoreTag: opts?.ignoreTag\n });\n } else {\n this.ast = message;\n }\n if (!Array.isArray(this.ast)) {\n throw new TypeError(\"A message must be provided as a String or AST.\");\n }\n this.formats = mergeConfigs(IntlMessageFormat.formats, overrideFormats);\n this.locales = locales;\n this.formatters = opts && opts.formatters || createDefaultFormatters(this.formatterCache);\n }\n static get defaultLocale() {\n if (!IntlMessageFormat.memoizedDefaultLocale) {\n IntlMessageFormat.memoizedDefaultLocale = new Intl.NumberFormat().resolvedOptions().locale;\n }\n return IntlMessageFormat.memoizedDefaultLocale;\n }\n};\nIntlMessageFormat.memoizedDefaultLocale = null;\nIntlMessageFormat.__parse = parse;\nIntlMessageFormat.formats = {\n number: {\n integer: {\n maximumFractionDigits: 0\n },\n currency: {\n style: \"currency\"\n },\n percent: {\n style: \"percent\"\n }\n },\n date: {\n short: {\n month: \"numeric\",\n day: \"numeric\",\n year: \"2-digit\"\n },\n medium: {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\"\n },\n long: {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\"\n },\n full: {\n weekday: \"long\",\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\"\n }\n },\n time: {\n short: {\n hour: \"numeric\",\n minute: \"numeric\"\n },\n medium: {\n hour: \"numeric\",\n minute: \"numeric\",\n second: \"numeric\"\n },\n long: {\n hour: \"numeric\",\n minute: \"numeric\",\n second: \"numeric\",\n timeZoneName: \"short\"\n },\n full: {\n hour: \"numeric\",\n minute: \"numeric\",\n second: \"numeric\",\n timeZoneName: \"short\"\n }\n }\n};\n\n// bazel-out/darwin-fastbuild/bin/packages/intl-messageformat/lib_esnext/index.js\nvar lib_esnext_default = IntlMessageFormat;\nexport {\n ErrorCode,\n FormatError,\n IntlMessageFormat,\n InvalidValueError,\n InvalidValueTypeError,\n MissingValueError,\n PART_TYPE,\n lib_esnext_default as default,\n formatToParts,\n isFormatXMLElementFn\n};\n/*! *****************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n//# sourceMappingURL=intl-messageformat.esm.js.map\n", "// Copyright 2018 The Lighthouse Authors. All Rights Reserved.\n// 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\n// 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.\n\nimport {type LocalizedMessages, type UIStrings} from './i18n-impl.js';\n\nimport * as IntlMessageFormat from '../intl-messageformat/intl-messageformat.js';\n\nconst EMPTY_VALUES_OBJECT = {};\n\n/**\n * This class is usually created at module instantiation time and\n * holds the filename, the UIStrings object and a reference to\n * all the localization data.\n *\n * Later, once needed, users can request a `LocalizedStringSet` that represents\n * all the translated strings, in a given locale for the specific file and\n * UIStrings object.\n *\n * Please note that this class is implemented with invariant in mind that the\n * DevTools locale never changes. Otherwise we would have to use a Map as\n * the cache. For performance reasons, we store the single possible map entry\n * as a property directly.\n *\n * The DevTools locale CANNOT be passed via the constructor. When instances\n * of `RegisteredFileStrings` are created, the DevTools locale has not yet\n * been determined.\n */\nexport class RegisteredFileStrings {\n private localizedStringSet?: LocalizedStringSet;\n\n constructor(private filename: string, private stringStructure: UIStrings, private localizedMessages: Map<Intl.UnicodeBCP47LocaleIdentifier, LocalizedMessages>) {\n }\n\n getLocalizedStringSetFor(locale: Intl.UnicodeBCP47LocaleIdentifier): LocalizedStringSet {\n if (this.localizedStringSet) {\n return this.localizedStringSet;\n }\n\n const localeData = this.localizedMessages.get(locale);\n if (!localeData) {\n throw new Error(`No locale data registered for '${locale}'`);\n }\n\n this.localizedStringSet = new LocalizedStringSet(this.filename, this.stringStructure, locale, localeData);\n return this.localizedStringSet;\n }\n}\n\nexport type Values = Record<string, string|number|boolean>;\n\n/**\n * A set of translated strings for a single file in a specific locale.\n *\n * The class is a wrapper around `IntlMessageFormat#format` plus a cache\n * to speed up consecutive lookups of the same message.\n */\nexport class LocalizedStringSet {\n private readonly cachedSimpleStrings = new Map<string, string>();\n private readonly cachedMessageFormatters = new Map<string, IntlMessageFormat.IntlMessageFormat>();\n\n /** For pseudo locales, use 'de-DE' for number formatting */\n private readonly localeForFormatter: Intl.UnicodeBCP47LocaleIdentifier;\n\n constructor(private filename: string, private stringStructure: UIStrings, locale: Intl.UnicodeBCP47LocaleIdentifier, private localizedMessages: LocalizedMessages) {\n this.localeForFormatter = (locale === 'en-XA' || locale === 'en-XL') ? 'de-DE' : locale;\n }\n\n getLocalizedString(message: string, values: Values = EMPTY_VALUES_OBJECT): string {\n if (values === EMPTY_VALUES_OBJECT || Object.keys(values).length === 0) {\n return this.getSimpleLocalizedString(message);\n }\n return this.getFormattedLocalizedString(message, values);\n }\n\n getMessageFormatterFor(message: string): IntlMessageFormat.IntlMessageFormat {\n const keyname = Object.keys(this.stringStructure).find(key => this.stringStructure[key] === message);\n if (!keyname) {\n throw new Error(`Unable to locate '${message}' in UIStrings object`);\n }\n const i18nId = `${this.filename} | ${keyname}`;\n const localeMessage = this.localizedMessages[i18nId];\n\n // The requested string might not yet have been collected into en-US.json or\n // been translated yet. Fall back to the original TypeScript UIStrings message.\n const messageToTranslate = localeMessage ? localeMessage.message : message;\n return new IntlMessageFormat.IntlMessageFormat(messageToTranslate, this.localeForFormatter, undefined, {ignoreTag: true});\n }\n\n private getSimpleLocalizedString(message: string): string {\n const cachedSimpleString = this.cachedSimpleStrings.get(message);\n if (cachedSimpleString) {\n return cachedSimpleString;\n }\n\n const formatter = this.getMessageFormatterFor(message);\n const translatedString = formatter.format() as string;\n this.cachedSimpleStrings.set(message, translatedString);\n return translatedString;\n }\n\n private getFormattedLocalizedString(message: string, values: Values): string {\n let formatter = this.cachedMessageFormatters.get(message);\n if (!formatter) {\n formatter = this.getMessageFormatterFor(message);\n this.cachedMessageFormatters.set(message, formatter);\n }\n\n try {\n return formatter.format(values) as string;\n } catch (e) {\n // The message could have been updated and use different placeholders then\n // the translation. This is a rare edge case so it's fine to create a temporary\n // IntlMessageFormat and fall back to the UIStrings message.\n const formatter = new IntlMessageFormat.IntlMessageFormat(message, this.localeForFormatter, undefined, {ignoreTag: true});\n return formatter.format(values) as string;\n }\n }\n}\n", "// Copyright 2021 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {getLocalizedString, registerUIStrings} from './i18nImpl.js';\n\nconst UIStrings = {\n /**\n *@description \u03BCs is the short form of micro-seconds and the placeholder is a number\n *@example {2} PH1\n */\n fmms: '{PH1}\u00A0\u03BCs',\n /**\n *@description ms is the short form of milli-seconds and the placeholder is a decimal number\n *@example {2.14} PH1\n */\n fms: '{PH1}\u00A0ms',\n /**\n *@description s is short for seconds and the placeholder is a decimal number\n *@example {2.14} PH1\n */\n fs: '{PH1}\u00A0s',\n /**\n *@description min is short for minutes and the placeholder is a decimal number\n *@example {2.2} PH1\n */\n fmin: '{PH1}\u00A0min',\n /**\n *@description hrs is short for hours and the placeholder is a decimal number\n *@example {2.2} PH1\n */\n fhrs: '{PH1}\u00A0hrs',\n /**\n *@description days formatting and the placeholder is a decimal number\n *@example {2.2} PH1\n */\n fdays: '{PH1}\u00A0days',\n};\n\nconst str_ = registerUIStrings('core/i18n/time-utilities.ts', UIStrings);\nconst i18nString = getLocalizedString.bind(undefined, str_);\n\nexport const preciseMillisToString = function(ms: number, precision?: number): string {\n precision = precision || 0;\n return i18nString(UIStrings.fms, {PH1: ms.toFixed(precision)});\n};\n\nexport const millisToString = function(ms: number, higherResolution?: boolean): string {\n if (!isFinite(ms)) {\n return '-';\n }\n\n if (ms === 0) {\n return '0';\n }\n\n if (higherResolution && ms < 0.1) {\n return i18nString(UIStrings.fmms, {PH1: (ms * 1000).toFixed(0)});\n }\n if (higherResolution && ms < 1000) {\n return i18nString(UIStrings.fms, {PH1: (ms).toFixed(2)});\n }\n if (ms < 1000) {\n return i18nString(UIStrings.fms, {PH1: (ms).toFixed(0)});\n }\n\n const seconds = ms / 1000;\n if (seconds < 60) {\n return i18nString(UIStrings.fs, {PH1: (seconds).toFixed(2)});\n }\n\n const minutes = seconds / 60;\n if (minutes < 60) {\n return i18nString(UIStrings.fmin, {PH1: (minutes).toFixed(1)});\n }\n\n const hours = minutes / 60;\n if (hours < 24) {\n return i18nString(UIStrings.fhrs, {PH1: (hours).toFixed(1)});\n }\n\n const days = hours / 24;\n return i18nString(UIStrings.fdays, {PH1: (days).toFixed(1)});\n};\n\nexport const secondsToString = function(seconds: number, higherResolution?: boolean): string {\n if (!isFinite(seconds)) {\n return '-';\n }\n return millisToString(seconds * 1000, higherResolution);\n};\n", "// Copyright 2014 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as i18n from '../i18n/i18n.js';\nimport type * as Platform from '../platform/platform.js';\n\nconst UIStrings = {\n /**\n *@description The UI destination when right clicking an item that can be revealed\n */\n elementsPanel: 'Elements panel',\n /**\n *@description The UI destination when right clicking an item that can be revealed\n */\n stylesSidebar: 'styles sidebar',\n /**\n *@description The UI destination when right clicking an item that can be revealed\n */\n changesDrawer: 'Changes drawer',\n /**\n *@description The UI destination when right clicking an item that can be revealed\n */\n issuesView: 'Issues view',\n /**\n *@description The UI destination when right clicking an item that can be revealed\n */\n networkPanel: 'Network panel',\n /**\n *@description The UI destination when right clicking an item that can be revealed\n */\n applicationPanel: 'Application panel',\n /**\n *@description The UI destination when right clicking an item that can be revealed\n */\n sourcesPanel: 'Sources panel',\n};\nconst str_ = i18n.i18n.registerUIStrings('core/common/Revealer.ts', UIStrings);\nconst i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);\n\nexport interface Revealer {\n reveal(object: Object, omitFocus?: boolean): Promise<void>;\n}\n\nexport let reveal = async function(revealable: Object|null, omitFocus?: boolean): Promise<void> {\n if (!revealable) {\n return Promise.reject(new Error('Can\\'t reveal ' + revealable));\n }\n const revealers =\n await Promise.all(getApplicableRegisteredRevealers(revealable).map(registration => registration.loadRevealer()));\n\n if (!revealers.length) {\n return Promise.reject(new Error('Can\\'t reveal ' + revealable));\n }\n return reveal(revealers);\n function reveal(revealers: Revealer[]): Promise<void> {\n const promises = [];\n for (let i = 0; i < revealers.length; ++i) {\n promises.push(revealers[i].reveal((revealable as Object), omitFocus));\n }\n return Promise.race(promises);\n }\n};\n\nexport function setRevealForTest(newReveal: (arg0: Object|null, arg1?: boolean|undefined) => Promise<void>): void {\n reveal = newReveal;\n}\n\nexport const revealDestination = function(revealable: Object|null): string|null {\n const extension = revealable ? getApplicableRegisteredRevealers(revealable)[0] : registeredRevealers[0];\n if (!extension) {\n return null;\n }\n return extension.destination?.() || null;\n};\n\nconst registeredRevealers: RevealerRegistration[] = [];\n\nexport function registerRevealer(registration: RevealerRegistration): void {\n registeredRevealers.push(registration);\n}\n\nfunction getApplicableRegisteredRevealers(revealable: Object): RevealerRegistration[] {\n return registeredRevealers.filter(isRevealerApplicableToContextTypes);\n\n function isRevealerApplicableToContextTypes(revealerRegistration: RevealerRegistration): boolean {\n if (!revealerRegistration.contextTypes) {\n return true;\n }\n for (const contextType of revealerRegistration.contextTypes()) {\n if (revealable instanceof contextType) {\n return true;\n }\n }\n return false;\n }\n}\nexport interface RevealerRegistration {\n contextTypes: () => Array<Function>;\n loadRevealer: () => Promise<Revealer>;\n destination?: RevealerDestination;\n}\n\nexport const RevealerDestination = {\n ELEMENTS_PANEL: i18nLazyString(UIStrings.elementsPanel),\n STYLES_SIDEBAR: i18nLazyString(UIStrings.stylesSidebar),\n CHANGES_DRAWER: i18nLazyString(UIStrings.changesDrawer),\n ISSUES_VIEW: i18nLazyString(UIStrings.issuesView),\n NETWORK_PANEL: i18nLazyString(UIStrings.networkPanel),\n APPLICATION_PANEL: i18nLazyString(UIStrings.applicationPanel),\n SOURCES_PANEL: i18nLazyString(UIStrings.sourcesPanel),\n};\n\nexport type RevealerDestination = () => Platform.UIString.LocalizedString;\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nconst UNINITIALIZED = Symbol('uninitialized');\nconst ERROR_STATE = Symbol('error');\n\nexport function lazy<T>(producer: () => T): () => symbol | T {\n let value: T|typeof ERROR_STATE|typeof UNINITIALIZED = UNINITIALIZED;\n let error: null = null;\n\n return (): symbol|T => {\n if (value === ERROR_STATE) {\n throw error;\n } else if (value !== UNINITIALIZED) {\n return value;\n }\n\n try {\n value = producer();\n return value;\n } catch (err) {\n error = err;\n value = ERROR_STATE;\n throw error;\n }\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\ntype ReleaseFunction = () => void;\n\n/**\n * Use Mutex class to coordinate local concurrent operations.\n * Once `acquire` promise resolves, you hold the lock and must\n * call `release` function returned by `acquire` to release the\n * lock. Failing to `release` the lock may lead to deadlocks.\n */\nexport class Mutex {\n #locked = false;\n #acquirers: Array<() => void> = [];\n\n // This is FIFO.\n acquire(): Promise<ReleaseFunction> {\n const state = {resolved: false};\n if (this.#locked) {\n return new Promise(resolve => {\n this.#acquirers.push(() => resolve(this.#release.bind(this, state)));\n });\n }\n this.#locked = true;\n return Promise.resolve(this.#release.bind(this, state));\n }\n\n #release(state: {resolved: boolean}): void {\n if (state.resolved) {\n throw new Error('Cannot release more than once.');\n }\n state.resolved = true;\n\n const resolve = this.#acquirers.shift();\n if (!resolve) {\n this.#locked = false;\n return;\n }\n resolve();\n }\n\n async run<T>(action: () => Promise<T>): Promise<T> {\n const release = await this.acquire();\n try {\n // Note we need to await here because we want the await to release AFTER\n // that await happens. Returning action() will trigger the release\n // immediately which is counter to what we want.\n const result = await action();\n return result;\n } finally {\n release();\n }\n }\n}\n", "/*\n * Copyright (C) 2012 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nimport * as Platform from '../platform/platform.js';\n\n/**\n * http://tools.ietf.org/html/rfc3986#section-5.2.4\n */\nexport function normalizePath(path: string): string {\n if (path.indexOf('..') === -1 && path.indexOf('.') === -1) {\n return path;\n }\n\n // Remove leading slash (will be added back below) so we\n // can handle all (including empty) segments consistently.\n const segments = (path[0] === '/' ? path.substring(1) : path).split('/');\n const normalizedSegments = [];\n for (const segment of segments) {\n if (segment === '.') {\n continue;\n } else if (segment === '..') {\n normalizedSegments.pop();\n } else {\n normalizedSegments.push(segment);\n }\n }\n let normalizedPath = normalizedSegments.join('/');\n if (path[0] === '/' && normalizedPath) {\n normalizedPath = '/' + normalizedPath;\n }\n if (normalizedPath[normalizedPath.length - 1] !== '/' &&\n ((path[path.length - 1] === '/') || (segments[segments.length - 1] === '.') ||\n (segments[segments.length - 1] === '..'))) {\n normalizedPath = normalizedPath + '/';\n }\n\n return normalizedPath;\n}\n\n/**\n * File paths in DevTools that are represented either as unencoded absolute or relative paths, or encoded paths, or URLs.\n * @example\n * RawPathString: \u201C/Hello World/file.js\u201D\n * EncodedPathString: \u201C/Hello%20World/file.js\u201D\n * UrlString: \u201Cfile:///Hello%20World/file/js\u201D\n */\ntype BrandedPathString =\n Platform.DevToolsPath.UrlString|Platform.DevToolsPath.RawPathString|Platform.DevToolsPath.EncodedPathString;\n\nexport class ParsedURL {\n isValid: boolean;\n url: string;\n scheme: string;\n user: string;\n host: string;\n port: string;\n path: string;\n queryParams: string;\n fragment: string;\n folderPathComponents: string;\n lastPathComponent: string;\n readonly blobInnerScheme: string|undefined;\n #displayNameInternal?: string;\n #dataURLDisplayNameInternal?: string;\n\n constructor(url: string) {\n this.isValid = false;\n this.url = url;\n this.scheme = '';\n this.user = '';\n this.host = '';\n this.port = '';\n this.path = '';\n this.queryParams = '';\n this.fragment = '';\n this.folderPathComponents = '';\n this.lastPathComponent = '';\n\n const isBlobUrl = this.url.startsWith('blob:');\n const urlToMatch = isBlobUrl ? url.substring(5) : url;\n const match = urlToMatch.match(ParsedURL.urlRegex());\n if (match) {\n this.isValid = true;\n if (isBlobUrl) {\n this.blobInnerScheme = match[2].toLowerCase();\n this.scheme = 'blob';\n } else {\n this.scheme = match[2].toLowerCase();\n }\n this.user = match[3] ?? '';\n this.host = match[4] ?? '';\n this.port = match[5] ?? '';\n this.path = match[6] ?? '/';\n this.queryParams = match[7] ?? '';\n this.fragment = match[8] ?? '';\n } else {\n if (this.url.startsWith('data:')) {\n this.scheme = 'data';\n return;\n }\n if (this.url.startsWith('blob:')) {\n this.scheme = 'blob';\n return;\n }\n if (this.url === 'about:blank') {\n this.scheme = 'about';\n return;\n }\n this.path = this.url;\n }\n\n const lastSlashExceptTrailingIndex = this.path.lastIndexOf('/', this.path.length - 2);\n if (lastSlashExceptTrailingIndex !== -1) {\n this.lastPathComponent = this.path.substring(lastSlashExceptTrailingIndex + 1);\n } else {\n this.lastPathComponent = this.path;\n }\n const lastSlashIndex = this.path.lastIndexOf('/');\n if (lastSlashIndex !== -1) {\n this.folderPathComponents = this.path.substring(0, lastSlashIndex);\n }\n }\n\n static fromString(string: string): ParsedURL|null {\n const parsedURL = new ParsedURL(string.toString());\n if (parsedURL.isValid) {\n return parsedURL;\n }\n return null;\n }\n\n static preEncodeSpecialCharactersInPath(path: string): string {\n // Based on net::FilePathToFileURL. Ideally we would handle\n // '\\\\' as well on non-Windows file systems.\n for (const specialChar of ['%', ';', '#', '?', ' ']) {\n (path as string) = path.replaceAll(specialChar, encodeURIComponent(specialChar));\n }\n return path;\n }\n\n static rawPathToEncodedPathString(path: Platform.DevToolsPath.RawPathString):\n Platform.DevToolsPath.EncodedPathString {\n const partiallyEncoded = ParsedURL.preEncodeSpecialCharactersInPath(path);\n if (path.startsWith('/')) {\n return new URL(partiallyEncoded, 'file:///').pathname as Platform.DevToolsPath.EncodedPathString;\n }\n // URL prepends a '/'\n return new URL('/' + partiallyEncoded, 'file:///').pathname.substr(1) as Platform.DevToolsPath.EncodedPathString;\n }\n\n /**\n * @param name Must not be encoded\n */\n static encodedFromParentPathAndName(parentPath: Platform.DevToolsPath.EncodedPathString, name: string):\n Platform.DevToolsPath.EncodedPathString {\n return ParsedURL.concatenate(parentPath, '/', ParsedURL.preEncodeSpecialCharactersInPath(name));\n }\n\n /**\n * @param name Must not be encoded\n */\n static urlFromParentUrlAndName(parentUrl: Platform.DevToolsPath.UrlString, name: string):\n Platform.DevToolsPath.UrlString {\n return ParsedURL.concatenate(parentUrl, '/', ParsedURL.preEncodeSpecialCharactersInPath(name));\n }\n\n static encodedPathToRawPathString(encPath: Platform.DevToolsPath.EncodedPathString):\n Platform.DevToolsPath.RawPathString {\n return decodeURIComponent(encPath) as Platform.DevToolsPath.RawPathString;\n }\n\n static rawPathToUrlString(fileSystemPath: Platform.DevToolsPath.RawPathString): Platform.DevToolsPath.UrlString {\n let preEncodedPath: string = ParsedURL.preEncodeSpecialCharactersInPath(\n fileSystemPath.replace(/\\\\/g, '/') as Platform.DevToolsPath.RawPathString);\n preEncodedPath = preEncodedPath.replace(/\\\\/g, '/');\n if (!preEncodedPath.startsWith('file://')) {\n if (preEncodedPath.startsWith('/')) {\n preEncodedPath = 'file://' + preEncodedPath;\n } else {\n preEncodedPath = 'file:///' + preEncodedPath;\n }\n }\n return new URL(preEncodedPath).toString() as Platform.DevToolsPath.UrlString;\n }\n\n static relativePathToUrlString(\n relativePath: Platform.DevToolsPath.RawPathString,\n baseURL: Platform.DevToolsPath.UrlString): Platform.DevToolsPath.UrlString {\n const preEncodedPath: string = ParsedURL.preEncodeSpecialCharactersInPath(\n relativePath.replace(/\\\\/g, '/') as Platform.DevToolsPath.RawPathString);\n return new URL(preEncodedPath, baseURL).toString() as Platform.DevToolsPath.UrlString;\n }\n\n static urlToRawPathString(fileURL: Platform.DevToolsPath.UrlString, isWindows?: boolean):\n Platform.DevToolsPath.RawPathString {\n console.assert(fileURL.startsWith('file://'), 'This must be a file URL.');\n const decodedFileURL = decodeURIComponent(fileURL);\n if (isWindows) {\n return decodedFileURL.substr('file:///'.length).replace(/\\//g, '\\\\') as Platform.DevToolsPath.RawPathString;\n }\n return decodedFileURL.substr('file://'.length) as Platform.DevToolsPath.RawPathString;\n }\n\n static sliceUrlToEncodedPathString(url: Platform.DevToolsPath.UrlString, start: number):\n Platform.DevToolsPath.EncodedPathString {\n return url.substring(start) as Platform.DevToolsPath.EncodedPathString;\n }\n\n static substr<DevToolsPathType extends BrandedPathString>(\n devToolsPath: DevToolsPathType, from: number, length?: number): DevToolsPathType {\n return devToolsPath.substr(from, length) as DevToolsPathType;\n }\n\n static substring<DevToolsPathType extends BrandedPathString>(\n devToolsPath: DevToolsPathType, start: number, end?: number): DevToolsPathType {\n return devToolsPath.substring(start, end) as DevToolsPathType;\n }\n\n static prepend<DevToolsPathType extends BrandedPathString>(prefix: string, devToolsPath: DevToolsPathType):\n DevToolsPathType {\n return prefix + devToolsPath as DevToolsPathType;\n }\n\n static concatenate<DevToolsPathType extends BrandedPathString>(\n devToolsPath: DevToolsPathType, ...appendage: string[]): DevToolsPathType {\n return devToolsPath.concat(...appendage) as DevToolsPathType;\n }\n\n static trim<DevToolsPathType extends BrandedPathString>(devToolsPath: DevToolsPathType): DevToolsPathType {\n return devToolsPath.trim() as DevToolsPathType;\n }\n\n static slice<DevToolsPathType extends BrandedPathString>(\n devToolsPath: DevToolsPathType, start?: number, end?: number): DevToolsPathType {\n return devToolsPath.slice(start, end) as DevToolsPathType;\n }\n\n static join<DevToolsPathType extends BrandedPathString>(devToolsPaths: DevToolsPathType[], separator?: string):\n DevToolsPathType {\n return devToolsPaths.join(separator) as DevToolsPathType;\n }\n\n static split<DevToolsPathType extends BrandedPathString>(\n devToolsPath: DevToolsPathType, separator: string|RegExp, limit?: number): DevToolsPathType[] {\n return devToolsPath.split(separator, limit) as DevToolsPathType[];\n }\n\n static toLowerCase<DevToolsPathType extends BrandedPathString>(devToolsPath: DevToolsPathType): DevToolsPathType {\n return devToolsPath.toLowerCase() as DevToolsPathType;\n }\n\n static isValidUrlString(str: string): str is Platform.DevToolsPath.UrlString {\n return new ParsedURL(str).isValid;\n }\n\n static urlWithoutHash(url: string): string {\n const hashIndex = url.indexOf('#');\n if (hashIndex !== -1) {\n return url.substr(0, hashIndex);\n }\n return url;\n }\n\n static urlRegex(): RegExp {\n if (ParsedURL.urlRegexInstance) {\n return ParsedURL.urlRegexInstance;\n }\n // RegExp groups:\n // 1 - scheme, hostname, ?port\n // 2 - scheme (using the RFC3986 grammar)\n // 3 - ?user:password\n // 4 - hostname\n // 5 - ?port\n // 6 - ?path\n // 7 - ?query\n // 8 - ?fragment\n const schemeRegex = /([A-Za-z][A-Za-z0-9+.-]*):\\/\\//;\n const userRegex = /(?:([A-Za-z0-9\\-._~%!$&'()*+,;=:]*)@)?/;\n const hostRegex = /((?:\\[::\\d?\\])|(?:[^\\s\\/:]*))/;\n const portRegex = /(?::([\\d]+))?/;\n const pathRegex = /(\\/[^#?]*)?/;\n const queryRegex = /(?:\\?([^#]*))?/;\n const fragmentRegex = /(?:#(.*))?/;\n\n ParsedURL.urlRegexInstance = new RegExp(\n '^(' + schemeRegex.source + userRegex.source + hostRegex.source + portRegex.source + ')' + pathRegex.source +\n queryRegex.source + fragmentRegex.source + '$');\n return ParsedURL.urlRegexInstance;\n }\n\n static extractPath(url: Platform.DevToolsPath.UrlString): Platform.DevToolsPath.EncodedPathString {\n const parsedURL = this.fromString(url);\n return (parsedURL ? parsedURL.path : '') as Platform.DevToolsPath.EncodedPathString;\n }\n\n static extractOrigin(url: Platform.DevToolsPath.UrlString): Platform.DevToolsPath.UrlString {\n const parsedURL = this.fromString(url);\n return parsedURL ? parsedURL.securityOrigin() : Platform.DevToolsPath.EmptyUrlString;\n }\n\n static extractExtension(url: string): string {\n url = ParsedURL.urlWithoutHash(url);\n const indexOfQuestionMark = url.indexOf('?');\n if (indexOfQuestionMark !== -1) {\n url = url.substr(0, indexOfQuestionMark);\n }\n const lastIndexOfSlash = url.lastIndexOf('/');\n if (lastIndexOfSlash !== -1) {\n url = url.substr(lastIndexOfSlash + 1);\n }\n const lastIndexOfDot = url.lastIndexOf('.');\n if (lastIndexOfDot !== -1) {\n url = url.substr(lastIndexOfDot + 1);\n const lastIndexOfPercent = url.indexOf('%');\n if (lastIndexOfPercent !== -1) {\n return url.substr(0, lastIndexOfPercent);\n }\n return url;\n }\n return '';\n }\n\n static extractName(url: string): string {\n let index = url.lastIndexOf('/');\n const pathAndQuery = index !== -1 ? url.substr(index + 1) : url;\n index = pathAndQuery.indexOf('?');\n return index < 0 ? pathAndQuery : pathAndQuery.substr(0, index);\n }\n\n static completeURL(baseURL: Platform.DevToolsPath.UrlString, href: string): Platform.DevToolsPath.UrlString|null {\n // Return special URLs as-is.\n const trimmedHref = href.trim();\n if (trimmedHref.startsWith('data:') || trimmedHref.startsWith('blob:') || trimmedHref.startsWith('javascript:') ||\n trimmedHref.startsWith('mailto:')) {\n return href as Platform.DevToolsPath.UrlString;\n }\n\n // Return absolute URLs with normalized path and other components as-is.\n const parsedHref = this.fromString(trimmedHref);\n if (parsedHref && parsedHref.scheme) {\n const securityOrigin = parsedHref.securityOrigin();\n const pathText = normalizePath(parsedHref.path);\n const queryText = parsedHref.queryParams && `?${parsedHref.queryParams}`;\n const fragmentText = parsedHref.fragment && `#${parsedHref.fragment}`;\n return securityOrigin + pathText + queryText + fragmentText as Platform.DevToolsPath.UrlString;\n }\n\n const parsedURL = this.fromString(baseURL);\n if (!parsedURL) {\n return null;\n }\n\n if (parsedURL.isDataURL()) {\n return href as Platform.DevToolsPath.UrlString;\n }\n\n if (href.length > 1 && href.charAt(0) === '/' && href.charAt(1) === '/') {\n // href starts with \"//\" which is a full URL with the protocol dropped (use the baseURL protocol).\n return parsedURL.scheme + ':' + href as Platform.DevToolsPath.UrlString;\n }\n\n const securityOrigin = parsedURL.securityOrigin();\n const pathText = parsedURL.path;\n const queryText = parsedURL.queryParams ? '?' + parsedURL.queryParams : '';\n\n // Empty href resolves to a URL without fragment.\n if (!href.length) {\n return securityOrigin + pathText + queryText as Platform.DevToolsPath.UrlString;\n }\n\n if (href.charAt(0) === '#') {\n return securityOrigin + pathText + queryText + href as Platform.DevToolsPath.UrlString;\n }\n\n if (href.charAt(0) === '?') {\n return securityOrigin + pathText + href as Platform.DevToolsPath.UrlString;\n }\n\n const hrefMatches = href.match(/^[^#?]*/);\n if (!hrefMatches || !href.length) {\n throw new Error('Invalid href');\n }\n let hrefPath: string = hrefMatches[0];\n const hrefSuffix = href.substring(hrefPath.length);\n if (hrefPath.charAt(0) !== '/') {\n hrefPath = parsedURL.folderPathComponents + '/' + hrefPath;\n }\n return securityOrigin + normalizePath(hrefPath) + hrefSuffix as Platform.DevToolsPath.UrlString;\n }\n\n static splitLineAndColumn(string: string): {\n url: Platform.DevToolsPath.UrlString,\n lineNumber: (number|undefined),\n columnNumber: (number|undefined),\n } {\n // Only look for line and column numbers in the path to avoid matching port numbers.\n const beforePathMatch = string.match(ParsedURL.urlRegex());\n let beforePath = '';\n let pathAndAfter: string = string;\n if (beforePathMatch) {\n beforePath = beforePathMatch[1];\n pathAndAfter = string.substring(beforePathMatch[1].length);\n }\n\n const lineColumnRegEx = /(?::(\\d+))?(?::(\\d+))?$/;\n const lineColumnMatch = lineColumnRegEx.exec(pathAndAfter);\n let lineNumber;\n let columnNumber;\n console.assert(Boolean(lineColumnMatch));\n if (!lineColumnMatch) {\n return {url: string as Platform.DevToolsPath.UrlString, lineNumber: 0, columnNumber: 0};\n }\n\n if (typeof (lineColumnMatch[1]) === 'string') {\n lineNumber = parseInt(lineColumnMatch[1], 10);\n // Immediately convert line and column to 0-based numbers.\n lineNumber = isNaN(lineNumber) ? undefined : lineNumber - 1;\n }\n if (typeof (lineColumnMatch[2]) === 'string') {\n columnNumber = parseInt(lineColumnMatch[2], 10);\n columnNumber = isNaN(columnNumber) ? undefined : columnNumber - 1;\n }\n\n let url: Platform.DevToolsPath.UrlString =\n beforePath + pathAndAfter.substring(0, pathAndAfter.length - lineColumnMatch[0].length) as\n Platform.DevToolsPath.UrlString;\n if (lineColumnMatch[1] === undefined && lineColumnMatch[2] === undefined) {\n const wasmCodeOffsetRegex = /wasm-function\\[\\d+\\]:0x([a-z0-9]+)$/g;\n const wasmCodeOffsetMatch = wasmCodeOffsetRegex.exec(pathAndAfter);\n if (wasmCodeOffsetMatch && typeof (wasmCodeOffsetMatch[1]) === 'string') {\n url = ParsedURL.removeWasmFunctionInfoFromURL(url);\n columnNumber = parseInt(wasmCodeOffsetMatch[1], 16);\n columnNumber = isNaN(columnNumber) ? undefined : columnNumber;\n }\n }\n\n return {url, lineNumber, columnNumber};\n }\n\n static removeWasmFunctionInfoFromURL(url: string): Platform.DevToolsPath.UrlString {\n const wasmFunctionRegEx = /:wasm-function\\[\\d+\\]/;\n const wasmFunctionIndex = url.search(wasmFunctionRegEx);\n if (wasmFunctionIndex === -1) {\n return url as Platform.DevToolsPath.UrlString;\n }\n return ParsedURL.substring(url as Platform.DevToolsPath.UrlString, 0, wasmFunctionIndex);\n }\n\n private static beginsWithWindowsDriveLetter(url: string): boolean {\n return /^[A-Za-z]:/.test(url);\n }\n\n private static beginsWithScheme(url: string): boolean {\n return /^[A-Za-z][A-Za-z0-9+.-]*:/.test(url);\n }\n\n static isRelativeURL(url: string): boolean {\n return !this.beginsWithScheme(url) || this.beginsWithWindowsDriveLetter(url);\n }\n\n get displayName(): string {\n if (this.#displayNameInternal) {\n return this.#displayNameInternal;\n }\n\n if (this.isDataURL()) {\n return this.dataURLDisplayName();\n }\n if (this.isBlobURL()) {\n return this.url;\n }\n if (this.isAboutBlank()) {\n return this.url;\n }\n\n this.#displayNameInternal = this.lastPathComponent;\n if (!this.#displayNameInternal) {\n this.#displayNameInternal = (this.host || '') + '/';\n }\n if (this.#displayNameInternal === '/') {\n this.#displayNameInternal = this.url;\n }\n return this.#displayNameInternal;\n }\n\n dataURLDisplayName(): string {\n if (this.#dataURLDisplayNameInternal) {\n return this.#dataURLDisplayNameInternal;\n }\n if (!this.isDataURL()) {\n return '';\n }\n this.#dataURLDisplayNameInternal = Platform.StringUtilities.trimEndWithMaxLength(this.url, 20);\n return this.#dataURLDisplayNameInternal;\n }\n\n isAboutBlank(): boolean {\n return this.url === 'about:blank';\n }\n\n isDataURL(): boolean {\n return this.scheme === 'data';\n }\n\n isHttpOrHttps(): boolean {\n return this.scheme === 'http' || this.scheme === 'https';\n }\n\n isBlobURL(): boolean {\n return this.url.startsWith('blob:');\n }\n\n lastPathComponentWithFragment(): string {\n return this.lastPathComponent + (this.fragment ? '#' + this.fragment : '');\n }\n\n domain(): string {\n if (this.isDataURL()) {\n return 'data:';\n }\n return this.host + (this.port ? ':' + this.port : '');\n }\n\n securityOrigin(): Platform.DevToolsPath.UrlString {\n if (this.isDataURL()) {\n return 'data:' as Platform.DevToolsPath.UrlString;\n }\n const scheme = this.isBlobURL() ? this.blobInnerScheme : this.scheme;\n return scheme + '://' + this.domain() as Platform.DevToolsPath.UrlString;\n }\n\n urlWithoutScheme(): string {\n if (this.scheme && this.url.startsWith(this.scheme + '://')) {\n return this.url.substring(this.scheme.length + 3);\n }\n return this.url;\n }\n\n static urlRegexInstance: RegExp|null = null;\n}\n", "/*\n * Copyright (C) 2012 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\nexport class Progress {\n setTotalWork(totalWork: number): void {\n }\n setTitle(title: string): void {\n }\n setWorked(worked: number, title?: string): void {\n }\n incrementWorked(worked?: number): void {\n }\n done(): void {\n }\n isCanceled(): boolean {\n return false;\n }\n}\n\nexport class CompositeProgress {\n readonly parent: Progress;\n readonly #children: SubProgress[];\n #childrenDone: number;\n\n constructor(parent: Progress) {\n this.parent = parent;\n this.#children = [];\n this.#childrenDone = 0;\n this.parent.setTotalWork(1);\n this.parent.setWorked(0);\n }\n\n childDone(): void {\n if (++this.#childrenDone !== this.#children.length) {\n return;\n }\n this.parent.done();\n }\n\n createSubProgress(weight?: number): SubProgress {\n const child = new SubProgress(this, weight);\n this.#children.push(child);\n return child;\n }\n\n update(): void {\n let totalWeights = 0;\n let done = 0;\n\n for (let i = 0; i < this.#children.length; ++i) {\n const child = this.#children[i];\n if (child.getTotalWork()) {\n done += child.getWeight() * child.getWorked() / child.getTotalWork();\n }\n totalWeights += child.getWeight();\n }\n this.parent.setWorked(done / totalWeights);\n }\n}\n\nexport class SubProgress implements Progress {\n readonly #composite: CompositeProgress;\n #weight: number;\n #worked: number;\n #totalWork: number;\n constructor(composite: CompositeProgress, weight?: number) {\n this.#composite = composite;\n this.#weight = weight || 1;\n this.#worked = 0;\n\n this.#totalWork = 0;\n }\n\n isCanceled(): boolean {\n return this.#composite.parent.isCanceled();\n }\n\n setTitle(title: string): void {\n this.#composite.parent.setTitle(title);\n }\n\n done(): void {\n this.setWorked(this.#totalWork);\n this.#composite.childDone();\n }\n\n setTotalWork(totalWork: number): void {\n this.#totalWork = totalWork;\n this.#composite.update();\n }\n\n setWorked(worked: number, title?: string): void {\n this.#worked = worked;\n if (typeof title !== 'undefined') {\n this.setTitle(title);\n }\n this.#composite.update();\n }\n\n incrementWorked(worked?: number): void {\n this.setWorked(this.#worked + (worked || 1));\n }\n\n getWeight(): number {\n return this.#weight;\n }\n\n getWorked(): number {\n return this.#worked;\n }\n\n getTotalWork(): number {\n return this.#totalWork;\n }\n}\n\nexport class ProgressProxy implements Progress {\n readonly #delegate: Progress|null|undefined;\n readonly #doneCallback: (() => void)|undefined;\n constructor(delegate?: Progress|null, doneCallback?: (() => void)) {\n this.#delegate = delegate;\n this.#doneCallback = doneCallback;\n }\n\n isCanceled(): boolean {\n return this.#delegate ? this.#delegate.isCanceled() : false;\n }\n\n setTitle(title: string): void {\n if (this.#delegate) {\n this.#delegate.setTitle(title);\n }\n }\n\n done(): void {\n if (this.#delegate) {\n this.#delegate.done();\n }\n if (this.#doneCallback) {\n this.#doneCallback();\n }\n }\n\n setTotalWork(totalWork: number): void {\n if (this.#delegate) {\n this.#delegate.setTotalWork(totalWork);\n }\n }\n\n setWorked(worked: number, title?: string): void {\n if (this.#delegate) {\n this.#delegate.setWorked(worked, title);\n }\n }\n\n incrementWorked(worked?: number): void {\n if (this.#delegate) {\n this.#delegate.incrementWorked(worked);\n }\n }\n}\n", "// Copyright 2021 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\ninterface PromiseInfo<T> {\n promise: Promise<T>;\n resolve: (obj: T) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * A class that facilitates resolving a id to an object of type T. If the id does not yet resolve, a promise\n * is created that gets resolved once `onResolve` is called with the corresponding id.\n *\n * This class enables clients to control the duration of the wait and the lifetime of the associated\n * promises by using the `clear` method on this class.\n */\nexport abstract class ResolverBase<Id, T> {\n #unresolvedIds: Map<Id, PromiseInfo<T>> = new Map();\n\n protected abstract getForId(id: Id): T|null;\n protected abstract startListening(): void;\n protected abstract stopListening(): void;\n\n /**\n * Returns a promise that resolves once the `id` can be resolved to an object.\n */\n async waitFor(id: Id): Promise<T> {\n const obj = this.getForId(id);\n if (!obj) {\n return this.getOrCreatePromise(id);\n }\n return obj;\n }\n\n /**\n * Resolve the `id`. Returns the object immediatelly if it can be resolved,\n * and otherwise waits for the object to appear and calls `callback` once\n * it is resolved.\n */\n tryGet(id: Id, callback: (t: T) => void): T|null {\n const obj = this.getForId(id);\n if (!obj) {\n const swallowTheError = (): void => {};\n void this.getOrCreatePromise(id).catch(swallowTheError).then(obj => {\n if (obj) {\n callback(obj);\n }\n });\n return null;\n }\n return obj;\n }\n\n /**\n * Aborts all waiting and rejects all unresolved promises.\n */\n clear(): void {\n this.stopListening();\n for (const [id, {reject}] of this.#unresolvedIds.entries()) {\n reject(new Error(`Object with ${id} never resolved.`));\n }\n this.#unresolvedIds.clear();\n }\n\n private getOrCreatePromise(id: Id): Promise<T> {\n const promiseInfo = this.#unresolvedIds.get(id);\n if (promiseInfo) {\n return promiseInfo.promise;\n }\n let resolve: (value: T) => void = () => {};\n let reject: (error: Error) => void = () => {};\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n this.#unresolvedIds.set(id, {promise, resolve, reject});\n this.startListening();\n return promise;\n }\n\n protected onResolve(id: Id, t: T): void {\n const promiseInfo = this.#unresolvedIds.get(id);\n this.#unresolvedIds.delete(id);\n if (this.#unresolvedIds.size === 0) {\n this.stopListening();\n }\n promiseInfo?.resolve(t);\n }\n}\n", "// Copyright 2021 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/*\n * Copyright (C) 2012 Google Inc. All rights reserved.\n * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of Apple Computer, Inc. (\"Apple\") nor the names of\n * its contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nimport * as i18n from '../i18n/i18n.js';\nimport type * as Platform from '../platform/platform.js';\n\nimport {ParsedURL} from './ParsedURL.js';\n\nconst UIStrings = {\n /**\n *@description Text that appears in a tooltip the xhr and fetch resource types filter.\n */\n xhrAndFetch: '`XHR` and `Fetch`',\n /**\n *@description Text that appears in a tooltip for the JavaScript types filter.\n */\n scripts: 'Scripts',\n /**\n *@description Text that appears on a button for the JavaScript resource type filter.\n */\n js: 'JS',\n /**\n *@description Text that appears in a tooltip for the css types filter.\n */\n stylesheets: 'Stylesheets',\n /**\n *@description Text that appears on a button for the css resource type filter.\n */\n css: 'CSS',\n /**\n *@description Text that appears in a tooltip for the image types filter.\n */\n images: 'Images',\n /**\n *@description Text that appears on a button for the image resource type filter.\n */\n img: 'Img',\n /**\n *@description Text that appears on a button for the media resource type filter.\n */\n media: 'Media',\n /**\n *@description Text that appears in a tooltip for the resource types filter.\n */\n fonts: 'Fonts',\n /**\n *@description Text that appears on a button for the font resource type filter.\n */\n font: 'Font',\n /**\n *@description Text for documents, a type of resources\n */\n documents: 'Documents',\n /**\n *@description Text that appears on a button for the document resource type filter.\n */\n doc: 'Doc',\n /**\n *@description Text that appears in a tooltip for the websocket types filter.\n */\n websockets: 'WebSockets',\n /**\n *@description Text that appears on a button for the websocket resource type filter.\n */\n ws: 'WS',\n /**\n *@description Text that appears in a tooltip for the WebAssembly types filter.\n */\n webassembly: 'WebAssembly',\n /**\n *@description Text that appears on a button for the WebAssembly resource type filter.\n */\n wasm: 'Wasm',\n /**\n *@description Text that appears on a button for the manifest resource type filter.\n */\n manifest: 'Manifest',\n /**\n *@description Text for other types of items\n */\n other: 'Other',\n /**\n *@description Name of a network resource type\n */\n document: 'Document',\n /**\n *@description Name of a network resource type\n */\n stylesheet: 'Stylesheet',\n /**\n *@description Text in Image View of the Sources panel\n */\n image: 'Image',\n /**\n *@description Label for a group of JavaScript files\n */\n script: 'Script',\n /**\n *@description Name of a network resource type\n */\n texttrack: 'TextTrack',\n /**\n *@description Name of a network resource type\n */\n fetch: 'Fetch',\n /**\n *@description Name of a network resource type\n */\n eventsource: 'EventSource',\n /**\n *@description Name of a network resource type\n */\n websocket: 'WebSocket',\n /**\n *@description Name of a network resource type\n */\n webtransport: 'WebTransport',\n /**\n *@description Name of a network resource type\n */\n signedexchange: 'SignedExchange',\n /**\n *@description Name of a network resource type\n */\n ping: 'Ping',\n /**\n *@description Name of a network resource type\n */\n cspviolationreport: 'CSPViolationReport',\n /**\n *@description Name of a network initiator type\n */\n preflight: 'Preflight',\n /**\n *@description Name of a network initiator type\n */\n webbundle: 'WebBundle',\n};\nconst str_ = i18n.i18n.registerUIStrings('core/common/ResourceType.ts', UIStrings);\nconst i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);\n\nexport class ResourceType {\n readonly #nameInternal: string;\n readonly #titleInternal: () => Platform.UIString.LocalizedString;\n readonly #categoryInternal: ResourceCategory;\n readonly #isTextTypeInternal: boolean;\n\n constructor(\n name: string, title: () => Platform.UIString.LocalizedString, category: ResourceCategory, isTextType: boolean) {\n this.#nameInternal = name;\n this.#titleInternal = title;\n this.#categoryInternal = category;\n this.#isTextTypeInternal = isTextType;\n }\n\n static fromMimeType(mimeType: string|null): ResourceType {\n if (!mimeType) {\n return resourceTypes.Other;\n }\n if (mimeType.startsWith('text/html')) {\n return resourceTypes.Document;\n }\n if (mimeType.startsWith('text/css')) {\n return resourceTypes.Stylesheet;\n }\n if (mimeType.startsWith('image/')) {\n return resourceTypes.Image;\n }\n if (mimeType.startsWith('text/')) {\n return resourceTypes.Script;\n }\n\n if (mimeType.includes('font')) {\n return resourceTypes.Font;\n }\n if (mimeType.includes('script')) {\n return resourceTypes.Script;\n }\n if (mimeType.includes('octet')) {\n return resourceTypes.Other;\n }\n if (mimeType.includes('application')) {\n return resourceTypes.Script;\n }\n\n return resourceTypes.Other;\n }\n\n static fromMimeTypeOverride(mimeType: string|null): ResourceType|null {\n if (mimeType === 'application/manifest+json') {\n return resourceTypes.Manifest;\n }\n if (mimeType === 'application/wasm') {\n return resourceTypes.Wasm;\n }\n if (mimeType === 'application/webbundle') {\n return resourceTypes.WebBundle;\n }\n\n return null;\n }\n\n static fromURL(url: string): ResourceType|null {\n return resourceTypeByExtension.get(ParsedURL.extractExtension(url)) || null;\n }\n\n static fromName(name: string): ResourceType|null {\n for (const resourceTypeId in resourceTypes) {\n const resourceType = (resourceTypes as {\n [x: string]: ResourceType,\n })[resourceTypeId];\n if (resourceType.name() === name) {\n return resourceType;\n }\n }\n return null;\n }\n\n static mimeFromURL(url: Platform.DevToolsPath.UrlString): string|undefined {\n const name = ParsedURL.extractName(url);\n if (mimeTypeByName.has(name)) {\n return mimeTypeByName.get(name);\n }\n\n let ext = ParsedURL.extractExtension(url).toLowerCase();\n if (ext === 'html' && name.endsWith('.component.html')) {\n ext = 'component.html';\n }\n return mimeTypeByExtension.get(ext);\n }\n\n static mimeFromExtension(ext: string): string|undefined {\n return mimeTypeByExtension.get(ext);\n }\n\n static simplifyContentType(contentType: string): string {\n const regex = new RegExp('^application(.*json$|\\/json\\+.*)');\n return regex.test(contentType) ? 'application/json' : contentType;\n }\n\n /**\n * Adds suffixes iff the mimeType is 'text/javascript' to denote whether the JS is minified or from\n * a source map.\n */\n static mediaTypeForMetrics(mimeType: string, isFromSourceMap: boolean, isMinified: boolean): string {\n if (mimeType !== 'text/javascript') {\n return mimeType;\n }\n\n if (isFromSourceMap) {\n // SourceMap has precedence as that is a known fact, whereas minification is a heuristic we\n // apply to the JS content.\n return 'text/javascript+sourcemapped';\n }\n if (isMinified) {\n return 'text/javascript+minified';\n }\n return 'text/javascript+plain';\n }\n\n name(): string {\n return this.#nameInternal;\n }\n\n title(): string {\n return this.#titleInternal();\n }\n\n category(): ResourceCategory {\n return this.#categoryInternal;\n }\n\n isTextType(): boolean {\n return this.#isTextTypeInternal;\n }\n\n isScript(): boolean {\n return this.#nameInternal === 'script' || this.#nameInternal === 'sm-script';\n }\n\n hasScripts(): boolean {\n return this.isScript() || this.isDocument();\n }\n\n isStyleSheet(): boolean {\n return this.#nameInternal === 'stylesheet' || this.#nameInternal === 'sm-stylesheet';\n }\n\n hasStyleSheets(): boolean {\n return this.isStyleSheet() || this.isDocument();\n }\n\n isDocument(): boolean {\n return this.#nameInternal === 'document';\n }\n\n isDocumentOrScriptOrStyleSheet(): boolean {\n return this.isDocument() || this.isScript() || this.isStyleSheet();\n }\n\n isFont(): boolean {\n return this.#nameInternal === 'font';\n }\n\n isImage(): boolean {\n return this.#nameInternal === 'image';\n }\n\n isFromSourceMap(): boolean {\n return this.#nameInternal.startsWith('sm-');\n }\n\n isWebbundle(): boolean {\n return this.#nameInternal === 'webbundle';\n }\n\n toString(): string {\n return this.#nameInternal;\n }\n\n canonicalMimeType(): string {\n if (this.isDocument()) {\n return 'text/html';\n }\n if (this.isScript()) {\n return 'text/javascript';\n }\n if (this.isStyleSheet()) {\n return 'text/css';\n }\n return '';\n }\n}\n\nexport class ResourceCategory {\n title: () => Platform.UIString.LocalizedString;\n shortTitle: () => Platform.UIString.LocalizedString;\n constructor(title: () => Platform.UIString.LocalizedString, shortTitle: () => Platform.UIString.LocalizedString) {\n this.title = title;\n this.shortTitle = shortTitle;\n }\n}\n\nexport const resourceCategories = {\n XHR: new ResourceCategory(i18nLazyString(UIStrings.xhrAndFetch), i18n.i18n.lockedLazyString('Fetch/XHR')),\n Script: new ResourceCategory(i18nLazyString(UIStrings.scripts), i18nLazyString(UIStrings.js)),\n Stylesheet: new ResourceCategory(i18nLazyString(UIStrings.stylesheets), i18nLazyString(UIStrings.css)),\n Image: new ResourceCategory(i18nLazyString(UIStrings.images), i18nLazyString(UIStrings.img)),\n Media: new ResourceCategory(i18nLazyString(UIStrings.media), i18nLazyString(UIStrings.media)),\n Font: new ResourceCategory(i18nLazyString(UIStrings.fonts), i18nLazyString(UIStrings.font)),\n Document: new ResourceCategory(i18nLazyString(UIStrings.documents), i18nLazyString(UIStrings.doc)),\n WebSocket: new ResourceCategory(i18nLazyString(UIStrings.websockets), i18nLazyString(UIStrings.ws)),\n Wasm: new ResourceCategory(i18nLazyString(UIStrings.webassembly), i18nLazyString(UIStrings.wasm)),\n Manifest: new ResourceCategory(i18nLazyString(UIStrings.manifest), i18nLazyString(UIStrings.manifest)),\n Other: new ResourceCategory(i18nLazyString(UIStrings.other), i18nLazyString(UIStrings.other)),\n};\n\n/**\n * This enum is a superset of all types defined in WebCore::InspectorPageAgent::resourceTypeJson\n * For DevTools-only types that are based on MIME-types that are backed by other request types\n * (for example Wasm that is based on Fetch), additional types are added here.\n * For these types, make sure to update `fromMimeTypeOverride` to implement the custom logic.\n */\nexport const resourceTypes = {\n Document: new ResourceType('document', i18nLazyString(UIStrings.document), resourceCategories.Document, true),\n Stylesheet: new ResourceType('stylesheet', i18nLazyString(UIStrings.stylesheet), resourceCategories.Stylesheet, true),\n Image: new ResourceType('image', i18nLazyString(UIStrings.image), resourceCategories.Image, false),\n Media: new ResourceType('media', i18nLazyString(UIStrings.media), resourceCategories.Media, false),\n Font: new ResourceType('font', i18nLazyString(UIStrings.font), resourceCategories.Font, false),\n Script: new ResourceType('script', i18nLazyString(UIStrings.script), resourceCategories.Script, true),\n TextTrack: new ResourceType('texttrack', i18nLazyString(UIStrings.texttrack), resourceCategories.Other, true),\n XHR: new ResourceType('xhr', i18n.i18n.lockedLazyString('XHR'), resourceCategories.XHR, true),\n Fetch: new ResourceType('fetch', i18nLazyString(UIStrings.fetch), resourceCategories.XHR, true),\n Prefetch: new ResourceType('prefetch', i18n.i18n.lockedLazyString('Prefetch'), resourceCategories.Document, true),\n EventSource: new ResourceType('eventsource', i18nLazyString(UIStrings.eventsource), resourceCategories.XHR, true),\n WebSocket: new ResourceType('websocket', i18nLazyString(UIStrings.websocket), resourceCategories.WebSocket, false),\n // TODO(yoichio): Consider creating new category WT or WS/WT with WebSocket.\n WebTransport:\n new ResourceType('webtransport', i18nLazyString(UIStrings.webtransport), resourceCategories.WebSocket, false),\n Wasm: new ResourceType('wasm', i18nLazyString(UIStrings.wasm), resourceCategories.Wasm, false),\n Manifest: new ResourceType('manifest', i18nLazyString(UIStrings.manifest), resourceCategories.Manifest, true),\n SignedExchange:\n new ResourceType('signed-exchange', i18nLazyString(UIStrings.signedexchange), resourceCategories.Other, false),\n Ping: new ResourceType('ping', i18nLazyString(UIStrings.ping), resourceCategories.Other, false),\n CSPViolationReport: new ResourceType(\n 'csp-violation-report', i18nLazyString(UIStrings.cspviolationreport), resourceCategories.Other, false),\n Other: new ResourceType('other', i18nLazyString(UIStrings.other), resourceCategories.Other, false),\n Preflight: new ResourceType('preflight', i18nLazyString(UIStrings.preflight), resourceCategories.Other, true),\n SourceMapScript: new ResourceType('sm-script', i18nLazyString(UIStrings.script), resourceCategories.Script, true),\n SourceMapStyleSheet:\n new ResourceType('sm-stylesheet', i18nLazyString(UIStrings.stylesheet), resourceCategories.Stylesheet, true),\n WebBundle: new ResourceType('webbundle', i18nLazyString(UIStrings.webbundle), resourceCategories.Other, false),\n};\n\nconst mimeTypeByName = new Map([\n // CoffeeScript\n ['Cakefile', 'text/x-coffeescript'],\n]);\n\n// clang-format off\nexport const resourceTypeByExtension = new Map([\n ['js', resourceTypes.Script],\n ['mjs', resourceTypes.Script],\n\n ['css', resourceTypes.Stylesheet],\n ['xsl', resourceTypes.Stylesheet],\n\n ['avif', resourceTypes.Image],\n ['bmp', resourceTypes.Image],\n ['gif', resourceTypes.Image],\n ['ico', resourceTypes.Image],\n ['jpeg', resourceTypes.Image],\n ['jpg', resourceTypes.Image],\n ['jxl', resourceTypes.Image],\n ['png', resourceTypes.Image],\n ['svg', resourceTypes.Image],\n ['tif', resourceTypes.Image],\n ['tiff', resourceTypes.Image],\n\n ['vue', resourceTypes.Document],\n\n ['webmanifest', resourceTypes.Manifest],\n\n ['webp', resourceTypes.Media],\n\n ['otf', resourceTypes.Font],\n ['ttc', resourceTypes.Font],\n ['ttf', resourceTypes.Font],\n ['woff', resourceTypes.Font],\n ['woff2', resourceTypes.Font],\n\n ['wasm', resourceTypes.Wasm],\n]);\n// clang-format on\n\nexport const mimeTypeByExtension = new Map([\n // Web extensions\n ['js', 'text/javascript'],\n ['mjs', 'text/javascript'],\n ['css', 'text/css'],\n ['html', 'text/html'],\n ['htm', 'text/html'],\n ['xml', 'application/xml'],\n ['xsl', 'application/xml'],\n ['wasm', 'application/wasm'],\n ['webmanifest', 'application/manifest+json'],\n\n // HTML Embedded Scripts, ASP], JSP\n ['asp', 'application/x-aspx'],\n ['aspx', 'application/x-aspx'],\n ['jsp', 'application/x-jsp'],\n\n // C/C++\n ['c', 'text/x-c++src'],\n ['cc', 'text/x-c++src'],\n ['cpp', 'text/x-c++src'],\n ['h', 'text/x-c++src'],\n ['m', 'text/x-c++src'],\n ['mm', 'text/x-c++src'],\n\n // CoffeeScript\n ['coffee', 'text/x-coffeescript'],\n\n // Dart\n ['dart', 'application/vnd.dart'],\n\n // TypeScript\n ['ts', 'text/typescript'],\n ['tsx', 'text/typescript-jsx'],\n\n // JSON\n ['json', 'application/json'],\n ['gyp', 'application/json'],\n ['gypi', 'application/json'],\n ['map', 'application/json'],\n\n // C#\n ['cs', 'text/x-csharp'],\n\n // Go\n ['go', 'text/x-go'],\n\n // Java\n ['java', 'text/x-java'],\n\n // Kotlin\n ['kt', 'text/x-kotlin'],\n\n // Scala\n ['scala', 'text/x-scala'],\n\n // Less\n ['less', 'text/x-less'],\n\n // PHP\n ['php', 'application/x-httpd-php'],\n ['phtml', 'application/x-httpd-php'],\n\n // Python\n ['py', 'text/x-python'],\n\n // Shell\n ['sh', 'text/x-sh'],\n\n // Google Stylesheets (GSS)\n ['gss', 'text/x-gss'],\n\n // SASS (.sass & .scss)\n ['sass', 'text/x-sass'],\n ['scss', 'text/x-scss'],\n\n // Video Text Tracks.\n ['vtt', 'text/vtt'],\n\n // LiveScript\n ['ls', 'text/x-livescript'],\n\n // Markdown\n ['md', 'text/markdown'],\n\n // ClojureScript\n ['cljs', 'text/x-clojure'],\n ['cljc', 'text/x-clojure'],\n ['cljx', 'text/x-clojure'],\n\n // Stylus\n ['styl', 'text/x-styl'],\n\n // JSX\n ['jsx', 'text/jsx'],\n\n // Image\n ['avif', 'image/avif'],\n ['bmp', 'image/bmp'],\n ['gif', 'image/gif'],\n ['ico', 'image/ico'],\n ['jpeg', 'image/jpeg'],\n ['jpg', 'image/jpeg'],\n ['jxl', 'image/jxl'],\n ['png', 'image/png'],\n ['svg', 'image/svg+xml'],\n ['tif', 'image/tif'],\n ['tiff', 'image/tiff'],\n ['webp', 'image/webp'],\n\n // Font\n ['otf', 'font/otf'],\n ['ttc', 'font/collection'],\n ['ttf', 'font/ttf'],\n ['woff', 'font/woff'],\n ['woff2', 'font/woff2'],\n\n // Angular\n ['component.html', 'text/x.angular'],\n\n // Svelte\n ['svelte', 'text/x.svelte'],\n\n // Vue\n ['vue', 'text/x.vue'],\n]);\n", "// Copyright 2016 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../platform/platform.js';\n\nexport class Segment<T> {\n begin: number;\n end: number;\n data: T;\n\n constructor(begin: number, end: number, data: T) {\n if (begin > end) {\n throw new Error('Invalid segment');\n }\n this.begin = begin;\n this.end = end;\n this.data = data;\n }\n\n intersects(that: Segment<T>): boolean {\n return this.begin < that.end && that.begin < this.end;\n }\n}\n\nexport class SegmentedRange<T> {\n #segmentsInternal: Segment<T>[];\n readonly #mergeCallback: ((arg0: Segment<T>, arg1: Segment<T>) => Segment<T>| null)|undefined;\n\n constructor(mergeCallback?: ((arg0: Segment<T>, arg1: Segment<T>) => Segment<T>| null)) {\n this.#segmentsInternal = [];\n this.#mergeCallback = mergeCallback;\n }\n\n append(newSegment: Segment<T>): void {\n // 1. Find the proper insertion point for new segment\n let startIndex =\n Platform.ArrayUtilities.lowerBound(this.#segmentsInternal, newSegment, (a, b) => a.begin - b.begin);\n let endIndex = startIndex;\n let merged: (Segment<T>|null)|null = null;\n if (startIndex > 0) {\n // 2. Try mering the preceding segment\n const precedingSegment = this.#segmentsInternal[startIndex - 1];\n merged = this.tryMerge(precedingSegment, newSegment);\n if (merged) {\n --startIndex;\n newSegment = merged;\n } else if (this.#segmentsInternal[startIndex - 1].end >= newSegment.begin) {\n // 2a. If merge failed and segments overlap, adjust preceding segment.\n // If an old segment entirely contains new one, split it in two.\n if (newSegment.end < precedingSegment.end) {\n this.#segmentsInternal.splice(\n startIndex, 0, new Segment<T>(newSegment.end, precedingSegment.end, precedingSegment.data));\n }\n precedingSegment.end = newSegment.begin;\n }\n }\n // 3. Consume all segments that are entirely covered by the new one.\n while (endIndex < this.#segmentsInternal.length && this.#segmentsInternal[endIndex].end <= newSegment.end) {\n ++endIndex;\n }\n // 4. Merge or adjust the succeeding segment if it overlaps.\n if (endIndex < this.#segmentsInternal.length) {\n merged = this.tryMerge(newSegment, this.#segmentsInternal[endIndex]);\n if (merged) {\n endIndex++;\n newSegment = merged;\n } else if (newSegment.intersects(this.#segmentsInternal[endIndex])) {\n this.#segmentsInternal[endIndex].begin = newSegment.end;\n }\n }\n this.#segmentsInternal.splice(startIndex, endIndex - startIndex, newSegment);\n }\n\n appendRange(that: SegmentedRange<T>): void {\n that.segments().forEach(segment => this.append(segment));\n }\n\n segments(): Segment<T>[] {\n return this.#segmentsInternal;\n }\n\n private tryMerge(first: Segment<T>, second: Segment<T>): Segment<T>|null {\n const merged = this.#mergeCallback && this.#mergeCallback(first, second);\n if (!merged) {\n return null;\n }\n merged.begin = first.begin;\n merged.end = Math.max(first.end, second.end);\n return merged;\n }\n}\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as i18n from '../i18n/i18n.js';\nimport type * as Platform from '../platform/platform.js';\nimport * as Root from '../root/root.js';\n\nimport {type SettingStorageType} from './Settings.js';\n\nconst UIStrings = {\n /**\n *@description Title of the Elements Panel\n */\n elements: 'Elements',\n /**\n *@description Text for DevTools appearance\n */\n appearance: 'Appearance',\n /**\n *@description Name of the Sources panel\n */\n sources: 'Sources',\n /**\n *@description Title of the Network tool\n */\n network: 'Network',\n /**\n *@description Text for the performance of something\n */\n performance: 'Performance',\n /**\n *@description Title of the Console tool\n */\n console: 'Console',\n /**\n *@description A title of the 'Persistence' setting category\n */\n persistence: 'Persistence',\n /**\n *@description Text that refers to the debugger\n */\n debugger: 'Debugger',\n /**\n *@description Text describing global shortcuts and settings that are available throughout the DevTools\n */\n global: 'Global',\n /**\n *@description Title of the Rendering tool\n */\n rendering: 'Rendering',\n /**\n *@description Title of a section on CSS Grid tooling\n */\n grid: 'Grid',\n /**\n *@description Text for the mobile platform, as opposed to desktop\n */\n mobile: 'Mobile',\n /**\n *@description Text for the memory of the page\n */\n memory: 'Memory',\n /**\n *@description Text for the extension of the page\n */\n extension: 'Extension',\n /**\n *@description Text for the adorner of the page\n */\n adorner: 'Adorner',\n /**\n * @description Header for the \"Sync\" section in the settings UI. The \"Sync\"\n * section allows users to configure which DevTools data is synced via Chrome Sync.\n */\n sync: 'Sync',\n};\nconst str_ = i18n.i18n.registerUIStrings('core/common/SettingRegistration.ts', UIStrings);\nconst i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);\nlet registeredSettings: Array<SettingRegistration> = [];\nconst settingNameSet = new Set<string>();\n\nexport function registerSettingExtension(registration: SettingRegistration): void {\n const settingName = registration.settingName;\n if (settingNameSet.has(settingName)) {\n throw new Error(`Duplicate setting name '${settingName}'`);\n }\n settingNameSet.add(settingName);\n registeredSettings.push(registration);\n}\n\nexport function getRegisteredSettings(): Array<SettingRegistration> {\n return registeredSettings.filter(\n setting =>\n Root.Runtime.Runtime.isDescriptorEnabled({experiment: setting.experiment, condition: setting.condition}));\n}\n\nexport function registerSettingsForTest(settings: Array<SettingRegistration>, forceReset: boolean = false): void {\n if (registeredSettings.length === 0 || forceReset) {\n registeredSettings = settings;\n settingNameSet.clear();\n for (const setting of settings) {\n const settingName = setting.settingName;\n if (settingNameSet.has(settingName)) {\n throw new Error(`Duplicate setting name '${settingName}'`);\n }\n settingNameSet.add(settingName);\n }\n }\n}\n\nexport function resetSettings(): void {\n registeredSettings = [];\n settingNameSet.clear();\n}\n\nexport function maybeRemoveSettingExtension(settingName: string): boolean {\n const settingIndex = registeredSettings.findIndex(setting => setting.settingName === settingName);\n if (settingIndex < 0 || !settingNameSet.delete(settingName)) {\n return false;\n }\n registeredSettings.splice(settingIndex, 1);\n return true;\n}\n\n// TODO(crbug.com/1167717): Make this a const enum again\n// eslint-disable-next-line rulesdir/const_enum\nexport enum SettingCategory {\n NONE = '', // `NONE` must be a falsy value. Legacy code uses if-checks for the category.\n ELEMENTS = 'ELEMENTS',\n APPEARANCE = 'APPEARANCE',\n SOURCES = 'SOURCES',\n NETWORK = 'NETWORK',\n PERFORMANCE = 'PERFORMANCE',\n CONSOLE = 'CONSOLE',\n PERSISTENCE = 'PERSISTENCE',\n DEBUGGER = 'DEBUGGER',\n GLOBAL = 'GLOBAL',\n RENDERING = 'RENDERING',\n GRID = 'GRID',\n MOBILE = 'MOBILE',\n EMULATION = 'EMULATION',\n MEMORY = 'MEMORY',\n EXTENSIONS = 'EXTENSIONS',\n ADORNER = 'ADORNER',\n SYNC = 'SYNC',\n}\n\nexport function getLocalizedSettingsCategory(category: SettingCategory): Platform.UIString.LocalizedString {\n switch (category) {\n case SettingCategory.ELEMENTS:\n return i18nString(UIStrings.elements);\n case SettingCategory.APPEARANCE:\n return i18nString(UIStrings.appearance);\n case SettingCategory.SOURCES:\n return i18nString(UIStrings.sources);\n case SettingCategory.NETWORK:\n return i18nString(UIStrings.network);\n case SettingCategory.PERFORMANCE:\n return i18nString(UIStrings.performance);\n case SettingCategory.CONSOLE:\n return i18nString(UIStrings.console);\n case SettingCategory.PERSISTENCE:\n return i18nString(UIStrings.persistence);\n case SettingCategory.DEBUGGER:\n return i18nString(UIStrings.debugger);\n case SettingCategory.GLOBAL:\n return i18nString(UIStrings.global);\n case SettingCategory.RENDERING:\n return i18nString(UIStrings.rendering);\n case SettingCategory.GRID:\n return i18nString(UIStrings.grid);\n case SettingCategory.MOBILE:\n return i18nString(UIStrings.mobile);\n case SettingCategory.EMULATION:\n return i18nString(UIStrings.console);\n case SettingCategory.MEMORY:\n return i18nString(UIStrings.memory);\n case SettingCategory.EXTENSIONS:\n return i18nString(UIStrings.extension);\n case SettingCategory.ADORNER:\n return i18nString(UIStrings.adorner);\n case SettingCategory.NONE:\n return i18n.i18n.lockedString('');\n case SettingCategory.SYNC:\n return i18nString(UIStrings.sync);\n }\n}\n\n// TODO(crbug.com/1167717): Make this a const enum again\n// eslint-disable-next-line rulesdir/const_enum\nexport enum SettingType {\n ARRAY = 'array',\n REGEX = 'regex',\n ENUM = 'enum',\n BOOLEAN = 'boolean',\n}\n\nexport interface RegExpSettingItem {\n /**\n * A regular expression matched against URLs for ignore listing.\n */\n pattern: string;\n /**\n * If true, ignore this rule.\n */\n disabled?: boolean;\n /**\n * When a rule is disabled due to requesting through a script's context menu\n * that it no longer be ignore listed, this field is set to the URL of that\n * script, so that if the user requests through the same context menu to\n * enable ignore listing, the rule can be reenabled.\n */\n disabledForUrl?: Platform.DevToolsPath.UrlString;\n}\n\nexport interface SettingRegistration {\n /**\n * The category with which the setting is displayed in the UI.\n */\n category?: SettingCategory;\n /**\n * Used to sort on screen the settings that belong to the same category.\n */\n order?: number;\n /**\n * The title with which the setting is shown on screen.\n */\n title?: () => Platform.UIString.LocalizedString;\n /**\n * The title with which the setting is shown on screen, if the platform running DevTools is 'mac'.\n * If not set, the 'title' field will be used instead.\n */\n titleMac?: () => Platform.UIString.LocalizedString;\n /**\n * The identifier of the setting.\n */\n settingName: string;\n /**\n * Determines how the possible values of the setting are expressed.\n *\n * - If the setting can only be enabled and disabled use BOOLEAN\n * - If the setting has a list of possible values use ENUM\n * - If each setting value is a set of objects use ARRAY\n * - If the setting value is a regular expression use REGEX\n */\n settingType: SettingType;\n /**\n * The value set by default to the setting.\n */\n defaultValue: unknown;\n /**\n * Words used to find a setting in the Command Menu.\n */\n tags?: Array<() => Platform.UIString.LocalizedString>;\n /**\n * The possible values the setting can have, each with a description composed of a title and an optional text.\n */\n options?: Array<SettingExtensionOption>;\n /**\n * Whether DevTools must be reloaded for a change in the setting to take effect.\n */\n reloadRequired?: boolean;\n /**\n * Determines if the setting value is stored in the global, local or session storage.\n */\n storageType?: SettingStorageType;\n /**\n * A condition that, when present in the queryParamsObject of Runtime, constraints the value\n * of the setting to be changed only if the user set it.\n */\n userActionCondition?: string;\n /**\n * The name of the experiment a setting is associated with. Enabling and disabling the declared\n * experiment will enable and disable the setting respectively.\n */\n experiment?: Root.Runtime.ExperimentName;\n /**\n * A condition represented as a string the setting's availability depends on. Conditions come\n * from the queryParamsObject defined in Runtime and just as the experiment field, they determine the availability\n * of the setting. A condition can be negated by prepending a \u2018!\u2019 to the value of the condition\n * property and in that case the behaviour of the setting's availability will be inverted.\n */\n condition?: Root.Runtime.ConditionName;\n\n /**\n * If a setting is deprecated, define this notice to show an appropriate warning according to the `warning` propertiy.\n * If `disabled` is set, the setting will be disabled in the settings UI. In that case, `experiment` optionally can be\n * set to link to an experiment (by experiment name). The information icon in the settings UI can then be clicked to\n * jump to the experiment. If a setting is not disabled, the experiment entry will be ignored.\n */\n deprecationNotice?: {disabled: boolean, warning: () => Platform.UIString.LocalizedString, experiment?: string};\n}\ninterface LocalizedSettingExtensionOption {\n value: boolean|string;\n title: () => Platform.UIString.LocalizedString;\n text?: () => Platform.UIString.LocalizedString;\n raw?: false;\n}\ninterface RawSettingExtensionOption {\n value: boolean|string;\n title: () => Platform.UIString.LocalizedString;\n /**\n * Text used to describe the option. Must be localized if 'raw' is false.\n */\n text?: string;\n raw: true;\n}\nexport type SettingExtensionOption = LocalizedSettingExtensionOption|RawSettingExtensionOption;\n", "/*\n * Copyright (C) 2009 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nimport type * as Platform from '../platform/platform.js';\nimport * as Root from '../root/root.js';\n\nimport {Format, type Color} from './Color.js';\nimport {Console} from './Console.js';\nimport {type GenericEvents, type EventDescriptor, type EventTargetEvent} from './EventTarget.js';\nimport {ObjectWrapper} from './Object.js';\nimport {\n getLocalizedSettingsCategory,\n getRegisteredSettings,\n maybeRemoveSettingExtension,\n type RegExpSettingItem,\n registerSettingExtension,\n registerSettingsForTest,\n resetSettings,\n SettingCategory,\n type SettingExtensionOption,\n type SettingRegistration,\n SettingType,\n} from './SettingRegistration.js';\n\nlet settingsInstance: Settings|undefined;\n\nexport class Settings {\n readonly #sessionStorage: SettingsStorage;\n settingNameSet: Set<string>;\n orderValuesBySettingCategory: Map<SettingCategory, Set<number>>;\n #eventSupport: ObjectWrapper<GenericEvents>;\n #registry: Map<string, Setting<unknown>>;\n readonly moduleSettings: Map<string, Setting<unknown>>;\n\n private constructor(\n private readonly syncedStorage: SettingsStorage, readonly globalStorage: SettingsStorage,\n private readonly localStorage: SettingsStorage) {\n this.#sessionStorage = new SettingsStorage({});\n\n this.settingNameSet = new Set();\n\n this.orderValuesBySettingCategory = new Map();\n\n this.#eventSupport = new ObjectWrapper<GenericEvents>();\n this.#registry = new Map();\n this.moduleSettings = new Map();\n\n for (const registration of getRegisteredSettings()) {\n const {settingName, defaultValue, storageType} = registration;\n const isRegex = registration.settingType === SettingType.REGEX;\n\n const setting = isRegex && typeof defaultValue === 'string' ?\n this.createRegExpSetting(settingName, defaultValue, undefined, storageType) :\n this.createSetting(settingName, defaultValue, storageType);\n\n if (Root.Runtime.Runtime.platform() === 'mac' && registration.titleMac) {\n setting.setTitleFunction(registration.titleMac);\n } else {\n setting.setTitleFunction(registration.title);\n }\n if (registration.userActionCondition) {\n setting.setRequiresUserAction(Boolean(Root.Runtime.Runtime.queryParam(registration.userActionCondition)));\n }\n setting.setRegistration(registration);\n\n this.registerModuleSetting(setting);\n }\n }\n\n static hasInstance(): boolean {\n return typeof settingsInstance !== 'undefined';\n }\n\n static instance(opts: {\n forceNew: boolean|null,\n syncedStorage: SettingsStorage|null,\n globalStorage: SettingsStorage|null,\n localStorage: SettingsStorage|null,\n } = {forceNew: null, syncedStorage: null, globalStorage: null, localStorage: null}): Settings {\n const {forceNew, syncedStorage, globalStorage, localStorage} = opts;\n if (!settingsInstance || forceNew) {\n if (!syncedStorage || !globalStorage || !localStorage) {\n throw new Error(`Unable to create settings: global and local storage must be provided: ${new Error().stack}`);\n }\n\n settingsInstance = new Settings(syncedStorage, globalStorage, localStorage);\n }\n\n return settingsInstance;\n }\n\n static removeInstance(): void {\n settingsInstance = undefined;\n }\n\n private registerModuleSetting(setting: Setting<unknown>): void {\n const settingName = setting.name;\n const category = setting.category();\n const order = setting.order();\n if (this.settingNameSet.has(settingName)) {\n throw new Error(`Duplicate Setting name '${settingName}'`);\n }\n if (category && order) {\n const orderValues = this.orderValuesBySettingCategory.get(category) || new Set();\n if (orderValues.has(order)) {\n throw new Error(`Duplicate order value '${order}' for settings category '${category}'`);\n }\n orderValues.add(order);\n this.orderValuesBySettingCategory.set(category, orderValues);\n }\n this.settingNameSet.add(settingName);\n this.moduleSettings.set(setting.name, setting);\n }\n\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n moduleSetting<T = any>(settingName: string): Setting<T> {\n const setting = this.moduleSettings.get(settingName) as Setting<T>;\n if (!setting) {\n throw new Error('No setting registered: ' + settingName);\n }\n return setting;\n }\n\n settingForTest(settingName: string): Setting<unknown> {\n const setting = this.#registry.get(settingName);\n if (!setting) {\n throw new Error('No setting registered: ' + settingName);\n }\n return setting;\n }\n\n createSetting<T>(key: string, defaultValue: T, storageType?: SettingStorageType): Setting<T> {\n const storage = this.storageFromType(storageType);\n let setting = (this.#registry.get(key) as Setting<T>);\n if (!setting) {\n setting = new Setting(key, defaultValue, this.#eventSupport, storage);\n this.#registry.set(key, setting);\n }\n return setting;\n }\n\n createLocalSetting<T>(key: string, defaultValue: T): Setting<T> {\n return this.createSetting(key, defaultValue, SettingStorageType.Local);\n }\n\n createRegExpSetting(key: string, defaultValue: string, regexFlags?: string, storageType?: SettingStorageType):\n RegExpSetting {\n if (!this.#registry.get(key)) {\n this.#registry.set(\n key, new RegExpSetting(key, defaultValue, this.#eventSupport, this.storageFromType(storageType), regexFlags));\n }\n return this.#registry.get(key) as RegExpSetting;\n }\n\n clearAll(): void {\n this.globalStorage.removeAll();\n this.syncedStorage.removeAll();\n this.localStorage.removeAll();\n new VersionController().resetToCurrent();\n }\n\n private storageFromType(storageType?: SettingStorageType): SettingsStorage {\n switch (storageType) {\n case SettingStorageType.Local:\n return this.localStorage;\n case SettingStorageType.Session:\n return this.#sessionStorage;\n case SettingStorageType.Global:\n return this.globalStorage;\n case SettingStorageType.Synced:\n return this.syncedStorage;\n }\n return this.globalStorage;\n }\n\n getRegistry(): Map<string, Setting<unknown>> {\n return this.#registry;\n }\n}\n\nexport interface SettingsBackingStore {\n register(setting: string): void;\n get(setting: string): Promise<string>;\n set(setting: string, value: string): void;\n remove(setting: string): void;\n clear(): void;\n}\n\nexport const NOOP_STORAGE: SettingsBackingStore = {\n register: () => {},\n set: () => {},\n get: () => Promise.resolve(''),\n remove: () => {},\n clear: () => {},\n};\n\nexport class SettingsStorage {\n constructor(\n private object: Record<string, string>, private readonly backingStore: SettingsBackingStore = NOOP_STORAGE,\n private readonly storagePrefix: string = '') {\n }\n\n register(name: string): void {\n name = this.storagePrefix + name;\n this.backingStore.register(name);\n }\n\n set(name: string, value: string): void {\n name = this.storagePrefix + name;\n this.object[name] = value;\n this.backingStore.set(name, value);\n }\n\n has(name: string): boolean {\n name = this.storagePrefix + name;\n return name in this.object;\n }\n\n get(name: string): string {\n name = this.storagePrefix + name;\n return this.object[name];\n }\n\n async forceGet(originalName: string): Promise<string> {\n const name = this.storagePrefix + originalName;\n const value = await this.backingStore.get(name);\n if (value && value !== this.object[name]) {\n this.set(originalName, value);\n } else if (!value) {\n this.remove(originalName);\n }\n return value;\n }\n\n remove(name: string): void {\n name = this.storagePrefix + name;\n delete this.object[name];\n this.backingStore.remove(name);\n }\n\n removeAll(): void {\n this.object = {};\n this.backingStore.clear();\n }\n\n dumpSizes(): void {\n Console.instance().log('Ten largest settings: ');\n\n const sizes: {\n [x: string]: number,\n // @ts-expect-error __proto__ optimization\n } = {__proto__: null};\n for (const key in this.object) {\n sizes[key] = this.object[key].length;\n }\n const keys = Object.keys(sizes);\n\n function comparator(key1: string, key2: string): number {\n return sizes[key2] - sizes[key1];\n }\n\n keys.sort(comparator);\n\n for (let i = 0; i < 10 && i < keys.length; ++i) {\n Console.instance().log('Setting: \\'' + keys[i] + '\\', size: ' + sizes[keys[i]]);\n }\n }\n}\n\nfunction removeSetting(setting: Setting<unknown>): void {\n const name = setting.name;\n const settings = Settings.instance();\n\n settings.getRegistry().delete(name);\n settings.moduleSettings.delete(name);\n\n setting.storage.remove(name);\n}\n\nexport class Deprecation {\n readonly disabled: boolean;\n readonly warning: Platform.UIString.LocalizedString;\n readonly experiment?: Root.Runtime.Experiment;\n\n constructor({deprecationNotice}: SettingRegistration) {\n if (!deprecationNotice) {\n throw new Error('Cannot create deprecation info for a non-deprecated setting');\n }\n this.disabled = deprecationNotice.disabled;\n this.warning = deprecationNotice.warning();\n this.experiment = deprecationNotice.experiment ?\n Root.Runtime.experiments.allConfigurableExperiments().find(e => e.name === deprecationNotice.experiment) :\n undefined;\n }\n}\n\nexport class Setting<V> {\n #titleFunction?: () => Platform.UIString.LocalizedString;\n #titleInternal!: string;\n #registration: SettingRegistration|null = null;\n #requiresUserAction?: boolean;\n #value?: V;\n // TODO(crbug.com/1172300) Type cannot be inferred without changes to consumers. See above.\n #serializer: Serializer<unknown, V> = JSON;\n #hadUserAction?: boolean;\n #disabled?: boolean;\n #deprecation: Deprecation|null = null;\n\n constructor(\n readonly name: string, readonly defaultValue: V, private readonly eventSupport: ObjectWrapper<GenericEvents>,\n readonly storage: SettingsStorage) {\n storage.register(name);\n }\n\n setSerializer(serializer: Serializer<unknown, V>): void {\n this.#serializer = serializer;\n }\n\n addChangeListener(listener: (arg0: EventTargetEvent<V>) => void, thisObject?: Object): EventDescriptor {\n return this.eventSupport.addEventListener(this.name, listener, thisObject);\n }\n\n removeChangeListener(listener: (arg0: EventTargetEvent<V>) => void, thisObject?: Object): void {\n this.eventSupport.removeEventListener(this.name, listener, thisObject);\n }\n\n title(): string {\n if (this.#titleInternal) {\n return this.#titleInternal;\n }\n if (this.#titleFunction) {\n return this.#titleFunction();\n }\n return '';\n }\n\n setTitleFunction(titleFunction: (() => Platform.UIString.LocalizedString)|undefined): void {\n if (titleFunction) {\n this.#titleFunction = titleFunction;\n }\n }\n\n setTitle(title: string): void {\n this.#titleInternal = title;\n }\n\n setRequiresUserAction(requiresUserAction: boolean): void {\n this.#requiresUserAction = requiresUserAction;\n }\n\n disabled(): boolean {\n return this.#disabled || false;\n }\n\n setDisabled(disabled: boolean): void {\n this.#disabled = disabled;\n this.eventSupport.dispatchEventToListeners(this.name);\n }\n\n get(): V {\n if (this.#requiresUserAction && !this.#hadUserAction) {\n return this.defaultValue;\n }\n\n if (typeof this.#value !== 'undefined') {\n return this.#value;\n }\n\n this.#value = this.defaultValue;\n if (this.storage.has(this.name)) {\n try {\n this.#value = this.#serializer.parse(this.storage.get(this.name));\n } catch (e) {\n this.storage.remove(this.name);\n }\n }\n return this.#value;\n }\n\n async forceGet(): Promise<V> {\n const name = this.name;\n const oldValue = this.storage.get(name);\n const value = await this.storage.forceGet(name);\n this.#value = this.defaultValue;\n if (value) {\n try {\n this.#value = this.#serializer.parse(value);\n } catch (e) {\n this.storage.remove(this.name);\n }\n }\n\n if (oldValue !== value) {\n this.eventSupport.dispatchEventToListeners(this.name, this.#value);\n }\n\n return this.#value;\n }\n\n set(value: V): void {\n this.#hadUserAction = true;\n this.#value = value;\n try {\n const settingString = this.#serializer.stringify(value);\n try {\n this.storage.set(this.name, settingString);\n } catch (e) {\n this.printSettingsSavingError(e.message, this.name, settingString);\n }\n } catch (e) {\n Console.instance().error('Cannot stringify setting with name: ' + this.name + ', error: ' + e.message);\n }\n this.eventSupport.dispatchEventToListeners(this.name, value);\n }\n\n setRegistration(registration: SettingRegistration): void {\n this.#registration = registration;\n const {deprecationNotice} = registration;\n if (deprecationNotice?.disabled) {\n const experiment = deprecationNotice.experiment ?\n Root.Runtime.experiments.allConfigurableExperiments().find(e => e.name === deprecationNotice.experiment) :\n undefined;\n if ((!experiment || experiment.isEnabled())) {\n this.set(this.defaultValue);\n this.setDisabled(true);\n }\n }\n }\n\n type(): SettingType|null {\n if (this.#registration) {\n return this.#registration.settingType;\n }\n return null;\n }\n\n options(): SimpleSettingOption[] {\n if (this.#registration && this.#registration.options) {\n return this.#registration.options.map(opt => {\n const {value, title, text, raw} = opt;\n return {\n value: value,\n title: title(),\n text: typeof text === 'function' ? text() : text,\n raw: raw,\n };\n });\n }\n return [];\n }\n\n reloadRequired(): boolean|null {\n if (this.#registration) {\n return this.#registration.reloadRequired || null;\n }\n return null;\n }\n\n category(): SettingCategory|null {\n if (this.#registration) {\n return this.#registration.category || null;\n }\n return null;\n }\n\n tags(): string|null {\n if (this.#registration && this.#registration.tags) {\n // Get localized keys and separate by null character to prevent fuzzy matching from matching across them.\n return this.#registration.tags.map(tag => tag()).join('\\0');\n }\n return null;\n }\n\n order(): number|null {\n if (this.#registration) {\n return this.#registration.order || null;\n }\n return null;\n }\n\n get deprecation(): Deprecation|null {\n if (!this.#registration || !this.#registration.deprecationNotice) {\n return null;\n }\n if (!this.#deprecation) {\n this.#deprecation = new Deprecation(this.#registration);\n }\n return this.#deprecation;\n }\n\n private printSettingsSavingError(message: string, name: string, value: string): void {\n const errorMessage =\n 'Error saving setting with name: ' + this.name + ', value length: ' + value.length + '. Error: ' + message;\n console.error(errorMessage);\n Console.instance().error(errorMessage);\n this.storage.dumpSizes();\n }\n}\n\n// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class RegExpSetting extends Setting<any> {\n #regexFlags: string|undefined;\n #regex?: RegExp|null;\n\n constructor(\n name: string, defaultValue: string, eventSupport: ObjectWrapper<GenericEvents>, storage: SettingsStorage,\n regexFlags?: string) {\n super(name, defaultValue ? [{pattern: defaultValue}] : [], eventSupport, storage);\n this.#regexFlags = regexFlags;\n }\n\n override get(): string {\n const result = [];\n const items = this.getAsArray();\n for (let i = 0; i < items.length; ++i) {\n const item = items[i];\n if (item.pattern && !item.disabled) {\n result.push(item.pattern);\n }\n }\n return result.join('|');\n }\n\n getAsArray(): RegExpSettingItem[] {\n return super.get();\n }\n\n override set(value: string): void {\n this.setAsArray([{pattern: value, disabled: false}]);\n }\n\n setAsArray(value: RegExpSettingItem[]): void {\n this.#regex = undefined;\n super.set(value);\n }\n\n asRegExp(): RegExp|null {\n if (typeof this.#regex !== 'undefined') {\n return this.#regex;\n }\n this.#regex = null;\n try {\n const pattern = this.get();\n if (pattern) {\n this.#regex = new RegExp(pattern, this.#regexFlags || '');\n }\n } catch (e) {\n }\n return this.#regex;\n }\n}\n\nexport class VersionController {\n static readonly GLOBAL_VERSION_SETTING_NAME = 'inspectorVersion';\n static readonly SYNCED_VERSION_SETTING_NAME = 'syncedInspectorVersion';\n static readonly LOCAL_VERSION_SETTING_NAME = 'localInspectorVersion';\n\n static readonly CURRENT_VERSION = 35;\n\n readonly #globalVersionSetting: Setting<number>;\n readonly #syncedVersionSetting: Setting<number>;\n readonly #localVersionSetting: Setting<number>;\n\n constructor() {\n // If no version setting is found, we initialize with the current version and don't do anything.\n this.#globalVersionSetting = Settings.instance().createSetting(\n VersionController.GLOBAL_VERSION_SETTING_NAME, VersionController.CURRENT_VERSION, SettingStorageType.Global);\n this.#syncedVersionSetting = Settings.instance().createSetting(\n VersionController.SYNCED_VERSION_SETTING_NAME, VersionController.CURRENT_VERSION, SettingStorageType.Synced);\n this.#localVersionSetting = Settings.instance().createSetting(\n VersionController.LOCAL_VERSION_SETTING_NAME, VersionController.CURRENT_VERSION, SettingStorageType.Local);\n }\n\n /**\n * Force re-sets all version number settings to the current version without\n * running any migrations.\n */\n resetToCurrent(): void {\n this.#globalVersionSetting.set(VersionController.CURRENT_VERSION);\n this.#syncedVersionSetting.set(VersionController.CURRENT_VERSION);\n this.#localVersionSetting.set(VersionController.CURRENT_VERSION);\n }\n\n /**\n * Runs the appropriate migrations and updates the version settings accordingly.\n *\n * To determine what migrations to run we take the minimum of all version number settings.\n *\n * IMPORTANT: All migrations must be idempotent since they might be applied multiple times.\n */\n updateVersion(): void {\n const currentVersion = VersionController.CURRENT_VERSION;\n const minimumVersion =\n Math.min(this.#globalVersionSetting.get(), this.#syncedVersionSetting.get(), this.#localVersionSetting.get());\n const methodsToRun = this.methodsToRunToUpdateVersion(minimumVersion, currentVersion);\n console.assert(\n // @ts-ignore\n this[`updateVersionFrom${currentVersion}To${currentVersion + 1}`] === undefined,\n 'Unexpected migration method found. Increment CURRENT_VERSION or remove the method.');\n for (const method of methodsToRun) {\n // @ts-ignore Special version method matching\n this[method].call(this);\n }\n this.resetToCurrent();\n }\n\n private methodsToRunToUpdateVersion(oldVersion: number, currentVersion: number): string[] {\n const result = [];\n for (let i = oldVersion; i < currentVersion; ++i) {\n result.push('updateVersionFrom' + i + 'To' + (i + 1));\n }\n return result;\n }\n\n private updateVersionFrom0To1(): void {\n this.clearBreakpointsWhenTooMany(Settings.instance().createLocalSetting('breakpoints', []), 500000);\n }\n\n private updateVersionFrom1To2(): void {\n Settings.instance().createSetting('previouslyViewedFiles', []).set([]);\n }\n\n private updateVersionFrom2To3(): void {\n Settings.instance().createSetting('fileSystemMapping', {}).set({});\n removeSetting(Settings.instance().createSetting('fileMappingEntries', []));\n }\n\n private updateVersionFrom3To4(): void {\n const advancedMode = Settings.instance().createSetting('showHeaSnapshotObjectsHiddenProperties', false);\n moduleSetting('showAdvancedHeapSnapshotProperties').set(advancedMode.get());\n removeSetting(advancedMode);\n }\n\n private updateVersionFrom4To5(): void {\n const settingNames: {\n [x: string]: string,\n } = {\n 'FileSystemViewSidebarWidth': 'fileSystemViewSplitViewState',\n 'elementsSidebarWidth': 'elementsPanelSplitViewState',\n 'StylesPaneSplitRatio': 'stylesPaneSplitViewState',\n 'heapSnapshotRetainersViewSize': 'heapSnapshotSplitViewState',\n 'InspectorView.splitView': 'InspectorView.splitViewState',\n 'InspectorView.screencastSplitView': 'InspectorView.screencastSplitViewState',\n 'Inspector.drawerSplitView': 'Inspector.drawerSplitViewState',\n 'layerDetailsSplitView': 'layerDetailsSplitViewState',\n 'networkSidebarWidth': 'networkPanelSplitViewState',\n 'sourcesSidebarWidth': 'sourcesPanelSplitViewState',\n 'scriptsPanelNavigatorSidebarWidth': 'sourcesPanelNavigatorSplitViewState',\n 'sourcesPanelSplitSidebarRatio': 'sourcesPanelDebuggerSidebarSplitViewState',\n 'timeline-details': 'timelinePanelDetailsSplitViewState',\n 'timeline-split': 'timelinePanelRecorsSplitViewState',\n 'timeline-view': 'timelinePanelTimelineStackSplitViewState',\n 'auditsSidebarWidth': 'auditsPanelSplitViewState',\n 'layersSidebarWidth': 'layersPanelSplitViewState',\n 'profilesSidebarWidth': 'profilesPanelSplitViewState',\n 'resourcesSidebarWidth': 'resourcesPanelSplitViewState',\n };\n const empty = {};\n for (const oldName in settingNames) {\n const newName = settingNames[oldName];\n const oldNameH = oldName + 'H';\n\n let newValue: {}|null = null;\n const oldSetting = Settings.instance().createSetting(oldName, empty);\n if (oldSetting.get() !== empty) {\n newValue = newValue || {};\n // @ts-expect-error\n newValue.vertical = {};\n // @ts-expect-error\n newValue.vertical.size = oldSetting.get();\n removeSetting(oldSetting);\n }\n const oldSettingH = Settings.instance().createSetting(oldNameH, empty);\n if (oldSettingH.get() !== empty) {\n newValue = newValue || {};\n // @ts-expect-error\n newValue.horizontal = {};\n // @ts-expect-error\n newValue.horizontal.size = oldSettingH.get();\n removeSetting(oldSettingH);\n }\n if (newValue) {\n Settings.instance().createSetting(newName, {}).set(newValue);\n }\n }\n }\n\n private updateVersionFrom5To6(): void {\n const settingNames: {\n [x: string]: string,\n } = {\n 'debuggerSidebarHidden': 'sourcesPanelSplitViewState',\n 'navigatorHidden': 'sourcesPanelNavigatorSplitViewState',\n 'WebInspector.Drawer.showOnLoad': 'Inspector.drawerSplitViewState',\n };\n\n for (const oldName in settingNames) {\n const oldSetting = Settings.instance().createSetting(oldName, null);\n if (oldSetting.get() === null) {\n removeSetting(oldSetting);\n continue;\n }\n\n const newName = settingNames[oldName];\n const invert = oldName === 'WebInspector.Drawer.showOnLoad';\n const hidden = oldSetting.get() !== invert;\n removeSetting(oldSetting);\n const showMode = hidden ? 'OnlyMain' : 'Both';\n\n const newSetting = Settings.instance().createSetting(newName, {});\n const newValue = newSetting.get() || {};\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n newValue.vertical = newValue.vertical || {};\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n newValue.vertical.showMode = showMode;\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n newValue.horizontal = newValue.horizontal || {};\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n newValue.horizontal.showMode = showMode;\n newSetting.set(newValue);\n }\n }\n\n private updateVersionFrom6To7(): void {\n const settingNames = {\n 'sourcesPanelNavigatorSplitViewState': 'sourcesPanelNavigatorSplitViewState',\n 'elementsPanelSplitViewState': 'elementsPanelSplitViewState',\n 'stylesPaneSplitViewState': 'stylesPaneSplitViewState',\n 'sourcesPanelDebuggerSidebarSplitViewState': 'sourcesPanelDebuggerSidebarSplitViewState',\n };\n\n const empty = {};\n for (const name in settingNames) {\n const setting =\n Settings.instance().createSetting<{vertical?: {size?: number}, horizontal?: {size?: number}}>(name, empty);\n const value = setting.get();\n if (value === empty) {\n continue;\n }\n // Zero out saved percentage sizes, and they will be restored to defaults.\n if (value.vertical && value.vertical.size && value.vertical.size < 1) {\n value.vertical.size = 0;\n }\n if (value.horizontal && value.horizontal.size && value.horizontal.size < 1) {\n value.horizontal.size = 0;\n }\n setting.set(value);\n }\n }\n\n private updateVersionFrom7To8(): void {\n }\n\n private updateVersionFrom8To9(): void {\n const settingNames = ['skipStackFramesPattern', 'workspaceFolderExcludePattern'];\n\n for (let i = 0; i < settingNames.length; ++i) {\n const setting = Settings.instance().createSetting<string|unknown[]>(settingNames[i], '');\n let value = setting.get();\n if (!value) {\n return;\n }\n if (typeof value === 'string') {\n value = [value];\n }\n for (let j = 0; j < value.length; ++j) {\n if (typeof value[j] === 'string') {\n value[j] = {pattern: value[j]};\n }\n }\n setting.set(value);\n }\n }\n\n private updateVersionFrom9To10(): void {\n // This one is localStorage specific, which is fine.\n if (!window.localStorage) {\n return;\n }\n for (const key in window.localStorage) {\n if (key.startsWith('revision-history')) {\n window.localStorage.removeItem(key);\n }\n }\n }\n\n private updateVersionFrom10To11(): void {\n const oldSettingName = 'customDevicePresets';\n const newSettingName = 'customEmulatedDeviceList';\n const oldSetting = Settings.instance().createSetting<unknown>(oldSettingName, undefined);\n const list = oldSetting.get();\n if (!Array.isArray(list)) {\n return;\n }\n const newList = [];\n for (let i = 0; i < list.length; ++i) {\n const value = list[i];\n const device: {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [x: string]: any,\n } = {};\n device['title'] = value['title'];\n device['type'] = 'unknown';\n device['user-agent'] = value['userAgent'];\n device['capabilities'] = [];\n if (value['touch']) {\n device['capabilities'].push('touch');\n }\n if (value['mobile']) {\n device['capabilities'].push('mobile');\n }\n device['screen'] = {};\n device['screen']['vertical'] = {width: value['width'], height: value['height']};\n device['screen']['horizontal'] = {width: value['height'], height: value['width']};\n device['screen']['device-pixel-ratio'] = value['deviceScaleFactor'];\n device['modes'] = [];\n device['show-by-default'] = true;\n device['show'] = 'Default';\n newList.push(device);\n }\n if (newList.length) {\n Settings.instance().createSetting<unknown[]>(newSettingName, []).set(newList);\n }\n removeSetting(oldSetting);\n }\n\n private updateVersionFrom11To12(): void {\n this.migrateSettingsFromLocalStorage();\n }\n\n private updateVersionFrom12To13(): void {\n this.migrateSettingsFromLocalStorage();\n removeSetting(Settings.instance().createSetting('timelineOverviewMode', ''));\n }\n\n private updateVersionFrom13To14(): void {\n const defaultValue = {'throughput': -1, 'latency': 0};\n Settings.instance().createSetting('networkConditions', defaultValue).set(defaultValue);\n }\n\n private updateVersionFrom14To15(): void {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const setting = Settings.instance().createLocalSetting<any>('workspaceExcludedFolders', {});\n const oldValue = setting.get();\n const newValue: {\n [x: string]: string[],\n } = {};\n for (const fileSystemPath in oldValue) {\n newValue[fileSystemPath] = [];\n for (const entry of oldValue[fileSystemPath]) {\n newValue[fileSystemPath].push(entry.path);\n }\n }\n setting.set(newValue);\n }\n\n private updateVersionFrom15To16(): void {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const setting = Settings.instance().createSetting<any>('InspectorView.panelOrder', {});\n const tabOrders = setting.get();\n for (const key of Object.keys(tabOrders)) {\n tabOrders[key] = (tabOrders[key] + 1) * 10;\n }\n setting.set(tabOrders);\n }\n\n private updateVersionFrom16To17(): void {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const setting = Settings.instance().createSetting<any>('networkConditionsCustomProfiles', []);\n const oldValue = setting.get();\n const newValue = [];\n if (Array.isArray(oldValue)) {\n for (const preset of oldValue) {\n if (typeof preset.title === 'string' && typeof preset.value === 'object' &&\n typeof preset.value.throughput === 'number' && typeof preset.value.latency === 'number') {\n newValue.push({\n title: preset.title,\n value: {download: preset.value.throughput, upload: preset.value.throughput, latency: preset.value.latency},\n });\n }\n }\n }\n setting.set(newValue);\n }\n\n private updateVersionFrom17To18(): void {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const setting = Settings.instance().createLocalSetting<any>('workspaceExcludedFolders', {});\n const oldValue = setting.get();\n const newValue: {\n [x: string]: string,\n } = {};\n for (const oldKey in oldValue) {\n let newKey = oldKey.replace(/\\\\/g, '/');\n if (!newKey.startsWith('file://')) {\n if (newKey.startsWith('/')) {\n newKey = 'file://' + newKey;\n } else {\n newKey = 'file:///' + newKey;\n }\n }\n newValue[newKey] = oldValue[oldKey];\n }\n setting.set(newValue);\n }\n\n private updateVersionFrom18To19(): void {\n const defaultColumns = {status: true, type: true, initiator: true, size: true, time: true};\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const visibleColumnSettings = Settings.instance().createSetting<any>('networkLogColumnsVisibility', defaultColumns);\n const visibleColumns = visibleColumnSettings.get();\n visibleColumns.name = true;\n visibleColumns.timeline = true;\n\n const configs: {\n [x: string]: {\n visible: number,\n },\n } = {};\n for (const columnId in visibleColumns) {\n if (!visibleColumns.hasOwnProperty(columnId)) {\n continue;\n }\n configs[columnId.toLowerCase()] = {visible: visibleColumns[columnId]};\n }\n const newSetting = Settings.instance().createSetting('networkLogColumns', {});\n newSetting.set(configs);\n removeSetting(visibleColumnSettings);\n }\n\n private updateVersionFrom19To20(): void {\n const oldSetting = Settings.instance().createSetting('InspectorView.panelOrder', {});\n const newSetting = Settings.instance().createSetting('panel-tabOrder', {});\n newSetting.set(oldSetting.get());\n removeSetting(oldSetting);\n }\n\n private updateVersionFrom20To21(): void {\n const networkColumns = Settings.instance().createSetting('networkLogColumns', {});\n const columns = (networkColumns.get() as {\n [x: string]: string,\n });\n delete columns['timeline'];\n delete columns['waterfall'];\n networkColumns.set(columns);\n }\n\n private updateVersionFrom21To22(): void {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const breakpointsSetting = Settings.instance().createLocalSetting<any>('breakpoints', []);\n const breakpoints = breakpointsSetting.get();\n for (const breakpoint of breakpoints) {\n breakpoint['url'] = breakpoint['sourceFileId'];\n delete breakpoint['sourceFileId'];\n }\n breakpointsSetting.set(breakpoints);\n }\n\n private updateVersionFrom22To23(): void {\n // This update is no-op.\n }\n\n private updateVersionFrom23To24(): void {\n const oldSetting = Settings.instance().createSetting('searchInContentScripts', false);\n const newSetting = Settings.instance().createSetting('searchInAnonymousAndContentScripts', false);\n newSetting.set(oldSetting.get());\n removeSetting(oldSetting);\n }\n\n private updateVersionFrom24To25(): void {\n const defaultColumns = {status: true, type: true, initiator: true, size: true, time: true};\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const networkLogColumnsSetting = Settings.instance().createSetting<any>('networkLogColumns', defaultColumns);\n const columns = networkLogColumnsSetting.get();\n delete columns.product;\n networkLogColumnsSetting.set(columns);\n }\n\n private updateVersionFrom25To26(): void {\n const oldSetting = Settings.instance().createSetting('messageURLFilters', {});\n const urls = Object.keys(oldSetting.get());\n const textFilter = urls.map(url => `-url:${url}`).join(' ');\n if (textFilter) {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const textFilterSetting = Settings.instance().createSetting<any>('console.textFilter', '');\n const suffix = textFilterSetting.get() ? ` ${textFilterSetting.get()}` : '';\n textFilterSetting.set(`${textFilter}${suffix}`);\n }\n removeSetting(oldSetting);\n }\n\n private updateVersionFrom26To27(): void {\n function renameKeyInObjectSetting(settingName: string, from: string, to: string): void {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const setting = Settings.instance().createSetting<any>(settingName, {});\n const value = setting.get();\n if (from in value) {\n value[to] = value[from];\n delete value[from];\n setting.set(value);\n }\n }\n\n function renameInStringSetting(settingName: string, from: string, to: string): void {\n const setting = Settings.instance().createSetting(settingName, '');\n const value = setting.get();\n if (value === from) {\n setting.set(to);\n }\n }\n\n renameKeyInObjectSetting('panel-tabOrder', 'audits2', 'audits');\n renameKeyInObjectSetting('panel-closeableTabs', 'audits2', 'audits');\n renameInStringSetting('panel-selectedTab', 'audits2', 'audits');\n }\n\n private updateVersionFrom27To28(): void {\n const setting = Settings.instance().createSetting('uiTheme', 'systemPreferred');\n if (setting.get() === 'default') {\n setting.set('systemPreferred');\n }\n }\n\n private updateVersionFrom28To29(): void {\n function renameKeyInObjectSetting(settingName: string, from: string, to: string): void {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const setting = Settings.instance().createSetting<any>(settingName, {});\n const value = setting.get();\n if (from in value) {\n value[to] = value[from];\n delete value[from];\n setting.set(value);\n }\n }\n\n function renameInStringSetting(settingName: string, from: string, to: string): void {\n const setting = Settings.instance().createSetting(settingName, '');\n const value = setting.get();\n if (value === from) {\n setting.set(to);\n }\n }\n\n renameKeyInObjectSetting('panel-tabOrder', 'audits', 'lighthouse');\n renameKeyInObjectSetting('panel-closeableTabs', 'audits', 'lighthouse');\n renameInStringSetting('panel-selectedTab', 'audits', 'lighthouse');\n }\n\n private updateVersionFrom29To30(): void {\n // Create new location agnostic setting\n const closeableTabSetting = Settings.instance().createSetting('closeableTabs', {});\n\n // Read current settings\n const panelCloseableTabSetting = Settings.instance().createSetting('panel-closeableTabs', {});\n const drawerCloseableTabSetting = Settings.instance().createSetting('drawer-view-closeableTabs', {});\n const openTabsInPanel = panelCloseableTabSetting.get();\n const openTabsInDrawer = panelCloseableTabSetting.get();\n\n // Set #value of new setting\n const newValue = Object.assign(openTabsInDrawer, openTabsInPanel);\n closeableTabSetting.set(newValue);\n\n // Remove old settings\n removeSetting(panelCloseableTabSetting);\n removeSetting(drawerCloseableTabSetting);\n }\n\n private updateVersionFrom30To31(): void {\n // Remove recorder_recordings setting that was used for storing recordings\n // by an old recorder experiment.\n const recordingsSetting = Settings.instance().createSetting('recorder_recordings', []);\n removeSetting(recordingsSetting);\n }\n\n updateVersionFrom31To32(): void {\n // Introduce the new 'resourceTypeName' property on stored breakpoints. Prior to\n // this change we synchronized the breakpoint only by URL, but since we don't\n // know on which resource type the given breakpoint was set, we just assume\n // 'script' here to keep things simple.\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const breakpointsSetting = Settings.instance().createLocalSetting<any>('breakpoints', []);\n const breakpoints = breakpointsSetting.get();\n for (const breakpoint of breakpoints) {\n breakpoint['resourceTypeName'] = 'script';\n }\n breakpointsSetting.set(breakpoints);\n }\n\n updateVersionFrom32To33(): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const previouslyViewedFilesSetting = Settings.instance().createLocalSetting<any>('previouslyViewedFiles', []);\n let previouslyViewedFiles = previouslyViewedFilesSetting.get();\n\n // Discard old 'previouslyViewedFiles' items that don't have a 'url' property.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n previouslyViewedFiles = previouslyViewedFiles.filter((previouslyViewedFile: any) => 'url' in previouslyViewedFile);\n\n // Introduce the new 'resourceTypeName' property on previously viewed files.\n // Prior to this change we only keyed them based on the URL, but since we\n // don't know which resource type the given file had, we just assume 'script'\n // here to keep things simple.\n for (const previouslyViewedFile of previouslyViewedFiles) {\n previouslyViewedFile['resourceTypeName'] = 'script';\n }\n\n previouslyViewedFilesSetting.set(previouslyViewedFiles);\n }\n\n updateVersionFrom33To34(): void {\n // Introduces the 'isLogpoint' property on stored breakpoints. This information was\n // previously encoded in the 'condition' itself. This migration leaves the condition\n // alone but ensures that 'isLogpoint' is accurate for already stored breakpoints.\n // This enables us to use the 'isLogpoint' property in code.\n // A separate migration will remove the special encoding from the condition itself\n // once all refactorings are done.\n\n // The prefix/suffix are hardcoded here, since these constants will be removed in\n // the future.\n const logpointPrefix = '/** DEVTOOLS_LOGPOINT */ console.log(';\n const logpointSuffix = ')';\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const breakpointsSetting = Settings.instance().createLocalSetting<any>('breakpoints', []);\n const breakpoints = breakpointsSetting.get();\n for (const breakpoint of breakpoints) {\n const isLogpoint =\n breakpoint.condition.startsWith(logpointPrefix) && breakpoint.condition.endsWith(logpointSuffix);\n breakpoint['isLogpoint'] = isLogpoint;\n }\n breakpointsSetting.set(breakpoints);\n }\n\n updateVersionFrom34To35(): void {\n // Uses the 'isLogpoint' property on stored breakpoints to remove the prefix/suffix\n // from logpoints. This way, we store the entered log point condition as the user\n // entered it.\n\n // The prefix/suffix are hardcoded here, since these constants will be removed in\n // the future.\n const logpointPrefix = '/** DEVTOOLS_LOGPOINT */ console.log(';\n const logpointSuffix = ')';\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const breakpointsSetting = Settings.instance().createLocalSetting<any>('breakpoints', []);\n const breakpoints = breakpointsSetting.get();\n for (const breakpoint of breakpoints) {\n const {condition, isLogpoint} = breakpoint;\n if (isLogpoint) {\n breakpoint.condition = condition.slice(logpointPrefix.length, condition.length - logpointSuffix.length);\n }\n }\n breakpointsSetting.set(breakpoints);\n }\n\n /*\n * Any new migration should be added before this comment.\n *\n * IMPORTANT: Migrations must be idempotent, since they may be applied\n * multiple times! E.g. when renaming a setting one has to check that the\n * a setting with the new name does not yet exist.\n * ----------------------------------------------------------------------- */\n\n private migrateSettingsFromLocalStorage(): void {\n // This step migrates all the settings except for the ones below into the browser profile.\n const localSettings = new Set<string>([\n 'advancedSearchConfig',\n 'breakpoints',\n 'consoleHistory',\n 'domBreakpoints',\n 'eventListenerBreakpoints',\n 'fileSystemMapping',\n 'lastSelectedSourcesSidebarPaneTab',\n 'previouslyViewedFiles',\n 'savedURLs',\n 'watchExpressions',\n 'workspaceExcludedFolders',\n 'xhrBreakpoints',\n ]);\n if (!window.localStorage) {\n return;\n }\n\n for (const key in window.localStorage) {\n if (localSettings.has(key)) {\n continue;\n }\n const value = window.localStorage[key];\n window.localStorage.removeItem(key);\n Settings.instance().globalStorage.set(key, value);\n }\n }\n\n private clearBreakpointsWhenTooMany(breakpointsSetting: Setting<unknown[]>, maxBreakpointsCount: number): void {\n // If there are too many breakpoints in a storage, it is likely due to a recent bug that caused\n // periodical breakpoints duplication leading to inspector slowness.\n if (breakpointsSetting.get().length > maxBreakpointsCount) {\n breakpointsSetting.set([]);\n }\n }\n}\n\n// TODO(crbug.com/1167717): Make this a const enum again\n// eslint-disable-next-line rulesdir/const_enum\nexport enum SettingStorageType {\n /**\n * Synced storage persists settings with the active Chrome profile but also\n * syncs the settings across devices via Chrome Sync.\n */\n Synced = 'Synced',\n /** Global storage persists settings with the active Chrome profile */\n Global = 'Global',\n /** Uses Window.localStorage */\n Local = 'Local',\n /** Session storage dies when DevTools window closes */\n Session = 'Session',\n}\n\nexport function moduleSetting(settingName: string): Setting<unknown> {\n return Settings.instance().moduleSetting(settingName);\n}\n\nexport function settingForTest(settingName: string): Setting<unknown> {\n return Settings.instance().settingForTest(settingName);\n}\n\nexport function detectColorFormat(color: Color): Format {\n let format;\n const formatSetting = Settings.instance().moduleSetting('colorFormat').get();\n if (formatSetting === Format.RGB) {\n format = Format.RGB;\n } else if (formatSetting === Format.HSL) {\n format = Format.HSL;\n } else if (formatSetting === Format.HWB) {\n format = Format.HWB;\n } else if (formatSetting === Format.HEX) {\n format = color.asLegacyColor().detectHEXFormat();\n } else {\n format = color.format();\n }\n\n return format;\n}\n\nexport {\n getLocalizedSettingsCategory,\n getRegisteredSettings,\n maybeRemoveSettingExtension,\n registerSettingExtension,\n RegExpSettingItem,\n SettingCategory,\n SettingExtensionOption,\n SettingRegistration,\n SettingType,\n registerSettingsForTest,\n resetSettings,\n};\n\nexport interface Serializer<I, O> {\n stringify: (value: I) => string;\n parse: (value: string) => O;\n}\n\nexport interface SimpleSettingOption {\n value: string|boolean;\n title: string;\n text?: string;\n raw?: boolean;\n}\n", "/*\n * Copyright (C) 2014 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nexport interface HistoryEntry {\n valid(): boolean;\n\n reveal(): void;\n}\n\nexport class SimpleHistoryManager {\n #entries: HistoryEntry[];\n #activeEntryIndex: number;\n #coalescingReadonly: number;\n readonly #historyDepth: number;\n constructor(historyDepth: number) {\n this.#entries = [];\n this.#activeEntryIndex = -1;\n\n // Lock is used to make sure that reveal() does not\n // make any changes to the history while we are\n // rolling back or rolling over.\n this.#coalescingReadonly = 0;\n this.#historyDepth = historyDepth;\n }\n\n private readOnlyLock(): void {\n ++this.#coalescingReadonly;\n }\n\n private releaseReadOnlyLock(): void {\n --this.#coalescingReadonly;\n }\n\n private getPreviousValidIndex(): number {\n if (this.empty()) {\n return -1;\n }\n\n let revealIndex = this.#activeEntryIndex - 1;\n while (revealIndex >= 0 && !this.#entries[revealIndex].valid()) {\n --revealIndex;\n }\n if (revealIndex < 0) {\n return -1;\n }\n\n return revealIndex;\n }\n\n private getNextValidIndex(): number {\n let revealIndex = this.#activeEntryIndex + 1;\n\n while (revealIndex < this.#entries.length && !this.#entries[revealIndex].valid()) {\n ++revealIndex;\n }\n if (revealIndex >= this.#entries.length) {\n return -1;\n }\n\n return revealIndex;\n }\n\n private readOnly(): boolean {\n return Boolean(this.#coalescingReadonly);\n }\n\n filterOut(filterOutCallback: (arg0: HistoryEntry) => boolean): void {\n if (this.readOnly()) {\n return;\n }\n const filteredEntries = [];\n let removedBeforeActiveEntry = 0;\n for (let i = 0; i < this.#entries.length; ++i) {\n if (!filterOutCallback(this.#entries[i])) {\n filteredEntries.push(this.#entries[i]);\n } else if (i <= this.#activeEntryIndex) {\n ++removedBeforeActiveEntry;\n }\n }\n this.#entries = filteredEntries;\n this.#activeEntryIndex = Math.max(0, this.#activeEntryIndex - removedBeforeActiveEntry);\n }\n\n empty(): boolean {\n return !this.#entries.length;\n }\n\n active(): HistoryEntry|null {\n return this.empty() ? null : this.#entries[this.#activeEntryIndex];\n }\n\n push(entry: HistoryEntry): void {\n if (this.readOnly()) {\n return;\n }\n if (!this.empty()) {\n this.#entries.splice(this.#activeEntryIndex + 1);\n }\n this.#entries.push(entry);\n if (this.#entries.length > this.#historyDepth) {\n this.#entries.shift();\n }\n this.#activeEntryIndex = this.#entries.length - 1;\n }\n\n canRollback(): boolean {\n return this.getPreviousValidIndex() >= 0;\n }\n\n canRollover(): boolean {\n return this.getNextValidIndex() >= 0;\n }\n\n rollback(): boolean {\n const revealIndex = this.getPreviousValidIndex();\n if (revealIndex === -1) {\n return false;\n }\n this.readOnlyLock();\n this.#activeEntryIndex = revealIndex;\n this.#entries[revealIndex].reveal();\n this.releaseReadOnlyLock();\n\n return true;\n }\n\n rollover(): boolean {\n const revealIndex = this.getNextValidIndex();\n if (revealIndex === -1) {\n return false;\n }\n\n this.readOnlyLock();\n this.#activeEntryIndex = revealIndex;\n this.#entries[revealIndex].reveal();\n this.releaseReadOnlyLock();\n\n return true;\n }\n}\n", "// Copyright 2015 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport interface OutputStream {\n write(data: string): Promise<void>;\n close(): Promise<void>;\n}\n\nexport class StringOutputStream implements OutputStream {\n #dataInternal: string;\n constructor() {\n this.#dataInternal = '';\n }\n\n async write(chunk: string): Promise<void> {\n this.#dataInternal += chunk;\n }\n\n async close(): Promise<void> {\n }\n\n data(): string {\n return this.#dataInternal;\n }\n}\n", "// Copyright 2016 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Extracts the element type of an array like, eg:\n// ElementType<number[]> -> number\n// ElementTYpe<string> -> string\ntype ElementType<T extends ArrayLike<unknown>> = T extends ArrayLike<infer E>? E : never;\n\n// Abstracts some generic operations that have different implementions depending\n// on whether we operate on strings or array of things.\ninterface TrieableTrait<T extends ArrayLike<ElementType<T>>> {\n empty(): T;\n append(base: T, appendage: ElementType<T>): T;\n slice(base: T, start: number, end: number): T;\n}\n\nexport class Trie<T extends ArrayLike<ElementType<T>>> {\n #size!: number;\n #root: number;\n #edges!: Map<ElementType<T>, number>[];\n #isWord!: boolean[];\n #wordsInSubtree!: number[];\n #freeNodes!: number[];\n #traitImpl: TrieableTrait<T>;\n\n constructor(traitImpl: TrieableTrait<T>) {\n this.#root = 0;\n this.#traitImpl = traitImpl;\n this.clear();\n }\n\n static newStringTrie(): Trie<string> {\n return new Trie<string>({\n empty: () => '',\n append: (base, appendage) => base + appendage,\n slice: (base, start, end) => base.slice(start, end),\n });\n }\n\n static newArrayTrie<T extends ElementType<T>[]>(): Trie<ElementType<T>[]> {\n return new Trie<ElementType<T>[]>({\n empty: () => [],\n append: (base, appendage) => base.concat([appendage]),\n slice: (base, start, end) => base.slice(start, end),\n });\n }\n\n add(word: T): void {\n let node: number = this.#root;\n ++this.#wordsInSubtree[this.#root];\n for (let i = 0; i < word.length; ++i) {\n const edge = word[i];\n let next = this.#edges[node].get(edge);\n if (!next) {\n if (this.#freeNodes.length) {\n next = (this.#freeNodes.pop() as number);\n } else {\n next = this.#size++;\n this.#isWord.push(false);\n this.#wordsInSubtree.push(0);\n this.#edges.push(new Map());\n }\n this.#edges[node].set(edge, next);\n }\n ++this.#wordsInSubtree[next];\n node = next;\n }\n this.#isWord[node] = true;\n }\n\n remove(word: T): boolean {\n if (!this.has(word)) {\n return false;\n }\n let node: number = this.#root;\n --this.#wordsInSubtree[this.#root];\n for (let i = 0; i < word.length; ++i) {\n const edge = word[i];\n const next = this.#edges[node].get(edge) as number;\n if (!--this.#wordsInSubtree[next]) {\n this.#edges[node].delete(edge);\n this.#freeNodes.push(next);\n }\n node = next;\n }\n this.#isWord[node] = false;\n return true;\n }\n\n has(word: T): boolean {\n let node: number|undefined = this.#root;\n for (let i = 0; i < word.length; ++i) {\n node = this.#edges[node].get(word[i]);\n if (!node) {\n return false;\n }\n }\n return this.#isWord[node];\n }\n\n words(prefix?: T): T[] {\n prefix = prefix ?? this.#traitImpl.empty();\n let node: number|undefined = this.#root;\n for (let i = 0; i < prefix.length; ++i) {\n node = this.#edges[node].get(prefix[i]);\n if (!node) {\n return [];\n }\n }\n const results: T[] = [];\n this.dfs(node, prefix, results);\n return results;\n }\n\n private dfs(node: number, prefix: T, results: T[]): void {\n if (this.#isWord[node]) {\n results.push(prefix);\n }\n const edges = this.#edges[node];\n for (const [edge, node] of edges) {\n const newPrefix = this.#traitImpl.append(prefix, edge);\n this.dfs(node, newPrefix, results);\n }\n }\n\n longestPrefix(word: T, fullWordOnly: boolean): T {\n let node: number|undefined = this.#root;\n let wordIndex = 0;\n for (let i = 0; i < word.length; ++i) {\n node = this.#edges[node].get(word[i]);\n if (!node) {\n break;\n }\n if (!fullWordOnly || this.#isWord[node]) {\n wordIndex = i + 1;\n }\n }\n return this.#traitImpl.slice(word, 0, wordIndex);\n }\n\n clear(): void {\n this.#size = 1;\n this.#root = 0;\n this.#edges = [new Map()];\n this.#isWord = [false];\n this.#wordsInSubtree = [0];\n this.#freeNodes = [];\n }\n}\n", "// Copyright 2014 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport type FinishCallback = (err: Error) => void;\n\nexport class Throttler {\n readonly #timeout: number;\n #isRunningProcess: boolean;\n #asSoonAsPossible: boolean;\n #process: (() => (Promise<unknown>))|null;\n #lastCompleteTime: number;\n #schedulePromise: Promise<unknown>;\n #scheduleResolve!: (value: unknown) => void;\n #processTimeout?: number;\n\n constructor(timeout: number) {\n this.#timeout = timeout;\n this.#isRunningProcess = false;\n this.#asSoonAsPossible = false;\n this.#process = null;\n this.#lastCompleteTime = 0;\n\n this.#schedulePromise = new Promise(fulfill => {\n this.#scheduleResolve = fulfill;\n });\n }\n\n private processCompleted(): void {\n this.#lastCompleteTime = this.getTime();\n this.#isRunningProcess = false;\n if (this.#process) {\n this.innerSchedule(false);\n }\n this.processCompletedForTests();\n }\n\n private processCompletedForTests(): void {\n // For sniffing in tests.\n }\n\n get process(): (() => (Promise<unknown>))|null {\n return this.#process;\n }\n\n private onTimeout(): void {\n this.#processTimeout = undefined;\n this.#asSoonAsPossible = false;\n this.#isRunningProcess = true;\n\n void Promise.resolve()\n .then(this.#process)\n .catch(console.error.bind(console))\n .then(this.processCompleted.bind(this))\n .then(this.#scheduleResolve);\n this.#schedulePromise = new Promise(fulfill => {\n this.#scheduleResolve = fulfill;\n });\n this.#process = null;\n }\n\n schedule(process: () => (Promise<unknown>), asSoonAsPossible?: boolean): Promise<void> {\n // Deliberately skip previous #process.\n this.#process = process;\n\n // Run the first scheduled task instantly.\n const hasScheduledTasks = Boolean(this.#processTimeout) || this.#isRunningProcess;\n const okToFire = this.getTime() - this.#lastCompleteTime > this.#timeout;\n asSoonAsPossible = Boolean(asSoonAsPossible) || (!hasScheduledTasks && okToFire);\n\n const forceTimerUpdate = asSoonAsPossible && !this.#asSoonAsPossible;\n this.#asSoonAsPossible = this.#asSoonAsPossible || asSoonAsPossible;\n\n this.innerSchedule(forceTimerUpdate);\n\n return this.#schedulePromise as Promise<void>;\n }\n\n private innerSchedule(forceTimerUpdate: boolean): void {\n if (this.#isRunningProcess) {\n return;\n }\n if (this.#processTimeout && !forceTimerUpdate) {\n return;\n }\n if (this.#processTimeout) {\n this.clearTimeout(this.#processTimeout);\n }\n\n const timeout = this.#asSoonAsPossible ? 0 : this.#timeout;\n this.#processTimeout = this.setTimeout(this.onTimeout.bind(this), timeout);\n }\n\n private clearTimeout(timeoutId: number): void {\n clearTimeout(timeoutId);\n }\n\n private setTimeout(operation: () => void, timeout: number): number {\n return window.setTimeout(operation, timeout);\n }\n\n private getTime(): number {\n return window.performance.now();\n }\n}\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../platform/platform.js';\n\n/**\n * Metadata to map between bytecode #offsets and line numbers in the\n * disassembly for WebAssembly modules.\n */\n\ninterface FunctionBodyOffset {\n start: number;\n end: number;\n}\nexport class WasmDisassembly {\n readonly lines: string[];\n readonly #offsets: number[];\n #functionBodyOffsets: FunctionBodyOffset[];\n\n constructor(lines: string[], offsets: number[], functionBodyOffsets: FunctionBodyOffset[]) {\n if (lines.length !== offsets.length) {\n throw new Error('Lines and offsets don\\'t match');\n }\n this.lines = lines;\n this.#offsets = offsets;\n this.#functionBodyOffsets = functionBodyOffsets;\n }\n\n get lineNumbers(): number {\n return this.#offsets.length;\n }\n\n bytecodeOffsetToLineNumber(bytecodeOffset: number): number {\n return Platform.ArrayUtilities.upperBound(\n this.#offsets, bytecodeOffset, Platform.ArrayUtilities.DEFAULT_COMPARATOR) -\n 1;\n }\n\n lineNumberToBytecodeOffset(lineNumber: number): number {\n return this.#offsets[lineNumber];\n }\n\n /**\n * returns an iterable enumerating all the non-breakable line numbers in the disassembly\n */\n * nonBreakableLineNumbers(): Iterable<number> {\n let lineNumber = 0;\n let functionIndex = 0;\n while (lineNumber < this.lineNumbers) {\n if (functionIndex < this.#functionBodyOffsets.length) {\n const offset = this.lineNumberToBytecodeOffset(lineNumber);\n if (offset >= this.#functionBodyOffsets[functionIndex].start) {\n lineNumber = this.bytecodeOffsetToLineNumber(this.#functionBodyOffsets[functionIndex++].end) + 1;\n continue;\n }\n }\n yield lineNumber++;\n }\n }\n}\n", "/*\n * Copyright (C) 2014 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nexport class WorkerWrapper {\n readonly #workerPromise: Promise<Worker>;\n #disposed?: boolean;\n\n private constructor(workerLocation: URL) {\n this.#workerPromise = new Promise(fulfill => {\n const worker = new Worker(workerLocation, {type: 'module'});\n worker.onmessage = (event: MessageEvent<unknown>): void => {\n console.assert(event.data === 'workerReady');\n worker.onmessage = null;\n fulfill(worker);\n };\n });\n }\n\n static fromURL(url: URL): WorkerWrapper {\n return new WorkerWrapper(url);\n }\n\n postMessage(message: unknown): void {\n void this.#workerPromise.then(worker => {\n if (!this.#disposed) {\n worker.postMessage(message);\n }\n });\n }\n\n dispose(): void {\n this.#disposed = true;\n void this.#workerPromise.then(worker => worker.terminate());\n }\n\n terminate(): void {\n this.dispose();\n }\n\n set onmessage(listener: (event: MessageEvent) => void) {\n void this.#workerPromise.then(worker => {\n worker.onmessage = listener;\n });\n }\n\n set onerror(listener: (event: Event) => void) {\n void this.#workerPromise.then(worker => {\n worker.onerror = listener;\n });\n }\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\nimport {getNavigationForTraceEvent} from './Trace.js';\n\nexport const millisecondsToMicroseconds = (value: Types.Timing.MilliSeconds): Types.Timing.MicroSeconds =>\n Types.Timing.MicroSeconds(value * 1000);\n\nexport const secondsToMilliseconds = (value: Types.Timing.Seconds): Types.Timing.MilliSeconds =>\n Types.Timing.MilliSeconds(value * 1000);\n\nexport const secondsToMicroseconds = (value: Types.Timing.Seconds): Types.Timing.MicroSeconds =>\n millisecondsToMicroseconds(secondsToMilliseconds(value));\n\nexport const microSecondsToMilliseconds = (value: Types.Timing.MicroSeconds): Types.Timing.MilliSeconds =>\n Types.Timing.MilliSeconds(value / 1000);\n\nexport const microSecondsToSeconds = (value: Types.Timing.MicroSeconds): Types.Timing.Seconds =>\n Types.Timing.Seconds(value / 1000 / 1000);\n\nexport function detectBestTimeUnit(timeInMicroseconds: Types.Timing.MicroSeconds): Types.Timing.TimeUnit {\n if (timeInMicroseconds < 1000) {\n return Types.Timing.TimeUnit.MICROSECONDS;\n }\n\n const timeInMilliseconds = timeInMicroseconds / 1000;\n if (timeInMilliseconds < 1000) {\n return Types.Timing.TimeUnit.MILLISECONDS;\n }\n\n const timeInSeconds = timeInMilliseconds / 1000;\n if (timeInSeconds < 60) {\n return Types.Timing.TimeUnit.SECONDS;\n }\n\n return Types.Timing.TimeUnit.MINUTES;\n}\n\ninterface FormatOptions extends Intl.NumberFormatOptions {\n format?: Types.Timing.TimeUnit;\n}\n\nconst defaultFormatOptions = {\n style: 'unit',\n unit: 'millisecond',\n unitDisplay: 'narrow',\n};\n\n// Create a bunch of common formatters up front, so that we're not creating\n// them repeatedly during rendering.\nconst serialize = (value: {}): string => JSON.stringify(value);\nconst formatterFactory = (key: string|undefined): Intl.NumberFormat => {\n return new Intl.NumberFormat(navigator.language, key ? JSON.parse(key) : {});\n};\nconst formatters = new Map<string, Intl.NumberFormat>();\n\n// Microsecond Formatter.\nPlatform.MapUtilities.getWithDefault(formatters, serialize({style: 'decimal'}), formatterFactory);\n\n// Millisecond Formatter\nPlatform.MapUtilities.getWithDefault(formatters, serialize(defaultFormatOptions), formatterFactory);\n\n// Second Formatter\nPlatform.MapUtilities.getWithDefault(\n formatters, serialize({...defaultFormatOptions, unit: 'second'}), formatterFactory);\n\n// Minute Formatter\nPlatform.MapUtilities.getWithDefault(\n formatters, serialize({...defaultFormatOptions, unit: 'minute'}), formatterFactory);\n\nexport function formatMicrosecondsTime(\n timeInMicroseconds: Types.Timing.MicroSeconds, opts: FormatOptions = {}): string {\n if (!opts.format) {\n opts.format = detectBestTimeUnit(timeInMicroseconds);\n }\n\n const timeInMilliseconds = timeInMicroseconds / 1000;\n const timeInSeconds = timeInMilliseconds / 1000;\n const formatterOpts = {...defaultFormatOptions, ...opts};\n\n switch (opts.format) {\n case Types.Timing.TimeUnit.MICROSECONDS: {\n const formatter =\n Platform.MapUtilities.getWithDefault(formatters, serialize({style: 'decimal'}), formatterFactory);\n return `${formatter.format(timeInMicroseconds)}\u03BCs`;\n }\n\n case Types.Timing.TimeUnit.MILLISECONDS: {\n const formatter = Platform.MapUtilities.getWithDefault(formatters, serialize(formatterOpts), formatterFactory);\n return formatter.format(timeInMilliseconds);\n }\n\n case Types.Timing.TimeUnit.SECONDS: {\n const formatter = Platform.MapUtilities.getWithDefault(\n formatters, serialize({...formatterOpts, unit: 'second'}), formatterFactory);\n return formatter.format(timeInSeconds);\n }\n\n default: {\n // Switch to mins & seconds.\n const minuteFormatter = Platform.MapUtilities.getWithDefault(\n formatters, serialize({...formatterOpts, unit: 'minute'}), formatterFactory);\n const secondFormatter = Platform.MapUtilities.getWithDefault(\n formatters, serialize({...formatterOpts, unit: 'second'}), formatterFactory);\n const timeInMinutes = timeInSeconds / 60;\n const [mins, divider, fraction] = minuteFormatter.formatToParts(timeInMinutes);\n\n let seconds = 0;\n if (divider && fraction) {\n // Convert the fraction value (a string) to the nearest second.\n seconds = Math.round(Number(`0.${fraction.value}`) * 60);\n }\n return `${minuteFormatter.format(Number(mins.value))} ${secondFormatter.format(seconds)}`;\n }\n }\n}\n\nexport function timeStampForEventAdjustedByClosestNavigation(\n event: Types.TraceEvents.TraceEventData,\n traceBounds: Types.Timing.TraceWindow,\n navigationsByNavigationId: Map<string, Types.TraceEvents.TraceEventNavigationStart>,\n navigationsByFrameId: Map<string, Types.TraceEvents.TraceEventNavigationStart[]>,\n ): Types.Timing.MicroSeconds {\n let eventTimeStamp = event.ts - traceBounds.min;\n if (event.args?.data?.navigationId) {\n const navigationForEvent = navigationsByNavigationId.get(event.args.data.navigationId);\n if (navigationForEvent) {\n eventTimeStamp = event.ts - navigationForEvent.ts;\n }\n } else if (event.args?.data?.frame) {\n const navigationForEvent = getNavigationForTraceEvent(event, event.args.data.frame, navigationsByFrameId);\n if (navigationForEvent) {\n eventTimeStamp = event.ts - navigationForEvent.ts;\n }\n }\n return Types.Timing.MicroSeconds(eventTimeStamp);\n}\n\nexport interface EventTimingsData<\n ValueType extends Types.Timing.MicroSeconds|Types.Timing.MilliSeconds|Types.Timing.Seconds,\n> {\n startTime: ValueType;\n endTime: ValueType;\n duration: ValueType;\n selfTime: ValueType;\n}\n\nexport function eventTimingsMicroSeconds(event: Types.TraceEvents.TraceEventData):\n EventTimingsData<Types.Timing.MicroSeconds> {\n return {\n startTime: event.ts,\n endTime: Types.Timing.MicroSeconds(event.ts + (event.dur || Types.Timing.MicroSeconds(0))),\n duration: Types.Timing.MicroSeconds(event.dur || 0),\n // TODO(crbug.com/1434599): Implement selfTime calculation for events\n // from the new engine.\n selfTime: Types.Timing.MicroSeconds(event.dur || 0),\n };\n}\nexport function eventTimingsMilliSeconds(event: Types.TraceEvents.TraceEventData):\n EventTimingsData<Types.Timing.MilliSeconds> {\n const microTimes = eventTimingsMicroSeconds(event);\n return {\n startTime: microSecondsToMilliseconds(microTimes.startTime),\n endTime: microSecondsToMilliseconds(microTimes.endTime),\n duration: microSecondsToMilliseconds(microTimes.duration),\n selfTime: microSecondsToMilliseconds(microTimes.selfTime),\n };\n}\nexport function eventTimingsSeconds(event: Types.TraceEvents.TraceEventData): EventTimingsData<Types.Timing.Seconds> {\n const microTimes = eventTimingsMicroSeconds(event);\n return {\n startTime: microSecondsToSeconds(microTimes.startTime),\n endTime: microSecondsToSeconds(microTimes.endTime),\n duration: microSecondsToSeconds(microTimes.duration),\n selfTime: microSecondsToSeconds(microTimes.selfTime),\n };\n}\n\nexport function traceBoundsMilliseconds(bounds: Types.Timing.TraceWindow): {\n min: Types.Timing.MilliSeconds,\n max: Types.Timing.MilliSeconds,\n range: Types.Timing.MilliSeconds,\n} {\n return {\n min: microSecondsToMilliseconds(bounds.min),\n max: microSecondsToMilliseconds(bounds.max),\n range: microSecondsToMilliseconds(bounds.range),\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Types from '../types/types.js';\nimport * as Common from '../../../core/common/common.js';\nimport * as Platform from '../../../core/platform/platform.js';\n\nexport function extractOriginFromTrace(firstNavigationURL: string): string|null {\n const url = Common.ParsedURL.ParsedURL.fromString(firstNavigationURL);\n if (url) {\n // We do this to save some space in the toolbar - seeing the `www` is less\n // useful than seeing `foo.com` if it's truncated at narrow widths\n if (url.host.startsWith('www.')) {\n return url.host.slice(4);\n }\n return url.host;\n }\n return null;\n}\n\nexport type EventsInThread<T extends Types.TraceEvents.TraceEventData> = Map<Types.TraceEvents.ThreadID, T[]>;\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nexport function addEventToProcessThread<T extends Types.TraceEvents.TraceEventData>(\n event: T,\n eventsInProcessThread: Map<Types.TraceEvents.ProcessID, EventsInThread<T>>,\n ): void {\n const {tid, pid} = event;\n let eventsInThread = eventsInProcessThread.get(pid);\n if (!eventsInThread) {\n eventsInThread = new Map<Types.TraceEvents.ThreadID, T[]>();\n }\n\n let events = eventsInThread.get(tid);\n if (!events) {\n events = [];\n }\n\n events.push(event);\n eventsInThread.set(event.tid, events);\n eventsInProcessThread.set(event.pid, eventsInThread);\n}\n\ntype TimeSpan = {\n ts: Types.Timing.MicroSeconds,\n dur?: Types.Timing.MicroSeconds,\n};\nfunction eventTimeComparator(a: TimeSpan, b: TimeSpan): -1|0|1 {\n const aBeginTime = a.ts;\n const bBeginTime = b.ts;\n if (aBeginTime < bBeginTime) {\n return -1;\n }\n if (aBeginTime > bBeginTime) {\n return 1;\n }\n const aDuration = a.dur ?? 0;\n const bDuration = b.dur ?? 0;\n const aEndTime = aBeginTime + aDuration;\n const bEndTime = bBeginTime + bDuration;\n if (aEndTime > bEndTime) {\n return -1;\n }\n if (aEndTime < bEndTime) {\n return 1;\n }\n return 0;\n}\n/**\n * Sorts all the events in place, in order, by their start time. If they have\n * the same start time, orders them by longest first.\n */\nexport function sortTraceEventsInPlace(events: {ts: Types.Timing.MicroSeconds, dur?: Types.Timing.MicroSeconds}[]):\n void {\n events.sort(eventTimeComparator);\n}\n\n/**\n * Returns an array of ordered events that results after merging the two\n * ordered input arrays.\n */\nexport function mergeEventsInOrder<T extends Types.TraceEvents.TraceEventData>(\n eventsArray1: T[], eventsArray2: T[]): T[] {\n const result = [];\n let i = 0;\n let j = 0;\n while (i < eventsArray1.length && j < eventsArray2.length) {\n const event1 = eventsArray1[i];\n const event2 = eventsArray2[j];\n const compareValue = eventTimeComparator(event1, event2);\n if (compareValue <= 0) {\n result.push(event1);\n i++;\n }\n if (compareValue === 1) {\n result.push(event2);\n j++;\n }\n }\n while (i < eventsArray1.length) {\n result.push(eventsArray1[i++]);\n }\n while (j < eventsArray2.length) {\n result.push(eventsArray2[j++]);\n }\n return result;\n}\n\nexport function getNavigationForTraceEvent(\n event: Types.TraceEvents.TraceEventData,\n eventFrameId: string,\n navigationsByFrameId: Map<string, Types.TraceEvents.TraceEventNavigationStart[]>,\n ): Types.TraceEvents.TraceEventNavigationStart|null {\n const navigations = navigationsByFrameId.get(eventFrameId);\n if (!navigations || eventFrameId === '') {\n // This event's navigation has been filtered out by the meta handler as a noise event\n // or contains an empty frameId.\n return null;\n }\n\n const eventNavigationIndex =\n Platform.ArrayUtilities.nearestIndexFromEnd(navigations, navigation => navigation.ts <= event.ts);\n\n if (eventNavigationIndex === null) {\n // This event's navigation has been filtered out by the meta handler as a noise event.\n return null;\n }\n return navigations[eventNavigationIndex];\n}\n\nexport function extractId(event: Types.TraceEvents.TraceEventNestableAsync): string|undefined {\n return event.id || event.id2?.global || event.id2?.local;\n}\n\nexport function activeURLForFrameAtTime(\n frameId: string, time: Types.Timing.MicroSeconds,\n rendererProcessesByFrame: Map<\n string,\n Map<Types.TraceEvents.ProcessID, {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindow}[]>>):\n string|null {\n const processData = rendererProcessesByFrame.get(frameId);\n if (!processData) {\n return null;\n }\n for (const processes of processData.values()) {\n for (const processInfo of processes) {\n if (processInfo.window.min > time || processInfo.window.max < time) {\n continue;\n }\n return processInfo.frame.url;\n }\n }\n return null;\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Helpers from '../helpers/helpers.js';\n\nimport {type TraceEventHandlerName, HandlerState} from './types.js';\n\nimport {ScoreClassification} from './PageLoadMetricsHandler.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport {data as screenshotsHandlerData} from './ScreenshotsHandler.js';\nimport * as Platform from '../../../core/platform/platform.js';\n\nimport * as Types from '../types/types.js';\n\n// We start with a score of zero and step through all Layout Shift records from\n// all renderers. Each record not only tells us which renderer it is, but also\n// the unweighted and weighted scores. The unweighted score is the score we would\n// get if the renderer were the only one in the viewport. The weighted score, on\n// the other hand, accounts for how much of the viewport that particular render\n// takes up when the shift happened. An ad frame in the corner of the viewport\n// that shifts is considered less disruptive, therefore, than if it were taking\n// up the whole viewport.\n//\n// Next, we step through all the records from all renderers and add the weighted\n// score to a running total across all of the renderers. We create a new \"cluster\"\n// and reset the running total when:\n//\n// 1. We observe a outermost frame navigation, or\n// 2. When there's a gap between records of > 1s, or\n// 3. When there's more than 5 seconds of continuous layout shifting.\n//\n// Note that for it to be Cumulative Layout Shift in the sense described in the\n// documentation we would need to guarantee that we are tracking from navigation\n// to unload. However, we don't make any such guarantees here (since a developer\n// can record and stop when they please), so we support the cluster approach,\n// and we can give them a score, but it is effectively a \"session\" score, a\n// score for the given recording, and almost certainly not the\n// navigation-to-unload CLS score.\n\ninterface LayoutShifts {\n clusters: LayoutShiftCluster[];\n sessionMaxScore: number;\n // The session window which contains the SessionMaxScore\n clsWindowID: number;\n // We use these to calculate root causes for a given LayoutShift\n prePaintEvents: Types.TraceEvents.TraceEventPrePaint[];\n layoutInvalidationEvents: Types.TraceEvents.TraceEventLayoutInvalidation[];\n styleRecalcInvalidationEvents: Types.TraceEvents.TraceEventStyleRecalcInvalidation[];\n scoreRecords: ScoreRecord[];\n}\n\n// This represents the maximum #time we will allow a cluster to go before we\n// reset it.\nexport const MAX_CLUSTER_DURATION = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(5000));\n\n// This represents the maximum #time we will allow between layout shift events\n// before considering it to be the start of a new cluster.\nexport const MAX_SHIFT_TIME_DELTA = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(1000));\n\n// Layout shifts are reported globally to the developer, irrespective of which\n// frame they originated in. However, each process does have its own individual\n// CLS score, so we need to segment by process. This means Layout Shifts from\n// sites with one process (no subframes, or subframes from the same origin)\n// will be reported together. In the case of multiple renderers (frames across\n// different origins), we offer the developer the ability to switch renderer in\n// the UI.\nconst layoutShiftEvents: Types.TraceEvents.TraceEventLayoutShift[] = [];\n\n// These events denote potential node resizings. We store them to link captured\n// layout shifts to the resizing of unsized elements.\nconst layoutInvalidationEvents: Types.TraceEvents.TraceEventLayoutInvalidation[] = [];\nconst styleRecalcInvalidationEvents: Types.TraceEvents.TraceEventStyleRecalcInvalidation[] = [];\n\n// Layout shifts happen during PrePaint as part of the rendering lifecycle.\n// We determine if a LayoutInvalidation event is a potential root cause of a layout\n// shift if the next PrePaint after the LayoutInvalidation is the parent\n// node of such shift.\nconst prePaintEvents: Types.TraceEvents.TraceEventPrePaint[] = [];\n\nlet sessionMaxScore = 0;\n\nlet clsWindowID = -1;\n\nconst clusters: LayoutShiftCluster[] = [];\n\n// Represents a point in time in which a LS score change\n// was recorded.\ntype ScoreRecord = {\n ts: number,\n score: number,\n};\n\n// The complete timeline of LS score changes in a trace.\n// Includes drops to 0 when session windows end.\nconst scoreRecords: ScoreRecord[] = [];\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('LayoutShifts Handler was not reset');\n }\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function reset(): void {\n handlerState = HandlerState.UNINITIALIZED;\n layoutShiftEvents.length = 0;\n layoutInvalidationEvents.length = 0;\n prePaintEvents.length = 0;\n clusters.length = 0;\n sessionMaxScore = 0;\n scoreRecords.length = 0;\n clsWindowID = -1;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Handler is not initialized');\n }\n\n if (Types.TraceEvents.isTraceEventLayoutShift(event) && !event.args.data?.had_recent_input) {\n layoutShiftEvents.push(event);\n return;\n }\n if (Types.TraceEvents.isTraceEventLayoutInvalidation(event)) {\n layoutInvalidationEvents.push(event);\n return;\n }\n if (Types.TraceEvents.isTraceEventStyleRecalcInvalidation(event)) {\n styleRecalcInvalidationEvents.push(event);\n }\n if (Types.TraceEvents.isTraceEventPrePaint(event)) {\n prePaintEvents.push(event);\n return;\n }\n}\n\nfunction traceWindowFromTime(time: Types.Timing.MicroSeconds): Types.Timing.TraceWindow {\n return {\n min: time,\n max: time,\n range: Types.Timing.MicroSeconds(0),\n };\n}\n\nfunction updateTraceWindowMax(traceWindow: Types.Timing.TraceWindow, newMax: Types.Timing.MicroSeconds): void {\n traceWindow.max = newMax;\n traceWindow.range = Types.Timing.MicroSeconds(traceWindow.max - traceWindow.min);\n}\n\nfunction findNextScreenshotSource(timestamp: Types.Timing.MicroSeconds): string|undefined {\n const screenshots = screenshotsHandlerData();\n const screenshotIndex = findNextScreenshotEventIndex(screenshots, timestamp);\n if (!screenshotIndex) {\n return undefined;\n }\n return `data:img/png;base64,${screenshots[screenshotIndex].args.snapshot}`;\n}\n\nexport function findNextScreenshotEventIndex(\n screenshots: Types.TraceEvents.TraceEventSnapshot[], timestamp: Types.Timing.MicroSeconds): number|null {\n return Platform.ArrayUtilities.nearestIndexFromBeginning(screenshots, frame => frame.ts > timestamp);\n}\n\nfunction buildScoreRecords(): void {\n const {traceBounds} = metaHandlerData();\n scoreRecords.push({ts: traceBounds.min, score: 0});\n\n for (const cluster of clusters) {\n let clusterScore = 0;\n if (cluster.events[0].args.data) {\n scoreRecords.push({ts: cluster.clusterWindow.min, score: cluster.events[0].args.data.weighted_score_delta});\n }\n for (let i = 0; i < cluster.events.length; i++) {\n const event = cluster.events[i];\n if (!event.args.data) {\n continue;\n }\n clusterScore += event.args.data.weighted_score_delta;\n scoreRecords.push({ts: event.ts, score: clusterScore});\n }\n scoreRecords.push({ts: cluster.clusterWindow.max, score: 0});\n }\n}\n\nexport async function finalize(): Promise<void> {\n // Ensure the events are sorted by #time ascending.\n layoutShiftEvents.sort((a, b) => a.ts - b.ts);\n prePaintEvents.sort((a, b) => a.ts - b.ts);\n layoutInvalidationEvents.sort((a, b) => a.ts - b.ts);\n\n // Each function transforms the data used by the next, as such the invoke order\n // is important.\n await buildLayoutShiftsClusters();\n buildScoreRecords();\n handlerState = HandlerState.FINALIZED;\n}\nasync function buildLayoutShiftsClusters(): Promise<void> {\n const {navigationsByFrameId, mainFrameId, traceBounds} = metaHandlerData();\n const navigations = navigationsByFrameId.get(mainFrameId) || [];\n if (layoutShiftEvents.length === 0) {\n return;\n }\n let firstShiftTime = layoutShiftEvents[0].ts;\n let lastShiftTime = layoutShiftEvents[0].ts;\n let lastShiftNavigation = null;\n // Now step through each and create clusters.\n // A cluster is equivalent to a session window (see https://web.dev/cls/#what-is-cls).\n // To make the line chart clear, we explicitly demark the limits of each session window\n // by starting the cumulative score of the window at the time of the first layout shift\n // and ending it (dropping the line back to 0) when the window ends according to the\n // thresholds (MAX_CLUSTER_DURATION, MAX_SHIFT_TIME_DELTA).\n for (const event of layoutShiftEvents) {\n // First detect if either the cluster duration or the #time between this and\n // the last shift has been exceeded.\n const clusterDurationExceeded = event.ts - firstShiftTime > MAX_CLUSTER_DURATION;\n const maxTimeDeltaSinceLastShiftExceeded = event.ts - lastShiftTime > MAX_SHIFT_TIME_DELTA;\n\n // Next take a look at navigations. If between this and the last shift we have navigated,\n // note it.\n const currentShiftNavigation = Platform.ArrayUtilities.nearestIndexFromEnd(navigations, nav => nav.ts < event.ts);\n const hasNavigated = lastShiftNavigation !== currentShiftNavigation && currentShiftNavigation !== null;\n\n // If any of the above criteria are met or if we don't have any cluster yet we should\n // start a new one.\n if (clusterDurationExceeded || maxTimeDeltaSinceLastShiftExceeded || hasNavigated || !clusters.length) {\n // The cluster starts #time should be the timestamp of the first layout shift in it.\n const clusterStartTime = event.ts;\n\n // If the last session window ended because the max delta time between shifts\n // was exceeded set the endtime to MAX_SHIFT_TIME_DELTA microseconds after the\n // last shift in the session.\n const endTimeByMaxSessionDuration = clusterDurationExceeded ? firstShiftTime + MAX_CLUSTER_DURATION : Infinity;\n\n // If the last session window ended because the max session duration was\n // surpassed, set the endtime so that the window length = MAX_CLUSTER_DURATION;\n const endTimeByMaxShiftGap = maxTimeDeltaSinceLastShiftExceeded ? lastShiftTime + MAX_SHIFT_TIME_DELTA : Infinity;\n\n // If there was a navigation during the last window, close it at the time\n // of the navigation.\n const endTimeByNavigation = hasNavigated ? navigations[currentShiftNavigation].ts : Infinity;\n\n // End the previous cluster at the time of the first of the criteria above that was met.\n const previousClusterEndTime = Math.min(endTimeByMaxSessionDuration, endTimeByMaxShiftGap, endTimeByNavigation);\n\n // If there is an existing cluster update its closing time.\n if (clusters.length > 0) {\n const currentCluster = clusters[clusters.length - 1];\n updateTraceWindowMax(currentCluster.clusterWindow, Types.Timing.MicroSeconds(previousClusterEndTime));\n }\n\n clusters.push({\n events: [],\n clusterWindow: traceWindowFromTime(clusterStartTime),\n clusterCumulativeScore: 0,\n scoreWindows: {\n good: traceWindowFromTime(clusterStartTime),\n needsImprovement: null,\n bad: null,\n },\n });\n\n firstShiftTime = clusterStartTime;\n }\n\n // Given the above we should have a cluster available, so pick the most\n // recent one and append the shift, bump its score and window values accordingly.\n const currentCluster = clusters[clusters.length - 1];\n const timeFromNavigation = currentShiftNavigation !== null ?\n Types.Timing.MicroSeconds(event.ts - navigations[currentShiftNavigation].ts) :\n undefined;\n\n currentCluster.clusterCumulativeScore += event.args.data ? event.args.data.weighted_score_delta : 0;\n if (!event.args.data) {\n continue;\n }\n const shift: Types.TraceEvents.SyntheticLayoutShift = {\n ...event,\n args: {\n frame: event.args.frame,\n data: {\n ...event.args.data,\n rawEvent: event,\n },\n },\n parsedData: {\n screenshotSource: findNextScreenshotSource(event.ts),\n timeFromNavigation,\n cumulativeWeightedScoreInWindow: currentCluster.clusterCumulativeScore,\n // The score of the session window is temporarily set to 0 just\n // to initialize it. Since we need to get the score of all shifts\n // in the session window to determine its value, its definite\n // value is set when stepping through the built clusters.\n sessionWindowData: {cumulativeWindowScore: 0, id: clusters.length},\n },\n };\n currentCluster.events.push(shift);\n updateTraceWindowMax(currentCluster.clusterWindow, event.ts);\n\n lastShiftTime = event.ts;\n lastShiftNavigation = currentShiftNavigation;\n }\n\n // Now step through each cluster and set up the times at which the value\n // goes from Good, to needs improvement, to Bad. Note that if there is a\n // large jump we may go from Good to Bad without ever creating a Needs\n // Improvement window at all.\n for (const cluster of clusters) {\n let weightedScore = 0;\n let windowID = -1;\n // If this is the last cluster update its window. The cluster duration is determined\n // by the minimum between: time to next navigation, trace end time, time to maximum\n // cluster duration and time to maximum gap between layout shifts.\n if (cluster === clusters[clusters.length - 1]) {\n const clusterEndByMaxDuration = MAX_CLUSTER_DURATION + cluster.clusterWindow.min;\n const clusterEndByMaxGap = cluster.clusterWindow.max + MAX_SHIFT_TIME_DELTA;\n const nextNavigationIndex =\n Platform.ArrayUtilities.nearestIndexFromBeginning(navigations, nav => nav.ts > cluster.clusterWindow.max);\n const nextNavigationTime = nextNavigationIndex ? navigations[nextNavigationIndex].ts : Infinity;\n const clusterEnd = Math.min(clusterEndByMaxDuration, clusterEndByMaxGap, traceBounds.max, nextNavigationTime);\n updateTraceWindowMax(cluster.clusterWindow, Types.Timing.MicroSeconds(clusterEnd));\n }\n for (const shift of cluster.events) {\n weightedScore += shift.args.data ? shift.args.data.weighted_score_delta : 0;\n windowID = shift.parsedData.sessionWindowData.id;\n const ts = shift.ts;\n // Update the the CLS score of this shift's session window now that\n // we have it.\n shift.parsedData.sessionWindowData.cumulativeWindowScore = cluster.clusterCumulativeScore;\n if (weightedScore < LayoutShiftsThreshold.NEEDS_IMPROVEMENT) {\n // Expand the Good window.\n updateTraceWindowMax(cluster.scoreWindows.good, ts);\n } else if (\n weightedScore >= LayoutShiftsThreshold.NEEDS_IMPROVEMENT && weightedScore < LayoutShiftsThreshold.BAD) {\n if (!cluster.scoreWindows.needsImprovement) {\n // Close the Good window, and open the needs improvement window.\n updateTraceWindowMax(cluster.scoreWindows.good, Types.Timing.MicroSeconds(ts - 1));\n cluster.scoreWindows.needsImprovement = traceWindowFromTime(ts);\n }\n\n // Expand the needs improvement window.\n updateTraceWindowMax(cluster.scoreWindows.needsImprovement, ts);\n } else if (weightedScore >= LayoutShiftsThreshold.BAD) {\n if (!cluster.scoreWindows.bad) {\n // We may jump from Good to Bad here, so update whichever window is open.\n if (cluster.scoreWindows.needsImprovement) {\n updateTraceWindowMax(cluster.scoreWindows.needsImprovement, Types.Timing.MicroSeconds(ts - 1));\n } else {\n updateTraceWindowMax(cluster.scoreWindows.good, Types.Timing.MicroSeconds(ts - 1));\n }\n\n cluster.scoreWindows.bad = traceWindowFromTime(shift.ts);\n }\n\n // Expand the Bad window.\n updateTraceWindowMax(cluster.scoreWindows.bad, ts);\n }\n\n // At this point the windows are set by the timestamps of the events, but the\n // next cluster begins at the timestamp of its first event. As such we now\n // need to expand the score window to the end of the cluster, and we do so\n // by using the Bad widow if it's there, or the NI window, or finally the\n // Good window.\n if (cluster.scoreWindows.bad) {\n updateTraceWindowMax(cluster.scoreWindows.bad, cluster.clusterWindow.max);\n } else if (cluster.scoreWindows.needsImprovement) {\n updateTraceWindowMax(cluster.scoreWindows.needsImprovement, cluster.clusterWindow.max);\n } else {\n updateTraceWindowMax(cluster.scoreWindows.good, cluster.clusterWindow.max);\n }\n }\n if (weightedScore > sessionMaxScore) {\n clsWindowID = windowID;\n sessionMaxScore = weightedScore;\n }\n }\n}\n\nexport function data(): LayoutShifts {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Layout Shifts Handler is not finalized');\n }\n\n return {\n clusters: [...clusters],\n sessionMaxScore: sessionMaxScore,\n clsWindowID,\n prePaintEvents: [...prePaintEvents],\n layoutInvalidationEvents: [...layoutInvalidationEvents],\n styleRecalcInvalidationEvents: [],\n scoreRecords: [...scoreRecords],\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Screenshots', 'Meta'];\n}\n\nexport function stateForLayoutShiftScore(score: number): ScoreClassification {\n let state = ScoreClassification.GOOD;\n if (score >= LayoutShiftsThreshold.NEEDS_IMPROVEMENT) {\n state = ScoreClassification.OK;\n }\n\n if (score >= LayoutShiftsThreshold.BAD) {\n state = ScoreClassification.BAD;\n }\n\n return state;\n}\n\nexport interface LayoutShiftCluster {\n clusterWindow: Types.Timing.TraceWindow;\n clusterCumulativeScore: number;\n events: Types.TraceEvents.SyntheticLayoutShift[];\n // For convenience we split apart the cluster into good, NI, and bad windows.\n // Since a cluster may remain in the good window, we mark NI and bad as being\n // possibly null.\n scoreWindows: {\n good: Types.Timing.TraceWindow,\n needsImprovement: Types.Timing.TraceWindow|null,\n bad: Types.Timing.TraceWindow|null,\n };\n}\n\n// Based on https://web.dev/cls/\nexport const enum LayoutShiftsThreshold {\n GOOD = 0,\n NEEDS_IMPROVEMENT = 0.1,\n BAD = 0.25,\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/**\n * This handler stores page load metrics, including web vitals,\n * and exports them in the shape of a map with the following shape:\n * Map(FrameId -> Map(navigationID -> metrics) )\n *\n * It also exports all markers in a trace in an array.\n *\n * Some metrics are taken directly from a page load events (AKA markers) like DCL.\n * Others require processing multiple events to be determined, like CLS and TBT.\n */\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nimport {type TraceEventHandlerName} from './types.js';\n\nimport * as Types from '../types/types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\n\n/**\n * This represents the metric scores for all navigations, for all frames in a trace.\n * Given a frame id, the map points to another map from navigation id to metric scores.\n * The metric scores include the event related to the metric as well as the data regarding\n * the score itself.\n */\nconst metricScoresByFrameId =\n new Map</* Frame id */ string, Map</* navigation id */ string, Map<MetricName, MetricScore>>>();\n\n/**\n * Page load events with no associated duration that happened in the\n * main frame.\n */\nlet allMarkerEvents: Types.TraceEvents.PageLoadEvent[] = [];\n\nexport function reset(): void {\n metricScoresByFrameId.clear();\n pageLoadEventsArray = [];\n allMarkerEvents = [];\n selectedLCPCandidateEvents.clear();\n}\n\nlet pageLoadEventsArray: Types.TraceEvents.PageLoadEvent[] = [];\n\n// Once we've found the LCP events in the trace we want to fetch their DOM Node\n// from the backend. We could do this by parsing through our Map of frame =>\n// navigation => metric, but it's easier to keep a set of LCP events. As we\n// parse the trace, any time we store an LCP candidate as the potential LCP\n// event, we store the event here. If we later find a new candidate in the\n// trace, we store that and delete the prior event. When we've parsed the\n// entire trace this set will contain all the LCP events that were used - e.g.\n// the candidates that were the actual LCP events.\nconst selectedLCPCandidateEvents = new Set<Types.TraceEvents.TraceEventLargestContentfulPaintCandidate>();\n\nexport const MarkerName =\n ['MarkDOMContent', 'MarkLoad', 'firstPaint', 'firstContentfulPaint', 'largestContentfulPaint::Candidate'] as const;\n\nconst markerTypeGuards = [\n Types.TraceEvents.isTraceEventMarkDOMContent,\n Types.TraceEvents.isTraceEventMarkLoad,\n Types.TraceEvents.isTraceEventFirstPaint,\n Types.TraceEvents.isTraceEventFirstContentfulPaint,\n Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate,\n Types.TraceEvents.isTraceEventNavigationStart,\n];\n\ninterface MakerEvent extends Types.TraceEvents.TraceEventData {\n name: typeof MarkerName[number];\n}\n\nexport function isTraceEventMarkerEvent(event: Types.TraceEvents.TraceEventData): event is MakerEvent {\n return markerTypeGuards.some(fn => fn(event));\n}\n\nconst pageLoadEventTypeGuards = [\n ...markerTypeGuards,\n Types.TraceEvents.isTraceEventInteractiveTime,\n];\n\nexport function eventIsPageLoadEvent(event: Types.TraceEvents.TraceEventData):\n event is Types.TraceEvents.PageLoadEvent {\n return pageLoadEventTypeGuards.some(fn => fn(event));\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (!eventIsPageLoadEvent(event)) {\n return;\n }\n pageLoadEventsArray.push(event);\n}\n\nfunction storePageLoadMetricAgainstNavigationId(\n navigation: Types.TraceEvents.TraceEventNavigationStart, event: Types.TraceEvents.PageLoadEvent): void {\n const navigationId = navigation.args.data?.navigationId;\n if (!navigationId) {\n throw new Error('Navigation event unexpectedly had no navigation ID.');\n }\n const frameId = getFrameIdForPageLoadEvent(event);\n const {rendererProcessesByFrame} = metaHandlerData();\n\n // If either of these pieces of data do not exist, the most likely\n // explanation is that the page load metric we found is for a frame/process\n // combo that the MetaHandler discarded. This typically happens if we get a\n // navigation event with an empty URL. Therefore, we will silently return and\n // drop this metric. If we didn't care about the navigation, we certainly do\n // not need to care about metrics for that navigation.\n const rendererProcessesInFrame = rendererProcessesByFrame.get(frameId);\n if (!rendererProcessesInFrame) {\n return;\n }\n const processData = rendererProcessesInFrame.get(event.pid);\n if (!processData) {\n return;\n }\n\n if (Types.TraceEvents.isTraceEventNavigationStart(event)) {\n return;\n }\n\n // We compare the timestamp of the event to determine if it happened during the\n // time window in which its process was considered active.\n const minTime = processData[0].window.min;\n const maxTime = processData.at(-1)?.window.max || 0;\n const eventBelongsToProcess = event.ts >= minTime && event.ts <= maxTime;\n\n if (!eventBelongsToProcess) {\n // If the event occurred outside its process' active time window we ignore it.\n return;\n }\n\n if (Types.TraceEvents.isTraceEventFirstContentfulPaint(event)) {\n const fcpTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const score = Helpers.Timing.formatMicrosecondsTime(fcpTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const classification = scoreClassificationForFirstContentfulPaint(fcpTime);\n const metricScore = {event, score, metricName: MetricName.FCP, classification, navigation};\n storeMetricScore(frameId, navigationId, metricScore);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventFirstPaint(event)) {\n const paintTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const score = Helpers.Timing.formatMicrosecondsTime(paintTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const classification = ScoreClassification.UNCLASSIFIED;\n const metricScore = {event, score, metricName: MetricName.FP, classification, navigation};\n storeMetricScore(frameId, navigationId, metricScore);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventMarkDOMContent(event)) {\n const dclTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const score = Helpers.Timing.formatMicrosecondsTime(dclTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const metricScore = {\n event,\n score,\n metricName: MetricName.DCL,\n classification: scoreClassificationForDOMContentLoaded(dclTime),\n navigation,\n };\n storeMetricScore(frameId, navigationId, metricScore);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventInteractiveTime(event)) {\n const ttiValue = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const ttiScore = Helpers.Timing.formatMicrosecondsTime(ttiValue, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const tti = {\n event,\n score: ttiScore,\n metricName: MetricName.TTI,\n classification: scoreClassificationForTimeToInteractive(ttiValue),\n navigation,\n };\n storeMetricScore(frameId, navigationId, tti);\n\n const tbtValue =\n Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(event.args.args.total_blocking_time_ms));\n const tbtScore = Helpers.Timing.formatMicrosecondsTime(tbtValue, {\n format: Types.Timing.TimeUnit.MILLISECONDS,\n maximumFractionDigits: 2,\n });\n const tbt = {\n event,\n score: tbtScore,\n metricName: MetricName.TBT,\n classification: scoreClassificationForTotalBlockingTime(tbtValue),\n navigation,\n };\n storeMetricScore(frameId, navigationId, tbt);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventMarkLoad(event)) {\n const loadTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const score = Helpers.Timing.formatMicrosecondsTime(loadTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const metricScore = {\n event,\n score,\n metricName: MetricName.L,\n classification: ScoreClassification.UNCLASSIFIED,\n navigation,\n };\n storeMetricScore(frameId, navigationId, metricScore);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(event)) {\n const candidateIndex = event.args.data?.candidateIndex;\n if (!candidateIndex) {\n throw new Error('Largest Contenful Paint unexpectedly had no candidateIndex.');\n }\n const lcpTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const lcpScore = Helpers.Timing.formatMicrosecondsTime(lcpTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const lcp = {\n event,\n score: lcpScore,\n metricName: MetricName.LCP,\n classification: scoreClassificationForLargestContentfulPaint(lcpTime),\n navigation,\n };\n const metricsByNavigation = Platform.MapUtilities.getWithDefault(metricScoresByFrameId, frameId, () => new Map());\n const metrics = Platform.MapUtilities.getWithDefault(metricsByNavigation, navigationId, () => new Map());\n const lastLCPCandidate = metrics.get(MetricName.LCP);\n if (lastLCPCandidate === undefined) {\n selectedLCPCandidateEvents.add(lcp.event);\n storeMetricScore(frameId, navigationId, lcp);\n return;\n }\n const lastLCPCandidateEvent = lastLCPCandidate.event;\n\n if (!Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(lastLCPCandidateEvent)) {\n return;\n }\n const lastCandidateIndex = lastLCPCandidateEvent.args.data?.candidateIndex;\n if (!lastCandidateIndex) {\n // lastCandidateIndex cannot be undefined because we don't store candidates with\n // with an undefined candidateIndex value. This check is only to make TypeScript\n // treat the field as not undefined below.\n return;\n }\n if (lastCandidateIndex < candidateIndex) {\n selectedLCPCandidateEvents.delete(lastLCPCandidateEvent);\n selectedLCPCandidateEvents.add(lcp.event);\n storeMetricScore(frameId, navigationId, lcp);\n }\n return;\n }\n if (Types.TraceEvents.isTraceEventLayoutShift(event)) {\n return;\n }\n return Platform.assertNever(event, `Unexpected event type: ${event}`);\n}\n\nfunction storeMetricScore(frameId: string, navigationId: string, metricScore: MetricScore): void {\n const metricsByNavigation = Platform.MapUtilities.getWithDefault(metricScoresByFrameId, frameId, () => new Map());\n const metrics = Platform.MapUtilities.getWithDefault(metricsByNavigation, navigationId, () => new Map());\n // If an entry with that metric name is present, delete it so that the new entry that\n // will replace it is added at the end of the map. This way we guarantee the map entries\n // are ordered in ASC manner by timestamp.\n metrics.delete(metricScore.metricName);\n metrics.set(metricScore.metricName, metricScore);\n}\n\nexport function getFrameIdForPageLoadEvent(event: Types.TraceEvents.PageLoadEvent): string {\n if (Types.TraceEvents.isTraceEventFirstContentfulPaint(event) ||\n Types.TraceEvents.isTraceEventInteractiveTime(event) ||\n Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(event) ||\n Types.TraceEvents.isTraceEventNavigationStart(event) || Types.TraceEvents.isTraceEventLayoutShift(event) ||\n Types.TraceEvents.isTraceEventFirstPaint(event)) {\n return event.args.frame;\n }\n if (Types.TraceEvents.isTraceEventMarkDOMContent(event) || Types.TraceEvents.isTraceEventMarkLoad(event)) {\n const frameId = event.args.data?.frame;\n if (!frameId) {\n throw new Error('MarkDOMContent unexpectedly had no frame ID.');\n }\n return frameId;\n }\n Platform.assertNever(event, `Unexpected event type: ${event}`);\n}\n\nfunction getNavigationForPageLoadEvent(event: Types.TraceEvents.PageLoadEvent):\n Types.TraceEvents.TraceEventNavigationStart|null {\n if (Types.TraceEvents.isTraceEventFirstContentfulPaint(event) ||\n Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(event) ||\n Types.TraceEvents.isTraceEventFirstPaint(event)) {\n const navigationId = event.args.data?.navigationId;\n if (!navigationId) {\n throw new Error('Trace event unexpectedly had no navigation ID.');\n }\n const {navigationsByNavigationId} = metaHandlerData();\n const navigation = navigationsByNavigationId.get(navigationId);\n\n if (!navigation) {\n // This event's navigation has been filtered out by the meta handler as a noise event.\n return null;\n }\n return navigation;\n }\n\n if (Types.TraceEvents.isTraceEventMarkDOMContent(event) || Types.TraceEvents.isTraceEventInteractiveTime(event) ||\n Types.TraceEvents.isTraceEventLayoutShift(event) || Types.TraceEvents.isTraceEventMarkLoad(event)) {\n const frameId = getFrameIdForPageLoadEvent(event);\n const {navigationsByFrameId} = metaHandlerData();\n return Helpers.Trace.getNavigationForTraceEvent(event, frameId, navigationsByFrameId);\n }\n\n if (Types.TraceEvents.isTraceEventNavigationStart(event)) {\n // We don't want to compute metrics of the navigation relative to itself, so we'll avoid avoid all that.\n return null;\n }\n\n return Platform.assertNever(event, `Unexpected event type: ${event}`);\n}\n\n/**\n * Classifications sourced from\n * https://web.dev/fcp/\n */\nexport function scoreClassificationForFirstContentfulPaint(fcpScoreInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n const FCP_GOOD_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(1.8));\n const FCP_MEDIUM_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(3.0));\n let scoreClassification = ScoreClassification.BAD;\n if (fcpScoreInMicroseconds <= FCP_MEDIUM_TIMING) {\n scoreClassification = ScoreClassification.OK;\n }\n if (fcpScoreInMicroseconds <= FCP_GOOD_TIMING) {\n scoreClassification = ScoreClassification.GOOD;\n }\n return scoreClassification;\n}\n\n/**\n * Classifications sourced from\n * https://web.dev/interactive/#how-lighthouse-determines-your-tti-score\n */\n\nexport function scoreClassificationForTimeToInteractive(ttiTimeInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n const TTI_GOOD_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(3.8));\n const TTI_MEDIUM_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(7.3));\n let scoreClassification = ScoreClassification.BAD;\n if (ttiTimeInMicroseconds <= TTI_MEDIUM_TIMING) {\n scoreClassification = ScoreClassification.OK;\n }\n if (ttiTimeInMicroseconds <= TTI_GOOD_TIMING) {\n scoreClassification = ScoreClassification.GOOD;\n }\n return scoreClassification;\n}\n\n/**\n * Classifications sourced from\n * https://web.dev/lcp/#what-is-lcp\n */\n\nexport function scoreClassificationForLargestContentfulPaint(lcpTimeInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n const LCP_GOOD_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(2.5));\n const LCP_MEDIUM_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(4));\n let scoreClassification = ScoreClassification.BAD;\n if (lcpTimeInMicroseconds <= LCP_MEDIUM_TIMING) {\n scoreClassification = ScoreClassification.OK;\n }\n if (lcpTimeInMicroseconds <= LCP_GOOD_TIMING) {\n scoreClassification = ScoreClassification.GOOD;\n }\n return scoreClassification;\n}\n\n/**\n * DCL does not have a classification.\n */\nexport function scoreClassificationForDOMContentLoaded(_dclTimeInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n return ScoreClassification.UNCLASSIFIED;\n}\n\n/**\n * Classifications sourced from\n * https://web.dev/lighthouse-total-blocking-#time/\n */\n\nexport function scoreClassificationForTotalBlockingTime(tbtTimeInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n const TBT_GOOD_TIMING = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(200));\n const TBT_MEDIUM_TIMING = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(600));\n let scoreClassification = ScoreClassification.BAD;\n if (tbtTimeInMicroseconds <= TBT_MEDIUM_TIMING) {\n scoreClassification = ScoreClassification.OK;\n }\n if (tbtTimeInMicroseconds <= TBT_GOOD_TIMING) {\n scoreClassification = ScoreClassification.GOOD;\n }\n return scoreClassification;\n}\n\n/**\n * Gets all the Largest Contentful Paint scores of all the frames in the\n * trace.\n */\nfunction gatherFinalLCPEvents(): Types.TraceEvents.PageLoadEvent[] {\n const allFinalLCPEvents: Types.TraceEvents.PageLoadEvent[] = [];\n const dataForAllFrames = [...metricScoresByFrameId.values()];\n const dataForAllNavigations = dataForAllFrames.flatMap(frameData => [...frameData.values()]);\n for (let i = 0; i < dataForAllNavigations.length; i++) {\n const navigationData = dataForAllNavigations[i];\n const lcpInNavigation = navigationData.get(MetricName.LCP);\n if (!lcpInNavigation || !lcpInNavigation.event) {\n continue;\n }\n\n allFinalLCPEvents.push(lcpInNavigation.event);\n }\n return allFinalLCPEvents;\n}\n\nexport async function finalize(): Promise<void> {\n pageLoadEventsArray.sort((a, b) => a.ts - b.ts);\n\n for (const pageLoadEvent of pageLoadEventsArray) {\n const navigation = getNavigationForPageLoadEvent(pageLoadEvent);\n if (navigation) {\n // Event's navigation was not filtered out as noise.\n storePageLoadMetricAgainstNavigationId(navigation, pageLoadEvent);\n }\n }\n // NOTE: if you are looking for the TBT calculation, it has temporarily been\n // removed. See crbug.com/1424335 for details.\n const allFinalLCPEvents = gatherFinalLCPEvents();\n const mainFrame = metaHandlerData().mainFrameId;\n // Filter out LCP candidates to use only definitive LCP values\n const allEventsButLCP =\n pageLoadEventsArray.filter(event => !Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(event));\n const markerEvents = [...allFinalLCPEvents, ...allEventsButLCP].filter(isTraceEventMarkerEvent);\n // Filter by main frame and sort.\n allMarkerEvents =\n markerEvents.filter(event => getFrameIdForPageLoadEvent(event) === mainFrame).sort((a, b) => a.ts - b.ts);\n}\n\nexport type PageLoadMetricsData = {\n metricScoresByFrameId: Map<string, Map<string, Map<MetricName, MetricScore>>>,\n allMarkerEvents: Types.TraceEvents.PageLoadEvent[],\n};\n\nexport function data(): PageLoadMetricsData {\n return {\n /**\n * This represents the metric scores for all navigations, for all frames in a trace.\n * Given a frame id, the map points to another map from navigation id to metric scores.\n * The metric scores include the event related to the metric as well as the data regarding\n * the score itself.\n */\n metricScoresByFrameId: new Map(metricScoresByFrameId),\n\n /**\n * Page load events with no associated duration that happened in the\n * main frame.\n */\n allMarkerEvents: [...allMarkerEvents],\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n\nexport const enum ScoreClassification {\n GOOD = 'good',\n OK = 'ok',\n BAD = 'bad',\n // Some metrics (such as DOMContentLoaded) don't have a Good/OK/Bad classification, hence this additional entry.\n UNCLASSIFIED = 'unclassified',\n}\n\nexport const enum MetricName {\n // First Contentful Paint\n FCP = 'FCP',\n // First Paint\n FP = 'FP',\n // MarkLoad\n L = 'L',\n LCP = 'LCP',\n // Mark DOM Content\n DCL = 'DCL',\n // Time To Interactive\n TTI = 'TTI',\n // Total Blocking Time\n TBT = 'TBT',\n // Cumulative Layout Shift\n CLS = 'CLS',\n}\n\nexport interface MetricScore {\n score: string;\n metricName: MetricName;\n classification: ScoreClassification;\n event?: Types.TraceEvents.PageLoadEvent;\n // The last navigation that occured before this metric score.\n navigation?: Types.TraceEvents.TraceEventNavigationStart;\n estimated?: boolean;\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport {type TraceEventHandlerName} from './types.js';\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nconst eventsInProcessThread =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventSnapshot[]>>();\n\nlet snapshots: Types.TraceEvents.TraceEventSnapshot[] = [];\nexport function reset(): void {\n eventsInProcessThread.clear();\n snapshots.length = 0;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (event.ph !== Types.TraceEvents.Phase.OBJECT_SNAPSHOT || event.name !== 'Screenshot') {\n return;\n }\n\n Helpers.Trace.addEventToProcessThread(event, eventsInProcessThread);\n}\n\nexport async function finalize(): Promise<void> {\n const {browserProcessId, browserThreadId} = metaHandlerData();\n const browserThreads = eventsInProcessThread.get(browserProcessId);\n if (browserThreads) {\n snapshots = browserThreads.get(browserThreadId) || [];\n }\n}\n\nexport function data(): Types.TraceEvents.TraceEventSnapshot[] {\n return [...snapshots];\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\nexport interface MemoryData {\n updateCountersByProcess: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventUpdateCounters[]>;\n}\n\nconst updateCountersByProcess: MemoryData['updateCountersByProcess'] = new Map();\n\nexport function reset(): void {\n updateCountersByProcess.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventUpdateCounters(event)) {\n const countersForProcess = Platform.MapUtilities.getWithDefault(updateCountersByProcess, event.pid, () => []);\n countersForProcess.push(event);\n updateCountersByProcess.set(event.pid, countersForProcess);\n }\n}\n\nexport function data(): MemoryData {\n return {updateCountersByProcess: new Map(updateCountersByProcess)};\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport {type TraceEventHandlerName, HandlerState} from './types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nimport * as Types from '../types/types.js';\n\nconst MILLISECONDS_TO_MICROSECONDS = 1000;\nconst SECONDS_TO_MICROSECONDS = 1000000;\n\n// Network requests from traces are actually formed of 5 trace records.\n// This handler tracks all trace records based on the request ID, and\n// then creates a new synthetic trace event for those network requests.\n//\n// This interface, then, defines the shape of the object we intend to\n// keep for each request in the trace. In the finalize we will convert\n// these 5 types of trace records to a synthetic complete event that\n// represents a composite of these trace records.\ninterface TraceEventsForNetworkRequest {\n changePriority?: Types.TraceEvents.TraceEventResourceChangePriority;\n willSendRequests?: Types.TraceEvents.TraceEventResourceWillSendRequest[];\n sendRequests?: Types.TraceEvents.TraceEventResourceSendRequest[];\n receiveResponse?: Types.TraceEvents.TraceEventResourceReceiveResponse;\n resourceFinish?: Types.TraceEvents.TraceEventResourceFinish;\n receivedData?: Types.TraceEvents.TraceEventResourceReceivedData[];\n resourceMarkAsCached?: Types.TraceEvents.TraceEventResourceMarkAsCached;\n}\n\ninterface NetworkRequestData {\n byOrigin: Map<string, {\n renderBlocking: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n nonRenderBlocking: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n all: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n }>;\n byTime: Types.TraceEvents.TraceEventSyntheticNetworkRequest[];\n}\n\nconst requestMap = new Map<string, TraceEventsForNetworkRequest>();\nconst requestsByOrigin = new Map<string, {\n renderBlocking: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n nonRenderBlocking: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n all: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n}>();\nconst requestsByTime: Types.TraceEvents.TraceEventSyntheticNetworkRequest[] = [];\n\nfunction storeTraceEventWithRequestId<K extends keyof TraceEventsForNetworkRequest>(\n requestId: string, key: K, value: TraceEventsForNetworkRequest[K]): void {\n if (!requestMap.has(requestId)) {\n requestMap.set(requestId, {});\n }\n\n const traceEvents = requestMap.get(requestId);\n if (!traceEvents) {\n throw new Error(`Unable to locate trace events for request ID ${requestId}`);\n }\n\n if (Array.isArray(traceEvents[key])) {\n const target = traceEvents[key] as Types.TraceEvents.TraceEventData[];\n const values = value as Types.TraceEvents.TraceEventData[];\n target.push(...values);\n } else {\n traceEvents[key] = value;\n }\n}\n\nfunction firstPositiveValueInList(entries: number[]): number {\n for (const entry of entries) {\n if (entry > 0) {\n return entry;\n }\n }\n\n // In the event we don't find a positive value, we return 0 so as to\n // be a mathematical noop. It's typically not correct to return \u2013 say \u2013\n // a -1 here because it would affect the calculation of stats below.\n return 0;\n}\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n requestsByOrigin.clear();\n requestMap.clear();\n requestsByTime.length = 0;\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Network Request handler is not initialized');\n }\n\n if (Types.TraceEvents.isTraceEventResourceChangePriority(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'changePriority', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceWillSendRequest(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'willSendRequests', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceSendRequest(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'sendRequests', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceReceiveResponse(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'receiveResponse', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceReceivedData(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'receivedData', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceFinish(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'resourceFinish', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceMarkAsCached(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'resourceMarkAsCached', event);\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Network Request handler is not initialized');\n }\n\n const {rendererProcessesByFrame} = metaHandlerData();\n for (const [requestId, request] of requestMap.entries()) {\n // If we have an incomplete set of events here, we choose to drop the network\n // request rather than attempt to synthesize the missing data.\n if (!request.sendRequests || !request.receiveResponse) {\n continue;\n }\n\n // In the data we may get multiple willSendRequests and sendRequests, which\n // will indicate that there are redirects for a given (sub)resource. In the\n // case of a navigation, e.g., example.com/ we will get willSendRequests,\n // and we should use these to calculate time spent in redirects.\n // In the case of sub-resources, however, e.g., example.com/foo.js we will\n // *only* get sendRequests, and we use these instead of willSendRequests\n // to detect the time in redirects. We always use the sendRequest for the\n // url, priority etc since it contains those values, but we use the\n // willSendRequest (if it exists) to calculate the timestamp and durations\n // of redirects.\n const redirects: Types.TraceEvents.TraceEventSyntheticNetworkRedirect[] = [];\n for (let i = 0; i < request.sendRequests.length - 1; i++) {\n const sendRequest = request.sendRequests[i];\n const nextSendRequest = request.sendRequests[i + 1];\n\n // Use the willSendRequests as the source for redirects if possible.\n // We default to those of the sendRequests, however, since willSendRequest\n // is not guaranteed to be present in the data for every request.\n let ts = sendRequest.ts;\n let dur = Types.Timing.MicroSeconds(nextSendRequest.ts - sendRequest.ts);\n if (request.willSendRequests && request.willSendRequests[i] && request.willSendRequests[i + 1]) {\n const willSendRequest = request.willSendRequests[i];\n const nextWillSendRequest = request.willSendRequests[i + 1];\n ts = willSendRequest.ts;\n dur = Types.Timing.MicroSeconds(nextWillSendRequest.ts - willSendRequest.ts);\n }\n\n redirects.push({\n url: sendRequest.args.data.url,\n priority: sendRequest.args.data.priority,\n requestMethod: sendRequest.args.data.requestMethod,\n ts,\n dur,\n });\n }\n\n // If a ResourceFinish event with an encoded data length is received,\n // then the resource was not cached; it was fetched before it was\n // requested, e.g. because it was pushed in this navigation.\n const isPushedResource = request.resourceFinish?.args.data.encodedDataLength !== 0;\n // This works around crbug.com/998397, which reports pushed resources, and resources served by a service worker as disk cached.\n const isDiskCached = request.receiveResponse.args.data.fromCache &&\n !request.receiveResponse.args.data.fromServiceWorker && !isPushedResource;\n // If the request contains a resourceMarkAsCached event, it was served from memory cache.\n const isMemoryCached = request.resourceMarkAsCached !== undefined;\n\n // The timing data returned is from the original (uncached) request, which\n // means that if we leave the above network record data as-is when the\n // request came from either the disk cache or memory cache, our calculations\n // will be incorrect.\n //\n // Here we add a flag so when we calculate the timestamps of the various\n // events, we can overwrite them.\n // These timestamps may not be perfect (indeed they don't always match\n // the Network CDP domain exactly, which is likely an artifact of the way\n // the data is routed on the backend), but they're the closest we have.\n const isCached = isMemoryCached || isDiskCached;\n\n const timing = request.receiveResponse.args.data.timing;\n // If a non-cached request has no |timing| indicates data URLs, we ignore it.\n if (!timing && !isCached) {\n continue;\n }\n\n const firstSendRequest = request.sendRequests[0];\n const finalSendRequest = request.sendRequests[request.sendRequests.length - 1];\n\n const initialPriority = finalSendRequest.args.data.priority;\n let finalPriority = initialPriority;\n if (request.changePriority) {\n finalPriority = request.changePriority.args.data.priority;\n }\n\n // Start time\n // =======================\n // The time where the request started, which is either the first willSendRequest\n // event if there is one, or, if there is not, the sendRequest.\n const startTime = (request.willSendRequests && request.willSendRequests.length) ?\n Types.Timing.MicroSeconds(request.willSendRequests[0].ts) :\n Types.Timing.MicroSeconds(firstSendRequest.ts);\n\n // End redirect time\n // =======================\n // It's possible that when we start requesting data we will receive redirections.\n // Here we note the time of the *last* willSendRequest / sendRequest event,\n // which is used later on in the calculations for time queueing etc.\n const endRedirectTime = (request.willSendRequests && request.willSendRequests.length) ?\n Types.Timing.MicroSeconds(request.willSendRequests[request.willSendRequests.length - 1].ts) :\n Types.Timing.MicroSeconds(finalSendRequest.ts);\n\n // Finish time and end time\n // =======================\n // The finish time and the end time are subtly different.\n // - Finish time: records the point at which the network stack stopped receiving the data\n // - End time: the timestamp of the finish event itself (if one exists)\n //\n // The end time, then, will be slightly after the finish time.\n const endTime = request.resourceFinish ? request.resourceFinish.ts : endRedirectTime;\n const finishTime = request.resourceFinish?.args.data.finishTime ?\n Types.Timing.MicroSeconds(request.resourceFinish.args.data.finishTime * SECONDS_TO_MICROSECONDS) :\n Types.Timing.MicroSeconds(endTime);\n\n // Network duration\n // =======================\n // Time spent on the network.\n const networkDuration = isCached ? Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((finishTime || endRedirectTime) - endRedirectTime);\n\n // Processing duration\n // =======================\n // Time spent from start to end.\n const processingDuration = Types.Timing.MicroSeconds(endTime - (finishTime || endTime));\n\n // Redirection duration\n // =======================\n // Time between the first willSendRequest / sendRequest and last. This we place in *front* of the\n // queueing, since the queueing time that we know about from the trace data is only the last request,\n // i.e., the one that occurs after all the redirects.\n const redirectionDuration = Types.Timing.MicroSeconds(endRedirectTime - startTime);\n\n // Queueing\n // =======================\n // The amount of time queueing is the time between the request's start time to the requestTime\n // arg recorded in the receiveResponse event. In the cases where the recorded start time is larger\n // that the requestTime we set queueing time to zero.\n const queueing = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds(Platform.NumberUtilities.clamp(\n (timing.requestTime * SECONDS_TO_MICROSECONDS - endRedirectTime), 0, Number.MAX_VALUE));\n\n // Stalled\n // =======================\n // If the request is cached, the amount of time stalled is the time between the start time and\n // receiving a response.\n // Otherwise it is whichever positive number comes first from the following timing info:\n // DNS start, Connection start, Send Start, or the time duration between our start time and\n // receiving a response.\n const stalled = isCached ? Types.Timing.MicroSeconds(request.receiveResponse.ts - startTime) :\n Types.Timing.MicroSeconds(firstPositiveValueInList([\n timing.dnsStart * MILLISECONDS_TO_MICROSECONDS,\n timing.connectStart * MILLISECONDS_TO_MICROSECONDS,\n timing.sendStart * MILLISECONDS_TO_MICROSECONDS,\n (request.receiveResponse.ts - endRedirectTime),\n ]));\n\n // Sending HTTP request\n // =======================\n // Time when the HTTP request is sent.\n const sendStartTime = isCached ?\n startTime :\n Types.Timing.MicroSeconds(\n timing.requestTime * SECONDS_TO_MICROSECONDS + timing.sendStart * MILLISECONDS_TO_MICROSECONDS);\n\n // Waiting\n // =======================\n // Time from when the send finished going to when the headers were received.\n const waiting = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.receiveHeadersEnd - timing.sendEnd) * MILLISECONDS_TO_MICROSECONDS);\n\n // Download\n // =======================\n // Time from receipt of headers to the finish time.\n const downloadStart = isCached ?\n startTime :\n Types.Timing.MicroSeconds(\n timing.requestTime * SECONDS_TO_MICROSECONDS + timing.receiveHeadersEnd * MILLISECONDS_TO_MICROSECONDS);\n const download = isCached ? Types.Timing.MicroSeconds(endTime - request.receiveResponse.ts) :\n Types.Timing.MicroSeconds(((finishTime || downloadStart) - downloadStart));\n\n const totalTime = Types.Timing.MicroSeconds(networkDuration + processingDuration);\n\n // Collect a few values from the timing info.\n // If the Network request is cached, we zero out them.\n const dnsLookup = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.dnsEnd - timing.dnsStart) * MILLISECONDS_TO_MICROSECONDS);\n const ssl = isCached ? Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.sslEnd - timing.sslStart) * MILLISECONDS_TO_MICROSECONDS);\n const proxyNegotiation = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.proxyEnd - timing.proxyStart) * MILLISECONDS_TO_MICROSECONDS);\n const requestSent = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.sendEnd - timing.sendStart) * MILLISECONDS_TO_MICROSECONDS);\n const initialConnection = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.connectEnd - timing.connectStart) * MILLISECONDS_TO_MICROSECONDS);\n\n // Finally get some of the general data from the trace events.\n const {frame, url, renderBlocking} = finalSendRequest.args.data;\n const {encodedDataLength, decodedBodyLength} =\n request.resourceFinish ? request.resourceFinish.args.data : {encodedDataLength: 0, decodedBodyLength: 0};\n const {host, protocol, pathname, search} = new URL(url);\n const isHttps = protocol === 'https:';\n const requestingFrameUrl =\n Helpers.Trace.activeURLForFrameAtTime(frame, finalSendRequest.ts, rendererProcessesByFrame) || '';\n\n // Construct a synthetic trace event for this network request.\n const networkEvent: Types.TraceEvents.TraceEventSyntheticNetworkRequest = {\n args: {\n data: {\n // All data we create from trace events should be added to |syntheticData|.\n syntheticData: {\n dnsLookup,\n download,\n downloadStart,\n finishTime,\n initialConnection,\n isDiskCached,\n isHttps,\n isMemoryCached,\n isPushedResource,\n networkDuration,\n processingDuration,\n proxyNegotiation,\n queueing,\n redirectionDuration,\n requestSent,\n sendStartTime,\n ssl,\n stalled,\n totalTime,\n waiting,\n },\n // All fields below are from TraceEventsForNetworkRequest.\n decodedBodyLength,\n encodedDataLength,\n frame,\n fromServiceWorker: request.receiveResponse.args.data.fromServiceWorker,\n host,\n mimeType: request.receiveResponse.args.data.mimeType,\n pathname,\n priority: finalPriority,\n initialPriority,\n protocol,\n redirects,\n // In the event the property isn't set, assume non-blocking.\n renderBlocking: renderBlocking ? renderBlocking : 'non_blocking',\n requestId,\n requestingFrameUrl,\n requestMethod: finalSendRequest.args.data.requestMethod,\n search,\n statusCode: request.receiveResponse.args.data.statusCode,\n stackTrace: finalSendRequest.args.data.stackTrace,\n timing,\n url,\n },\n },\n cat: 'loading',\n name: 'SyntheticNetworkRequest',\n ph: Types.TraceEvents.Phase.COMPLETE,\n dur: Types.Timing.MicroSeconds(endTime - startTime),\n tdur: Types.Timing.MicroSeconds(endTime - startTime),\n ts: Types.Timing.MicroSeconds(startTime),\n tts: Types.Timing.MicroSeconds(startTime),\n pid: finalSendRequest.pid,\n tid: finalSendRequest.tid,\n };\n\n const requests = Platform.MapUtilities.getWithDefault(requestsByOrigin, host, () => {\n return {\n renderBlocking: [],\n nonRenderBlocking: [],\n all: [],\n };\n });\n\n // For ease of rendering we sometimes want to differentiate between\n // render-blocking and non-render-blocking, so we divide the data here.\n if (networkEvent.args.data.renderBlocking === 'non_blocking') {\n requests.nonRenderBlocking.push(networkEvent);\n } else {\n requests.renderBlocking.push(networkEvent);\n }\n\n // However, there are also times where we just want to loop through all\n // the captured requests, so here we store all of them together.\n requests.all.push(networkEvent);\n requestsByTime.push(networkEvent);\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): NetworkRequestData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Network Request handler is not finalized');\n }\n\n return {\n byOrigin: new Map(requestsByOrigin),\n byTime: [...requestsByTime],\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\n// This handler serves two purposes. It generates a list of events that are\n// used to show user clicks in the timeline. It is also used to gather\n// EventTimings into Interactions, which we use to show interactions and\n// highlight long interactions to the user, along with INP.\n\n// We don't need to know which process / thread these events occurred in,\n// because they are effectively global, so we just track all that we find.\nconst allEvents: Types.TraceEvents.TraceEventEventTiming[] = [];\n\nexport const LONG_INTERACTION_THRESHOLD = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(200));\n\nexport interface UserInteractionsData {\n /** All the user events we found in the trace */\n allEvents: readonly Types.TraceEvents.TraceEventEventTiming[];\n /** All the interaction events we found in the trace that had an\n * interactionId and a duration > 0\n **/\n interactionEvents: readonly Types.TraceEvents.SyntheticInteractionEvent[];\n /** If the user rapidly generates interaction events (think typing into a\n * text box), in the UI we only really want to show the user the longest\n * interaction in that set.\n * For example picture interactions like this:\n * ===[interaction A]==========\n * =[interaction B]======\n * =[interaction C]=\n *\n * These events all end at the same time, and so in this instance we only want\n * to show the first interaction A on the timeline, as that is the longest one\n * and the one the developer should be focusing on. So this array of events is\n * all the interaction events filtered down, removing any nested interactions\n * entirely.\n **/\n interactionEventsWithNoNesting: readonly Types.TraceEvents.SyntheticInteractionEvent[];\n // The longest duration interaction event. Can be null if the trace has no interaction events.\n longestInteractionEvent: Readonly<Types.TraceEvents.SyntheticInteractionEvent>|null;\n // All interactions that went over the interaction threshold (200ms, see https://web.dev/inp/)\n interactionsOverThreshold: Readonly<Set<Types.TraceEvents.SyntheticInteractionEvent>>;\n}\n\nlet longestInteractionEvent: Types.TraceEvents.SyntheticInteractionEvent|null = null;\n\nconst interactionEvents: Types.TraceEvents.SyntheticInteractionEvent[] = [];\nconst interactionEventsWithNoNesting: Types.TraceEvents.SyntheticInteractionEvent[] = [];\nconst eventTimingEndEventsById = new Map<string, Types.TraceEvents.TraceEventEventTimingEnd>();\nconst eventTimingStartEventsForInteractions: Types.TraceEvents.TraceEventEventTimingBegin[] = [];\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n allEvents.length = 0;\n interactionEvents.length = 0;\n eventTimingStartEventsForInteractions.length = 0;\n eventTimingEndEventsById.clear();\n interactionEventsWithNoNesting.length = 0;\n longestInteractionEvent = null;\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Handler is not initialized');\n }\n\n if (!Types.TraceEvents.isTraceEventEventTiming(event)) {\n return;\n }\n\n if (Types.TraceEvents.isTraceEventEventTimingEnd(event)) {\n // Store the end event; for each start event that is an interaction, we need the matching end event to calculate the duration correctly.\n eventTimingEndEventsById.set(event.id, event);\n }\n\n allEvents.push(event);\n\n // From this point on we want to find events that represent interactions.\n // These events are always start events - those are the ones that contain all\n // the metadata about the interaction.\n if (!event.args.data || !Types.TraceEvents.isTraceEventEventTimingStart(event)) {\n return;\n }\n const {duration, interactionId} = event.args.data;\n // We exclude events for the sake of interactions if:\n // 1. They have no duration.\n // 2. They have no interactionId\n // 3. They have an interactionId of 0: this indicates that it's not an\n // interaction that we care about because it hasn't had its own interactionId\n // set (0 is the default on the backend).\n // See: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/timing/responsiveness_metrics.cc;l=133;drc=40c209a9c365ebb9f16fb99dfe78c7fe768b9594\n\n if (duration < 1 || interactionId === undefined || interactionId === 0) {\n return;\n }\n\n // Store the start event. In the finalize() function we will pair this with\n // its end event and create the synthetic interaction event.\n eventTimingStartEventsForInteractions.push(event);\n}\n\n/**\n * See https://web.dev/better-responsiveness-metric/#interaction-types for the\n * table that defines these sets.\n **/\nconst pointerEventTypes = new Set([\n 'pointerdown',\n 'touchstart',\n 'pointerup',\n 'touchend',\n 'mousedown',\n 'mouseup',\n 'click',\n]);\n\nconst keyboardEventTypes = new Set([\n 'keydown',\n 'keypress',\n 'keyup',\n]);\n\nexport type InteractionCategory = 'KEYBOARD'|'POINTER'|'OTHER';\nexport function categoryOfInteraction(interaction: Types.TraceEvents.SyntheticInteractionEvent): InteractionCategory {\n if (pointerEventTypes.has(interaction.type)) {\n return 'POINTER';\n }\n if (keyboardEventTypes.has(interaction.type)) {\n return 'KEYBOARD';\n }\n\n return 'OTHER';\n}\n\n/**\n * We define a set of interactions as nested where:\n * 1. Their end times align.\n * 2. The longest interaction's start time is earlier than all other\n * interactions with the same end time.\n * 3. The interactions are of the same category [each interaction is either\n * categorised as keyboard, or pointer.]\n *\n * =============A=[pointerup]=\n * ====B=[pointerdown]=\n * ===C=[pointerdown]==\n * ===D=[pointerup]===\n *\n * In this example, B, C and D are all nested and therefore should not be\n * returned from this function.\n *\n * However, in this example we would only consider B nested (under A) and D\n * nested (under C). A and C both stay because they are of different types.\n * ========A=[keydown]====\n * =======B=[keyup]=====\n * ====C=[pointerdown]=\n * =D=[pointerup]=\n **/\nexport function removeNestedInteractions(interactions: readonly Types.TraceEvents.SyntheticInteractionEvent[]):\n readonly Types.TraceEvents.SyntheticInteractionEvent[] {\n /**\n * Because we nest events only that are in the same category, we store the\n * longest event for a given end time by category.\n **/\n const earliestEventForEndTimePerCategory:\n Record<InteractionCategory, Map<Types.Timing.MicroSeconds, Types.TraceEvents.SyntheticInteractionEvent>> = {\n POINTER: new Map(),\n KEYBOARD: new Map(),\n OTHER: new Map(),\n };\n\n function storeEventIfEarliestForCategoryAndEndTime(interaction: Types.TraceEvents.SyntheticInteractionEvent): void {\n const category = categoryOfInteraction(interaction);\n const mapToUse = earliestEventForEndTimePerCategory[category];\n const endTime = Types.Timing.MicroSeconds(interaction.ts + interaction.dur);\n\n const earliestCurrentEvent = mapToUse.get(endTime);\n if (!earliestCurrentEvent) {\n mapToUse.set(endTime, interaction);\n return;\n }\n if (interaction.ts < earliestCurrentEvent.ts) {\n mapToUse.set(endTime, interaction);\n }\n }\n\n for (const interaction of interactions) {\n storeEventIfEarliestForCategoryAndEndTime(interaction);\n }\n\n // Combine all the events that we have kept from all the per-category event\n // maps back into an array and sort them by timestamp.\n const keptEvents = Object.values(earliestEventForEndTimePerCategory)\n .flatMap(eventsByEndTime => Array.from(eventsByEndTime.values()));\n keptEvents.sort((eventA, eventB) => {\n return eventA.ts - eventB.ts;\n });\n return keptEvents;\n}\n\nexport async function finalize(): Promise<void> {\n // For each interaction start event, find the async end event by the ID, and then create the Synthetic Interaction event.\n for (const interactionStartEvent of eventTimingStartEventsForInteractions) {\n const endEvent = eventTimingEndEventsById.get(interactionStartEvent.id);\n if (!endEvent) {\n // If we cannot find an end event, bail and drop this event.\n continue;\n }\n if (!interactionStartEvent.args.data?.type || !interactionStartEvent.args.data?.interactionId) {\n // A valid interaction event that we care about has to have a type (e.g.\n // pointerdown, keyup).\n //\n // We also need to ensure it has an interactionId. We already checked\n // this in the handleEvent() function, but we do it here also to satisfy\n // TypeScript.\n continue;\n }\n\n const interactionEvent: Types.TraceEvents.SyntheticInteractionEvent = {\n // Use the start event to define the common fields.\n cat: interactionStartEvent.cat,\n name: interactionStartEvent.name,\n pid: interactionStartEvent.pid,\n tid: interactionStartEvent.tid,\n ph: interactionStartEvent.ph,\n args: {\n data: {\n beginEvent: interactionStartEvent,\n endEvent: endEvent,\n },\n },\n ts: interactionStartEvent.ts,\n dur: Types.Timing.MicroSeconds(endEvent.ts - interactionStartEvent.ts),\n type: interactionStartEvent.args.data.type,\n interactionId: interactionStartEvent.args.data.interactionId,\n };\n if (!longestInteractionEvent || longestInteractionEvent.dur < interactionEvent.dur) {\n longestInteractionEvent = interactionEvent;\n }\n interactionEvents.push(interactionEvent);\n }\n\n handlerState = HandlerState.FINALIZED;\n interactionEventsWithNoNesting.push(...removeNestedInteractions(interactionEvents));\n}\n\nexport function data(): UserInteractionsData {\n return {\n allEvents: [...allEvents],\n interactionEvents: [...interactionEvents],\n interactionEventsWithNoNesting: [...interactionEventsWithNoNesting],\n longestInteractionEvent,\n interactionsOverThreshold: new Set(interactionEvents.filter(event => {\n return event.dur > LONG_INTERACTION_THRESHOLD;\n })),\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\n/**\n * IMPORTANT!\n * See UserTimings.md in this directory for some handy documentation on\n * UserTimings and the trace events we parse currently.\n **/\nconst syntheticEvents: Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[] = [];\nconst performanceMeasureEvents: (Types.TraceEvents.TraceEventPerformanceMeasureBegin|\n Types.TraceEvents.TraceEventPerformanceMeasureEnd)[] = [];\nconst performanceMarkEvents: Types.TraceEvents.TraceEventPerformanceMark[] = [];\n\nconst consoleTimings: (Types.TraceEvents.TraceEventConsoleTimeBegin|Types.TraceEvents.TraceEventConsoleTimeEnd)[] = [];\n\nconst timestampEvents: Types.TraceEvents.TraceEventTimeStamp[] = [];\n\nexport interface UserTimingsData {\n /**\n * Events triggered with the performance.measure() API.\n * https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure\n */\n performanceMeasures: readonly Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[];\n /**\n * Events triggered with the performance.mark() API.\n * https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark\n */\n performanceMarks: readonly Types.TraceEvents.TraceEventPerformanceMark[];\n /**\n * Events triggered with the console.time(), console.timeEnd() and\n * console.timeLog() API.\n * https://developer.mozilla.org/en-US/docs/Web/API/console/time\n */\n consoleTimings: readonly Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[];\n /**\n * Events triggered with the console.timeStamp() API\n * https://developer.mozilla.org/en-US/docs/Web/API/console/timeStamp\n */\n timestampEvents: readonly Types.TraceEvents.TraceEventTimeStamp[];\n}\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n syntheticEvents.length = 0;\n performanceMeasureEvents.length = 0;\n performanceMarkEvents.length = 0;\n consoleTimings.length = 0;\n timestampEvents.length = 0;\n handlerState = HandlerState.INITIALIZED;\n}\n\nconst resourceTimingNames = [\n 'workerStart',\n 'redirectStart',\n 'redirectEnd',\n 'fetchStart',\n 'domainLookupStart',\n 'domainLookupEnd',\n 'connectStart',\n 'connectEnd',\n 'secureConnectionStart',\n 'requestStart',\n 'responseStart',\n 'responseEnd',\n];\nconst navTimingNames = [\n 'navigationStart',\n 'unloadEventStart',\n 'unloadEventEnd',\n 'redirectStart',\n 'redirectEnd',\n 'fetchStart',\n 'commitNavigationEnd',\n 'domainLookupStart',\n 'domainLookupEnd',\n 'connectStart',\n 'connectEnd',\n 'secureConnectionStart',\n 'requestStart',\n 'responseStart',\n 'responseEnd',\n 'domLoading',\n 'domInteractive',\n 'domContentLoadedEventStart',\n 'domContentLoadedEventEnd',\n 'domComplete',\n 'loadEventStart',\n 'loadEventEnd',\n];\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('UserTimings handler is not initialized');\n }\n\n // These are events dispatched under the blink.user_timing category\n // but that the user didn't add. Filter them out so that they do not\n // Appear in the timings track (they still appear in the main thread\n // flame chart).\n const ignoredNames = [...resourceTimingNames, ...navTimingNames];\n if (ignoredNames.includes(event.name)) {\n return;\n }\n\n if (Types.TraceEvents.isTraceEventPerformanceMeasure(event)) {\n performanceMeasureEvents.push(event);\n return;\n }\n if (Types.TraceEvents.isTraceEventPerformanceMark(event)) {\n performanceMarkEvents.push(event);\n }\n if (Types.TraceEvents.isTraceEventConsoleTime(event)) {\n consoleTimings.push(event);\n }\n if (Types.TraceEvents.isTraceEventTimeStamp(event)) {\n timestampEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('UserTimings handler is not initialized');\n }\n\n const matchedEvents: Map<string, {\n begin: Types.TraceEvents.TraceEventNestableAsyncBegin | null,\n end: Types.TraceEvents.TraceEventNestableAsyncEnd | null,\n }> = new Map();\n\n for (const event of [...performanceMeasureEvents, ...consoleTimings]) {\n const id = Helpers.Trace.extractId(event);\n if (id === undefined) {\n continue;\n }\n // Create a synthetic id to prevent collisions across categories.\n // Console timings can be dispatched with the same id, so use the\n // event name as well to generate unique ids.\n const syntheticId = `${event.cat}:${id}:${event.name}`;\n const otherEventsWithID = Platform.MapUtilities.getWithDefault(matchedEvents, syntheticId, () => {\n return {begin: null, end: null};\n });\n const isStartEvent = event.ph === Types.TraceEvents.Phase.ASYNC_NESTABLE_START;\n const isEndEvent = event.ph === Types.TraceEvents.Phase.ASYNC_NESTABLE_END;\n\n if (isStartEvent) {\n otherEventsWithID.begin = event;\n } else if (isEndEvent) {\n otherEventsWithID.end = event;\n }\n }\n\n for (const [id, eventsPair] of matchedEvents.entries()) {\n if (!eventsPair.begin || !eventsPair.end) {\n // This should never happen, the backend only creates the events once it\n // has them both, so we should never get into this state.\n // If we do, something is very wrong, so let's just drop that problematic event.\n continue;\n }\n\n const event: Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent = {\n cat: eventsPair.end.cat,\n ph: eventsPair.end.ph,\n pid: eventsPair.end.pid,\n tid: eventsPair.end.tid,\n id,\n // Both events have the same name, so it doesn't matter which we pick to\n // use as the description\n name: eventsPair.begin.name,\n dur: Types.Timing.MicroSeconds(eventsPair.end.ts - eventsPair.begin.ts),\n ts: eventsPair.begin.ts,\n args: {\n data: {\n beginEvent: eventsPair.begin,\n endEvent: eventsPair.end,\n },\n },\n };\n\n if (event.dur < 0) {\n // Avoid any pairs that have created a negative duration; this is bad\n // trace data and we should just ignore them.\n continue;\n }\n syntheticEvents.push(event);\n }\n syntheticEvents.sort((a, b) => a.ts - b.ts);\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): UserTimingsData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('UserTimings handler is not finalized');\n }\n\n return {\n performanceMeasures: syntheticEvents.filter(Types.TraceEvents.isTraceEventPerformanceMeasure),\n consoleTimings: syntheticEvents.filter(Types.TraceEvents.isTraceEventConsoleTime),\n performanceMarks: [...performanceMarkEvents],\n timestampEvents: [...timestampEvents],\n };\n}\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nexport interface WarningsData {\n // Tracks warnings keyed by the event.\n perEvent: Map<Types.TraceEvents.TraceEventData, Warning[]>;\n // The same data in reverse: for each type of warning, track the events.\n // Useful if we need to enumerate issues by type of issue\n perWarning: Map<Warning, Types.TraceEvents.TraceEventData[]>;\n}\n\nexport type Warning = 'LONG_TASK'|'IDLE_CALLBACK_OVER_TIME'|'FORCED_LAYOUT'|'FORCED_STYLE';\n\nconst warningsPerEvent: WarningsData['perEvent'] = new Map();\nconst eventsPerWarning: WarningsData['perWarning'] = new Map();\n\nconst FORCED_LAYOUT_AND_STYLES_THRESHOLD = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(10));\n\nexport function reset(): void {\n warningsPerEvent.clear();\n eventsPerWarning.clear();\n}\n\nfunction storeWarning(event: Types.TraceEvents.TraceEventData, warning: Warning): void {\n const existingWarnings = Platform.MapUtilities.getWithDefault(warningsPerEvent, event, () => []);\n existingWarnings.push(warning);\n warningsPerEvent.set(event, existingWarnings);\n\n const existingEvents = Platform.MapUtilities.getWithDefault(eventsPerWarning, warning, () => []);\n existingEvents.push(event);\n eventsPerWarning.set(warning, existingEvents);\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (event.name === Types.TraceEvents.KnownEventName.RunTask) {\n const longTaskThreshold = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(50));\n const {duration} = Helpers.Timing.eventTimingsMicroSeconds(event);\n if (duration > longTaskThreshold) {\n storeWarning(event, 'LONG_TASK');\n }\n return;\n }\n\n if (Types.TraceEvents.isTraceEventFireIdleCallback(event)) {\n const {duration} = Helpers.Timing.eventTimingsMilliSeconds(event);\n if (duration > event.args.data.allottedMilliseconds) {\n storeWarning(event, 'IDLE_CALLBACK_OVER_TIME');\n }\n return;\n }\n\n if (event.name === Types.TraceEvents.KnownEventName.Layout) {\n if (event.dur && event.dur >= FORCED_LAYOUT_AND_STYLES_THRESHOLD) {\n storeWarning(event, 'FORCED_LAYOUT');\n }\n return;\n }\n\n if (event.name === Types.TraceEvents.KnownEventName.RecalculateStyles ||\n event.name === Types.TraceEvents.KnownEventName.UpdateLayoutTree) {\n if (event.dur && event.dur >= FORCED_LAYOUT_AND_STYLES_THRESHOLD) {\n storeWarning(event, 'FORCED_STYLE');\n }\n return;\n }\n}\n\nexport function data(): WarningsData {\n return {\n perEvent: new Map(warningsPerEvent),\n perWarning: new Map(eventsPerWarning),\n };\n}\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\n\nexport interface WorkersData {\n workerSessionIdEvents: readonly Types.TraceEvents.TraceEventTracingSessionIdForWorker[];\n}\n\nconst sessionIdEvents: Types.TraceEvents.TraceEventTracingSessionIdForWorker[] = [];\n\nexport function reset(): void {\n sessionIdEvents.length = 0;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventTracingSessionIdForWorker(event)) {\n sessionIdEvents.push(event);\n }\n}\n\nexport function data(): WorkersData {\n return {\n workerSessionIdEvents: [...sessionIdEvents],\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as Animations from './AnimationHandler.js';\nexport * as GPU from './GPUHandler.js';\nexport * as LargestImagePaint from './LargestImagePaintHandler.js';\nexport * as LargestTextPaint from './LargestTextPaintHandler.js';\nexport * as LayoutShifts from './LayoutShiftsHandler.js';\nexport * as Memory from './MemoryHandler.js';\nexport * as Meta from './MetaHandler.js';\nexport * as NetworkRequests from './NetworkRequestsHandler.js';\nexport * as PageLoadMetrics from './PageLoadMetricsHandler.js';\nexport * as Renderer from './RendererHandler.js';\nexport * as Samples from './SamplesHandler.js';\nexport * as Screenshots from './ScreenshotsHandler.js';\nexport * as UserInteractions from './UserInteractionsHandler.js';\nexport * as UserTimings from './UserTimingsHandler.js';\nexport * as Warnings from './WarningsHandler.js';\nexport * as Workers from './WorkersHandler.js';\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\nimport type * as Protocol from '../../../generated/protocol.js';\n/**\n * If the LCP resource was an image, and that image was fetched over the\n * network, we want to be able to find the network request in order to construct\n * the critical path for an LCP image.\n * Within the trace file there are `LargestImagePaint::Candidate` events.\n * Within their data object, they contain a `DOMNodeId` property, which maps to\n * the DOM Node ID for that image.\n *\n * This id maps exactly to the `data.nodeId` property that a\n * `LargestContentfulPaint::Candidate` will have. So, when we find an image\n * paint candidate, we can store it, keying it on the node ID.\n * Then, when it comes to finding the network request for an LCP image, we can\n *\n * use the nodeId from the LCP candidate to find the image candidate. That image\n * candidate also contains a `imageUrl` property, which will have the full URL\n * to the image.\n **/\nconst imageByDOMNodeId = new Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestImagePaintCandidate>();\n\nexport function reset(): void {\n imageByDOMNodeId.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (!Types.TraceEvents.isTraceEventLargestImagePaintCandidate(event)) {\n return;\n }\n\n if (!event.args.data) {\n return;\n }\n\n imageByDOMNodeId.set(event.args.data.DOMNodeId, event);\n}\n\nexport function data(): Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestImagePaintCandidate> {\n return new Map(imageByDOMNodeId);\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Protocol from '../../../generated/protocol.js';\nimport * as Types from '../types/types.js';\n/**\n * A trace file will contain all the text paints that were candidates for the\n * LargestTextPaint. If an LCP event is text, it will point to one of these\n * candidates, so we store them by their DOM Node ID.\n **/\nconst textPaintByDOMNodeId =\n new Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestTextPaintCandidate>();\n\nexport function reset(): void {\n textPaintByDOMNodeId.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (!Types.TraceEvents.isTraceEventLargestTextPaintCandidate(event)) {\n return;\n }\n\n if (!event.args.data) {\n return;\n }\n\n textPaintByDOMNodeId.set(event.args.data.DOMNodeId, event);\n}\n\nexport function data(): Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestTextPaintCandidate> {\n return new Map(textPaintByDOMNodeId);\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {data as metaHandlerData, type FrameProcessData} from './MetaHandler.js';\nimport {data as samplesHandlerData} from './SamplesHandler.js';\nimport {HandlerState, type TraceEventHandlerName} from './types.js';\n\n/**\n * This handler builds the hierarchy of trace events and profile calls\n * on each thread on each process.\n *\n * Throughout the code, trace events and profile calls are referred to\n * as \"entries\", but note they are different types of data. Trace events\n * come directly from the backend and it's the type the engine commonly\n * refers to. Profile calls on the other hand are built in the frontend,\n * and, for compatibility purposes, typed as an extension to the trace\n * event type.\n */\n\nconst processes = new Map<Types.TraceEvents.ProcessID, RendererProcess>();\n\n// We track the compositor tile worker thread name events so that at the end we\n// can return these keyed by the process ID. These are used in the frontend to\n// show the user the rasterization thread(s) on the main frame as tracks.\nconst compositorTileWorkers = Array<{\n pid: Types.TraceEvents.ProcessID,\n tid: Types.TraceEvents.ThreadID,\n}>();\nconst entryToNode = new Map<RendererEntry, RendererEntryNode>();\nconst allRendererEvents: Types.TraceEvents.TraceEventRendererEvent[] = [];\nlet nodeIdCount = 0;\nconst makeRendererEntrytNodeId = (): RendererEntryNodeId => (++nodeIdCount) as RendererEntryNodeId;\nconst completeEventStack: (Types.TraceEvents.TraceEventSyntheticCompleteEvent)[] = [];\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst makeRendererProcess = (): RendererProcess => ({\n url: null,\n isOnMainFrame: false,\n threads: new Map(),\n});\n\nconst makeRendererThread = (): RendererThread => ({\n name: null,\n entries: [],\n});\n\nconst makeEmptyRendererTree = (): RendererTree => ({\n nodes: new Map(),\n roots: new Set(),\n maxDepth: 0,\n});\n\nconst makeEmptyRendererEventNode = (entry: RendererEntry, id: RendererEntryNodeId): RendererEntryNode => ({\n entry,\n id,\n parentId: null,\n childrenIds: new Set(),\n depth: 0,\n});\n\nconst getOrCreateRendererProcess =\n (processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, pid: Types.TraceEvents.ProcessID):\n RendererProcess => {\n return Platform.MapUtilities.getWithDefault(processes, pid, makeRendererProcess);\n };\n\nconst getOrCreateRendererThread = (process: RendererProcess, tid: Types.TraceEvents.ThreadID): RendererThread => {\n return Platform.MapUtilities.getWithDefault(process.threads, tid, makeRendererThread);\n};\n\nexport function reset(): void {\n processes.clear();\n entryToNode.clear();\n allRendererEvents.length = 0;\n completeEventStack.length = 0;\n compositorTileWorkers.length = 0;\n nodeIdCount = -1;\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Renderer Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Renderer Handler is not initialized');\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name?.startsWith('CompositorTileWorker')) {\n compositorTileWorkers.push({\n pid: event.pid,\n tid: event.tid,\n });\n }\n\n if (Types.TraceEvents.isTraceEventBegin(event) || Types.TraceEvents.isTraceEventEnd(event)) {\n const process = getOrCreateRendererProcess(processes, event.pid);\n const thread = getOrCreateRendererThread(process, event.tid);\n const completeEvent = makeCompleteEvent(event);\n if (!completeEvent) {\n return;\n }\n thread.entries.push(completeEvent);\n allRendererEvents.push(completeEvent);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventInstant(event) || Types.TraceEvents.isTraceEventComplete(event)) {\n const process = getOrCreateRendererProcess(processes, event.pid);\n const thread = getOrCreateRendererThread(process, event.tid);\n thread.entries.push(event);\n allRendererEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Renderer Handler is not initialized');\n }\n\n const {mainFrameId, rendererProcessesByFrame, threadsInProcess} = metaHandlerData();\n assignMeta(processes, mainFrameId, rendererProcessesByFrame, threadsInProcess);\n sanitizeProcesses(processes);\n buildHierarchy(processes);\n sanitizeThreads(processes);\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): RendererHandlerData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Renderer Handler is not finalized');\n }\n\n return {\n processes: new Map(processes),\n compositorTileWorkers: new Map(gatherCompositorThreads()),\n entryToNode: new Map(entryToNode),\n allRendererEvents: [...allRendererEvents],\n };\n}\n\nfunction gatherCompositorThreads(): Map<Types.TraceEvents.ProcessID, Types.TraceEvents.ThreadID[]> {\n const threadsByProcess = new Map<Types.TraceEvents.ProcessID, Types.TraceEvents.ThreadID[]>();\n for (const worker of compositorTileWorkers) {\n const byProcess = threadsByProcess.get(worker.pid) || [];\n byProcess.push(worker.tid);\n threadsByProcess.set(worker.pid, byProcess);\n }\n return threadsByProcess;\n}\n\n/**\n * Steps through all the renderer processes we've located so far in the meta\n * handler, obtaining their URL, checking whether they are the main frame, and\n * collecting each one of their threads' name. This meta handler's data is\n * assigned to the renderer handler's data.\n */\nexport function assignMeta(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, mainFrameId: string,\n rendererProcessesByFrame: FrameProcessData,\n threadsInProcess:\n Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>):\n void {\n assignOrigin(processes, rendererProcessesByFrame);\n assignIsMainFrame(processes, mainFrameId, rendererProcessesByFrame);\n assignThreadName(processes, rendererProcessesByFrame, threadsInProcess);\n}\n\n/**\n * Assigns origins to all threads in all processes.\n * @see assignMeta\n */\nexport function assignOrigin(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, rendererProcessesByFrame: FrameProcessData): void {\n for (const renderProcessesByPid of rendererProcessesByFrame.values()) {\n for (const [pid, processWindows] of renderProcessesByPid) {\n for (const processInfo of processWindows.flat()) {\n const process = getOrCreateRendererProcess(processes, pid);\n // Sometimes a single process is responsible with rendering multiple\n // frames at the same time. For example, see https://crbug.com/1334563.\n // When this happens, we'd still like to assign a single url per process\n // so: 1) use the first frame rendered by this process as the url source\n // and 2) if the last url is \"about:blank\", use the next frame's url,\n // data from about:blank is irrelevant.\n if (process.url === null || process.url === 'about:blank') {\n // If we are here, it's because we care about this process and the URL. But before we store\n // it, we check if it is a valid URL by trying to create a URL object. If it isn't, we won't\n // set it, and this process will be filtered out later.\n try {\n new URL(processInfo.frame.url);\n process.url = processInfo.frame.url;\n } catch (e) {\n process.url = null;\n }\n }\n }\n }\n }\n}\n\n/**\n * Assigns whether or not a thread is the main frame to all threads in all processes.\n * @see assignMeta\n */\nexport function assignIsMainFrame(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, mainFrameId: string,\n rendererProcessesByFrame: FrameProcessData): void {\n for (const [frameId, renderProcessesByPid] of rendererProcessesByFrame) {\n for (const [pid] of renderProcessesByPid) {\n const process = getOrCreateRendererProcess(processes, pid);\n // We have this go in one direction; once a renderer has been flagged as\n // being on the main frame, we don't unset it to false if were to show up\n // in a subframe. Equally, if we already saw this renderer in a subframe,\n // but it becomes the main frame, the flag would get updated.\n if (frameId === mainFrameId) {\n process.isOnMainFrame = true;\n }\n }\n }\n}\n\n/**\n * Assigns the thread name to all threads in all processes.\n * @see assignMeta\n */\nexport function assignThreadName(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, rendererProcessesByFrame: FrameProcessData,\n threadsInProcess:\n Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>):\n void {\n for (const [, renderProcessesByPid] of rendererProcessesByFrame) {\n for (const [pid] of renderProcessesByPid) {\n const process = getOrCreateRendererProcess(processes, pid);\n for (const [tid, threadInfo] of threadsInProcess.get(pid) ?? []) {\n const thread = getOrCreateRendererThread(process, tid);\n thread.name = threadInfo?.args.name ?? `${tid}`;\n }\n }\n }\n}\n\n/**\n * Removes unneeded trace data opportunistically stored while handling events.\n * This currently does the following:\n * - Deletes processes with an unkonwn origin.\n */\nexport function sanitizeProcesses(processes: Map<Types.TraceEvents.ProcessID, RendererProcess>): void {\n for (const [pid, process] of processes) {\n // If the process had no url, or if it had a malformed url that could not be\n // parsed for some reason, or if it's an \"about:\" origin, delete it.\n // This is done because we don't really care about processes for which we\n // can't provide actionable insights to the user (e.g. about:blank pages).\n if (process.url === null) {\n processes.delete(pid);\n continue;\n }\n const asUrl = new URL(process.url);\n if (asUrl.protocol === 'about:') {\n processes.delete(pid);\n }\n }\n}\n\n/**\n * Removes unneeded trace data opportunistically stored while handling events.\n * This currently does the following:\n * - Deletes threads with no roots.\n */\nexport function sanitizeThreads(processes: Map<Types.TraceEvents.ProcessID, RendererProcess>): void {\n for (const [, process] of processes) {\n for (const [tid, thread] of process.threads) {\n // If the thread has no roots, delete it. Otherwise, there's going to\n // be space taken, even though nothing is rendered in the track manager.\n if (!thread.tree?.roots.size) {\n process.threads.delete(tid);\n }\n }\n }\n}\n\n/**\n * Creates a hierarchical structure from the trace events. Each thread in each\n * process will contribute to their own individual hierarchy.\n *\n * The trace data comes in as a contiguous array of events, against which we\n * make a couple of assumptions:\n *\n * 1. Events are temporally-ordered in terms of start time (though they're\n * not necessarily ordered as such in the data stream).\n * 2. If event B's start and end times are within event A's time boundaries\n * we assume that A is the parent of B.\n *\n * Therefore we expect to reformulate something like:\n *\n * [ Task A ][ Task B ][ Task C ][ Task D ][ Task E ]\n *\n * Into something hierarchically-arranged like below:\n *\n * |------------- Task A -------------||-- Task E --|\n * |-- Task B --||-- Task D --|\n * |- Task C -|\n */\nexport function buildHierarchy(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>,\n options?: {filter: {has: (name: Types.TraceEvents.KnownEventName) => boolean}}): void {\n for (const [pid, process] of processes) {\n for (const [tid, thread] of process.threads) {\n if (!thread.entries.length) {\n thread.tree = makeEmptyRendererTree();\n continue;\n }\n // Step 1. Massage the data.\n Helpers.Trace.sortTraceEventsInPlace(thread.entries);\n // Step 2. Inject profile calls from samples\n const cpuProfile = samplesHandlerData().profilesInProcess.get(pid)?.get(tid)?.parsedProfile;\n const samplesIntegrator = cpuProfile && new Helpers.SamplesIntegrator.SamplesIntegrator(cpuProfile, pid, tid);\n const profileCalls = samplesIntegrator?.buildProfileCalls(thread.entries);\n if (profileCalls) {\n thread.entries = Helpers.Trace.mergeEventsInOrder(thread.entries, profileCalls);\n }\n // Step 3. Build the tree.\n thread.tree = treify(thread.entries, options);\n }\n }\n}\n\n/**\n * Builds a hierarchy of the entries (trace events and profile calls) in\n * a particular thread of a particular process, assuming that they're\n * sorted, by iterating through all of the events in order.\n *\n * The approach is analogous to how a parser would be implemented. A\n * stack maintains local context. A scanner peeks and pops from the data\n * stream. Various \"tokens\" (events) are treated as \"whitespace\"\n * (ignored).\n *\n * The tree starts out empty and is populated as the hierarchy is built.\n * The nodes are also assumed to be created empty, with no known parent\n * or children.\n *\n * Complexity: O(n), where n = number of events\n */\nexport function treify(\n entries: RendererEntry[],\n options?: {filter: {has: (name: Types.TraceEvents.KnownEventName) => boolean}}): RendererTree {\n const stack = [];\n // Reset the node id counter for every new renderer.\n nodeIdCount = -1;\n const tree = makeEmptyRendererTree();\n for (let i = 0; i < entries.length; i++) {\n const event = entries[i];\n // If the current event should not be part of the tree, then simply proceed\n // with the next event.\n if (options && !options.filter.has(event.name as Types.TraceEvents.KnownEventName)) {\n continue;\n }\n\n const duration = event.dur || 0;\n const nodeId = makeRendererEntrytNodeId();\n const node = makeEmptyRendererEventNode(event, nodeId);\n\n // If the parent stack is empty, then the current event is a root. Create a\n // node for it, mark it as a root, then proceed with the next event.\n if (stack.length === 0) {\n tree.nodes.set(nodeId, node);\n tree.roots.add(nodeId);\n event.selfTime = Types.Timing.MicroSeconds(duration);\n stack.push(node);\n tree.maxDepth = Math.max(tree.maxDepth, stack.length);\n entryToNode.set(event, node);\n continue;\n }\n\n const parentNode = stack.at(-1);\n if (parentNode === undefined) {\n throw new Error('Impossible: no parent node found in the stack');\n }\n\n const parentEvent = parentNode.entry;\n\n const begin = event.ts;\n const parentBegin = parentEvent.ts;\n const parentDuration = parentEvent.dur || 0;\n const end = begin + duration;\n const parentEnd = parentBegin + parentDuration;\n // Check the relationship between the parent event at the top of the stack,\n // and the current event being processed. There are only 4 distinct\n // possiblities, only 2 of them actually valid, given the assumed sorting:\n // 1. Current event starts before the parent event, ends whenever. (invalid)\n // 2. Current event starts after the parent event, ends whenever. (valid)\n // 3. Current event starts during the parent event, ends after. (invalid)\n // 4. Current event starts and ends during the parent event. (valid)\n\n // 1. If the current event starts before the parent event, then the data is\n // not sorted properly, messed up some way, or this logic is incomplete.\n const startsBeforeParent = begin < parentBegin;\n if (startsBeforeParent) {\n throw new Error('Impossible: current event starts before the parent event');\n }\n\n // 2. If the current event starts after the parent event, then it's a new\n // parent. Pop, then handle current event again.\n const startsAfterParent = begin >= parentEnd;\n if (startsAfterParent) {\n stack.pop();\n i--;\n // The last created node has been discarded, so discard this id.\n nodeIdCount--;\n continue;\n }\n // 3. If the current event starts during the parent event, but ends\n // after it, then the data is messed up some way, for example a\n // profile call was sampled too late after its start, ignore the\n // problematic event.\n const endsAfterParent = end > parentEnd;\n if (endsAfterParent) {\n continue;\n }\n\n // 4. The only remaining case is the common case, where the current event is\n // contained within the parent event. Create a node for the current\n // event, establish the parent/child relationship, then proceed with the\n // next event.\n tree.nodes.set(nodeId, node);\n node.depth = stack.length;\n node.parentId = parentNode.id;\n parentNode.childrenIds.add(nodeId);\n event.selfTime = Types.Timing.MicroSeconds(duration);\n if (parentEvent.selfTime !== undefined) {\n parentEvent.selfTime = Types.Timing.MicroSeconds(parentEvent.selfTime - (event.dur || 0));\n }\n stack.push(node);\n tree.maxDepth = Math.max(tree.maxDepth, stack.length);\n entryToNode.set(event, node);\n }\n return tree;\n}\n\nexport function makeCompleteEvent(event: Types.TraceEvents.TraceEventBegin|Types.TraceEvents.TraceEventEnd):\n Types.TraceEvents.TraceEventSyntheticCompleteEvent|null {\n if (Types.TraceEvents.isTraceEventEnd(event)) {\n // Quietly ignore unbalanced close events, they're legit (we could\n // have missed start one).\n const beginEvent = completeEventStack.pop();\n if (!beginEvent) {\n return null;\n }\n if (beginEvent.name !== event.name || beginEvent.cat !== event.cat) {\n console.error(\n 'Begin/End events mismatch at ' + beginEvent.ts + ' (' + beginEvent.name + ') vs. ' + event.ts + ' (' +\n event.name + ')');\n return null;\n }\n // Update the begin event's duration using the timestamp of the end\n // event.\n beginEvent.dur = Types.Timing.MicroSeconds(event.ts - beginEvent.ts);\n return null;\n }\n\n // Create a synthetic event using the begin event, when we find the\n // matching end event later we will update its duration.\n const syntheticComplete: Types.TraceEvents.TraceEventSyntheticCompleteEvent = {\n ...event,\n ph: Types.TraceEvents.Phase.COMPLETE,\n dur: Types.Timing.MicroSeconds(0),\n };\n\n completeEventStack.push(syntheticComplete);\n return syntheticComplete;\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta', 'Samples'];\n}\n\nexport interface RendererHandlerData {\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>;\n /**\n * A map of all compositor workers (which we show in the UI as Rasterizers)\n * by the process ID.\n */\n compositorTileWorkers: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.ThreadID[]>;\n entryToNode: Map<RendererEntry, RendererEntryNode>;\n /**\n * All trace events and synthetic profile calls made from\n * samples.\n */\n allRendererEvents: Types.TraceEvents.TraceEventRendererEvent[];\n}\n\nexport interface RendererProcess {\n // In an ideal world this would be modelled as a URL, but URLs cannot be sent\n // between the main thread and workers, so we have to store it as a string.\n url: string|null;\n isOnMainFrame: boolean;\n threads: Map<Types.TraceEvents.ThreadID, RendererThread>;\n}\n\nexport interface RendererThread {\n name: string|null;\n /**\n * Contains trace events and synthetic profile calls made from\n * samples.\n */\n entries: RendererEntry[];\n tree?: RendererTree;\n}\n\nexport type RendererEntry = Types.TraceEvents.SyntheticRendererEvent|Types.TraceEvents.TraceEventSyntheticProfileCall;\n\nexport interface RendererTree {\n nodes: Map<RendererEntryNodeId, RendererEntryNode>;\n roots: Set<RendererEntryNodeId>;\n maxDepth: number;\n}\n\nexport interface RendererEntryNode {\n entry: RendererEntry;\n depth: number;\n id: RendererEntryNodeId;\n parentId?: RendererEntryNodeId|null;\n childrenIds: Set<RendererEntryNodeId>;\n}\n\nclass RendererEventNodeIdTag {\n /* eslint-disable-next-line no-unused-private-class-members */\n readonly #tag: (symbol|undefined);\n}\nexport type RendererEntryNodeId = number&RendererEventNodeIdTag;\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\nimport type * as Protocol from '../../../generated/protocol.js';\nimport {HandlerState} from './types.js';\nimport * as CPUProfile from '../../cpu_profile/cpu_profile.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nconst events =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventComplete[]>>();\n\nconst profilesInProcess = new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, ProfileData>>();\n\n// The profile head, containing its metadata like its start\n// time, comes in a \"Profile\" event. The sample data comes in\n// \"ProfileChunk\" events. We match these ProfileChunks with their head\n// using process and profile ids. However, in order to integrate sample\n// data with trace data, we need the thread id that owns each profile.\n// This thread id is extracted from the head event.\n// For this reason, we have a preprocessed data structure, where events\n// are matched by profile id, which we then finish processing to export\n// events matched by thread id.\nconst preprocessedData = new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ProfileID, PreprocessedData>>();\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function buildProfileCalls(): void {\n for (const [processId, profiles] of preprocessedData) {\n for (const [profileId, preProcessedData] of profiles) {\n const threadId = preProcessedData.threadId;\n if (!preProcessedData.rawProfile.nodes.length || !threadId) {\n continue;\n }\n const trackingStack: Partial<Types.TraceEvents.TraceEventSyntheticProfileCall>[] = [];\n\n const profileModel = new CPUProfile.CPUProfileDataModel.CPUProfileDataModel(preProcessedData.rawProfile);\n\n const finalizedData:\n ProfileData = {rawProfile: preProcessedData.rawProfile, parsedProfile: profileModel, profileCalls: []};\n\n profileModel.forEachFrame(openFrameCallback, closeFrameCallback);\n Helpers.Trace.sortTraceEventsInPlace(finalizedData.profileCalls);\n const dataByThread = Platform.MapUtilities.getWithDefault(profilesInProcess, processId, () => new Map());\n dataByThread.set(threadId, finalizedData);\n\n function openFrameCallback(\n _depth: number, node: CPUProfile.ProfileTreeModel.ProfileNode, timeStampMs: number): void {\n const ts = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(timeStampMs));\n trackingStack.push({callFrame: node.callFrame, ts, pid: processId, children: [], tid: threadId});\n }\n function closeFrameCallback(\n depth: number, node: CPUProfile.ProfileTreeModel.ProfileNode, _timeStamp: number, durMs: number,\n selfTimeMs: number): void {\n const partialProfileCall = trackingStack.pop();\n if (!partialProfileCall) {\n return;\n }\n const {callFrame, ts, pid, children, tid} = partialProfileCall;\n if (callFrame === undefined || ts === undefined || pid === undefined || profileId === undefined ||\n children === undefined || tid === undefined) {\n return;\n }\n const dur = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(durMs));\n const selfTime = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(selfTimeMs));\n const completeProfileCall: Types.TraceEvents.TraceEventSyntheticProfileCall = {\n callFrame,\n ts,\n pid,\n dur,\n selfTime,\n children,\n ph: Types.TraceEvents.Phase.COMPLETE,\n cat: '',\n name: 'ProfileCall',\n tid,\n nodeId: node.id,\n };\n const parent = trackingStack.at(-1);\n const calls = finalizedData.profileCalls;\n calls.push(completeProfileCall);\n if (!parent) {\n return;\n }\n parent.children = parent.children || [];\n parent.children.push(completeProfileCall);\n if (parent.selfTime) {\n parent.selfTime = Types.Timing.MicroSeconds(parent.selfTime - dur);\n }\n }\n }\n }\n}\n\nexport function reset(): void {\n events.clear();\n preprocessedData.clear();\n profilesInProcess.clear();\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Samples Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Samples Handler is not initialized');\n }\n\n if (Types.TraceEvents.isTraceEventProfile(event)) {\n // Do not use event.args.data.startTime as it is in CLOCK_MONOTONIC domain,\n // but use profileEvent.ts which has been translated to Perfetto's clock\n // domain. Also convert from ms to us.\n // Note: events are collected on a different thread than what's sampled.\n // The correct process and thread ids are specified by the profile.\n const profileData = getOrCreatePreProcessedData(event.pid, event.id);\n profileData.rawProfile.startTime = event.ts;\n profileData.threadId = event.tid;\n return;\n }\n if (Types.TraceEvents.isTraceEventProfileChunk(event)) {\n const profileData = getOrCreatePreProcessedData(event.pid, event.id);\n const cdpProfile = profileData.rawProfile;\n const nodesAndSamples: Types.TraceEvents.TraceEventPartialProfile|undefined =\n event.args?.data?.cpuProfile || {samples: []};\n const samples = nodesAndSamples?.samples || [];\n const nodes: CPUProfile.CPUProfileDataModel.ExtendedProfileNode[] = [];\n for (const n of nodesAndSamples?.nodes || []) {\n const lineNumber = n.callFrame.lineNumber || -1;\n const columnNumber = n.callFrame.columnNumber || -1;\n const scriptId = String(n.callFrame.scriptId) as Protocol.Runtime.ScriptId;\n const url = n.callFrame.url || '';\n const node = {\n ...n,\n callFrame: {\n ...n.callFrame,\n url,\n lineNumber,\n columnNumber,\n scriptId,\n },\n };\n nodes.push(node);\n }\n\n const timeDeltas = event.args.data?.timeDeltas || [];\n const lines = event.args.data?.lines || Array(samples.length).fill(0);\n cdpProfile.nodes.push(...nodes);\n cdpProfile.samples?.push(...samples);\n cdpProfile.timeDeltas?.push(...timeDeltas);\n cdpProfile.lines?.push(...lines);\n if (cdpProfile.samples && cdpProfile.timeDeltas && cdpProfile.samples.length !== cdpProfile.timeDeltas.length) {\n console.error('Failed to parse CPU profile.');\n return;\n }\n if (!cdpProfile.endTime && cdpProfile.timeDeltas) {\n const timeDeltas: number[] = cdpProfile.timeDeltas;\n cdpProfile.endTime = timeDeltas.reduce((x, y) => x + y, cdpProfile.startTime);\n }\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Samples Handler is not initialized');\n }\n buildProfileCalls();\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): SamplesHandlerData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Samples Handler is not finalized');\n }\n\n return {\n profilesInProcess: new Map(profilesInProcess),\n };\n}\n\nfunction getOrCreatePreProcessedData(\n processId: Types.TraceEvents.ProcessID, profileId: Types.TraceEvents.ProfileID): PreprocessedData {\n const profileById = Platform.MapUtilities.getWithDefault(preprocessedData, processId, () => new Map());\n return Platform.MapUtilities.getWithDefault<Types.TraceEvents.ProfileID, PreprocessedData>(\n profileById, profileId, () => ({\n rawProfile: {\n startTime: 0,\n endTime: 0,\n nodes: [],\n samples: [],\n timeDeltas: [],\n lines: [],\n },\n profileId,\n }));\n}\n\nexport interface SamplesHandlerData {\n profilesInProcess: typeof profilesInProcess;\n}\n\nexport type ProfileData = {\n rawProfile: CPUProfile.CPUProfileDataModel.ExtendedProfile,\n parsedProfile: CPUProfile.CPUProfileDataModel.CPUProfileDataModel,\n profileCalls: Types.TraceEvents.TraceEventSyntheticProfileCall[],\n};\n\ntype PreprocessedData = {\n rawProfile: CPUProfile.CPUProfileDataModel.ExtendedProfile,\n threadId?: Types.TraceEvents.ThreadID, profileId: Types.TraceEvents.ProfileID,\n};\n", "// Copyright 2014 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Common from '../../core/common/common.js';\nimport * as Platform from '../../core/platform/platform.js';\nimport type * as Protocol from '../../generated/protocol.js';\n\nimport {ProfileNode, ProfileTreeModel} from './ProfileTreeModel.js';\n\nexport class CPUProfileNode extends ProfileNode {\n override id: number;\n override self: number;\n // Position ticks are available in profile nodes coming from CDP\n // profiles and not in those coming from tracing. They are used to\n // calculate the line level execution time shown in the Sources panel\n // after recording a profile. For trace CPU profiles we use the\n // `lines` array instead.\n positionTicks: Protocol.Profiler.PositionTickInfo[]|undefined;\n override deoptReason: string|null;\n\n constructor(node: Protocol.Profiler.ProfileNode, samplingInterval: number /* milliseconds */) {\n const callFrame = node.callFrame || ({\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n functionName: node['functionName'],\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n scriptId: node['scriptId'],\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n url: node['url'],\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n lineNumber: node['lineNumber'] - 1,\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n columnNumber: node['columnNumber'] - 1,\n } as Protocol.Runtime.CallFrame);\n super(callFrame);\n this.id = node.id;\n this.self = (node.hitCount || 0) * samplingInterval;\n this.positionTicks = node.positionTicks;\n // Compatibility: legacy backends could provide \"no reason\" for optimized functions.\n this.deoptReason = node.deoptReason && node.deoptReason !== 'no reason' ? node.deoptReason : null;\n }\n}\n\nexport class CPUProfileDataModel extends ProfileTreeModel {\n profileStartTime: number /* milliseconds */;\n profileEndTime: number /* milliseconds */;\n timestamps: number[];\n samples: number[]|undefined;\n lines?: number[];\n totalHitCount: number;\n profileHead: CPUProfileNode;\n /**\n * A cache for the nodes we have parsed.\n * Note: \"Parsed\" nodes are different from the \"Protocol\" nodes, the\n * latter being the raw data we receive from the backend.\n */\n #idToParsedNode!: Map<number, ProfileNode>;\n gcNode?: ProfileNode;\n programNode?: ProfileNode;\n idleNode?: ProfileNode;\n #stackStartTimes?: number[];\n #stackChildrenDuration?: number[];\n constructor(profile: ExtendedProfile) {\n super();\n // @ts-ignore Legacy types\n const isLegacyFormat = Boolean(profile['head']);\n if (isLegacyFormat) {\n // Legacy format contains raw timestamps and start/stop times are in seconds.\n this.profileStartTime = profile.startTime * 1000;\n this.profileEndTime = profile.endTime * 1000;\n // @ts-ignore Legacy types\n this.timestamps = profile.timestamps;\n this.compatibilityConversionHeadToNodes(profile);\n } else {\n // Current format encodes timestamps as deltas. Start/stop times are in microseconds.\n this.profileStartTime = profile.startTime / 1000;\n this.profileEndTime = profile.endTime / 1000;\n this.timestamps = this.convertTimeDeltas(profile);\n }\n this.samples = profile.samples;\n\n // Lines are available only in profiles coming from tracing.\n // Elements in the lines array have a 1 to 1 correspondance with\n // samples, by array position. They can be 1 or 0 and indicate if\n // there is line data for a given sample, i.e. if a given sample\n // needs to be included to calculate the line level execution time\n // data, which we show in the sources panel after recording a\n // profile.\n this.lines = profile.lines;\n this.totalHitCount = 0;\n this.profileHead = this.translateProfileTree(profile.nodes);\n this.initialize(this.profileHead);\n this.extractMetaNodes();\n if (this.samples) {\n this.sortSamples();\n this.normalizeTimestamps();\n this.fixMissingSamples();\n }\n }\n\n private compatibilityConversionHeadToNodes(profile: Protocol.Profiler.Profile): void {\n // @ts-ignore Legacy types\n if (!profile.head || profile.nodes) {\n return;\n }\n const nodes: Protocol.Profiler.ProfileNode[] = [];\n // @ts-ignore Legacy types\n convertNodesTree(profile.head);\n profile.nodes = nodes;\n // @ts-ignore Legacy types\n delete profile.head;\n function convertNodesTree(node: Protocol.Profiler.ProfileNode): number {\n nodes.push(node);\n // @ts-ignore Legacy types\n node.children = (node.children as Protocol.Profiler.ProfileNode[]).map(convertNodesTree);\n return node.id;\n }\n }\n\n /**\n * Calculate timestamps using timeDeltas. Some CPU profile formats,\n * like the ones contained in traces have timeDeltas instead of\n * timestamps.\n */\n private convertTimeDeltas(profile: Protocol.Profiler.Profile): number[] {\n if (!profile.timeDeltas) {\n return [];\n }\n let lastTimeMicroSec = profile.startTime;\n const timestamps = new Array(profile.timeDeltas.length);\n for (let i = 0; i < profile.timeDeltas.length; ++i) {\n lastTimeMicroSec += profile.timeDeltas[i];\n timestamps[i] = lastTimeMicroSec;\n }\n return timestamps;\n }\n\n /**\n * Creates a Tree of CPUProfileNodes using the Protocol.Profiler.ProfileNodes.\n * As the tree is built, samples of native code (prefixed with \"native \") are\n * filtered out. Samples of filtered nodes are replaced with the parent of the\n * node being filtered.\n *\n * This function supports legacy and new definitions of the CDP Profiler.Profile\n * type.\n */\n private translateProfileTree(nodes: Protocol.Profiler.ProfileNode[]): CPUProfileNode {\n function isNativeNode(node: Protocol.Profiler.ProfileNode): boolean {\n if (node.callFrame) {\n return Boolean(node.callFrame.url) && node.callFrame.url.startsWith('native ');\n }\n // @ts-ignore Legacy types\n return Boolean(node['url']) && node['url'].startsWith('native ');\n }\n\n function buildChildrenFromParents(nodes: Protocol.Profiler.ProfileNode[]): void {\n if (nodes[0].children) {\n return;\n }\n nodes[0].children = [];\n for (let i = 1; i < nodes.length; ++i) {\n const node = nodes[i];\n // @ts-ignore Legacy types\n const parentNode = protocolNodeById.get(node.parent);\n // @ts-ignore Legacy types\n if (parentNode.children) {\n // @ts-ignore Legacy types\n parentNode.children.push(node.id);\n } else {\n // @ts-ignore Legacy types\n parentNode.children = [node.id];\n }\n }\n }\n\n /**\n * Calculate how many times each node was sampled in the profile, if\n * not available in the profile data.\n */\n function buildHitCountFromSamples(nodes: Protocol.Profiler.ProfileNode[], samples: number[]|undefined): void {\n // If hit count is available, this profile has the new format, so\n // no need to continue.`\n if (typeof (nodes[0].hitCount) === 'number') {\n return;\n }\n if (!samples) {\n throw new Error('Error: Neither hitCount nor samples are present in profile.');\n }\n for (let i = 0; i < nodes.length; ++i) {\n nodes[i].hitCount = 0;\n }\n for (let i = 0; i < samples.length; ++i) {\n const node = protocolNodeById.get(samples[i]);\n if (!node || node.hitCount === undefined) {\n continue;\n }\n node.hitCount++;\n }\n }\n\n // A cache for the raw nodes received from the traces / CDP.\n const protocolNodeById = new Map<number, Protocol.Profiler.ProfileNode>();\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n protocolNodeById.set(node.id, node);\n }\n\n buildHitCountFromSamples(nodes, this.samples);\n buildChildrenFromParents(nodes);\n this.totalHitCount = nodes.reduce((acc, node) => acc + (node.hitCount || 0), 0);\n const sampleTime = (this.profileEndTime - this.profileStartTime) / this.totalHitCount;\n const keepNatives = Boolean(\n Common.Settings.Settings.hasInstance() &&\n Common.Settings.Settings.instance().moduleSetting('showNativeFunctionsInJSProfile').get());\n const root = nodes[0];\n // If a node is filtered out, its samples are replaced with its parent,\n // so we keep track of the which id to use in the samples data.\n const idToUseForRemovedNode = new Map<number, number>([[root.id, root.id]]);\n this.#idToParsedNode = new Map();\n\n const resultRoot = new CPUProfileNode(root, sampleTime);\n this.#idToParsedNode.set(root.id, resultRoot);\n if (!root.children) {\n throw new Error('Missing children for root');\n }\n const parentNodeStack = root.children.map(() => resultRoot);\n const sourceNodeStack = root.children.map(id => protocolNodeById.get(id));\n while (sourceNodeStack.length) {\n let parentNode = parentNodeStack.pop();\n const sourceNode = sourceNodeStack.pop();\n if (!sourceNode || !parentNode) {\n continue;\n }\n if (!sourceNode.children) {\n sourceNode.children = [];\n }\n const targetNode = new CPUProfileNode(sourceNode, sampleTime);\n if (keepNatives || !isNativeNode(sourceNode)) {\n parentNode.children.push(targetNode);\n parentNode = targetNode;\n } else {\n parentNode.self += targetNode.self;\n }\n\n idToUseForRemovedNode.set(sourceNode.id, parentNode.id);\n parentNodeStack.push.apply(parentNodeStack, sourceNode.children.map(() => parentNode as CPUProfileNode));\n sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children.map(id => protocolNodeById.get(id)));\n this.#idToParsedNode.set(sourceNode.id, targetNode);\n }\n if (this.samples) {\n this.samples = this.samples.map(id => idToUseForRemovedNode.get(id) as number);\n }\n return resultRoot;\n }\n\n /**\n * Sorts the samples array using the timestamps array (there is a one\n * to one matching by index between the two).\n */\n private sortSamples(): void {\n if (!this.timestamps || !this.samples) {\n return;\n }\n\n const timestamps = this.timestamps;\n const samples = this.samples;\n const orderedIndices = timestamps.map((_x, index) => index);\n orderedIndices.sort((a, b) => timestamps[a] - timestamps[b]);\n\n this.timestamps = [];\n this.samples = [];\n\n for (let i = 0; i < orderedIndices.length; i++) {\n const orderedIndex = orderedIndices[i];\n this.timestamps.push(timestamps[orderedIndex]);\n this.samples.push(samples[orderedIndex]);\n }\n }\n\n /**\n * Fills in timestamps and/or time deltas from legacy profiles where\n * they could be missing.\n */\n private normalizeTimestamps(): void {\n if (!this.samples) {\n return;\n }\n let timestamps: number[] = this.timestamps;\n if (!timestamps) {\n // Support loading CPU profiles that are missing timestamps and\n // timedeltas\n const profileStartTime = this.profileStartTime;\n const interval = (this.profileEndTime - profileStartTime) / this.samples.length;\n // Add an extra timestamp used to calculate the last sample duration.\n timestamps = new Array(this.samples.length + 1);\n for (let i = 0; i < timestamps.length; ++i) {\n timestamps[i] = profileStartTime + i * interval;\n }\n this.timestamps = timestamps;\n return;\n }\n\n // Convert samples from micro to milliseconds\n for (let i = 0; i < timestamps.length; ++i) {\n timestamps[i] /= 1000;\n }\n if (this.samples.length === timestamps.length) {\n // Add an extra timestamp used to calculate the last sample duration.\n const lastTimestamp = timestamps.at(-1) || 0;\n const averageIntervalTime = (lastTimestamp - timestamps[0]) / (timestamps.length - 1);\n this.timestamps.push(lastTimestamp + averageIntervalTime);\n }\n this.profileStartTime = timestamps.at(0) || this.profileStartTime;\n this.profileEndTime = timestamps.at(-1) || this.profileEndTime;\n }\n\n /**\n * Some nodes do not refer to JS samples but to V8 system tasks, AKA\n * \"meta\" nodes. This function extracts those nodes from the profile.\n */\n private extractMetaNodes(): void {\n const topLevelNodes = this.profileHead.children;\n for (let i = 0; i < topLevelNodes.length && !(this.gcNode && this.programNode && this.idleNode); i++) {\n const node = topLevelNodes[i];\n if (node.functionName === '(garbage collector)') {\n this.gcNode = node;\n } else if (node.functionName === '(program)') {\n this.programNode = node;\n } else if (node.functionName === '(idle)') {\n this.idleNode = node;\n }\n }\n }\n\n private fixMissingSamples(): void {\n // Sometimes the V8 sampler is not able to parse the JS stack and returns\n // a (program) sample instead. The issue leads to call frames being split\n // apart when they shouldn't.\n // Here's a workaround for that. When there's a single (program) sample\n // between two call stacks sharing the same bottom node, it is replaced\n // with the preceeding sample.\n const samples = this.samples;\n if (!samples) {\n return;\n }\n const samplesCount = samples.length;\n if (!this.programNode || samplesCount < 3) {\n return;\n }\n const idToNode = this.#idToParsedNode;\n const programNodeId = this.programNode.id;\n const gcNodeId = this.gcNode ? this.gcNode.id : -1;\n const idleNodeId = this.idleNode ? this.idleNode.id : -1;\n let prevNodeId: number = samples[0];\n let nodeId: number = samples[1];\n for (let sampleIndex = 1; sampleIndex < samplesCount - 1; sampleIndex++) {\n const nextNodeId = samples[sampleIndex + 1];\n const prevNode = idToNode.get(prevNodeId);\n const nextNode = idToNode.get(nextNodeId);\n if (prevNodeId === undefined || nextNodeId === undefined || !prevNode || !nextNode) {\n console.error(`Unexpectedly found undefined nodes: ${prevNodeId} ${nextNodeId}`);\n continue;\n }\n if (nodeId === programNodeId && !isSystemNode(prevNodeId) && !isSystemNode(nextNodeId) &&\n bottomNode(prevNode) === bottomNode(nextNode)) {\n samples[sampleIndex] = prevNodeId;\n }\n prevNodeId = nodeId;\n nodeId = nextNodeId;\n }\n function bottomNode(node: ProfileNode): ProfileNode {\n while (node.parent && node.parent.parent) {\n node = node.parent;\n }\n return node;\n }\n function isSystemNode(nodeId: number): boolean {\n return nodeId === programNodeId || nodeId === gcNodeId || nodeId === idleNodeId;\n }\n }\n\n /**\n * Traverses the call tree derived from the samples calling back when a call is opened\n * and when it's closed\n */\n forEachFrame(\n openFrameCallback: (depth: number, node: ProfileNode, timestamp: number) => void,\n closeFrameCallback: (depth: number, node: ProfileNode, timestamp: number, dur: number, selfTime: number) => void,\n startTime?: number, stopTime?: number): void {\n if (!this.profileHead || !this.samples) {\n return;\n }\n\n startTime = startTime || 0;\n stopTime = stopTime || Infinity;\n const samples = this.samples;\n const timestamps = this.timestamps;\n const idToNode = this.#idToParsedNode;\n const gcNode = this.gcNode;\n const samplesCount = samples.length;\n const startIndex =\n Platform.ArrayUtilities.lowerBound(timestamps, startTime, Platform.ArrayUtilities.DEFAULT_COMPARATOR);\n let stackTop = 0;\n const stackNodes: ProfileNode[] = [];\n let prevId: number = this.profileHead.id;\n let sampleTime;\n let gcParentNode: ProfileNode|null = null;\n\n // Extra slots for gc being put on top,\n // and one at the bottom to allow safe stackTop-1 access.\n const stackDepth = this.maxDepth + 3;\n if (!this.#stackStartTimes) {\n this.#stackStartTimes = new Array(stackDepth);\n }\n const stackStartTimes = this.#stackStartTimes;\n if (!this.#stackChildrenDuration) {\n this.#stackChildrenDuration = new Array(stackDepth);\n }\n const stackChildrenDuration = this.#stackChildrenDuration;\n\n let node;\n let sampleIndex;\n for (sampleIndex = startIndex; sampleIndex < samplesCount; sampleIndex++) {\n sampleTime = timestamps[sampleIndex];\n if (sampleTime >= stopTime) {\n break;\n }\n const id = samples[sampleIndex];\n if (id === prevId) {\n continue;\n }\n node = idToNode.get(id);\n let prevNode: ProfileNode|null = idToNode.get(prevId) || null;\n if (!prevNode) {\n continue;\n }\n\n if (gcNode && node === gcNode) {\n // GC samples have no stack, so we just put GC node on top of the last recorded sample.\n gcParentNode = prevNode;\n openFrameCallback(gcParentNode.depth + 1, gcNode, sampleTime);\n stackStartTimes[++stackTop] = sampleTime;\n stackChildrenDuration[stackTop] = 0;\n prevId = id;\n continue;\n }\n if (gcNode && prevNode === gcNode && gcParentNode) {\n // end of GC frame\n const start = stackStartTimes[stackTop];\n const duration = sampleTime - start;\n stackChildrenDuration[stackTop - 1] += duration;\n closeFrameCallback(gcParentNode.depth + 1, gcNode, start, duration, duration - stackChildrenDuration[stackTop]);\n --stackTop;\n prevNode = gcParentNode;\n prevId = prevNode.id;\n gcParentNode = null;\n }\n\n // If the depth of this node is greater than the depth of the\n // previous one, new calls happened in between and we need to open\n // them, so track all of them in stackNodes.\n while (node && node.depth > prevNode.depth) {\n stackNodes.push(node);\n node = node.parent;\n }\n\n // If `prevNode` differs from `node`, the current sample was taken\n // after a change in the call stack, meaning that frames in the\n // path of `prevNode` that differ from those in the path of `node`\n // can be closed. So go down to the lowest common ancestor and\n // close current intervals.\n //\n // For example:\n //\n // prevNode node\n // | |\n // v v\n // [---D--]\n // [---C--][--E--]\n // [------B------] <- LCA\n // [------A------]\n //\n // Because a sample was taken with A, B and E in the stack, it\n // means C and D finished and we can close them.\n while (prevNode && prevNode !== node) {\n const start = stackStartTimes[stackTop];\n const duration = sampleTime - start;\n stackChildrenDuration[stackTop - 1] += duration;\n closeFrameCallback(prevNode.depth, prevNode, start, duration, duration - stackChildrenDuration[stackTop]);\n --stackTop;\n // Track calls to open after previous calls were closed\n // In the example above, this would add E to the tracking stack.\n if (node && node.depth === prevNode.depth) {\n stackNodes.push(node);\n node = node.parent;\n }\n prevNode = prevNode.parent;\n }\n\n // Go up the nodes stack and open new intervals.\n while (stackNodes.length) {\n const currentNode = stackNodes.pop();\n if (!currentNode) {\n break;\n }\n node = currentNode;\n openFrameCallback(currentNode.depth, currentNode, sampleTime);\n stackStartTimes[++stackTop] = sampleTime;\n stackChildrenDuration[stackTop] = 0;\n }\n\n prevId = id;\n }\n\n // Close remaining intervals.\n sampleTime = timestamps[sampleIndex] || this.profileEndTime;\n if (node && gcParentNode && idToNode.get(prevId) === gcNode) {\n const start = stackStartTimes[stackTop];\n const duration = sampleTime - start;\n stackChildrenDuration[stackTop - 1] += duration;\n closeFrameCallback(gcParentNode.depth + 1, node, start, duration, duration - stackChildrenDuration[stackTop]);\n --stackTop;\n prevId = gcParentNode.id;\n }\n for (let node = idToNode.get(prevId); node && node.parent; node = node.parent) {\n const start = stackStartTimes[stackTop];\n const duration = sampleTime - start;\n stackChildrenDuration[stackTop - 1] += duration;\n closeFrameCallback(node.depth, node, start, duration, duration - stackChildrenDuration[stackTop]);\n --stackTop;\n }\n }\n /**\n * Returns the node that corresponds to a given index of a sample.\n */\n nodeByIndex(index: number): ProfileNode|null {\n return this.samples && this.#idToParsedNode.get(this.samples[index]) || null;\n }\n /**\n * Returns the node that corresponds to a given node id.\n */\n nodeById(nodeId: number): ProfileNode|null {\n return this.#idToParsedNode.get(nodeId) || null;\n }\n\n nodes(): ProfileNode[]|null {\n if (!this.#idToParsedNode) {\n return null;\n }\n return [...this.#idToParsedNode.values()];\n }\n}\n\n// Format used by profiles coming from traces.\nexport type ExtendedProfileNode = Protocol.Profiler.ProfileNode&{parent?: number};\nexport type ExtendedProfile =\n Protocol.Profiler.Profile&{nodes: Protocol.Profiler.ProfileNode[] | ExtendedProfileNode[], lines?: number[]};\n", "// Copyright 2016 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Protocol from '../../generated/protocol.js';\nimport type * as Platform from '../../core/platform/platform.js';\n\nexport class ProfileNode {\n callFrame: Protocol.Runtime.CallFrame;\n callUID: string;\n self: number;\n total: number;\n id: number;\n parent: ProfileNode|null;\n children: ProfileNode[];\n functionName: string;\n depth!: number;\n deoptReason!: string|null;\n constructor(callFrame: Protocol.Runtime.CallFrame) {\n this.callFrame = callFrame;\n this.callUID = `${callFrame.functionName}@${callFrame.scriptId}:${callFrame.lineNumber}:${callFrame.columnNumber}`;\n this.self = 0;\n this.total = 0;\n this.id = 0;\n this.functionName = callFrame.functionName;\n this.parent = null;\n this.children = [];\n }\n\n get scriptId(): Protocol.Runtime.ScriptId {\n return String(this.callFrame.scriptId) as Protocol.Runtime.ScriptId;\n }\n\n get url(): Platform.DevToolsPath.UrlString {\n return this.callFrame.url as Platform.DevToolsPath.UrlString;\n }\n\n get lineNumber(): number {\n return this.callFrame.lineNumber;\n }\n\n get columnNumber(): number {\n return this.callFrame.columnNumber;\n }\n\n setFunctionName(name: string|null): void {\n if (name === null) {\n return;\n }\n this.functionName = name;\n }\n}\n\nexport class ProfileTreeModel {\n root!: ProfileNode;\n total!: number;\n maxDepth!: number;\n constructor() {\n }\n\n initialize(root: ProfileNode): void {\n this.root = root;\n this.assignDepthsAndParents();\n this.total = this.calculateTotals(this.root);\n }\n\n private assignDepthsAndParents(): void {\n const root = this.root;\n // TODO(crbug.com/1354548): start depth from 0 once profiler\n // panel dependencies are gone.\n root.depth = -1;\n root.parent = null;\n this.maxDepth = 0;\n const nodesToTraverse = [root];\n while (nodesToTraverse.length) {\n const parent = (nodesToTraverse.pop() as ProfileNode);\n const depth = parent.depth + 1;\n if (depth > this.maxDepth) {\n this.maxDepth = depth;\n }\n const children = parent.children;\n for (const child of children) {\n child.depth = depth;\n child.parent = parent;\n nodesToTraverse.push(child);\n }\n }\n }\n\n private calculateTotals(root: ProfileNode): number {\n const nodesToTraverse = [root];\n const dfsList = [];\n while (nodesToTraverse.length) {\n const node = (nodesToTraverse.pop() as ProfileNode);\n node.total = node.self;\n dfsList.push(node);\n nodesToTraverse.push(...node.children);\n }\n while (dfsList.length > 1) {\n const node = (dfsList.pop() as ProfileNode);\n if (node.parent) {\n node.parent.total += node.total;\n }\n }\n return root.total;\n }\n}\n", "// Copyright 2014 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n//\n// This is what was SDK.TracingModel moved into models/trace to avoid circular dependency issues. Our ultimate goal is to remove this model entirely once the migration to the new model is done\n\nimport * as Common from '../../core/common/common.js';\n\nimport * as Helpers from './helpers/helpers.js';\nimport {type EventPayload} from './TracingManager.js';\nimport * as Types from './types/types.js';\n\ntype IgnoreListArgs = {\n [key: string]: string|number|ObjectSnapshot,\n};\n\nexport class TracingModel {\n readonly #title: string|undefined;\n readonly #processById: Map<string|number, Process>;\n readonly #processByName: Map<string, Process>;\n #minimumRecordTimeInternal: number;\n #maximumRecordTimeInternal: number;\n readonly #devToolsMetadataEventsInternal: Event[];\n #asyncEvents: AsyncEvent[];\n readonly #openAsyncEvents: Map<string, AsyncEvent>;\n readonly #openNestableAsyncEvents: Map<string, AsyncEvent[]>;\n readonly #profileGroups: Map<string, ProfileEventsGroup>;\n readonly #parsedCategories: Map<string, Set<string>>;\n readonly #allEventsPayload: EventPayload[] = [];\n\n constructor(title?: string) {\n this.#title = title;\n this.#processById = new Map();\n this.#processByName = new Map();\n this.#minimumRecordTimeInternal = Number(Infinity);\n this.#maximumRecordTimeInternal = Number(-Infinity);\n this.#devToolsMetadataEventsInternal = [];\n this.#asyncEvents = [];\n this.#openAsyncEvents = new Map();\n this.#openNestableAsyncEvents = new Map();\n this.#profileGroups = new Map();\n this.#parsedCategories = new Map();\n }\n\n static isTopLevelEvent(event: CompatibleTraceEvent): boolean {\n return eventHasCategory(event, DevToolsTimelineEventCategory) && event.name === 'RunTask' ||\n eventHasCategory(event, LegacyTopLevelEventCategory) ||\n eventHasCategory(event, DevToolsMetadataEventCategory) &&\n event.name === 'Program'; // Older timelines may have this instead of toplevel.\n }\n\n static extractId(payload: EventPayload): string|undefined {\n const scope = payload.scope || '';\n if (typeof payload.id2 === 'undefined') {\n return scope && payload.id ? `${scope}@${payload.id}` : payload.id;\n }\n const id2 = payload.id2;\n if (typeof id2 === 'object' && ('global' in id2) !== ('local' in id2)) {\n return typeof id2['global'] !== 'undefined' ? `:${scope}:${id2['global']}` :\n `:${scope}:${payload.pid}:${id2['local']}`;\n }\n console.error(\n `Unexpected id2 field at ${payload.ts / 1000}, one and only one of 'local' and 'global' should be present.`);\n return undefined;\n }\n\n static browserMainThread(tracingModel: TracingModel): Thread|null {\n const processes = tracingModel.sortedProcesses();\n // Avoid warning for an empty #model.\n if (!processes.length) {\n return null;\n }\n const browserMainThreadName = 'CrBrowserMain';\n const browserProcesses = [];\n const browserMainThreads = [];\n for (const process of processes) {\n if (process.name().toLowerCase().endsWith('browser')) {\n browserProcesses.push(process);\n }\n browserMainThreads.push(...process.sortedThreads().filter(t => t.name() === browserMainThreadName));\n }\n if (browserMainThreads.length === 1) {\n return browserMainThreads[0];\n }\n if (browserProcesses.length === 1) {\n return browserProcesses[0].threadByName(browserMainThreadName);\n }\n const tracingStartedInBrowser =\n tracingModel.devToolsMetadataEvents().filter(e => e.name === 'TracingStartedInBrowser');\n if (tracingStartedInBrowser.length === 1) {\n return tracingStartedInBrowser[0].thread;\n }\n Common.Console.Console.instance().error(\n 'Failed to find browser main thread in trace, some timeline features may be unavailable');\n return null;\n }\n\n allRawEvents(): readonly EventPayload[] {\n return this.#allEventsPayload;\n }\n\n devToolsMetadataEvents(): Event[] {\n return this.#devToolsMetadataEventsInternal;\n }\n\n addEvents(events: readonly EventPayload[]): void {\n for (let i = 0; i < events.length; ++i) {\n this.addEvent(events[i]);\n }\n }\n\n tracingComplete(): void {\n this.processPendingAsyncEvents();\n for (const process of this.#processById.values()) {\n for (const thread of process.threads.values()) {\n thread.tracingComplete();\n }\n }\n }\n\n private addEvent(payload: EventPayload): void {\n this.#allEventsPayload.push(payload);\n let process = this.#processById.get(payload.pid);\n if (!process) {\n process = new Process(this, payload.pid);\n this.#processById.set(payload.pid, process);\n }\n\n const timestamp = payload.ts / 1000;\n // We do allow records for unrelated threads to arrive out-of-order,\n // so there's a chance we're getting records from the past.\n if (timestamp && timestamp < this.#minimumRecordTimeInternal &&\n eventPhasesOfInterestForTraceBounds.has(payload.ph as Types.TraceEvents.Phase) &&\n // UMA related events are ignored when calculating the minimumRecordTime because they might\n // be related to previous navigations that happened before the current trace started and\n // will currently not be displayed anyways.\n // See crbug.com/1201198\n (!payload.name.endsWith('::UMA'))) {\n this.#minimumRecordTimeInternal = timestamp;\n }\n\n if (payload.name === 'TracingStartedInBrowser') {\n // If we received a timestamp for tracing start, use that for minimumRecordTime.\n this.#minimumRecordTimeInternal = timestamp;\n }\n\n if (eventPhasesOfInterestForTraceBounds.has(payload.ph as Types.TraceEvents.Phase)) {\n const endTimeStamp = (payload.ts + (payload.dur || 0)) / 1000;\n this.#maximumRecordTimeInternal = Math.max(this.#maximumRecordTimeInternal, endTimeStamp);\n }\n const event = process.addEvent(payload);\n if (!event) {\n return;\n }\n if (payload.ph === Types.TraceEvents.Phase.SAMPLE) {\n this.addSampleEvent(event);\n return;\n }\n // Build async event when we've got events from all threads & processes, so we can sort them and process in the\n // chronological order. However, also add individual async events to the thread flow (above), so we can easily\n // display them on the same chart as other events, should we choose so.\n if (Types.TraceEvents.isAsyncPhase(payload.ph)) {\n this.#asyncEvents.push((event as AsyncEvent));\n }\n if (event.hasCategory(DevToolsMetadataEventCategory)) {\n this.#devToolsMetadataEventsInternal.push(event);\n }\n\n if (payload.ph !== Types.TraceEvents.Phase.METADATA) {\n return;\n }\n\n switch (payload.name) {\n case MetadataEvent.ProcessSortIndex: {\n process.setSortIndex(payload.args['sort_index']);\n break;\n }\n case MetadataEvent.ProcessName: {\n const processName = payload.args['name'];\n process.setName(processName);\n this.#processByName.set(processName, process);\n break;\n }\n case MetadataEvent.ThreadSortIndex: {\n process.threadById(payload.tid).setSortIndex(payload.args['sort_index']);\n break;\n }\n case MetadataEvent.ThreadName: {\n process.threadById(payload.tid).setName(payload.args['name']);\n break;\n }\n }\n }\n\n private addSampleEvent(event: Event): void {\n const id = `${event.thread.process().id()}:${event.id}`;\n const group = this.#profileGroups.get(id);\n if (group) {\n group.addChild(event);\n } else {\n this.#profileGroups.set(id, new ProfileEventsGroup(event));\n }\n }\n\n profileGroup(event: Event): ProfileEventsGroup|null {\n return this.#profileGroups.get(`${event.thread.process().id()}:${event.id}`) || null;\n }\n\n minimumRecordTime(): number {\n return this.#minimumRecordTimeInternal;\n }\n\n maximumRecordTime(): number {\n return this.#maximumRecordTimeInternal;\n }\n\n sortedProcesses(): Process[] {\n return NamedObject.sort([...this.#processById.values()]);\n }\n\n getProcessByName(name: string): Process|null {\n return this.#processByName.get(name) ?? null;\n }\n\n getProcessById(pid: number): Process|null {\n return this.#processById.get(pid) || null;\n }\n\n getThreadByName(processName: string, threadName: string): Thread|null {\n const process = this.getProcessByName(processName);\n return process && process.threadByName(threadName);\n }\n\n private processPendingAsyncEvents(): void {\n this.#asyncEvents.sort(Event.compareStartTime);\n for (let i = 0; i < this.#asyncEvents.length; ++i) {\n const event = this.#asyncEvents[i];\n if (Types.TraceEvents.isNestableAsyncPhase(event.phase)) {\n this.addNestableAsyncEvent(event);\n } else {\n this.addAsyncEvent(event);\n }\n }\n this.#asyncEvents = [];\n this.closeOpenAsyncEvents();\n }\n\n private closeOpenAsyncEvents(): void {\n for (const event of this.#openAsyncEvents.values()) {\n event.setEndTime(this.#maximumRecordTimeInternal);\n // FIXME: remove this once we figure a better way to convert async console\n // events to sync [waterfall] timeline records.\n event.steps[0].setEndTime(this.#maximumRecordTimeInternal);\n }\n this.#openAsyncEvents.clear();\n\n for (const eventStack of this.#openNestableAsyncEvents.values()) {\n while (eventStack.length) {\n const event = eventStack.pop();\n if (!event) {\n continue;\n }\n event.setEndTime(this.#maximumRecordTimeInternal);\n }\n }\n this.#openNestableAsyncEvents.clear();\n }\n\n private addNestableAsyncEvent(event: Event): void {\n const key = event.categoriesString + '.' + event.id;\n let openEventsStack = this.#openNestableAsyncEvents.get(key);\n\n switch (event.phase) {\n case Types.TraceEvents.Phase.ASYNC_NESTABLE_START: {\n if (!openEventsStack) {\n openEventsStack = [];\n this.#openNestableAsyncEvents.set(key, openEventsStack);\n }\n const asyncEvent = new AsyncEvent(event);\n openEventsStack.push(asyncEvent);\n event.thread.addAsyncEvent(asyncEvent);\n break;\n }\n\n case Types.TraceEvents.Phase.ASYNC_NESTABLE_INSTANT: {\n if (openEventsStack && openEventsStack.length) {\n const event = openEventsStack[openEventsStack.length - 1];\n if (event) {\n event.addStep(event);\n }\n }\n break;\n }\n\n case Types.TraceEvents.Phase.ASYNC_NESTABLE_END: {\n if (!openEventsStack || !openEventsStack.length) {\n break;\n }\n const top = openEventsStack.pop();\n if (!top) {\n break;\n }\n if (top.name !== event.name) {\n console.error(\n `Begin/end event mismatch for nestable async event, ${top.name} vs. ${event.name}, key: ${key}`);\n break;\n }\n top.addStep(event);\n }\n }\n }\n\n private addAsyncEvent(event: Event): void {\n const key = event.categoriesString + '.' + event.name + '.' + event.id;\n let asyncEvent = this.#openAsyncEvents.get(key);\n\n if (event.phase === Types.TraceEvents.Phase.ASYNC_BEGIN) {\n if (asyncEvent) {\n console.error(`Event ${event.name} has already been started`);\n return;\n }\n asyncEvent = new AsyncEvent(event);\n this.#openAsyncEvents.set(key, asyncEvent);\n event.thread.addAsyncEvent(asyncEvent);\n return;\n }\n if (!asyncEvent) {\n // Quietly ignore stray async events, we're probably too late for the start.\n return;\n }\n if (event.phase === Types.TraceEvents.Phase.ASYNC_END) {\n asyncEvent.addStep(event);\n this.#openAsyncEvents.delete(key);\n return;\n }\n if (event.phase === Types.TraceEvents.Phase.ASYNC_STEP_INTO ||\n event.phase === Types.TraceEvents.Phase.ASYNC_STEP_PAST) {\n const lastStep = asyncEvent.steps[asyncEvent.steps.length - 1];\n if (lastStep && lastStep.phase !== Types.TraceEvents.Phase.ASYNC_BEGIN && lastStep.phase !== event.phase) {\n console.assert(\n false,\n 'Async event step phase mismatch: ' + lastStep.phase + ' at ' + lastStep.startTime + ' vs. ' + event.phase +\n ' at ' + event.startTime);\n return;\n }\n asyncEvent.addStep(event);\n return;\n }\n console.assert(false, 'Invalid async event phase');\n }\n\n title(): string|undefined {\n return this.#title;\n }\n\n parsedCategoriesForString(str: string): Set<string> {\n let parsedCategories = this.#parsedCategories.get(str);\n if (!parsedCategories) {\n parsedCategories = new Set(str ? str.split(',') : []);\n this.#parsedCategories.set(str, parsedCategories);\n }\n return parsedCategories;\n }\n}\n\nexport const eventPhasesOfInterestForTraceBounds: Set<Types.TraceEvents.Phase> = new Set([\n Types.TraceEvents.Phase.BEGIN,\n Types.TraceEvents.Phase.END,\n Types.TraceEvents.Phase.COMPLETE,\n Types.TraceEvents.Phase.INSTANT,\n]);\n\nexport const MetadataEvent = {\n ProcessSortIndex: 'process_sort_index',\n ProcessName: 'process_name',\n ThreadSortIndex: 'thread_sort_index',\n ThreadName: 'thread_name',\n};\n\n// TODO(alph): LegacyTopLevelEventCategory is not recorded since M74 and used for loading\n// legacy profiles. Drop at some point.\nexport const LegacyTopLevelEventCategory = 'toplevel';\n\nexport const DevToolsMetadataEventCategory = 'disabled-by-default-devtools.timeline';\nexport const DevToolsTimelineEventCategory = 'disabled-by-default-devtools.timeline';\n\nexport function eventHasPayload(event: Event): event is PayloadEvent {\n return 'rawPayload' in event;\n}\n\nexport class Event {\n categoriesString: string;\n readonly #parsedCategories: Set<string>;\n name: string;\n phase: Types.TraceEvents.Phase;\n startTime: number;\n thread: Thread;\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any;\n id!: string|null;\n ordinal: number;\n selfTime: number;\n endTime?: number;\n duration?: number;\n\n // The constructor is protected so that we ensure that only classes or\n // subclasses can directly instantiate events. All other callers should\n // either create ConstructedEvent instances, which have a public constructor,\n // or use the static fromPayload method which can create an event instance\n // from the trace payload.\n protected constructor(\n categories: string|undefined, name: string, phase: Types.TraceEvents.Phase, startTime: number, thread: Thread) {\n this.categoriesString = categories || '';\n this.#parsedCategories = thread.getModel().parsedCategoriesForString(this.categoriesString);\n this.name = name;\n this.phase = phase;\n this.startTime = startTime;\n this.thread = thread;\n this.args = {};\n this.ordinal = 0;\n\n this.selfTime = 0;\n }\n\n static compareStartTime(a: Event|null, b: Event|null): number {\n if (!a || !b) {\n return 0;\n }\n\n return a.startTime - b.startTime;\n }\n\n static orderedCompareStartTime(a: Event, b: Event): number {\n // Array.mergeOrdered coalesces objects if comparator returns 0.\n // To change this behavior this comparator return -1 in the case events\n // startTime's are equal, so both events got placed into the result array.\n return a.startTime - b.startTime || a.ordinal - b.ordinal || -1;\n }\n\n hasCategory(categoryName: string): boolean {\n return this.#parsedCategories.has(categoryName);\n }\n\n setEndTime(endTime: number): void {\n if (endTime < this.startTime) {\n console.assert(false, 'Event out of order: ' + this.name);\n return;\n }\n this.endTime = endTime;\n this.duration = endTime - this.startTime;\n }\n\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n addArgs(args: any): void {\n // Shallow copy args to avoid modifying original #payload which may be saved to file.\n for (const name in args) {\n if (name in this.args) {\n console.error('Same argument name (' + name + ') is used for begin and end phases of ' + this.name);\n }\n\n (this.args as IgnoreListArgs)[name] = (args as IgnoreListArgs)[name];\n }\n }\n\n complete(endEvent: Event): void {\n if (endEvent.args) {\n this.addArgs(endEvent.args);\n } else {\n console.error('Missing mandatory event argument \\'args\\' at ' + endEvent.startTime);\n }\n this.setEndTime(endEvent.startTime);\n }\n}\n\n/**\n * Represents a tracing event that is not directly linked to an individual\n * object in the trace. We construct these events at times, particularly when\n * building up the CPU profile data for JS Profiling.\n **/\nexport class ConstructedEvent extends Event {\n // Because the constructor of Event is marked as protected, but we want\n // people to be able to create constructed events, we override the\n // constructor here, even though we are only calling super, in order to mark\n // it as public.\n constructor(\n categories: string|undefined, name: string, phase: Types.TraceEvents.Phase, startTime: number, thread: Thread) {\n super(categories, name, phase, startTime, thread);\n }\n}\n\n/**\n * Represents a tracing event that has been created directly from an object in\n * the trace file and therefore is guaranteed to have a payload associated with\n * it. The only way to create these events is to use the static fromPayload\n * method, which you must call with a payload.\n **/\nexport class PayloadEvent extends Event {\n #rawPayload: EventPayload;\n\n /**\n * Returns the raw payload that was used to create this event instance.\n **/\n rawLegacyPayload(): EventPayload {\n return this.#rawPayload;\n }\n\n /**\n * Returns the raw payload that was used to create this event instance, but\n * returns it typed as the new engine's TraceEventArgs option.\n **/\n rawPayload(): Types.TraceEvents.TraceEventData {\n return this.#rawPayload as unknown as Types.TraceEvents.TraceEventData;\n }\n\n protected constructor(\n categories: string|undefined, name: string, phase: Types.TraceEvents.Phase, startTime: number, thread: Thread,\n rawPayload: EventPayload) {\n super(categories, name, phase, startTime, thread);\n this.#rawPayload = rawPayload;\n }\n\n static fromPayload(payload: EventPayload, thread: Thread): PayloadEvent {\n const event = new PayloadEvent(payload.cat, payload.name, payload.ph, payload.ts / 1000, thread, payload);\n event.#rawPayload = payload;\n if (payload.args) {\n event.addArgs(payload.args);\n }\n if (typeof payload.dur === 'number') {\n event.setEndTime((payload.ts + payload.dur) / 1000);\n }\n const id = TracingModel.extractId(payload);\n if (typeof id !== 'undefined') {\n event.id = id;\n }\n\n return event;\n }\n}\n\nexport class ObjectSnapshot extends PayloadEvent {\n private constructor(\n category: string|undefined, name: string, startTime: number, thread: Thread, rawPayload: EventPayload) {\n super(category, name, Types.TraceEvents.Phase.OBJECT_SNAPSHOT, startTime, thread, rawPayload);\n }\n\n static override fromPayload(payload: EventPayload, thread: Thread): ObjectSnapshot {\n const snapshot = new ObjectSnapshot(payload.cat, payload.name, payload.ts / 1000, thread, payload);\n const id = TracingModel.extractId(payload);\n if (typeof id !== 'undefined') {\n snapshot.id = id;\n }\n if (!payload.args || !payload.args['snapshot']) {\n console.error('Missing mandatory \\'snapshot\\' argument at ' + payload.ts / 1000);\n return snapshot;\n }\n if (payload.args) {\n snapshot.addArgs(payload.args);\n }\n return snapshot;\n }\n\n getSnapshot(): ObjectSnapshot {\n const snapshot = this.args['snapshot'];\n if (!snapshot) {\n throw new Error('ObjectSnapshot has no snapshot argument.');\n }\n return snapshot;\n }\n}\n\nexport class AsyncEvent extends ConstructedEvent {\n steps: Event[];\n causedFrame: boolean;\n\n constructor(startEvent: Event) {\n super(startEvent.categoriesString, startEvent.name, startEvent.phase, startEvent.startTime, startEvent.thread);\n this.addArgs(startEvent.args);\n this.steps = [startEvent];\n this.causedFrame = false;\n }\n\n addStep(event: Event): void {\n this.steps.push(event);\n if (event.phase === Types.TraceEvents.Phase.ASYNC_END ||\n event.phase === Types.TraceEvents.Phase.ASYNC_NESTABLE_END) {\n this.setEndTime(event.startTime);\n // FIXME: ideally, we shouldn't do this, but this makes the logic of converting\n // async console events to sync ones much simpler.\n this.steps[0].setEndTime(event.startTime);\n }\n }\n}\n\nclass ProfileEventsGroup {\n children: Event[];\n constructor(event: Event) {\n this.children = [event];\n }\n\n addChild(event: Event): void {\n this.children.push(event);\n }\n}\n\nclass NamedObject {\n model: TracingModel;\n readonly idInternal: number;\n #nameInternal: string;\n #sortIndex: number;\n constructor(model: TracingModel, id: number) {\n this.model = model;\n this.idInternal = id;\n this.#nameInternal = '';\n this.#sortIndex = 0;\n }\n\n static sort<Item extends NamedObject>(array: Item[]): Item[] {\n return array.sort((a, b) => {\n return a.#sortIndex !== b.#sortIndex ? a.#sortIndex - b.#sortIndex : a.name().localeCompare(b.name());\n });\n }\n\n setName(name: string): void {\n this.#nameInternal = name;\n }\n\n name(): string {\n return this.#nameInternal;\n }\n\n id(): number {\n return this.idInternal;\n }\n\n setSortIndex(sortIndex: number): void {\n this.#sortIndex = sortIndex;\n }\n\n getModel(): TracingModel {\n return this.model;\n }\n}\n\nexport class Process extends NamedObject {\n readonly threads: Map<number, Thread>;\n readonly #threadByNameInternal: Map<string, Thread|null>;\n constructor(model: TracingModel, id: number) {\n super(model, id);\n this.threads = new Map();\n this.#threadByNameInternal = new Map();\n }\n\n threadById(id: number): Thread {\n let thread = this.threads.get(id);\n if (!thread) {\n thread = new Thread(this, id);\n this.threads.set(id, thread);\n }\n return thread;\n }\n\n threadByName(name: string): Thread|null {\n return this.#threadByNameInternal.get(name) || null;\n }\n\n setThreadByName(name: string, thread: Thread): void {\n this.#threadByNameInternal.set(name, thread);\n }\n\n addEvent(payload: EventPayload): Event|null {\n return this.threadById(payload.tid).addEvent(payload);\n }\n\n sortedThreads(): Thread[] {\n return NamedObject.sort([...this.threads.values()]);\n }\n}\n\nexport class Thread extends NamedObject {\n readonly #processInternal: Process;\n #eventsInternal: Event[];\n readonly #asyncEventsInternal: AsyncEvent[];\n #lastTopLevelEvent: Event|null;\n constructor(process: Process, id: number) {\n super(process.getModel(), id);\n this.#processInternal = process;\n\n this.#eventsInternal = [];\n this.#asyncEventsInternal = [];\n this.#lastTopLevelEvent = null;\n }\n\n /**\n * Whilst we are in the middle of migrating to the new Phase enum, we need to\n * be able to compare events with the legacy phase to the new enum. This method\n * does this by casting the event phase to a string, ensuring we can compare it\n * against either enum. Once the migration is complete (crbug.com/1417587), we\n * will be able to use === to compare with no TS errors and this method can be\n * removed.\n */\n #eventMatchesPhase(event: Event, phase: Types.TraceEvents.Phase): boolean {\n return (event.phase as string) === phase;\n }\n\n tracingComplete(): void {\n this.#asyncEventsInternal.sort(Event.compareStartTime);\n this.#eventsInternal.sort(Event.compareStartTime);\n const stack: Event[] = [];\n const toDelete = new Set<number>();\n for (let i = 0; i < this.#eventsInternal.length; ++i) {\n const e = this.#eventsInternal[i];\n e.ordinal = i;\n if (this.#eventMatchesPhase(e, Types.TraceEvents.Phase.END)) {\n toDelete.add(i); // Mark for removal.\n // Quietly ignore unbalanced close events, they're legit (we could have missed start one).\n if (!stack.length) {\n continue;\n }\n const top = stack.pop();\n if (!top) {\n continue;\n }\n if (top.name !== e.name || top.categoriesString !== e.categoriesString) {\n console.error(\n 'B/E events mismatch at ' + top.startTime + ' (' + top.name + ') vs. ' + e.startTime + ' (' + e.name +\n ')');\n } else {\n top.complete(e);\n }\n } else if (this.#eventMatchesPhase(e, Types.TraceEvents.Phase.BEGIN)) {\n stack.push(e);\n }\n }\n\n // Handle Begin events with no matching End.\n // This commonly happens due to a bug in the trace machinery. See crbug.com/982252\n while (stack.length) {\n const event = stack.pop();\n if (event) {\n // Masquerade the event as Instant, so it's rendered to the user.\n // The ideal fix is resolving crbug.com/1021571, but handling that without a perfetto migration appears prohibitive\n event.phase = Types.TraceEvents.Phase.INSTANT;\n }\n }\n this.#eventsInternal = this.#eventsInternal.filter((_, idx) => !toDelete.has(idx));\n }\n\n addEvent(payload: EventPayload): Event|null {\n const event = payload.ph === Types.TraceEvents.Phase.OBJECT_SNAPSHOT ? ObjectSnapshot.fromPayload(payload, this) :\n PayloadEvent.fromPayload(payload, this);\n if (TracingModel.isTopLevelEvent(event)) {\n // Discard nested \"top-level\" events.\n const lastTopLevelEvent = this.#lastTopLevelEvent;\n if (lastTopLevelEvent && (lastTopLevelEvent.endTime || 0) > event.startTime) {\n return null;\n }\n this.#lastTopLevelEvent = event;\n }\n this.#eventsInternal.push(event);\n return event;\n }\n\n addAsyncEvent(asyncEvent: AsyncEvent): void {\n this.#asyncEventsInternal.push(asyncEvent);\n }\n\n override setName(name: string): void {\n super.setName(name);\n this.#processInternal.setThreadByName(name, this);\n }\n\n process(): Process {\n return this.#processInternal;\n }\n\n events(): Event[] {\n return this.#eventsInternal;\n }\n\n asyncEvents(): AsyncEvent[] {\n return this.#asyncEventsInternal;\n }\n\n removeEventsByName(name: string): Event[] {\n const extracted: Event[] = [];\n this.#eventsInternal = this.#eventsInternal.filter(e => {\n if (!e) {\n return false;\n }\n\n if (e.name !== name) {\n return true;\n }\n\n extracted.push(e);\n return false;\n });\n\n return extracted;\n }\n}\n\nexport interface TimesForEventMs {\n startTime: Types.Timing.MilliSeconds;\n endTime?: Types.Timing.MilliSeconds;\n selfTime: Types.Timing.MilliSeconds;\n duration: Types.Timing.MilliSeconds;\n}\n\nexport function timesForEventInMilliseconds(event: Event|Types.TraceEvents.TraceEventData): TimesForEventMs {\n if (event instanceof Event) {\n return {\n startTime: Types.Timing.MilliSeconds(event.startTime),\n endTime: event.endTime ? Types.Timing.MilliSeconds(event.endTime) : undefined,\n duration: Types.Timing.MilliSeconds(event.duration || 0),\n selfTime: Types.Timing.MilliSeconds(event.selfTime),\n };\n }\n return Helpers.Timing.eventTimingsMilliSeconds(event);\n}\n// Parsed categories are cached to prevent calling cat.split() multiple\n// times on the same categories string.\nconst parsedCategories = new Map<string, Set<string>>();\nexport function eventHasCategory(event: CompatibleTraceEvent, category: string): boolean {\n if (event instanceof Event) {\n return event.hasCategory(category);\n }\n let parsedCategoriesForEvent = parsedCategories.get(event.cat);\n if (!parsedCategoriesForEvent) {\n parsedCategoriesForEvent = new Set(event.cat.split(',') || []);\n }\n return parsedCategoriesForEvent.has(category);\n}\n\nexport function phaseForEvent(event: Event|Types.TraceEvents.TraceEventData): Types.TraceEvents.Phase {\n if (event instanceof Event) {\n return event.phase;\n }\n return event.ph;\n}\n\nexport function threadIDForEvent(event: Event|Types.TraceEvents.TraceEventData): Types.TraceEvents.ThreadID {\n if (event instanceof Event) {\n return event.thread.idInternal as Types.TraceEvents.ThreadID;\n }\n return event.tid;\n}\n\nexport function eventIsFromNewEngine(event: CompatibleTraceEvent|null): event is Types.TraceEvents.TraceEventData {\n return event !== null && !(event instanceof Event);\n}\n\nexport type CompatibleTraceEvent = Event|Types.TraceEvents.TraceEventData;\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../core/platform/platform.js';\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\n\nimport type * as Types from './types/types.js';\nimport {TraceProcessor, TraceParseProgressEvent} from './Processor.js';\n\n// Note: this model is implemented in a way that can support multiple trace\n// processors. Currently there is only one implemented, but you will see\n// references to \"processors\" plural because it can easily be extended in the future.\n\nexport interface ParseConfig {\n metadata?: Types.File.MetaData;\n // Unused but will eventually be consumed by UIUtils Linkifier, etc.\n isFreshRecording?: boolean;\n}\n\n/**\n * The new trace engine model we are migrating to. The Model is responsible for\n * parsing arrays of raw trace events and storing the resulting data. It can\n * store multiple traces at once, and can return the data for any of them.\n * Currently as we migrate from the old engine to this, we are turning on the\n * model handlers incrementally as we need the data, to save performance costs\n * of running handlers that we do not use. Therefore, when the model is\n * constructed we pass through a set of handlers that should be used. Once we\n * have migrated all tracks in the Performance Panel to this model, we can\n * remove this ability to run a subset of handlers, as we will need all handlers\n * to be used at that point. For tests, if you want to construct a model with\n * all handlers, you can use the static `Model.createWithAllHandlers` method.\n **/\nexport class Model<EnabledModelHandlers extends {[key: string]: Handlers.Types.TraceEventHandler}> extends EventTarget {\n readonly #traces: ParsedTraceFile<EnabledModelHandlers>[] = [];\n readonly #nextNumberByDomain = new Map<string, number>();\n\n readonly #recordingsAvailable: string[] = [];\n #lastRecordingIndex = 0;\n #processor: TraceProcessor<Handlers.Types.HandlersWithMeta<EnabledModelHandlers>>;\n\n static createWithAllHandlers(): Model<typeof Handlers.ModelHandlers> {\n return new Model(Handlers.ModelHandlers);\n }\n\n static createWithRequiredHandlersForMigration(): Model<{\n [K in keyof typeof Handlers.Migration.ENABLED_TRACE_HANDLERS]: typeof Handlers.Migration.ENABLED_TRACE_HANDLERS[K];\n }> {\n return new Model(Handlers.Migration.ENABLED_TRACE_HANDLERS);\n }\n\n constructor(handlers: EnabledModelHandlers) {\n super();\n this.#processor = new TraceProcessor(handlers);\n }\n /**\n * Parses an array of trace events into a structured object containing all the\n * information parsed by the trace handlers.\n * You can `await` this function to pause execution until parsing is complete,\n * or instead rely on the `ModuleUpdateEvent` that is dispatched when the\n * parsing is finished.\n *\n * Once parsed, you then have to call the `traceParsedData` method, providing an\n * index of the trace you want to have the data for. This is because any model\n * can store a number of traces. Each trace is given an index, which starts at 0\n * and increments by one as a new trace is parsed.\n *\n * @example\n * // Awaiting the parse method() to block until parsing complete\n * await this.traceModel.parse(events);\n * const data = this.traceModel.traceParsedData(0)\n *\n * @example\n * // Using an event listener to be notified when tracing is complete.\n * this.traceModel.addEventListener(Trace.ModelUpdateEvent.eventName, (event) => {\n * if(event.data.data === 'done') {\n * // trace complete\n * const data = this.traceModel.traceParsedData(0);\n * }\n * });\n * void this.traceModel.parse(events);\n **/\n async parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], config?: ParseConfig): Promise<void> {\n const metadata = config?.metadata || {};\n const isFreshRecording = config?.isFreshRecording || false;\n // During parsing, periodically update any listeners on each processors'\n // progress (if they have any updates).\n const onTraceUpdate = (event: Event): void => {\n const {data} = event as TraceParseProgressEvent;\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.PROGRESS_UPDATE, data: data}));\n };\n\n this.#processor.addEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n\n // Create a parsed trace file. It will be populated with data from the processor.\n const file: ParsedTraceFile<EnabledModelHandlers> = {\n traceEvents,\n metadata,\n traceParsedData: null,\n };\n\n try {\n // Wait for all outstanding promises before finishing the async execution,\n // but perform all tasks in parallel.\n await this.#processor.parse(traceEvents, isFreshRecording);\n this.#storeParsedFileData(file, this.#processor.data);\n // We only push the file onto this.#traces here once we know it's valid\n // and there's been no errors in the parsing.\n this.#traces.push(file);\n } catch (e) {\n throw e;\n } finally {\n // All processors have finished parsing, no more updates are expected.\n this.#processor.removeEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n // Finally, update any listeners that all processors are 'done'.\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.COMPLETE, data: 'done'}));\n }\n }\n\n #storeParsedFileData(\n file: ParsedTraceFile<EnabledModelHandlers>,\n data: Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null): void {\n file.traceParsedData = data;\n this.#lastRecordingIndex++;\n let recordingName = `Trace ${this.#lastRecordingIndex}`;\n let origin: string|null = null;\n if (file.traceParsedData) {\n origin = Helpers.Trace.extractOriginFromTrace(file.traceParsedData.Meta.mainFrameURL);\n if (origin) {\n const nextSequenceForDomain = Platform.MapUtilities.getWithDefault(this.#nextNumberByDomain, origin, () => 1);\n recordingName = `${origin} (${nextSequenceForDomain})`;\n this.#nextNumberByDomain.set(origin, nextSequenceForDomain + 1);\n }\n }\n this.#recordingsAvailable.push(recordingName);\n }\n\n /**\n * Returns the parsed trace data indexed by the order in which it was stored.\n * If no index is given, the last stored parsed data is returned.\n */\n traceParsedData(index: number = this.#traces.length - 1):\n Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].traceParsedData;\n }\n\n metadata(index: number): Types.File.MetaData|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].metadata;\n }\n\n traceEvents(index: number): readonly Types.TraceEvents.TraceEventData[]|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].traceEvents;\n }\n\n size(): number {\n return this.#traces.length;\n }\n\n deleteTraceByIndex(recordingIndex: number): void {\n this.#traces.splice(recordingIndex, 1);\n this.#recordingsAvailable.splice(recordingIndex, 1);\n }\n\n getRecordingsAvailable(): string[] {\n return this.#recordingsAvailable;\n }\n\n resetProcessor(): void {\n this.#processor.reset();\n }\n}\n\n/**\n * This parsed trace file is used by the Model. It keeps multiple instances\n * of these so that the user can swap between them. The key is that it is\n * essentially the TraceFile plus whatever the model has parsed from it.\n */\nexport type ParsedTraceFile<Handlers extends {[key: string]: Handlers.Types.TraceEventHandler}> = Types.File.TraceFile&{\n traceParsedData: Handlers.Types.EnabledHandlerDataWithMeta<Handlers>| null,\n};\n\nexport const enum ModelUpdateType {\n COMPLETE = 'COMPLETE',\n PROGRESS_UPDATE = 'PROGRESS_UPDATE',\n}\n\nexport type ModelUpdateEventData = ModelUpdateEventComplete|ModelUpdateEventProgress;\n\nexport type ModelUpdateEventComplete = {\n type: ModelUpdateType.COMPLETE,\n data: 'done',\n};\nexport type ModelUpdateEventProgress = {\n type: ModelUpdateType.PROGRESS_UPDATE,\n data: TraceParseEventProgressData,\n};\n\nexport type TraceParseEventProgressData = {\n index: number,\n total: number,\n};\n\nexport class ModelUpdateEvent extends Event {\n static readonly eventName = 'modelupdate';\n constructor(public data: ModelUpdateEventData) {\n super(ModelUpdateEvent.eventName);\n }\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [ModelUpdateEvent.eventName]: ModelUpdateEvent;\n }\n}\n\nexport function isModelUpdateDataComplete(eventData: ModelUpdateEventData): eventData is ModelUpdateEventComplete {\n return eventData.type === ModelUpdateType.COMPLETE;\n}\n\nexport function isModelUpdateDataProgress(eventData: ModelUpdateEventData): eventData is ModelUpdateEventProgress {\n return eventData.type === ModelUpdateType.PROGRESS_UPDATE;\n}\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\nimport type * as Types from './types/types.js';\nimport * as Handlers from './handlers/handlers.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport type TraceParseEventProgressData = {\n index: number,\n total: number,\n};\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport class TraceProcessor<EnabledModelHandlers extends {[key: string]: Handlers.Types.TraceEventHandler}> extends\n EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n readonly #traceHandlers: Handlers.Types.HandlersWithMeta<EnabledModelHandlers>;\n #pauseDuration: number;\n #eventsPerChunk: number;\n #status = Status.IDLE;\n\n static createWithAllHandlers(): TraceProcessor<typeof Handlers.ModelHandlers> {\n return new TraceProcessor(Handlers.ModelHandlers);\n }\n\n constructor(traceHandlers: EnabledModelHandlers, {pauseDuration = 1, eventsPerChunk = 15_000} = {}) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n this.#pauseDuration = pauseDuration;\n this.#eventsPerChunk = eventsPerChunk;\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: EnabledModelHandlers): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys: Set<Handlers.Types.TraceEventHandlerName> = new Set();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.TraceEventHandlerName);\n for (const depName of (handler.deps?.() || [])) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], freshRecording = false): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n try {\n this.#status = Status.PARSING;\n await this.#parse(traceEvents, freshRecording);\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n }\n }\n\n async #parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], freshRecording: boolean): Promise<void> {\n // This iterator steps through all events, periodically yielding back to the\n // main thread to avoid blocking execution. It uses `dispatchEvent` to\n // provide status update events, and other various bits of config like the\n // pause duration and frequency.\n const traceEventIterator = new TraceEventIterator(traceEvents, this.#pauseDuration, this.#eventsPerChunk);\n\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];\n // Reset.\n for (const handler of sortedHandlers) {\n handler.reset();\n }\n\n // Initialize.\n for (const handler of sortedHandlers) {\n handler.initialize?.(freshRecording);\n }\n\n // Handle each event.\n for await (const item of traceEventIterator) {\n if (item.kind === IteratorItemType.STATUS_UPDATE) {\n this.dispatchEvent(new TraceParseProgressEvent(item.data));\n continue;\n }\n for (const handler of sortedHandlers) {\n handler.handleEvent(item.data);\n }\n }\n\n // Finalize.\n for (const handler of sortedHandlers) {\n await handler.finalize?.();\n }\n }\n\n get data(): Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n const data = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n Object.assign(data, {[name]: handler.data()});\n }\n\n return data as Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>;\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event hander whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(\n traceHandlers: Partial<{[key in Handlers.Types.TraceEventHandlerName]: Handlers.Types.TraceEventHandler}>):\n Map<Handlers.Types.TraceEventHandlerName, Handlers.Types.TraceEventHandler> {\n const sortedMap = new Map<Handlers.Types.TraceEventHandlerName, Handlers.Types.TraceEventHandler>();\n const visited = new Set<Handlers.Types.TraceEventHandlerName>();\n const visitHandler = (handlerName: Handlers.Types.TraceEventHandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.TraceEventHandlerName);\n }\n return sortedMap;\n}\n\nconst enum IteratorItemType {\n TRACE_EVENT = 1,\n STATUS_UPDATE = 2,\n}\n\ntype IteratorItem = IteratorTraceEventItem|IteratorStatusUpdateItem;\n\ntype IteratorTraceEventItem = {\n kind: IteratorItemType.TRACE_EVENT,\n data: Types.TraceEvents.TraceEventData,\n};\n\ntype IteratorStatusUpdateItem = {\n kind: IteratorItemType.STATUS_UPDATE,\n data: TraceParseEventProgressData,\n};\n\nclass TraceEventIterator {\n #eventCount: number;\n\n constructor(\n private traceEvents: readonly Types.TraceEvents.TraceEventData[], private pauseDuration: number,\n private eventsPerChunk: number) {\n this.#eventCount = 0;\n }\n\n async * [Symbol.asyncIterator](): AsyncGenerator<IteratorItem, void, void> {\n for (let i = 0, length = this.traceEvents.length; i < length; i++) {\n // Every so often we take a break just to render.\n if (++this.#eventCount % this.eventsPerChunk === 0) {\n // Take the opportunity to provide status update events.\n yield {kind: IteratorItemType.STATUS_UPDATE, data: {index: i, total: length}};\n // Wait for rendering before resuming.\n await new Promise(resolve => setTimeout(resolve, this.pauseDuration));\n }\n\n yield {kind: IteratorItemType.TRACE_EVENT, data: this.traceEvents[i]};\n }\n }\n}\n"],
5
- "mappings": "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,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,KAAK,OAAO,KAAK,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,OAAO,MAAM,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM,QAAQ,KAAK,QAAQ,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,KAAK,SAAS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",
3
+ "sources": ["../../../../front_end/models/trace/trace.ts", "../../../../front_end/models/trace/handlers/handlers.ts", "../../../../front_end/models/trace/handlers/Migration.ts", "../../../../front_end/models/trace/handlers/AnimationHandler.ts", "../../../../front_end/core/platform/array-utilities.ts", "../../../../front_end/core/platform/DevToolsPath.ts", "../../../../front_end/core/platform/map-utilities.ts", "../../../../front_end/core/platform/number-utilities.ts", "../../../../front_end/core/platform/typescript-utilities.ts", "../../../../front_end/core/platform/platform.ts", "../../../../front_end/models/trace/types/types.ts", "../../../../front_end/models/trace/types/Configuration.ts", "../../../../front_end/models/trace/types/File.ts", "../../../../front_end/models/trace/types/Timing.ts", "../../../../front_end/models/trace/types/TraceEvents.ts", "../../../../front_end/models/trace/handlers/types.ts", "../../../../front_end/models/trace/handlers/GPUHandler.ts", "../../../../front_end/models/trace/handlers/MetaHandler.ts", "../../../../front_end/models/trace/helpers/helpers.ts", "../../../../front_end/models/trace/helpers/SamplesIntegrator.ts", "../../../../front_end/core/root/Runtime.ts", "../../../../front_end/models/trace/helpers/Timing.ts", "../../../../front_end/models/trace/helpers/Trace.ts", "../../../../front_end/models/trace/handlers/LayoutShiftsHandler.ts", "../../../../front_end/models/trace/handlers/PageLoadMetricsHandler.ts", "../../../../front_end/models/trace/handlers/ScreenshotsHandler.ts", "../../../../front_end/models/trace/handlers/MemoryHandler.ts", "../../../../front_end/models/trace/handlers/NetworkRequestsHandler.ts", "../../../../front_end/models/trace/handlers/UserInteractionsHandler.ts", "../../../../front_end/models/trace/handlers/UserTimingsHandler.ts", "../../../../front_end/models/trace/handlers/WarningsHandler.ts", "../../../../front_end/models/trace/handlers/WorkersHandler.ts", "../../../../front_end/models/trace/handlers/ModelHandlers.ts", "../../../../front_end/models/trace/handlers/AuctionWorkletsHandler.ts", "../../../../front_end/models/trace/handlers/LargestImagePaintHandler.ts", "../../../../front_end/models/trace/handlers/LargestTextPaintHandler.ts", "../../../../front_end/models/trace/handlers/RendererHandler.ts", "../../../../front_end/models/trace/handlers/SamplesHandler.ts", "../../../../front_end/models/cpu_profile/CPUProfileDataModel.ts", "../../../../front_end/models/cpu_profile/ProfileTreeModel.ts", "../../../../front_end/models/trace/LegacyTracingModel.ts", "../../../../front_end/models/trace/ModelImpl.ts", "../../../../front_end/models/trace/Processor.ts", "../../../../front_end/models/trace/TreeManipulator.ts"],
4
+ "sourcesContent": ["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Extras from './extras/extras.js';\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\n// Purposefully use a shorter name here so references to this are\n// Legacy.TracingModel.\nimport * as Legacy from './LegacyTracingModel.js';\nimport * as TraceModel from './ModelImpl.js';\nimport * as Processor from './Processor.js';\nimport * as TracingManager from './TracingManager.js';\nimport * as TreeManipulator from './TreeManipulator.js';\nimport * as Types from './types/types.js';\n\nexport {\n Extras,\n Handlers,\n Helpers,\n Legacy,\n Processor,\n TraceModel,\n TracingManager,\n TreeManipulator,\n Types,\n};\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as Migration from './Migration.js';\nexport * as ModelHandlers from './ModelHandlers.js';\nexport * as Types from './types.js';\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Animations from './AnimationHandler.js';\nimport * as GPU from './GPUHandler.js';\nimport * as LayoutShifts from './LayoutShiftsHandler.js';\nimport * as Memory from './MemoryHandler.js';\nimport * as NetworkRequests from './NetworkRequestsHandler.js';\nimport * as PageLoadMetrics from './PageLoadMetricsHandler.js';\nimport * as Screenshots from './ScreenshotsHandler.js';\nimport type * as Renderer from './RendererHandler.js';\nimport type * as Samples from './SamplesHandler.js';\nimport * as UserInteractions from './UserInteractionsHandler.js';\nimport * as UserTimings from './UserTimingsHandler.js';\nimport * as Warnings from './WarningsHandler.js';\nimport * as Workers from './WorkersHandler.js';\n\nimport type * as Types from './types.js';\n\n// As we migrate the data engine we are incrementally enabling the new handlers\n// one by one, so we do not waste effort parsing data that we do not use. This\n// object should be updated when we add a new handler to enable it.\nexport const ENABLED_TRACE_HANDLERS = {\n Animations,\n UserTimings,\n PageLoadMetrics,\n UserInteractions,\n LayoutShifts,\n Screenshots,\n GPU,\n Memory,\n NetworkRequests,\n Warnings,\n Workers,\n};\n\nexport type EnabledHandlersDuringMigration = typeof ENABLED_TRACE_HANDLERS;\n\n// Renderer and Samples handler are only executed when the panel is run\n// from the component examples server. Thus we mark them as optional\n// properties during the migration.\nexport type PartialTraceData = Readonly<Types.EnabledHandlerDataWithMeta<EnabledHandlersDuringMigration>>&{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n readonly Renderer?: Readonly<ReturnType<typeof Renderer['data']>>,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n readonly Samples?: Readonly<ReturnType<typeof Samples['data']>>,\n};\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\nconst animations: Types.TraceEvents.TraceEventAnimation[] = [];\nconst animationsSyntheticEvents: Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[] = [];\n\nexport interface AnimationData {\n animations: readonly Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[];\n}\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n animations.length = 0;\n animationsSyntheticEvents.length = 0;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventAnimation(event)) {\n animations.push(event);\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n const matchedEvents = matchBeginningAndEndEvents();\n\n createSortedAnimationsSyntheticEvents(matchedEvents);\n\n handlerState = HandlerState.FINALIZED;\n}\n\nfunction matchBeginningAndEndEvents(): Map<string, {\n begin: Types.TraceEvents.TraceEventNestableAsyncBegin | null,\n end: Types.TraceEvents.TraceEventNestableAsyncEnd | null,\n}> {\n // map to store begin and end of the event\n const matchedEvents: Map<string, {\n begin: Types.TraceEvents.TraceEventNestableAsyncBegin | null,\n end: Types.TraceEvents.TraceEventNestableAsyncEnd | null,\n }> = new Map();\n\n // looking for start and end\n for (const event of animations) {\n const id = event.id2;\n\n if (id === undefined) {\n continue;\n }\n\n const syntheticId = `${event.cat}:${id.local}:${event.name}`;\n\n const otherEventsWithID = Platform.MapUtilities.getWithDefault(matchedEvents, syntheticId, () => {\n return {begin: null, end: null};\n });\n\n const isStartEvent = event.ph === Types.TraceEvents.Phase.ASYNC_NESTABLE_START;\n const isEndEvent = event.ph === Types.TraceEvents.Phase.ASYNC_NESTABLE_END;\n\n if (isStartEvent) {\n otherEventsWithID.begin = {\n ...event,\n ph: Types.TraceEvents.Phase.ASYNC_NESTABLE_START,\n id2: {\n local: event.id2?.local,\n },\n id: event.args?.id,\n };\n } else if (isEndEvent) {\n otherEventsWithID.end = {\n ...event,\n ph: Types.TraceEvents.Phase.ASYNC_NESTABLE_END,\n id2: {\n local: event.id2?.local,\n },\n id: event.args?.id,\n };\n }\n }\n\n return matchedEvents;\n}\n\nfunction createSortedAnimationsSyntheticEvents(matchedEvents: Map<string, {\n begin: Types.TraceEvents.TraceEventNestableAsyncBegin | null,\n end: Types.TraceEvents.TraceEventNestableAsyncEnd | null,\n}>): void {\n for (const [id, eventsPair] of matchedEvents.entries()) {\n if (!eventsPair.begin || !eventsPair.end) {\n continue;\n }\n\n const event: Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent = {\n cat: eventsPair.end.cat,\n ph: eventsPair.end.ph,\n pid: eventsPair.end.pid,\n tid: eventsPair.end.tid,\n id,\n name: eventsPair.begin.name,\n dur: Types.Timing.MicroSeconds(eventsPair.end.ts - eventsPair.begin.ts),\n ts: eventsPair.begin.ts,\n args: {\n data: {\n beginEvent: eventsPair.begin,\n endEvent: eventsPair.end,\n },\n },\n };\n\n if (event.dur < 0) {\n // We have seen in the backend that sometimes animation events get\n // generated with multiple begin entries, or multiple end entries, and this\n // can cause invalid data on the performance panel, so we drop them.\n // crbug.com/1472375\n continue;\n }\n animationsSyntheticEvents.push(event);\n }\n\n animationsSyntheticEvents.sort((a, b) => a.ts - b.ts);\n}\n\nexport function data(): AnimationData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Animation handler is not finalized');\n }\n\n return {\n animations: Array.from(animationsSyntheticEvents),\n };\n}\n", "// Copyright (c) 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport const removeElement = <T>(array: T[], element: T, firstOnly?: boolean): boolean => {\n let index = array.indexOf(element);\n if (index === -1) {\n return false;\n }\n if (firstOnly) {\n array.splice(index, 1);\n return true;\n }\n for (let i = index + 1, n = array.length; i < n; ++i) {\n if (array[i] !== element) {\n array[index++] = array[i];\n }\n }\n array.length = index;\n return true;\n};\n\ntype NumberComparator = (a: number, b: number) => number;\n\nfunction swap(array: number[], i1: number, i2: number): void {\n const temp = array[i1];\n array[i1] = array[i2];\n array[i2] = temp;\n}\n\nfunction partition(\n array: number[], comparator: NumberComparator, left: number, right: number, pivotIndex: number): number {\n const pivotValue = array[pivotIndex];\n swap(array, right, pivotIndex);\n let storeIndex = left;\n for (let i = left; i < right; ++i) {\n if (comparator(array[i], pivotValue) < 0) {\n swap(array, storeIndex, i);\n ++storeIndex;\n }\n }\n swap(array, right, storeIndex);\n return storeIndex;\n}\n\nfunction quickSortRange(\n array: number[], comparator: NumberComparator, left: number, right: number, sortWindowLeft: number,\n sortWindowRight: number): void {\n if (right <= left) {\n return;\n }\n const pivotIndex = Math.floor(Math.random() * (right - left)) + left;\n const pivotNewIndex = partition(array, comparator, left, right, pivotIndex);\n if (sortWindowLeft < pivotNewIndex) {\n quickSortRange(array, comparator, left, pivotNewIndex - 1, sortWindowLeft, sortWindowRight);\n }\n if (pivotNewIndex < sortWindowRight) {\n quickSortRange(array, comparator, pivotNewIndex + 1, right, sortWindowLeft, sortWindowRight);\n }\n}\n\nexport function sortRange(\n array: number[], comparator: NumberComparator, leftBound: number, rightBound: number, sortWindowLeft: number,\n sortWindowRight: number): number[] {\n if (leftBound === 0 && rightBound === (array.length - 1) && sortWindowLeft === 0 && sortWindowRight >= rightBound) {\n array.sort(comparator);\n } else {\n quickSortRange(array, comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight);\n }\n return array;\n}\nexport const binaryIndexOf = <T, S>(array: T[], value: S, comparator: (a: S, b: T) => number): number => {\n const index = lowerBound(array, value, comparator);\n return index < array.length && comparator(value, array[index]) === 0 ? index : -1;\n};\n\nfunction mergeOrIntersect<T>(\n array1: T[], array2: T[], comparator: (a: T, b: T) => number, mergeNotIntersect: boolean): T[] {\n const result = [];\n let i = 0;\n let j = 0;\n while (i < array1.length && j < array2.length) {\n const compareValue = comparator(array1[i], array2[j]);\n if (mergeNotIntersect || !compareValue) {\n result.push(compareValue <= 0 ? array1[i] : array2[j]);\n }\n if (compareValue <= 0) {\n i++;\n }\n if (compareValue >= 0) {\n j++;\n }\n }\n if (mergeNotIntersect) {\n while (i < array1.length) {\n result.push(array1[i++]);\n }\n while (j < array2.length) {\n result.push(array2[j++]);\n }\n }\n return result;\n}\n\nexport const intersectOrdered = <T>(array1: T[], array2: T[], comparator: (a: T, b: T) => number): T[] => {\n return mergeOrIntersect(array1, array2, comparator, false);\n};\n\nexport const mergeOrdered = <T>(array1: T[], array2: T[], comparator: (a: T, b: T) => number): T[] => {\n return mergeOrIntersect(array1, array2, comparator, true);\n};\n\nexport const DEFAULT_COMPARATOR = (a: string|number, b: string|number): -1|0|1 => {\n return a < b ? -1 : (a > b ? 1 : 0);\n};\n\n/**\n * Returns the index of the element closest to the needle that is equal to or\n * greater than it. Assumes that the provided array is sorted.\n *\n * If no element is found, the right bound is returned.\n *\n * Uses the provided comparator function to determine if two items are equal or\n * if one is greater than the other. If you are working with strings or\n * numbers, you can use ArrayUtilities.DEFAULT_COMPARATOR. Otherwise, you\n * should define one that takes the needle element and an element from the\n * array and returns a positive or negative number to indicate which is greater\n * than the other.\n *\n * When specified, |left| (inclusive) and |right| (exclusive) indices\n * define the search window.\n */\nexport function lowerBound<T>(\n array: Uint32Array|Int32Array, needle: T, comparator: (needle: T, b: number) => number, left?: number,\n right?: number): number;\nexport function lowerBound<S, T>(\n array: S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function lowerBound<S, T, A extends S[]>(\n array: A, needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number {\n let l = left || 0;\n let r = right !== undefined ? right : array.length;\n while (l < r) {\n const m = (l + r) >> 1;\n if (comparator(needle, array[m]) > 0) {\n l = m + 1;\n } else {\n r = m;\n }\n }\n return r;\n}\n\n/**\n * Returns the index of the element closest to the needle that is greater than\n * it. Assumes that the provided array is sorted.\n *\n * If no element is found, the right bound is returned.\n *\n * Uses the provided comparator function to determine if two items are equal or\n * if one is greater than the other. If you are working with strings or\n * numbers, you can use ArrayUtilities.DEFAULT_COMPARATOR. Otherwise, you\n * should define one that takes the needle element and an element from the\n * array and returns a positive or negative number to indicate which is greater\n * than the other.\n *\n * When specified, |left| (inclusive) and |right| (exclusive) indices\n * define the search window.\n */\nexport function upperBound<T>(\n array: Uint32Array, needle: T, comparator: (needle: T, b: number) => number, left?: number, right?: number): number;\nexport function upperBound<S, T>(\n array: S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function upperBound<S, T, A extends S[]>(\n array: A, needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number {\n let l = left || 0;\n let r = right !== undefined ? right : array.length;\n while (l < r) {\n const m = (l + r) >> 1;\n if (comparator(needle, array[m]) >= 0) {\n l = m + 1;\n } else {\n r = m;\n }\n }\n return r;\n}\n\nconst enum NearestSearchStart {\n BEGINNING = 'BEGINNING',\n END = 'END',\n}\n/**\n * Obtains the first or last item in the array that satisfies the predicate function.\n * So, for example, if the array were arr = [2, 4, 6, 8, 10], and you are looking for\n * the last item arr[i] such that arr[i] < 5 you would be returned 1, because\n * array[1] is 4, the last item in the array that satisfies the\n * predicate function.\n *\n * If instead you were looking for the first item in the same array that satisfies\n * arr[i] > 5 you would be returned 2 because array[2] = 6.\n *\n * Please note: this presupposes that the array is already ordered.\n */\nfunction nearestIndex<T>(\n arr: readonly T[], predicate: (arrayItem: T) => boolean, searchStart: NearestSearchStart): number|null {\n const searchFromEnd = searchStart === NearestSearchStart.END;\n if (arr.length === 0) {\n return null;\n }\n\n let left = 0;\n let right = arr.length - 1;\n let pivot = 0;\n let matchesPredicate = false;\n let moveToTheRight = false;\n let middle = 0;\n do {\n middle = left + (right - left) / 2;\n pivot = searchFromEnd ? Math.ceil(middle) : Math.floor(middle);\n matchesPredicate = predicate(arr[pivot]);\n moveToTheRight = matchesPredicate === searchFromEnd;\n if (moveToTheRight) {\n left = Math.min(right, pivot + (left === pivot ? 1 : 0));\n } else {\n right = Math.max(left, pivot + (right === pivot ? -1 : 0));\n }\n } while (right !== left);\n\n // Special-case: the indexed item doesn't pass the predicate. This\n // occurs when none of the items in the array are a match for the\n // predicate.\n if (!predicate(arr[left])) {\n return null;\n }\n return left;\n}\n\n/**\n * Obtains the first item in the array that satisfies the predicate function.\n * So, for example, if the array was arr = [2, 4, 6, 8, 10], and you are looking for\n * the first item arr[i] such that arr[i] > 5 you would be returned 2, because\n * array[2] is 6, the first item in the array that satisfies the\n * predicate function.\n *\n * Please note: this presupposes that the array is already ordered.\n */\nexport function nearestIndexFromBeginning<T>(arr: T[], predicate: (arrayItem: T) => boolean): number|null {\n return nearestIndex(arr, predicate, NearestSearchStart.BEGINNING);\n}\n\n/**\n * Obtains the last item in the array that satisfies the predicate function.\n * So, for example, if the array was arr = [2, 4, 6, 8, 10], and you are looking for\n * the last item arr[i] such that arr[i] < 5 you would be returned 1, because\n * arr[1] is 4, the last item in the array that satisfies the\n * predicate function.\n *\n * Please note: this presupposes that the array is already ordered.\n */\n\nexport function nearestIndexFromEnd<T>(arr: readonly T[], predicate: (arrayItem: T) => boolean): number|null {\n return nearestIndex(arr, predicate, NearestSearchStart.END);\n}\n\n// Type guard for ensuring that `arr` does not contain null or undefined\nexport function arrayDoesNotContainNullOrUndefined<T>(arr: (T|null|undefined)[]): arr is T[] {\n return !arr.includes(null) && !arr.includes(undefined);\n}\n", "// Copyright 2021 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {type Brand} from './brand.js';\n\n/**\n * File paths in DevTools that are represented as URLs\n * @example\n * \u201Cfile:///Hello%20World/file/js\u201D\n */\nexport type UrlString = Brand<string, 'UrlString'>;\nexport const EmptyUrlString = '' as UrlString;\n\n/**\n * File paths in DevTools that are represented as unencoded absolute\n * or relative paths\n * @example\n * \u201C/Hello World/file.js\u201D\n */\nexport type RawPathString = Brand<string, 'RawPathString'>;\nexport const EmptyRawPathString = '' as RawPathString;\n\n/**\n * File paths in DevTools that are represented as encoded paths\n * @example\n * \u201C/Hello%20World/file.js\u201D\n */\nexport type EncodedPathString = Brand<string, 'EncodedPathString'>;\nexport const EmptyEncodedPathString = '' as EncodedPathString;\n", "// Copyright (c) 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport const inverse = function<K, V>(map: Map<K, V>): Multimap<V, K> {\n const result = new Multimap<V, K>();\n for (const [key, value] of map.entries()) {\n result.set(value, key);\n }\n return result;\n};\n\nexport class Multimap<K, V> {\n private map = new Map<K, Set<V>>();\n\n set(key: K, value: V): void {\n let set = this.map.get(key);\n if (!set) {\n set = new Set();\n this.map.set(key, set);\n }\n set.add(value);\n }\n\n get(key: K): Set<V> {\n return this.map.get(key) || new Set();\n }\n\n has(key: K): boolean {\n return this.map.has(key);\n }\n\n hasValue(key: K, value: V): boolean {\n const set = this.map.get(key);\n if (!set) {\n return false;\n }\n return set.has(value);\n }\n\n get size(): number {\n return this.map.size;\n }\n\n delete(key: K, value: V): boolean {\n const values = this.get(key);\n if (!values) {\n return false;\n }\n const result = values.delete(value);\n if (!values.size) {\n this.map.delete(key);\n }\n return result;\n }\n\n deleteAll(key: K): void {\n this.map.delete(key);\n }\n\n keysArray(): K[] {\n return [...this.map.keys()];\n }\n\n valuesArray(): V[] {\n const result = [];\n for (const set of this.map.values()) {\n result.push(...set.values());\n }\n return result;\n }\n\n clear(): void {\n this.map.clear();\n }\n}\n\n/**\n * Gets value for key, assigning a default if value is falsy.\n */\nexport function getWithDefault<K extends {}, V>(\n map: WeakMap<K, V>|Map<K, V>, key: K, defaultValueFactory: (key?: K) => V): V {\n let value = map.get(key);\n if (!value) {\n value = defaultValueFactory(key);\n map.set(key, value);\n }\n\n return value;\n}\n", "// Copyright (c) 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport const clamp = (num: number, min: number, max: number): number => {\n let clampedNumber = num;\n if (num < min) {\n clampedNumber = min;\n } else if (num > max) {\n clampedNumber = max;\n }\n return clampedNumber;\n};\n\nexport const mod = (m: number, n: number): number => {\n return ((m % n) + n) % n;\n};\n\nexport const bytesToString = (bytes: number): string => {\n if (bytes < 1000) {\n return `${bytes.toFixed(0)}\\xA0B`;\n }\n\n const kilobytes = bytes / 1000;\n if (kilobytes < 100) {\n return `${kilobytes.toFixed(1)}\\xA0kB`;\n }\n if (kilobytes < 1000) {\n return `${kilobytes.toFixed(0)}\\xA0kB`;\n }\n\n const megabytes = kilobytes / 1000;\n if (megabytes < 100) {\n return `${megabytes.toFixed(1)}\\xA0MB`;\n }\n return `${megabytes.toFixed(0)}\\xA0MB`;\n};\n\nexport const toFixedIfFloating = (value: string): string => {\n if (!value || Number.isNaN(Number(value))) {\n return value;\n }\n const number = Number(value);\n return number % 1 ? number.toFixed(3) : String(number);\n};\n\n/**\n * Rounds a number (including float) down.\n */\nexport const floor = (value: number, precision: number = 0): number => {\n const mult = Math.pow(10, precision);\n return Math.floor(value * mult) / mult;\n};\n\n/**\n * Computes the great common divisor for two numbers.\n * If the numbers are floats, they will be rounded to an integer.\n */\nexport const greatestCommonDivisor = (a: number, b: number): number => {\n a = Math.round(a);\n b = Math.round(b);\n while (b !== 0) {\n const t = b;\n b = a % b;\n a = t;\n }\n return a;\n};\n\nconst commonRatios = new Map([\n ['8\u22365', '16\u223610'],\n]);\n\nexport const aspectRatio = (width: number, height: number): string => {\n const divisor = greatestCommonDivisor(width, height);\n if (divisor !== 0) {\n width /= divisor;\n height /= divisor;\n }\n const result = `${width}\u2236${height}`;\n return commonRatios.get(result) || result;\n};\n\nexport const withThousandsSeparator = function(num: number): string {\n let str = String(num);\n const re = /(\\d+)(\\d{3})/;\n while (str.match(re)) {\n str = str.replace(re, '$1\\xA0$2');\n } // \\xa0 is a non-breaking space\n return str;\n};\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/**\n * This is useful to keep TypeScript happy in a test - if you have a value\n * that's potentially `null` you can use this function to assert that it isn't,\n * and satisfy TypeScript that the value is present.\n */\nexport function assertNotNullOrUndefined<T>(val: T): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n throw new Error(`Expected given value to not be null/undefined but it was: ${val}`);\n }\n}\n\nexport function assertNever(type: never, message: string): never {\n throw new Error(message);\n}\n\n/**\n * This is useful to check on the type-level that the unhandled cases of\n * a switch are exactly `T` (where T is usually a union type of enum values).\n * @param caseVariable\n */\nexport function assertUnhandled<T>(_caseVariable: T): T {\n return _caseVariable;\n}\n\nexport type FieldsThatExtend<Type, Selector> = {\n [Key in keyof Type]: Type[Key] extends Selector ? Key : never;\n}[keyof Type];\n\nexport type PickFieldsThatExtend<Type, Selector> = Pick<Type, FieldsThatExtend<Type, Selector>>;\n\n/**\n * Turns a Union type (a | b) into an Intersection type (a & b).\n * This is a helper type to implement the \"NoUnion\" guard.\n *\n * Adapted from https://stackoverflow.com/a/50375286.\n *\n * The tautological `T extends any` is necessary to trigger distributivity for\n * plain unions, e.g. in IntersectionFromUnion<'a'|'b'> TypeScript expands it\n * to ('a' extends any ? (arg: 'a') => void : never)\n * | ('b' extends any ? (arg: 'b') => void : never)\n *\n * The second extends clause then asks TypeScript to find a type of the form\n * `(arg: infer U) => void` that upper-bounds the union, i.e., intuitively,\n * a type that converts to each of the union members. This forces U to be the\n * intersection of 'a' and 'b' in the example.\n *\n * Please note that some intersection types are simply impossible, e.g.\n * `string & number`. There is no type that fulfills both at the same time. A\n * union of this kind is reduced to `never`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype IntersectionFromUnion<T> = (T extends any ? (arg: T) => void : never) extends((arg: infer U) => void) ? U : never;\n\n/**\n * When writing generic code it may be desired to disallow Union types from\n * being passed. This type can be used in those cases.\n *\n * function foo<T>(argument: NoUnion<T>) {...}\n *\n * Would result in a compile error for foo<a|b>(...); invocations as `argument`\n * would be typed as `never`.\n *\n * Adapted from https://stackoverflow.com/a/50641073.\n *\n * Conditional types become distributive when receiving a union type. To\n * prevent this from happening, we use `[T] extends [IntersectionFromUnion<T>]`\n * instead of `T extends IntersectionFromUnion<T>`.\n * See: https://www.typescriptlang.org/docs/handbook/2/conditional-types.html\n */\nexport type NoUnion<T> = [T] extends [IntersectionFromUnion<T>] ? T : never;\n", "/*\n * Copyright (C) 2019 Google Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nimport * as ArrayUtilities from './array-utilities.js';\nimport * as Brand from './brand.js';\nimport * as DateUtilities from './date-utilities.js';\nimport * as DevToolsPath from './DevToolsPath.js';\nimport * as DOMUtilities from './dom-utilities.js';\nimport * as KeyboardUtilities from './keyboard-utilities.js';\nimport * as MapUtilities from './map-utilities.js';\nimport * as NumberUtilities from './number-utilities.js';\nimport * as PromiseUtilities from './promise-utilities.js';\nimport * as SetUtilities from './set-utilities.js';\nimport * as StringUtilities from './string-utilities.js';\nimport * as Timing from './Timing.js';\nimport * as TypeScriptUtilities from './typescript-utilities.js';\nimport * as UIString from './UIString.js';\nimport * as UserVisibleError from './UserVisibleError.js';\n\n// export {DCHECK} from './dcheck.js';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function DCHECK(condition: () => boolean, message: string = 'DCHECK'): void {\n if (!condition()) {\n throw new Error(message + ':' + new Error().stack);\n }\n}\n\n/* `assertNotNull` also need to be exposed, as TypeScript does not\n * allow `asserts` functions to be used with qualified access\n * (e.g. `Platform.TypeScriptUtilities.assertNotNull` causes a\n * compiler error)\n */\nexport {assertNever, assertNotNullOrUndefined, assertUnhandled} from './typescript-utilities.js';\nexport {\n ArrayUtilities,\n Brand,\n DateUtilities,\n DevToolsPath,\n DOMUtilities,\n KeyboardUtilities,\n MapUtilities,\n NumberUtilities,\n PromiseUtilities,\n SetUtilities,\n StringUtilities,\n Timing,\n TypeScriptUtilities,\n UIString,\n UserVisibleError,\n};\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as Configuration from './Configuration.js';\nexport * as File from './File.js';\nexport * as Timing from './Timing.js';\nexport * as TraceEvents from './TraceEvents.js';\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport type Configuration = Readonly<{\n settings: {\n showNativeFunctionsInJSProfile: boolean,\n },\n}>;\n\nexport const DEFAULT: Configuration = {\n settings: {\n showNativeFunctionsInJSProfile: false,\n },\n};\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {type TraceEventData} from './TraceEvents.js';\nexport type TraceFile = {\n traceEvents: readonly TraceEventData[],\n metadata: MetaData,\n};\n\nexport const enum DataOrigin {\n CPUProfile = 'CPUProfile',\n TraceEvents = 'TraceEvents',\n}\n\n/**\n * Trace metadata that we persist to the file. This will allow us to\n * store specifics for the trace, e.g., which tracks should be visible\n * on load.\n */\nexport interface MetaData {\n source?: 'DevTools';\n startTime?: string;\n networkThrottling?: string;\n cpuThrottling?: number;\n hardwareConcurrency?: number;\n dataOrigin?: DataOrigin;\n}\n\nexport type Contents = TraceFile|TraceEventData[];\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/* eslint-disable no-unused-private-class-members */\n\nexport type MicroSeconds = number&{_tag: 'MicroSeconds'};\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function MicroSeconds(value: number): MicroSeconds {\n return value as MicroSeconds;\n}\n\nexport type MilliSeconds = number&{_tag: 'MilliSeconds'};\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function MilliSeconds(value: number): MilliSeconds {\n return value as MilliSeconds;\n}\nexport type Seconds = number&{_tag: 'Seconds'};\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function Seconds(value: number): Seconds {\n return value as Seconds;\n}\n\nexport const enum TimeUnit {\n MICROSECONDS = 0,\n MILLISECONDS = 1,\n SECONDS = 2,\n MINUTES = 3,\n}\n\n// Other types.\n\nexport interface TraceWindow {\n min: MicroSeconds;\n max: MicroSeconds;\n range: MicroSeconds;\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/* eslint-disable no-unused-private-class-members */\nimport type * as Protocol from '../../../generated/protocol.js';\n\nimport {type MicroSeconds, type MilliSeconds, type Seconds} from './Timing.js';\n\n// Trace Events.\nexport const enum Phase {\n // Standard\n BEGIN = 'B',\n END = 'E',\n COMPLETE = 'X',\n INSTANT = 'I',\n COUNTER = 'C',\n\n // Async\n ASYNC_NESTABLE_START = 'b',\n ASYNC_NESTABLE_INSTANT = 'n',\n ASYNC_NESTABLE_END = 'e',\n ASYNC_STEP_INTO = 'T',\n ASYNC_BEGIN = 'S',\n ASYNC_END = 'F',\n ASYNC_STEP_PAST = 'p',\n\n // Flow\n FLOW_START = 's',\n FLOW_STEP = 't',\n FLOW_END = 'f',\n\n // Sample\n SAMPLE = 'P',\n\n // Object\n OBJECT_CREATED = 'N',\n OBJECT_SNAPSHOT = 'O',\n OBJECT_DESTROYED = 'D',\n\n // Metadata\n METADATA = 'M',\n\n // Memory Dump\n MEMORY_DUMP_GLOBAL = 'V',\n MEMORY_DUMP_PROCESS = 'v',\n\n // Mark\n MARK = 'R',\n\n // Clock sync\n CLOCK_SYNC = 'c',\n}\n\nexport function isNestableAsyncPhase(phase: Phase): boolean {\n return phase === Phase.ASYNC_NESTABLE_START || phase === Phase.ASYNC_NESTABLE_END ||\n phase === Phase.ASYNC_NESTABLE_INSTANT;\n}\n\nexport function isAsyncPhase(phase: Phase): boolean {\n return isNestableAsyncPhase(phase) || phase === Phase.ASYNC_BEGIN || phase === Phase.ASYNC_STEP_INTO ||\n phase === Phase.ASYNC_END || phase === Phase.ASYNC_STEP_PAST;\n}\n\nexport function isFlowPhase(phase: Phase): boolean {\n return phase === Phase.FLOW_START || phase === Phase.FLOW_STEP || phase === Phase.FLOW_END;\n}\n\nexport const enum TraceEventScope {\n THREAD = 't',\n PROCESS = 'p',\n GLOBAL = 'g',\n}\n\nexport interface TraceEventData {\n args?: TraceEventArgs;\n cat: string;\n name: string;\n ph: Phase;\n pid: ProcessID;\n tid: ThreadID;\n tts?: MicroSeconds;\n ts: MicroSeconds;\n tdur?: MicroSeconds;\n dur?: MicroSeconds;\n}\n\nexport interface TraceEventArgs {\n data?: TraceEventArgsData;\n}\n\nexport interface TraceEventArgsData {\n stackTrace?: TraceEventCallFrame[];\n navigationId?: string;\n frame?: string;\n}\n\nexport interface TraceEventCallFrame {\n codeType?: string;\n functionName: string;\n scriptId: number;\n columnNumber?: number;\n lineNumber?: number;\n url?: string;\n}\n\nexport interface TraceFrame {\n frame: string;\n name: string;\n processId: ProcessID;\n url: string;\n parent?: string;\n}\n\n// Sample events.\n\nexport interface TraceEventSample extends TraceEventData {\n ph: Phase.SAMPLE;\n}\n\nexport interface TraceEventProfile extends TraceEventSample {\n name: 'Profile';\n id: ProfileID;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n startTime: MicroSeconds,\n },\n };\n}\n\nexport interface TraceEventProfileChunk extends TraceEventSample {\n name: 'ProfileChunk';\n id: ProfileID;\n args: TraceEventArgs&{\n // `data` is only missing in \"fake\" traces\n data?: TraceEventArgsData & {\n cpuProfile?: TraceEventPartialProfile,\n timeDeltas?: MicroSeconds[],\n lines?: MicroSeconds[],\n },\n };\n}\n\nexport interface TraceEventPartialProfile {\n nodes?: TraceEventPartialNode[];\n samples: CallFrameID[];\n}\n\nexport interface TraceEventPartialNode {\n callFrame: TraceEventCallFrame;\n id: CallFrameID;\n parent?: CallFrameID;\n}\n\n// Complete events.\n\nexport interface TraceEventComplete extends TraceEventData {\n ph: Phase.COMPLETE;\n dur: MicroSeconds;\n}\n\nexport interface TraceEventFireIdleCallback extends TraceEventComplete {\n name: 'FireIdleCallback';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n allottedMilliseconds: MilliSeconds,\n frame: string,\n id: number,\n timedOut: boolean,\n },\n };\n}\n\nexport interface TraceEventDispatch extends TraceEventComplete {\n name: 'EventDispatch';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n type: string,\n },\n };\n}\n\nexport interface TraceEventParseHTML extends TraceEventComplete {\n name: 'ParseHTML';\n args: TraceEventArgs&{\n beginData: {\n frame: string,\n startLine: number,\n url: string,\n },\n endData?: {\n endLine: number,\n },\n };\n}\n\nexport interface TraceEventBegin extends TraceEventData {\n ph: Phase.BEGIN;\n}\n\nexport interface TraceEventEnd extends TraceEventData {\n ph: Phase.END;\n}\n\n/**\n * This denotes a complete event created from a pair of begin and end\n * events. For practicality, instead of always having to look for the\n * end event corresponding to a begin event, we create a synthetic\n * complete event that comprises the data of both from the beginning in\n * the RendererHandler.\n */\nexport type TraceEventSyntheticCompleteEvent = TraceEventComplete;\n\nexport interface TraceEventEventTiming extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_START|Phase.ASYNC_NESTABLE_END;\n name: KnownEventName.EventTiming;\n id: string;\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n cancelable: boolean,\n duration: MilliSeconds,\n processingEnd: MicroSeconds,\n processingStart: MicroSeconds,\n timeStamp: MicroSeconds,\n interactionId?: number, type: string,\n },\n };\n}\n\nexport interface TraceEventEventTimingBegin extends TraceEventEventTiming {\n ph: Phase.ASYNC_NESTABLE_START;\n}\nexport interface TraceEventEventTimingEnd extends TraceEventEventTiming {\n ph: Phase.ASYNC_NESTABLE_END;\n}\n\nexport interface TraceEventGPUTask extends TraceEventComplete {\n name: 'GPUTask';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n /* eslint-disable @typescript-eslint/naming-convention */\n renderer_pid: ProcessID,\n used_bytes: number,\n /* eslint-enable @typescript-eslint/naming-convention */\n },\n };\n}\n\nexport interface TraceEventSyntheticNetworkRedirect {\n url: string;\n priority: string;\n requestMethod?: string;\n ts: MicroSeconds;\n dur: MicroSeconds;\n}\n\n// TraceEventProcessedArgsData is used to store the processed data of a network\n// request. Which is used to distinguish from the date we extract from the\n// trace event directly.\ninterface TraceEventSyntheticArgsData {\n dnsLookup: MicroSeconds;\n download: MicroSeconds;\n downloadStart: MicroSeconds;\n finishTime: MicroSeconds;\n initialConnection: MicroSeconds;\n isDiskCached: boolean;\n isHttps: boolean;\n isMemoryCached: boolean;\n isPushedResource: boolean;\n networkDuration: MicroSeconds;\n processingDuration: MicroSeconds;\n proxyNegotiation: MicroSeconds;\n queueing: MicroSeconds;\n redirectionDuration: MicroSeconds;\n requestSent: MicroSeconds;\n sendStartTime: MicroSeconds;\n ssl: MicroSeconds;\n stalled: MicroSeconds;\n totalTime: MicroSeconds;\n waiting: MicroSeconds;\n}\n\nexport interface TraceEventSyntheticNetworkRequest extends TraceEventComplete {\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n syntheticData: TraceEventSyntheticArgsData,\n // All fields below are from TraceEventsForNetworkRequest,\n // Required fields\n decodedBodyLength: number,\n encodedDataLength: number,\n frame: string,\n fromServiceWorker: boolean,\n host: string,\n mimeType: string,\n pathname: string,\n search: string,\n priority: Priority,\n initialPriority: Priority,\n protocol: string,\n redirects: TraceEventSyntheticNetworkRedirect[],\n renderBlocking: RenderBlocking,\n requestId: string,\n requestingFrameUrl: string,\n statusCode: number,\n url: string,\n // Optional fields\n requestMethod?: string,\n timing?: TraceEventResourceReceiveResponseTimingData,\n },\n };\n cat: 'loading';\n name: 'SyntheticNetworkRequest';\n ph: Phase.COMPLETE;\n dur: MicroSeconds;\n tdur: MicroSeconds;\n ts: MicroSeconds;\n tts: MicroSeconds;\n pid: ProcessID;\n tid: ThreadID;\n}\n\nexport const enum AuctionWorkletType {\n BIDDER = 'bidder',\n SELLER = 'seller',\n // Not expected to be used, but here as a fallback in case new types get\n // added and we have yet to update the trace engine.\n UNKNOWN = 'unknown',\n}\n\nexport interface SyntheticAuctionWorkletEvent extends TraceEventInstant {\n name: 'SyntheticAuctionWorkletEvent';\n // The PID that the AuctionWorklet is running in.\n pid: ProcessID;\n // URL\n host: string;\n // An ID used to pair up runningInProcessEvents with doneWithProcessEvents\n target: string;\n type: AuctionWorkletType;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n // There are two threads for a worklet that we care about, so we gather\n // the thread_name events so we can know the PID and TID for them (and\n // hence display the right events in the track for each thread)\n utilityThread: TraceEventThreadName,\n v8HelperThread: TraceEventThreadName,\n } &\n (\n // This type looks odd, but this is because these events could either have:\n // 1. Just the DoneWithProcess event\n // 2. Just the RunningInProcess event\n // 3. Both events\n // But crucially it cannot have both events missing, hence listing all the\n // allowed cases.\n // Clang is disabled as the combination of nested types and optional\n // properties cause it to weirdly indent some of the properties and make it\n // very unreadable.\n // clang-format off\n {\n runningInProcessEvent: TraceEventAuctionWorkletRunningInProcess,\n doneWithProcessEvent: TraceEventAuctionWorkletDoneWithProcess,\n } |\n {\n runningInProcessEvent?: TraceEventAuctionWorkletRunningInProcess,\n doneWithProcessEvent: TraceEventAuctionWorkletDoneWithProcess,\n } |\n {\n doneWithProcessEvent?: TraceEventAuctionWorkletDoneWithProcess,\n runningInProcessEvent: TraceEventAuctionWorkletRunningInProcess,\n\n }),\n // clang-format on\n };\n}\nexport interface TraceEventAuctionWorkletRunningInProcess extends TraceEventData {\n name: 'AuctionWorkletRunningInProcess';\n ph: Phase.INSTANT;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n host: string,\n pid: ProcessID,\n target: string,\n type: AuctionWorkletType,\n },\n };\n}\nexport interface TraceEventAuctionWorkletDoneWithProcess extends TraceEventData {\n name: 'AuctionWorkletDoneWithProcess';\n ph: Phase.INSTANT;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n host: string,\n pid: ProcessID,\n target: string,\n type: AuctionWorkletType,\n },\n };\n}\n\nexport function isTraceEventAuctionWorkletRunningInProcess(event: TraceEventData):\n event is TraceEventAuctionWorkletRunningInProcess {\n return event.name === 'AuctionWorkletRunningInProcess';\n}\nexport function isTraceEventAuctionWorkletDoneWithProcess(event: TraceEventData):\n event is TraceEventAuctionWorkletDoneWithProcess {\n return event.name === 'AuctionWorkletDoneWithProcess';\n}\n\n// Snapshot events.\n\nexport interface TraceEventSnapshot extends TraceEventData {\n args: TraceEventArgs&{\n snapshot: string,\n };\n name: 'Screenshot';\n cat: 'disabled-by-default-devtools.screenshot';\n ph: Phase.OBJECT_SNAPSHOT;\n}\n\n// Animation events.\n\nexport interface TraceEventAnimation extends TraceEventData {\n args: TraceEventArgs&{\n id?: string,\n name?: string,\n nodeId?: number,\n nodeName?: string,\n state?: string,\n compositeFailed?: number,\n unsupportedProperties?: string[],\n };\n name: 'Animation';\n id2?: {\n local?: string,\n };\n}\n\n// Metadata events.\n\nexport interface TraceEventMetadata extends TraceEventData {\n ph: Phase.METADATA;\n args: TraceEventArgs&{\n name?: string,\n uptime?: string,\n };\n}\n\nexport interface TraceEventThreadName extends TraceEventMetadata {\n name: 'thread_name';\n args: TraceEventArgs&{\n name?: string,\n };\n}\n\nexport interface TraceEventProcessName extends TraceEventMetadata {\n name: 'process_name';\n}\n\n// Mark events.\n\nexport interface TraceEventMark extends TraceEventData {\n ph: Phase.MARK;\n}\n\nexport interface TraceEventNavigationStart extends TraceEventMark {\n name: 'navigationStart';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n documentLoaderURL: string,\n isLoadingMainFrame: boolean,\n // isOutermostMainFrame was introduced in crrev.com/c/3625434 and exists\n // because of Fenced Frames\n // [github.com/WICG/fenced-frame/tree/master/explainer].\n // Fenced frames introduce a situation where isLoadingMainFrame could be\n // true for a navigation, but that navigation be within an embedded \"main\n // frame\", and therefore it wouldn't be on the top level main frame.\n // In situations where we need to distinguish that, we can rely on\n // isOutermostMainFrame, which will only be true for navigations on the\n // top level main frame.\n\n // This flag is optional as it was introduced in May 2022; so users\n // reasonably may import traces from before that date that do not have\n // this field present.\n isOutermostMainFrame?: boolean, navigationId: string,\n },\n frame: string,\n };\n}\n\nexport interface TraceEventFirstContentfulPaint extends TraceEventMark {\n name: 'firstContentfulPaint';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n navigationId: string,\n },\n };\n}\n\nexport interface TraceEventFirstPaint extends TraceEventMark {\n name: 'firstPaint';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n navigationId: string,\n },\n };\n}\n\nexport type PageLoadEvent = TraceEventFirstContentfulPaint|TraceEventMarkDOMContent|TraceEventInteractiveTime|\n TraceEventLargestContentfulPaintCandidate|TraceEventLayoutShift|TraceEventFirstPaint|TraceEventMarkLoad|\n TraceEventNavigationStart;\n\nexport interface TraceEventLargestContentfulPaintCandidate extends TraceEventMark {\n name: 'largestContentfulPaint::Candidate';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n candidateIndex: number,\n isOutermostMainFrame: boolean,\n isMainFrame: boolean,\n navigationId: string,\n nodeId: Protocol.DOM.BackendNodeId,\n type?: string,\n },\n };\n}\nexport interface TraceEventLargestImagePaintCandidate extends TraceEventMark {\n name: 'LargestImagePaint::Candidate';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n candidateIndex: number,\n imageUrl: string,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n DOMNodeId: Protocol.DOM.BackendNodeId,\n },\n };\n}\nexport interface TraceEventLargestTextPaintCandidate extends TraceEventMark {\n name: 'LargestTextPaint::Candidate';\n args: TraceEventArgs&{\n frame: string,\n data?: TraceEventArgsData&{\n candidateIndex: number,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n DOMNodeId: Protocol.DOM.BackendNodeId,\n },\n };\n}\n\nexport interface TraceEventInteractiveTime extends TraceEventMark {\n name: 'InteractiveTime';\n args: TraceEventArgs&{\n args: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n total_blocking_time_ms: number,\n },\n frame: string,\n };\n}\n\n// Instant events.\n\nexport interface TraceEventInstant extends TraceEventData {\n ph: Phase.INSTANT;\n s: TraceEventScope;\n}\n\nexport interface TraceEventUpdateCounters extends TraceEventInstant {\n name: 'UpdateCounters';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n documents: number,\n jsEventListeners: number,\n jsHeapSizeUsed: number,\n nodes: number,\n },\n };\n}\n\nexport type TraceEventRendererEvent = TraceEventInstant|TraceEventComplete;\n\nexport interface TraceEventTracingStartedInBrowser extends TraceEventInstant {\n name: 'TracingStartedInBrowser';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n frameTreeNodeId: number,\n // Frames can only missing in \"fake\" traces\n frames?: TraceFrame[], persistentIds: boolean,\n },\n };\n}\n\nexport interface TraceEventTracingSessionIdForWorker extends TraceEventInstant {\n name: 'TracingSessionIdForWorker';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n url: string,\n workerId: WorkerId,\n workerThreadId: ThreadID,\n frame: string,\n },\n };\n}\nexport function isTraceEventTracingSessionIdForWorker(event: TraceEventData):\n event is TraceEventTracingSessionIdForWorker {\n return event.name === 'TracingSessionIdForWorker';\n}\n\nexport interface TraceEventFrameCommittedInBrowser extends TraceEventInstant {\n name: 'FrameCommittedInBrowser';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & TraceFrame,\n };\n}\n\nexport interface TraceEventMainFrameViewport extends TraceEventInstant {\n name: 'PaintTimingVisualizer::Viewport';\n args: {\n data: TraceEventArgsData&{\n // eslint-disable-next-line @typescript-eslint/naming-convention\n viewport_rect: number[],\n },\n };\n}\n\nexport interface TraceEventCommitLoad extends TraceEventInstant {\n name: 'CommitLoad';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n frame: string,\n isMainFrame: boolean,\n name: string,\n nodeId: number,\n page: string,\n parent: string,\n url: string,\n },\n };\n}\n\nexport interface TraceEventMarkDOMContent extends TraceEventInstant {\n name: 'MarkDOMContent';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n frame: string,\n isMainFrame: boolean,\n page: string,\n },\n };\n}\n\nexport interface TraceEventMarkLoad extends TraceEventInstant {\n name: 'MarkLoad';\n args: TraceEventArgs&{\n data?: TraceEventArgsData & {\n frame: string,\n isMainFrame: boolean,\n page: string,\n },\n };\n}\n\nexport interface TraceEventAsync extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_START|Phase.ASYNC_NESTABLE_INSTANT|Phase.ASYNC_NESTABLE_END|Phase.ASYNC_STEP_INTO|\n Phase.ASYNC_BEGIN|Phase.ASYNC_END|Phase.ASYNC_STEP_PAST;\n}\n\nexport type TraceRect = [number, number, number, number];\nexport type TraceImpactedNode = {\n // These keys come from the trace data, so we have to use underscores.\n /* eslint-disable @typescript-eslint/naming-convention */\n new_rect: TraceRect,\n node_id: Protocol.DOM.BackendNodeId,\n old_rect: TraceRect,\n /* eslint-enable @typescript-eslint/naming-convention */\n};\n\ntype LayoutShiftData = TraceEventArgsData&{\n // These keys come from the trace data, so we have to use underscores.\n /* eslint-disable @typescript-eslint/naming-convention */\n cumulative_score: number,\n frame_max_distance: number,\n had_recent_input: boolean,\n impacted_nodes: TraceImpactedNode[] | undefined,\n is_main_frame: boolean,\n overall_max_distance: number,\n region_rects: TraceRect[],\n score: number,\n weighted_score_delta: number,\n /* eslint-enable @typescript-eslint/naming-convention */\n};\n// These keys come from the trace data, so we have to use underscores.\nexport interface TraceEventLayoutShift extends TraceEventInstant {\n name: 'LayoutShift';\n normalized?: boolean;\n args: TraceEventArgs&{\n frame: string,\n data?: LayoutShiftData,\n };\n}\n\ninterface LayoutShiftSessionWindowData {\n // The sum of the weighted score of all the shifts\n // that belong to a session window.\n cumulativeWindowScore: number;\n // A consecutive generated in the frontend to\n // to identify a session window.\n id: number;\n}\nexport interface LayoutShiftParsedData {\n screenshotSource?: string;\n timeFromNavigation?: MicroSeconds;\n // The sum of the weighted scores of the shifts that\n // belong to a session window up until this shift\n // (inclusive).\n cumulativeWeightedScoreInWindow: number;\n sessionWindowData: LayoutShiftSessionWindowData;\n}\nexport interface SyntheticLayoutShift extends TraceEventLayoutShift {\n args: TraceEventArgs&{\n frame: string,\n data?: LayoutShiftData&{\n rawEvent: TraceEventLayoutShift,\n },\n };\n parsedData: LayoutShiftParsedData;\n}\n\nexport type Priority = 'Low'|'High'|'Medium'|'VeryHigh'|'Highest';\nexport type RenderBlocking = 'blocking'|'non_blocking'|'in_body_parser_blocking'|'potentially_blocking';\nexport interface TraceEventResourceSendRequest extends TraceEventInstant {\n name: 'ResourceSendRequest';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n frame: string,\n requestId: string,\n url: string,\n priority: Priority,\n // TODO(crbug.com/1457985): change requestMethod to enum when confirm in the backend code.\n requestMethod?: string,\n renderBlocking?: RenderBlocking,\n },\n };\n}\n\nexport interface TraceEventResourceChangePriority extends TraceEventInstant {\n name: 'ResourceChangePriority';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n requestId: string,\n priority: Priority,\n },\n };\n}\n\nexport interface TraceEventResourceWillSendRequest extends TraceEventInstant {\n name: 'ResourceWillSendRequest';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n requestId: string,\n },\n };\n}\n\nexport interface TraceEventResourceFinish extends TraceEventInstant {\n name: 'ResourceFinish';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n decodedBodyLength: number,\n didFail: boolean,\n encodedDataLength: number,\n finishTime: Seconds,\n requestId: string,\n },\n };\n}\n\nexport interface TraceEventResourceReceivedData extends TraceEventInstant {\n name: 'ResourceReceivedData';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n encodedDataLength: number,\n frame: string,\n requestId: string,\n },\n };\n}\n\ninterface TraceEventResourceReceiveResponseTimingData {\n connectEnd: MilliSeconds;\n connectStart: MilliSeconds;\n dnsEnd: MilliSeconds;\n dnsStart: MilliSeconds;\n proxyEnd: MilliSeconds;\n proxyStart: MilliSeconds;\n pushEnd: MilliSeconds;\n pushStart: MilliSeconds;\n receiveHeadersEnd: MilliSeconds;\n requestTime: Seconds;\n sendEnd: MilliSeconds;\n sendStart: MilliSeconds;\n sslEnd: MilliSeconds;\n sslStart: MilliSeconds;\n workerReady: MilliSeconds;\n workerStart: MilliSeconds;\n}\n\nexport interface TraceEventResourceReceiveResponse extends TraceEventInstant {\n name: 'ResourceReceiveResponse';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n encodedDataLength: number,\n frame: string,\n fromCache: boolean,\n fromServiceWorker: boolean,\n mimeType: string,\n requestId: string,\n responseTime: MilliSeconds,\n statusCode: number,\n timing: TraceEventResourceReceiveResponseTimingData,\n },\n };\n}\n\nexport interface TraceEventResourceMarkAsCached extends TraceEventInstant {\n name: 'ResourceMarkAsCached';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n requestId: string,\n },\n };\n}\n\nexport const enum LayoutInvalidationReason {\n SIZE_CHANGED = 'Size changed',\n ATTRIBUTE = 'Attribute',\n ADDED_TO_LAYOUT = 'Added to layout',\n SCROLLBAR_CHANGED = 'Scrollbar changed',\n REMOVED_FROM_LAYOUT = 'Removed from layout',\n STYLE_CHANGED = 'Style changed',\n FONTS_CHANGED = 'Fonts changed',\n UNKNOWN = 'Unknown',\n}\n\nexport interface TraceEventLayoutInvalidation extends TraceEventInstant {\n name: 'LayoutInvalidationTracking'|'ScheduleStyleInvalidationTracking';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n frame: string,\n nodeId: Protocol.DOM.BackendNodeId,\n reason: LayoutInvalidationReason,\n nodeName?: string,\n },\n };\n}\n\nexport const enum StyleRecalcInvalidationReason {\n ANIMATION = 'Animation',\n}\n\nexport interface TraceEventStyleRecalcInvalidation extends TraceEventInstant {\n name: 'StyleRecalcInvalidationTracking';\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n frame: string,\n nodeId: Protocol.DOM.BackendNodeId,\n reason: StyleRecalcInvalidationReason,\n subtree: boolean,\n nodeName?: string,\n extraData?: string,\n },\n };\n}\n\nexport interface TraceEventPrePaint extends TraceEventComplete {\n name: 'PrePaint';\n}\n\nexport type TraceEventNestableAsync = TraceEventNestableAsyncBegin|TraceEventNestableAsyncEnd;\nexport interface TraceEventNestableAsyncBegin extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_START;\n // The id2 field gives flexibility to explicitly specify if an event\n // id is global among processes or process local. However not all\n // events use it, so both kind of ids need to be marked as optional.\n id2?: {local?: string, global?: string};\n id?: string;\n}\n\nexport interface TraceEventNestableAsyncEnd extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_END;\n id2?: {local?: string, global?: string};\n id?: string;\n}\n\nexport type TraceEventAsyncPerformanceMeasure = TraceEventPerformanceMeasureBegin|TraceEventPerformanceMeasureEnd;\n\nexport interface TraceEventPerformanceMeasureBegin extends TraceEventNestableAsyncBegin {\n cat: 'blink.user_timing';\n id: string;\n}\n\nexport interface TraceEventPerformanceMeasureEnd extends TraceEventNestableAsyncEnd {\n cat: 'blink.user_timing';\n id: string;\n}\n\nexport interface TraceEventConsoleTimeBegin extends TraceEventNestableAsyncBegin {\n cat: 'blink.console';\n id2: {\n local: string,\n };\n}\n\nexport interface TraceEventConsoleTimeEnd extends TraceEventNestableAsyncEnd {\n cat: 'blink.console';\n id2: {\n local: string,\n };\n}\n\nexport interface TraceEventTimeStamp extends TraceEventData {\n cat: 'devtools.timeline';\n name: 'TimeStamp';\n ph: Phase.INSTANT;\n id: string;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n frame: string,\n message: string,\n },\n };\n}\n\nexport interface TraceEventPerformanceMark extends TraceEventData {\n cat: 'blink.user_timing';\n ph: Phase.INSTANT|Phase.MARK;\n id: string;\n}\n\n// Nestable async events with a duration are made up of two distinct\n// events: the begin, and the end. We need both of them to be able to\n// display the right information, so we create these synthetic events.\nexport interface TraceEventSyntheticNestableAsyncEvent extends TraceEventData {\n id?: string;\n id2?: {local?: string, global?: string};\n dur: MicroSeconds;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n beginEvent: TraceEventNestableAsyncBegin,\n endEvent: TraceEventNestableAsyncEnd,\n },\n };\n}\n\nexport interface TraceEventSyntheticUserTiming extends TraceEventSyntheticNestableAsyncEvent {\n id: string;\n dur: MicroSeconds;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n beginEvent: TraceEventPerformanceMeasureBegin,\n endEvent: TraceEventPerformanceMeasureEnd,\n },\n };\n}\n\nexport interface TraceEventSyntheticConsoleTiming extends TraceEventSyntheticNestableAsyncEvent {\n id2: {local: string};\n dur: MicroSeconds;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n beginEvent: TraceEventConsoleTimeBegin,\n endEvent: TraceEventConsoleTimeEnd,\n },\n };\n}\n\nexport interface SyntheticInteractionEvent extends TraceEventSyntheticNestableAsyncEvent {\n // InteractionID and type are available within the beginEvent's data, but we\n // put them on the top level for ease of access.\n interactionId: number;\n type: string;\n // This is equivalent to startEvent.ts;\n ts: MicroSeconds;\n // This duration can be calculated via endEvent.ts - startEvent.ts, but we do\n // that and put it here to make it easier. This also makes these events\n // consistent with real events that have a dur field.\n dur: MicroSeconds;\n args: TraceEventArgs&{\n data: TraceEventArgsData & {\n beginEvent: TraceEventEventTimingBegin,\n endEvent: TraceEventEventTimingEnd,\n },\n };\n}\n\n/**\n * An event created synthetically in the frontend that has a self time\n * (the time spent running the task itself).\n */\nexport interface SyntheticEventWithSelfTime extends TraceEventData {\n selfTime?: MicroSeconds;\n}\n\n/**\n * A profile call created in the frontend from samples disguised as a\n * trace event.\n */\nexport interface TraceEventSyntheticProfileCall extends SyntheticEventWithSelfTime {\n callFrame: Protocol.Runtime.CallFrame;\n nodeId: Protocol.integer;\n children?: TraceEventSyntheticProfileCall[];\n}\n\n/**\n * A trace event augmented synthetically in the frontend to contain\n * its self time.\n */\nexport type SyntheticRendererEvent = TraceEventRendererEvent&SyntheticEventWithSelfTime;\n\nexport function isSyntheticInteractionEvent(event: TraceEventData): event is SyntheticInteractionEvent {\n return Boolean(\n 'interactionId' in event && event.args?.data && 'beginEvent' in event.args.data && 'endEvent' in event.args.data);\n}\n\nclass ProfileIdTag {\n readonly #profileIdTag: (symbol|undefined);\n}\nexport type ProfileID = string&ProfileIdTag;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function ProfileID(value: string): ProfileID {\n return value as ProfileID;\n}\n\nclass CallFrameIdTag {\n readonly #callFrameIdTag: (symbol|undefined);\n}\nexport type CallFrameID = number&CallFrameIdTag;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function CallFrameID(value: number): CallFrameID {\n return value as CallFrameID;\n}\n\nclass ProcessIdTag {\n readonly #processIdTag: (symbol|undefined);\n}\nexport type ProcessID = number&ProcessIdTag;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function ProcessID(value: number): ProcessID {\n return value as ProcessID;\n}\n\nclass ThreadIdTag {\n readonly #threadIdTag: (symbol|undefined);\n}\nexport type ThreadID = number&ThreadIdTag;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function ThreadID(value: number): ThreadID {\n return value as ThreadID;\n}\n\nclass WorkerIdTag {\n readonly #workerIdTag: (symbol|undefined);\n}\nexport type WorkerId = string&WorkerIdTag;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function WorkerId(value: string): WorkerId {\n return value as WorkerId;\n}\n\nexport function isTraceEventComplete(event: TraceEventData): event is TraceEventComplete {\n return event.ph === Phase.COMPLETE;\n}\n\nexport function isTraceEventBegin(event: TraceEventData): event is TraceEventBegin {\n return event.ph === Phase.BEGIN;\n}\n\nexport function isTraceEventEnd(event: TraceEventData): event is TraceEventEnd {\n return event.ph === Phase.END;\n}\n\nexport function isTraceEventDispatch(event: TraceEventData): event is TraceEventDispatch {\n return event.name === 'EventDispatch';\n}\n\nexport function isTraceEventInstant(event: TraceEventData): event is TraceEventInstant {\n return event.ph === Phase.INSTANT;\n}\n\nexport function isTraceEventRendererEvent(event: TraceEventData): event is TraceEventRendererEvent {\n return isTraceEventInstant(event) || isTraceEventComplete(event);\n}\n\nexport function isTraceEventFireIdleCallback(event: TraceEventData): event is TraceEventFireIdleCallback {\n return event.name === 'FireIdleCallback';\n}\n\nexport function isTraceEventUpdateCounters(event: TraceEventData): event is TraceEventUpdateCounters {\n return event.name === 'UpdateCounters';\n}\n\nexport function isThreadName(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventThreadName {\n return traceEventData.name === 'thread_name';\n}\n\nexport function isProcessName(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventProcessName {\n return traceEventData.name === 'process_name';\n}\n\nexport function isTraceEventTracingStartedInBrowser(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventTracingStartedInBrowser {\n return traceEventData.name === 'TracingStartedInBrowser';\n}\n\nexport function isTraceEventFrameCommittedInBrowser(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventFrameCommittedInBrowser {\n return traceEventData.name === 'FrameCommittedInBrowser';\n}\n\nexport function isTraceEventCommitLoad(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventCommitLoad {\n return traceEventData.name === 'CommitLoad';\n}\n\nexport function isTraceEventNavigationStart(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventNavigationStart {\n return traceEventData.name === 'navigationStart';\n}\n\nexport function isTraceEventAnimation(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventAnimation {\n return traceEventData.name === 'Animation';\n}\n\nexport function isTraceEventLayoutShift(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventLayoutShift {\n return traceEventData.name === 'LayoutShift';\n}\n\nexport function isTraceEventLayoutInvalidation(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventLayoutInvalidation {\n return traceEventData.name === 'LayoutInvalidationTracking' ||\n traceEventData.name === 'ScheduleStyleInvalidationTracking';\n}\n\nexport function isTraceEventStyleRecalcInvalidation(traceEventData: TraceEventData):\n traceEventData is TraceEventStyleRecalcInvalidation {\n return traceEventData.name === 'StyleRecalcInvalidationTracking';\n}\n\nexport function isTraceEventFirstContentfulPaint(traceEventData: TraceEventData):\n traceEventData is TraceEventFirstContentfulPaint {\n return traceEventData.name === 'firstContentfulPaint';\n}\n\nexport function isTraceEventLargestContentfulPaintCandidate(traceEventData: TraceEventData):\n traceEventData is TraceEventLargestContentfulPaintCandidate {\n return traceEventData.name === 'largestContentfulPaint::Candidate';\n}\nexport function isTraceEventLargestImagePaintCandidate(traceEventData: TraceEventData):\n traceEventData is TraceEventLargestImagePaintCandidate {\n return traceEventData.name === 'LargestImagePaint::Candidate';\n}\nexport function isTraceEventLargestTextPaintCandidate(traceEventData: TraceEventData):\n traceEventData is TraceEventLargestTextPaintCandidate {\n return traceEventData.name === 'LargestTextPaint::Candidate';\n}\n\nexport function isTraceEventMarkLoad(traceEventData: TraceEventData): traceEventData is TraceEventMarkLoad {\n return traceEventData.name === 'MarkLoad';\n}\n\nexport function isTraceEventFirstPaint(traceEventData: TraceEventData): traceEventData is TraceEventFirstPaint {\n return traceEventData.name === 'firstPaint';\n}\n\nexport function isTraceEventMarkDOMContent(traceEventData: TraceEventData): traceEventData is TraceEventMarkDOMContent {\n return traceEventData.name === 'MarkDOMContent';\n}\n\nexport function isTraceEventInteractiveTime(traceEventData: TraceEventData):\n traceEventData is TraceEventInteractiveTime {\n return traceEventData.name === 'InteractiveTime';\n}\n\nexport function isTraceEventEventTiming(traceEventData: TraceEventData): traceEventData is TraceEventEventTiming {\n return traceEventData.name === KnownEventName.EventTiming;\n}\n\nexport function isTraceEventEventTimingEnd(traceEventData: TraceEventData): traceEventData is TraceEventEventTimingEnd {\n return isTraceEventEventTiming(traceEventData) && traceEventData.ph === Phase.ASYNC_NESTABLE_END;\n}\nexport function isTraceEventEventTimingStart(traceEventData: TraceEventData):\n traceEventData is TraceEventEventTimingBegin {\n return isTraceEventEventTiming(traceEventData) && traceEventData.ph === Phase.ASYNC_NESTABLE_START;\n}\n\nexport function isTraceEventGPUTask(traceEventData: TraceEventData): traceEventData is TraceEventGPUTask {\n return traceEventData.name === 'GPUTask';\n}\n\nexport function isTraceEventProfile(traceEventData: TraceEventData): traceEventData is TraceEventProfile {\n return traceEventData.name === 'Profile';\n}\n\nexport function isTraceEventProfileChunk(traceEventData: TraceEventData): traceEventData is TraceEventProfileChunk {\n return traceEventData.name === 'ProfileChunk';\n}\n\nexport function isTraceEventResourceChangePriority(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceChangePriority {\n return traceEventData.name === 'ResourceChangePriority';\n}\n\nexport function isTraceEventResourceSendRequest(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceSendRequest {\n return traceEventData.name === 'ResourceSendRequest';\n}\n\nexport function isTraceEventResourceReceiveResponse(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceReceiveResponse {\n return traceEventData.name === 'ResourceReceiveResponse';\n}\n\nexport function isTraceEventResourceMarkAsCached(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceMarkAsCached {\n return traceEventData.name === 'ResourceMarkAsCached';\n}\n\nexport function isTraceEventResourceFinish(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceFinish {\n return traceEventData.name === 'ResourceFinish';\n}\n\nexport function isTraceEventResourceWillSendRequest(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceWillSendRequest {\n return traceEventData.name === 'ResourceWillSendRequest';\n}\n\nexport function isTraceEventResourceReceivedData(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventResourceReceivedData {\n return traceEventData.name === 'ResourceReceivedData';\n}\n\nexport function isSyntheticNetworkRequestDetailsEvent(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventSyntheticNetworkRequest {\n return traceEventData.name === 'SyntheticNetworkRequest';\n}\n\nexport function isTraceEventPrePaint(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventPrePaint {\n return traceEventData.name === 'PrePaint';\n}\n\nexport function isTraceEventNavigationStartWithURL(event: TraceEventData): event is TraceEventNavigationStart {\n return Boolean(isTraceEventNavigationStart(event) && event.args.data && event.args.data.documentLoaderURL !== '');\n}\n\nexport function isTraceEventMainFrameViewport(\n traceEventData: TraceEventData,\n ): traceEventData is TraceEventMainFrameViewport {\n return traceEventData.name === 'PaintTimingVisualizer::Viewport';\n}\n\nexport function isSyntheticUserTimingTraceEvent(traceEventData: TraceEventData):\n traceEventData is TraceEventSyntheticUserTiming {\n if (traceEventData.cat !== 'blink.user_timing') {\n return false;\n }\n const data = traceEventData.args?.data;\n if (!data) {\n return false;\n }\n return 'beginEvent' in data && 'endEvent' in data;\n}\n\nexport function isSyntheticConsoleTimingTraceEvent(traceEventData: TraceEventData):\n traceEventData is TraceEventSyntheticConsoleTiming {\n if (traceEventData.cat !== 'blink.console') {\n return false;\n }\n const data = traceEventData.args?.data;\n if (!data) {\n return false;\n }\n return 'beginEvent' in data && 'endEvent' in data;\n}\n\nexport function isTraceEventPerformanceMeasure(traceEventData: TraceEventData):\n traceEventData is TraceEventPerformanceMeasureBegin|TraceEventPerformanceMeasureEnd {\n return traceEventData.cat === 'blink.user_timing' && isTraceEventAsyncPhase(traceEventData);\n}\n\nexport function isTraceEventPerformanceMark(traceEventData: TraceEventData):\n traceEventData is TraceEventPerformanceMark {\n return traceEventData.cat === 'blink.user_timing' &&\n (traceEventData.ph === Phase.MARK || traceEventData.ph === Phase.INSTANT);\n}\n\nexport function isTraceEventConsoleTime(traceEventData: TraceEventData): traceEventData is TraceEventConsoleTimeBegin|\n TraceEventConsoleTimeEnd {\n return traceEventData.cat === 'blink.console' && isTraceEventAsyncPhase(traceEventData);\n}\n\nexport function isTraceEventTimeStamp(traceEventData: TraceEventData): traceEventData is TraceEventTimeStamp {\n return traceEventData.ph === Phase.INSTANT && traceEventData.name === 'TimeStamp';\n}\n\nexport function isTraceEventParseHTML(traceEventData: TraceEventData): traceEventData is TraceEventParseHTML {\n return traceEventData.name === 'ParseHTML';\n}\n\nexport interface TraceEventAsync extends TraceEventData {\n ph: Phase.ASYNC_NESTABLE_START|Phase.ASYNC_NESTABLE_INSTANT|Phase.ASYNC_NESTABLE_END|Phase.ASYNC_STEP_INTO|\n Phase.ASYNC_BEGIN|Phase.ASYNC_END|Phase.ASYNC_STEP_PAST;\n}\n\nexport function isTraceEventAsyncPhase(traceEventData: TraceEventData): boolean {\n const asyncPhases = new Set([\n Phase.ASYNC_NESTABLE_START,\n Phase.ASYNC_NESTABLE_INSTANT,\n Phase.ASYNC_NESTABLE_END,\n Phase.ASYNC_STEP_INTO,\n Phase.ASYNC_BEGIN,\n Phase.ASYNC_END,\n Phase.ASYNC_STEP_PAST,\n ]);\n return asyncPhases.has(traceEventData.ph);\n}\n\nexport function isSyntheticLayoutShift(traceEventData: TraceEventData): traceEventData is SyntheticLayoutShift {\n if (!isTraceEventLayoutShift(traceEventData) || !traceEventData.args.data) {\n return false;\n }\n return 'rawEvent' in traceEventData.args.data;\n}\n\nexport function isProfileCall(event: TraceEventData): event is TraceEventSyntheticProfileCall {\n return 'callFrame' in event;\n}\n\n/**\n * This is an exhaustive list of events we track in the Performance\n * panel. Note not all of them are necessarliry shown in the flame\n * chart, some of them we only use for parsing.\n * TODO(crbug.com/1428024): Complete this enum.\n */\nexport const enum KnownEventName {\n /* Task */\n Program = 'Program',\n RunTask = 'RunTask',\n AsyncTask = 'AsyncTask',\n RunMicrotasks = 'RunMicrotasks',\n\n /* Load */\n XHRLoad = 'XHRLoad',\n XHRReadyStateChange = 'XHRReadyStateChange',\n /* Parse */\n ParseHTML = 'ParseHTML',\n ParseCSS = 'ParseAuthorStyleSheet',\n /* V8 */\n CompileScript = 'V8.CompileScript',\n CompileCode = 'V8.CompileCode',\n CompileModule = 'V8.CompileModule',\n Optimize = 'V8.OptimizeCode',\n WasmStreamFromResponseCallback = 'v8.wasm.streamFromResponseCallback',\n WasmCompiledModule = 'v8.wasm.compiledModule',\n WasmCachedModule = 'v8.wasm.cachedModule',\n WasmModuleCacheHit = 'v8.wasm.moduleCacheHit',\n WasmModuleCacheInvalid = 'v8.wasm.moduleCacheInvalid',\n /* Js */\n ProfileCall = 'ProfileCall',\n EvaluateScript = 'EvaluateScript',\n FunctionCall = 'FunctionCall',\n EventDispatch = 'EventDispatch',\n EvaluateModule = 'v8.evaluateModule',\n RequestMainThreadFrame = 'RequestMainThreadFrame',\n RequestAnimationFrame = 'RequestAnimationFrame',\n CancelAnimationFrame = 'CancelAnimationFrame',\n FireAnimationFrame = 'FireAnimationFrame',\n RequestIdleCallback = 'RequestIdleCallback',\n CancelIdleCallback = 'CancelIdleCallback',\n FireIdleCallback = 'FireIdleCallback',\n TimerInstall = 'TimerInstall',\n TimerRemove = 'TimerRemove',\n TimerFire = 'TimerFire',\n WebSocketCreate = 'WebSocketCreate',\n WebSocketSendHandshake = 'WebSocketSendHandshakeRequest',\n WebSocketReceiveHandshake = 'WebSocketReceiveHandshakeResponse',\n WebSocketDestroy = 'WebSocketDestroy',\n CryptoDoEncrypt = 'DoEncrypt',\n CryptoDoEncryptReply = 'DoEncryptReply',\n CryptoDoDecrypt = 'DoDecrypt',\n CryptoDoDecryptReply = 'DoDecryptReply',\n CryptoDoDigest = 'DoDigest',\n CryptoDoDigestReply = 'DoDigestReply',\n CryptoDoSign = 'DoSign',\n CryptoDoSignReply = 'DoSignReply',\n CryptoDoVerify = 'DoVerify',\n CryptoDoVerifyReply = 'DoVerifyReply',\n V8Execute = 'V8.Execute',\n\n /* Gc */\n GC = 'GCEvent',\n DOMGC = 'BlinkGC.AtomicPhase',\n IncrementalGCMarking = 'V8.GCIncrementalMarking',\n MajorGC = 'MajorGC',\n MinorGC = 'MinorGC',\n GCCollectGarbage = 'BlinkGC.AtomicPhase',\n\n /* Layout */\n ScheduleStyleRecalculation = 'ScheduleStyleRecalculation',\n RecalculateStyles = 'RecalculateStyles',\n Layout = 'Layout',\n UpdateLayoutTree = 'UpdateLayoutTree',\n InvalidateLayout = 'InvalidateLayout',\n LayoutInvalidationTracking = 'LayoutInvalidationTracking',\n ComputeIntersections = 'ComputeIntersections',\n HitTest = 'HitTest',\n PrePaint = 'PrePaint',\n Layerize = 'Layerize',\n LayoutShift = 'LayoutShift',\n UpdateLayerTree = 'UpdateLayerTree',\n ScheduleStyleInvalidationTracking = 'ScheduleStyleInvalidationTracking',\n StyleRecalcInvalidationTracking = 'StyleRecalcInvalidationTracking',\n StyleInvalidatorInvalidationTracking = 'StyleInvalidatorInvalidationTracking',\n\n /* Paint */\n ScrollLayer = 'ScrollLayer',\n UpdateLayer = 'UpdateLayer',\n PaintSetup = 'PaintSetup',\n Paint = 'Paint',\n PaintImage = 'PaintImage',\n Commit = 'Commit',\n CompositeLayers = 'CompositeLayers',\n RasterTask = 'RasterTask',\n ImageDecodeTask = 'ImageDecodeTask',\n ImageUploadTask = 'ImageUploadTask',\n DecodeImage = 'Decode Image',\n ResizeImage = 'Resize Image',\n DrawLazyPixelRef = 'Draw LazyPixelRef',\n DecodeLazyPixelRef = 'Decode LazyPixelRef',\n GPUTask = 'GPUTask',\n Rasterize = 'Rasterize',\n EventTiming = 'EventTiming',\n\n /* Compile */\n OptimizeCode = 'V8.OptimizeCode',\n CacheScript = 'v8.produceCache',\n CacheModule = 'v8.produceModuleCache',\n // V8Sample events are coming from tracing and contain raw stacks with function addresses.\n // After being processed with help of JitCodeAdded and JitCodeMoved events they\n // get translated into function infos and stored as stacks in JSSample events.\n V8Sample = 'V8Sample',\n JitCodeAdded = 'JitCodeAdded',\n JitCodeMoved = 'JitCodeMoved',\n StreamingCompileScript = 'v8.parseOnBackground',\n StreamingCompileScriptWaiting = 'v8.parseOnBackgroundWaiting',\n StreamingCompileScriptParsing = 'v8.parseOnBackgroundParsing',\n BackgroundDeserialize = 'v8.deserializeOnBackground',\n FinalizeDeserialization = 'V8.FinalizeDeserialization',\n\n /* Markers */\n CommitLoad = 'CommitLoad',\n MarkLoad = 'MarkLoad',\n MarkDOMContent = 'MarkDOMContent',\n MarkFirstPaint = 'firstPaint',\n MarkFCP = 'firstContentfulPaint',\n MarkLCPCandidate = 'largestContentfulPaint::Candidate',\n MarkLCPInvalidate = 'largestContentfulPaint::Invalidate',\n NavigationStart = 'navigationStart',\n TimeStamp = 'TimeStamp',\n ConsoleTime = 'ConsoleTime',\n UserTiming = 'UserTiming',\n InteractiveTime = 'InteractiveTime',\n\n /* Frames */\n BeginFrame = 'BeginFrame',\n NeedsBeginFrameChanged = 'NeedsBeginFrameChanged',\n BeginMainThreadFrame = 'BeginMainThreadFrame',\n ActivateLayerTree = 'ActivateLayerTree',\n DrawFrame = 'DrawFrame',\n DroppedFrame = 'DroppedFrame',\n FrameStartedLoading = 'FrameStartedLoading',\n\n /* Network request events */\n ResourceWillSendRequest = 'ResourceWillSendRequest',\n ResourceSendRequest = 'ResourceSendRequest',\n ResourceReceiveResponse = 'ResourceReceiveResponse',\n ResourceReceivedData = 'ResourceReceivedData',\n ResourceFinish = 'ResourceFinish',\n ResourceMarkAsCached = 'ResourceMarkAsCached',\n\n /* Web sockets */\n WebSocketSendHandshakeRequest = 'WebSocketSendHandshakeRequest',\n WebSocketReceiveHandshakeResponse = 'WebSocketReceiveHandshakeResponse',\n\n /* CPU Profiling */\n Profile = 'Profile',\n StartProfiling = 'CpuProfiler::StartProfiling',\n ProfileChunk = 'ProfileChunk',\n UpdateCounters = 'UpdateCounters',\n\n /* Other */\n Animation = 'Animation',\n ParseAuthorStyleSheet = 'ParseAuthorStyleSheet',\n EmbedderCallback = 'EmbedderCallback',\n SetLayerTreeId = 'SetLayerTreeId',\n TracingStartedInPage = 'TracingStartedInPage',\n TracingSessionIdForWorker = 'TracingSessionIdForWorker',\n LazyPixelRef = 'LazyPixelRef',\n LayerTreeHostImplSnapshot = 'cc::LayerTreeHostImpl',\n PictureSnapshot = 'cc::Picture',\n DisplayItemListSnapshot = 'cc::DisplayItemList',\n InputLatencyMouseMove = 'InputLatency::MouseMove',\n InputLatencyMouseWheel = 'InputLatency::MouseWheel',\n ImplSideFling = 'InputHandlerProxy::HandleGestureFling::started',\n}\n", "\n// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\nimport type * as Types from './../types/types.js';\nimport type * as ModelHandlers from './ModelHandlers.js';\n\nexport interface TraceEventHandler {\n reset(): void;\n initialize?(freshRecording?: boolean): void;\n handleEvent(data: {}): void;\n finalize?(): Promise<void>;\n data(): unknown;\n deps?(): TraceEventHandlerName[];\n handleUserConfig?(config: Types.Configuration.Configuration): void;\n}\nexport type TraceEventHandlerName = keyof typeof ModelHandlers;\n\n// This type maps TraceEventHandler names to the return type of their data\n// function. So, for example, if we are given an object with a key of 'foo'\n// and a value which is a TraceHandler containing a data() function that\n// returns a string, this type will be { foo: string }.\n//\n// This allows us to model the behavior of the TraceProcessor in the model,\n// which takes an object with TraceEventHandlers as part of its config, and\n// which ultimately returns an object keyed off the names of the\n// TraceEventHandlers, and with values that are derived from each\n// TraceEventHandler's data function.\n//\n// So, concretely, we provide a TraceEventHandler for calculating the #time\n// bounds of a trace called TraceBounds, whose data() function returns a\n// TraceWindow. The HandlerData, therefore, would determine that the\n// TraceProcessor would contain a key called 'TraceBounds' whose value is\n// a TraceWindow.\nexport type EnabledHandlerDataWithMeta<T extends {[key: string]: TraceEventHandler}> = {\n // We allow the user to configure which handlers are created by passing them\n // in when constructing a model instance. However, we then ensure that the\n // Meta handler is added to that, as the Model relies on some of the data\n // from the Meta handler when creating the file. Therefore, this type\n // explicitly defines that the Meta data is present, before then extending it\n // with the index type to represent all the other handlers.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Meta: Readonly<ReturnType<typeof ModelHandlers['Meta']['data']>>,\n}&{\n // For every key in the object, look up the TraceEventHandler's data function\n // and use its return type as the value for the object.\n [K in keyof T]: Readonly<ReturnType<T[K]['data']>>;\n};\n\nexport type HandlersWithMeta<T extends {[key: string]: TraceEventHandler}> = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n Meta: typeof ModelHandlers.Meta,\n}&{\n [K in keyof T]: T[K];\n};\n\n// Represents the final parsed data from all of the handlers. Note that because\n// we are currently in the middle of the migration of data engines, not all the\n// handlers are enabled. Therefore for now you should use the type defined in\n// models/trace/handlers/Migration.ts, `PartialTraceData`, which\n// represents the final parsed data for only the enabled handlers.\nexport type TraceParseData = Readonly<EnabledHandlerDataWithMeta<typeof ModelHandlers>>;\n\nexport type Handlers = typeof ModelHandlers;\n\nexport const enum HandlerState {\n UNINITIALIZED = 1,\n INITIALIZED = 2,\n FINALIZED = 3,\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {data as metaHandlerData} from './MetaHandler.js';\n\nimport {type TraceEventHandlerName, HandlerState} from './types.js';\n\nimport * as Types from '../types/types.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nconst eventsInProcessThread =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventGPUTask[]>>();\n\nlet mainGPUThreadTasks: Types.TraceEvents.TraceEventGPUTask[] = [];\n\nexport function reset(): void {\n eventsInProcessThread.clear();\n mainGPUThreadTasks = [];\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('GPU Handler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('GPU Handler is not initialized');\n }\n\n if (!Types.TraceEvents.isTraceEventGPUTask(event)) {\n return;\n }\n\n Helpers.Trace.addEventToProcessThread(event, eventsInProcessThread);\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('GPU Handler is not initialized');\n }\n\n const {gpuProcessId, gpuThreadId} = metaHandlerData();\n const gpuThreadsForProcess = eventsInProcessThread.get(gpuProcessId);\n if (gpuThreadsForProcess && gpuThreadId) {\n mainGPUThreadTasks = gpuThreadsForProcess.get(gpuThreadId) || [];\n }\n handlerState = HandlerState.FINALIZED;\n}\n\nexport interface GPUHandlerReturnData {\n mainGPUThreadTasks: readonly Types.TraceEvents.TraceEventGPUTask[];\n}\n\nexport function data(): GPUHandlerReturnData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('GPU Handler is not finalized');\n }\n return {\n mainGPUThreadTasks: [...mainGPUThreadTasks],\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\n// We track the renderer processes we see in each frame on the way through the trace.\nconst rendererProcessesByFrameId = new Map<\n string,\n Map<Types.TraceEvents.ProcessID, {window: Types.Timing.TraceWindow, frame: Types.TraceEvents.TraceFrame}[]>>();\n\n// We will often want to key data by Frame IDs, and commonly we'll care most\n// about the main frame's ID, so we store and expose that.\nlet mainFrameId: string = '';\nlet mainFrameURL: string = '';\n\nconst framesByProcessId = new Map<Types.TraceEvents.ProcessID, Map<string, Types.TraceEvents.TraceFrame>>();\n\n// We will often want to key data by the browser process, GPU process and top\n// level renderer IDs, so keep a track on those.\nlet browserProcessId: Types.TraceEvents.ProcessID = Types.TraceEvents.ProcessID(-1);\nlet browserThreadId: Types.TraceEvents.ThreadID = Types.TraceEvents.ThreadID(-1);\nlet gpuProcessId: Types.TraceEvents.ProcessID = Types.TraceEvents.ProcessID(-1);\nlet gpuThreadId: Types.TraceEvents.ThreadID = Types.TraceEvents.ThreadID(-1);\nlet viewportRect: DOMRect|null = null;\n\nconst topLevelRendererIds = new Set<Types.TraceEvents.ProcessID>();\nconst traceBounds: Types.Timing.TraceWindow = {\n min: Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY),\n max: Types.Timing.MicroSeconds(Number.NEGATIVE_INFINITY),\n range: Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY),\n};\n\n/**\n * These represent the user navigating. Values such as First Contentful Paint,\n * etc, are relative to the navigation.\n *\n * We store navigation events both by the frame and navigation ID. This means\n * when we need to look them up, we can use whichever ID we have.\n *\n * Note that these Maps will have the same values in them; these are just keyed\n * differently to make look-ups easier.\n *\n * We also additionally maintain an array of only navigations that occured on\n * the main frame. In many places in the UI we only care about highlighting\n * main frame navigations, so calculating this list here is better than\n * filtering either of the below maps over and over again at the UI layer.\n */\nconst navigationsByFrameId = new Map<string, Types.TraceEvents.TraceEventNavigationStart[]>();\nconst navigationsByNavigationId = new Map<string, Types.TraceEvents.TraceEventNavigationStart>();\nconst mainFrameNavigations: Types.TraceEvents.TraceEventNavigationStart[] = [];\n\n// Represents all the threads in the trace, organized by process. This is mostly for internal\n// bookkeeping so that during the finalize pass we can obtain the main and browser thread IDs.\nconst threadsInProcess =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>();\n\nlet traceStartedTimeFromTracingStartedEvent = Types.Timing.MicroSeconds(-1);\nconst eventPhasesOfInterestForTraceBounds = new Set([\n Types.TraceEvents.Phase.BEGIN,\n Types.TraceEvents.Phase.END,\n Types.TraceEvents.Phase.COMPLETE,\n Types.TraceEvents.Phase.INSTANT,\n]);\n\nlet handlerState = HandlerState.UNINITIALIZED;\nexport function reset(): void {\n navigationsByFrameId.clear();\n navigationsByNavigationId.clear();\n mainFrameNavigations.length = 0;\n\n browserProcessId = Types.TraceEvents.ProcessID(-1);\n browserThreadId = Types.TraceEvents.ThreadID(-1);\n gpuProcessId = Types.TraceEvents.ProcessID(-1);\n gpuThreadId = Types.TraceEvents.ThreadID(-1);\n viewportRect = null;\n topLevelRendererIds.clear();\n threadsInProcess.clear();\n rendererProcessesByFrameId.clear();\n framesByProcessId.clear();\n\n traceBounds.min = Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY);\n traceBounds.max = Types.Timing.MicroSeconds(Number.NEGATIVE_INFINITY);\n traceBounds.range = Types.Timing.MicroSeconds(Number.POSITIVE_INFINITY);\n traceStartedTimeFromTracingStartedEvent = Types.Timing.MicroSeconds(-1);\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Meta Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nfunction updateRendererProcessByFrame(\n event: Types.TraceEvents.TraceEventData, frame: Types.TraceEvents.TraceFrame): void {\n const framesInProcessById = Platform.MapUtilities.getWithDefault(framesByProcessId, frame.processId, () => new Map());\n framesInProcessById.set(frame.frame, frame);\n\n const rendererProcessInFrame = Platform.MapUtilities.getWithDefault(\n rendererProcessesByFrameId, frame.frame,\n () => new Map<\n Types.TraceEvents.ProcessID, {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindow}[]>());\n const rendererProcessInfo = Platform.MapUtilities.getWithDefault(rendererProcessInFrame, frame.processId, () => {\n return [];\n });\n const lastProcessData = rendererProcessInfo.at(-1);\n\n // Only store a new entry if the URL changed, otherwise it's just\n // redundant information.\n if (lastProcessData && lastProcessData.frame.url === frame.url) {\n return;\n }\n // For now we store the time of the event as the min. In the finalize we step\n // through each of these windows and update their max and range values.\n rendererProcessInfo.push({\n frame,\n window: {\n min: event.ts,\n max: Types.Timing.MicroSeconds(0),\n range: Types.Timing.MicroSeconds(0),\n },\n });\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Meta Handler is not initialized');\n }\n\n // If there is a timestamp (which meta events do not have), and the event does\n // not end with ::UMA then it, and the event is in the set of valid phases,\n // then it should be included for the purposes of calculating the trace bounds.\n // The UMA events in particular seem to be reported on page unloading, which\n // often extends the bounds of the trace unhelpfully.\n if (event.ts !== 0 && !event.name.endsWith('::UMA') && eventPhasesOfInterestForTraceBounds.has(event.ph)) {\n traceBounds.min = Types.Timing.MicroSeconds(Math.min(event.ts, traceBounds.min));\n const eventDuration = event.dur || Types.Timing.MicroSeconds(0);\n traceBounds.max = Types.Timing.MicroSeconds(Math.max(event.ts + eventDuration, traceBounds.max));\n }\n\n if (Types.TraceEvents.isProcessName(event) &&\n (event.args.name === 'Browser' || event.args.name === 'HeadlessBrowser')) {\n browserProcessId = event.pid;\n return;\n }\n\n if (Types.TraceEvents.isProcessName(event) && (event.args.name === 'Gpu' || event.args.name === 'GPU Process')) {\n gpuProcessId = event.pid;\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name === 'CrGpuMain') {\n gpuThreadId = event.tid;\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name === 'CrBrowserMain') {\n browserThreadId = event.tid;\n }\n\n if (Types.TraceEvents.isTraceEventMainFrameViewport(event) && viewportRect === null) {\n const rectAsArray = event.args.data.viewport_rect;\n const viewportX = rectAsArray[0];\n const viewportY = rectAsArray[1];\n const viewportWidth = rectAsArray[2];\n const viewportHeight = rectAsArray[5];\n viewportRect = new DOMRect(viewportX, viewportY, viewportWidth, viewportHeight);\n }\n\n // The TracingStartedInBrowser event includes the data on which frames are\n // in scope at the start of the trace. We use this to identify the frame with\n // no parent, i.e. the top level frame.\n if (Types.TraceEvents.isTraceEventTracingStartedInBrowser(event)) {\n traceStartedTimeFromTracingStartedEvent = event.ts;\n\n if (!event.args.data) {\n throw new Error('No frames found in trace data');\n }\n\n for (const frame of (event.args.data.frames ?? [])) {\n updateRendererProcessByFrame(event, frame);\n\n if (frame.parent) {\n continue;\n }\n\n mainFrameId = frame.frame;\n mainFrameURL = frame.url;\n topLevelRendererIds.add(frame.processId);\n }\n return;\n }\n\n // FrameCommittedInBrowser events tell us information about each frame\n // and we use these to track how long each individual renderer is active\n // for. We track all renderers here (top level and those in frames), but\n // for convenience we also populate a set of top level renderer IDs.\n if (Types.TraceEvents.isTraceEventFrameCommittedInBrowser(event)) {\n const frame = event.args.data;\n if (!frame) {\n return;\n }\n\n updateRendererProcessByFrame(event, frame);\n\n if (frame.parent) {\n return;\n }\n\n topLevelRendererIds.add(frame.processId);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventCommitLoad(event)) {\n const frameData = event.args.data;\n if (!frameData) {\n return;\n }\n\n const {frame, name, url} = frameData;\n updateRendererProcessByFrame(event, {processId: event.pid, frame, name, url});\n return;\n }\n\n // Track all threads based on the process & thread IDs.\n if (Types.TraceEvents.isThreadName(event)) {\n const threads = Platform.MapUtilities.getWithDefault(threadsInProcess, event.pid, () => new Map());\n threads.set(event.tid, event);\n return;\n }\n\n // Track all navigation events. Note that there can be navigation start events\n // but where the documentLoaderURL is empty. As far as the trace rendering is\n // concerned, these events are noise so we filter them out here.\n if (Types.TraceEvents.isTraceEventNavigationStartWithURL(event) && event.args.data) {\n const navigationId = event.args.data.navigationId;\n if (navigationsByNavigationId.has(navigationId)) {\n throw new Error('Found multiple navigation start events with the same navigation ID.');\n }\n navigationsByNavigationId.set(navigationId, event);\n\n const frameId = event.args.frame;\n const existingFrameNavigations = navigationsByFrameId.get(frameId) || [];\n existingFrameNavigations.push(event);\n navigationsByFrameId.set(frameId, existingFrameNavigations);\n if (frameId === mainFrameId) {\n mainFrameNavigations.push(event);\n }\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Handler is not initialized');\n }\n\n // We try to set the minimum time by finding the event with the smallest\n // timestamp. However, if we also got a timestamp from the\n // TracingStartedInBrowser event, we should always use that.\n // But in some traces (for example, CPU profiles) we do not get that event,\n // hence why we need to check we got a timestamp from it before setting it.\n if (traceStartedTimeFromTracingStartedEvent >= 0) {\n traceBounds.min = traceStartedTimeFromTracingStartedEvent;\n }\n traceBounds.range = Types.Timing.MicroSeconds(traceBounds.max - traceBounds.min);\n\n // If we go from foo.com to example.com we will get a new renderer, and\n // therefore the \"top level renderer\" will have a different PID as it has\n // changed. Here we step through each renderer process and updated its window\n // bounds, such that we end up with the time ranges in the trace for when\n // each particular renderer started and stopped being the main renderer\n // process.\n for (const [, processWindows] of rendererProcessesByFrameId) {\n const processWindowValues = [...processWindows.values()].flat();\n for (let i = 0; i < processWindowValues.length; i++) {\n const currentWindow = processWindowValues[i];\n const nextWindow = processWindowValues[i + 1];\n\n // For the last window we set its max to be positive infinity.\n // TODO: Move the trace bounds handler into meta so we can clamp first and last windows.\n if (!nextWindow) {\n currentWindow.window.max = Types.Timing.MicroSeconds(traceBounds.max);\n currentWindow.window.range = Types.Timing.MicroSeconds(traceBounds.max - currentWindow.window.min);\n } else {\n currentWindow.window.max = Types.Timing.MicroSeconds(nextWindow.window.min - 1);\n currentWindow.window.range = Types.Timing.MicroSeconds(currentWindow.window.max - currentWindow.window.min);\n }\n }\n }\n\n // Frame ids which we didn't register using either the TracingStartedInBrowser or\n // the FrameCommittedInBrowser events are considered noise, so we filter them out, as well\n // as the navigations that belong to such frames.\n for (const [frameId, navigations] of navigationsByFrameId) {\n // The frames in the rendererProcessesByFrameId map come only from the\n // TracingStartedInBrowser and FrameCommittedInBrowser events, so we can use it as point\n // of comparison to determine if a frameId should be discarded.\n if (rendererProcessesByFrameId.has(frameId)) {\n continue;\n }\n navigationsByFrameId.delete(frameId);\n for (const navigation of navigations) {\n if (!navigation.args.data) {\n continue;\n }\n navigationsByNavigationId.delete(navigation.args.data.navigationId);\n }\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\ntype MetaHandlerData = {\n traceBounds: Types.Timing.TraceWindow,\n browserProcessId: Types.TraceEvents.ProcessID,\n browserThreadId: Types.TraceEvents.ThreadID,\n gpuProcessId: Types.TraceEvents.ProcessID,\n gpuThreadId?: Types.TraceEvents.ThreadID,\n viewportRect?: DOMRect,\n navigationsByFrameId: Map<string, Types.TraceEvents.TraceEventNavigationStart[]>,\n navigationsByNavigationId: Map<string, Types.TraceEvents.TraceEventNavigationStart>,\n threadsInProcess:\n Map<Types.TraceEvents.ProcessID,\n Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>,\n mainFrameId: string,\n mainFrameURL: string,\n /**\n * A frame can have multiple renderer processes, at the same time,\n * a renderer process can have multiple URLs. This map tracks the\n * processes active on a given frame, with the time window in which\n * they were active. Because a renderer process might have multiple\n * URLs, each process in each frame has an array of windows, with an\n * entry for each URL it had.\n */\n rendererProcessesByFrame: FrameProcessData,\n topLevelRendererIds: Set<Types.TraceEvents.ProcessID>,\n frameByProcessId: Map<Types.TraceEvents.ProcessID, Map<string, Types.TraceEvents.TraceFrame>>,\n mainFrameNavigations: Types.TraceEvents.TraceEventNavigationStart[],\n};\n\nexport type FrameProcessData =\n Map<string,\n Map<Types.TraceEvents.ProcessID, {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindow}[]>>;\n\nexport function data(): MetaHandlerData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Meta Handler is not finalized');\n }\n\n return {\n traceBounds: {...traceBounds},\n browserProcessId,\n browserThreadId,\n gpuProcessId,\n gpuThreadId: gpuThreadId === Types.TraceEvents.ThreadID(-1) ? undefined : gpuThreadId,\n viewportRect: viewportRect || undefined,\n mainFrameId,\n mainFrameURL,\n navigationsByFrameId: new Map(navigationsByFrameId),\n navigationsByNavigationId: new Map(navigationsByNavigationId),\n threadsInProcess: new Map(threadsInProcess),\n rendererProcessesByFrame: new Map(rendererProcessesByFrameId),\n topLevelRendererIds: new Set(topLevelRendererIds),\n frameByProcessId: new Map(framesByProcessId),\n mainFrameNavigations: [...mainFrameNavigations],\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as SamplesIntegrator from './SamplesIntegrator.js';\nexport * as Timing from './Timing.js';\nexport * as Trace from './Trace.js';\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Root from '../../../core/root/root.js';\nimport type * as Protocol from '../../../generated/protocol.js';\nimport type * as CPUProfile from '../../cpu_profile/cpu_profile.js';\nimport * as Types from '../types/types.js';\n\nimport {millisecondsToMicroseconds} from './Timing.js';\nimport {mergeEventsInOrder} from './Trace.js';\n\ninterface Settings {\n showNativeFunctionsInJSProfile: boolean;\n}\n\n/**\n * This is a helper that integrates CPU profiling data coming in the\n * shape of samples, with trace events. Samples indicate what the JS\n * stack trace looked at a given point in time, but they don't have\n * duration. The SamplesIntegrator task is to make an approximation\n * of what the duration of each JS call was, given the sample data and\n * given the trace events profiled during that time. At the end of its\n * execution, the SamplesIntegrator returns an array of ProfileCalls\n * (under SamplesIntegrator::buildProfileCalls()), which\n * represent JS calls, with a call frame and duration. These calls have\n * the shape of a complete trace events and can be treated as flame\n * chart entries in the timeline.\n *\n * The approach to build the profile calls consists in tracking the\n * current stack as the following events happen (in order):\n * 1. A sample was done.\n * 2. A trace event started.\n * 3. A trace event ended.\n * Depending on the event and on the data that's coming with it the\n * stack is updated by adding or removing JS calls to it and updating\n * the duration of the calls in the tracking stack.\n *\n * note: Although this approach has been implemented since long ago, and\n * is relatively efficent (adds a complexity over the trace parsing of\n * O(n) where n is the number of samples) it has proven to be faulty.\n * It might be worthwhile experimenting with improvements or with a\n * completely different approach. Improving the approach is tracked in\n * crbug.com/1417439\n */\nexport class SamplesIntegrator {\n /**\n * The result of runing the samples integrator. Holds the JS calls\n * with their approximated duration after integrating samples into the\n * trace event tree.\n */\n #constructedProfileCalls: Types.TraceEvents.TraceEventSyntheticProfileCall[] = [];\n /**\n * tracks the state of the JS stack at each point in time to update\n * the profile call durations as new events arrive. This doesn't only\n * happen with new profile calls (in which case we would compare the\n * stack in them) but also with trace events (in which case we would\n * update the duration of the events we are tracking at the moment).\n */\n #currentJSStack: Types.TraceEvents.TraceEventSyntheticProfileCall[] = [];\n /**\n * Process holding the CPU profile and trace events.\n */\n #processId: Types.TraceEvents.ProcessID;\n /**\n * Thread holding the CPU profile and trace events.\n */\n #threadId: Types.TraceEvents.ThreadID;\n /**\n * Tracks the depth of the JS stack at the moment a trace event starts\n * or ends. It is assumed that for the duration of a trace event, the\n * JS stack's depth cannot decrease, since JS calls that started\n * before a trace event cannot end during the trace event. So as trace\n * events arrive, we store the \"locked\" amount of JS frames that were\n * in the stack before the event came.\n */\n #lockedJsStackDepth: number[] = [];\n /**\n * Used to keep track when samples should be integrated even if they\n * are not children of invocation trace events. This is useful in\n * cases where we can be missing the start of JS invocation events if\n * we start tracing half-way through.\n */\n #fakeJSInvocation = false;\n /**\n * The parsed CPU profile, holding the tree hierarchy of JS frames and\n * the sample data.\n */\n #profileModel: CPUProfile.CPUProfileDataModel.CPUProfileDataModel;\n /**\n * Because GC nodes don't have a stack, we artificially add a stack to\n * them which corresponds to that of the previous sample. This map\n * tracks which node is used for the stack of a GC call.\n */\n #nodeForGC = new Map<Types.TraceEvents.TraceEventSyntheticProfileCall, CPUProfile.ProfileTreeModel.ProfileNode>();\n\n #showNativeFunctionsInJSProfile: boolean;\n\n constructor(\n profileModel: CPUProfile.CPUProfileDataModel.CPUProfileDataModel, pid: Types.TraceEvents.ProcessID,\n tid: Types.TraceEvents.ThreadID, settings: Settings = {\n showNativeFunctionsInJSProfile: Types.Configuration.DEFAULT.settings.showNativeFunctionsInJSProfile,\n }) {\n this.#profileModel = profileModel;\n this.#threadId = tid;\n this.#processId = pid;\n this.#showNativeFunctionsInJSProfile = settings.showNativeFunctionsInJSProfile;\n }\n\n buildProfileCalls(traceEvents: Types.TraceEvents.TraceEventData[]):\n Types.TraceEvents.TraceEventSyntheticProfileCall[] {\n const mergedEvents = mergeEventsInOrder(traceEvents, this.callsFromProfileSamples());\n const stack = [];\n for (let i = 0; i < mergedEvents.length; i++) {\n const event = mergedEvents[i];\n if (stack.length === 0) {\n if (Types.TraceEvents.isProfileCall(event)) {\n this.#onProfileCall(event);\n continue;\n }\n stack.push(event);\n this.#onTraceEventStart(event);\n continue;\n }\n\n const parentEvent = stack.at(-1);\n if (parentEvent === undefined) {\n continue;\n }\n const begin = event.ts;\n const parentBegin = parentEvent.ts;\n const parentDuration = parentEvent.dur || 0;\n const parentEnd = parentBegin + parentDuration;\n\n const startsAfterParent = begin >= parentEnd;\n if (startsAfterParent) {\n this.#onTraceEventEnd(parentEvent);\n stack.pop();\n i--;\n continue;\n }\n if (Types.TraceEvents.isProfileCall(event)) {\n this.#onProfileCall(event, parentEvent);\n continue;\n }\n this.#onTraceEventStart(event);\n stack.push(event);\n }\n while (stack.length) {\n const last = stack.pop();\n if (last) {\n this.#onTraceEventEnd(last);\n }\n }\n return this.#constructedProfileCalls;\n }\n\n #onTraceEventStart(event: Types.TraceEvents.TraceEventData): void {\n // Because instant trace events have no duration, they don't provide\n // useful information for possible changes in the duration of calls\n // in the JS stack.\n if (event.ph === Types.TraceEvents.Phase.INSTANT) {\n return;\n }\n // Top level events cannot be nested into JS frames so we reset\n // the stack when we find one.\n if (event.name === Types.TraceEvents.KnownEventName.RunMicrotasks ||\n event.name === Types.TraceEvents.KnownEventName.RunTask) {\n this.#lockedJsStackDepth = [];\n this.#truncateJSStack(0, event.ts);\n this.#fakeJSInvocation = false;\n }\n\n if (this.#fakeJSInvocation) {\n this.#truncateJSStack(this.#lockedJsStackDepth.pop() || 0, event.ts);\n this.#fakeJSInvocation = false;\n }\n this.#extractStackTrace(event);\n // Keep track of the call frames in the stack before the event\n // happened. For the duration of this event, these frames cannot\n // change (none can be terminated before this event finishes).\n //\n // Also, every frame that is opened after this event, is considered\n // to be a descendant of the event. So once the event finishes, the\n // frames that were opened after it, need to be closed (see\n // onEndEvent).\n //\n // TODO(crbug.com/1417439):\n // The assumption that every frame opened after an event is a\n // descendant of the event is incorrect. For example, a JS call that\n // parents a trace event might have been sampled after the event was\n // dispatched. In this case the JS call would be discarded if this\n // event isn't an invocation event, otherwise the call will be\n // considered a child of the event. In both cases, the result would\n // be incorrect.\n this.#lockedJsStackDepth.push(this.#currentJSStack.length);\n }\n\n #onProfileCall(event: Types.TraceEvents.TraceEventSyntheticProfileCall, parent?: Types.TraceEvents.TraceEventData):\n void {\n if ((parent && SamplesIntegrator.isJSInvocationEvent(parent)) || this.#fakeJSInvocation) {\n this.#extractStackTrace(event);\n } else if (Types.TraceEvents.isProfileCall(event) && this.#currentJSStack.length === 0) {\n // Force JS Samples to show up even if we are not inside a JS\n // invocation event, because we can be missing the start of JS\n // invocation events if we start tracing half-way through. Pretend\n // we have a top-level JS invocation event.\n this.#fakeJSInvocation = true;\n const stackDepthBefore = this.#currentJSStack.length;\n this.#extractStackTrace(event);\n this.#lockedJsStackDepth.push(stackDepthBefore);\n }\n }\n\n #onTraceEventEnd(event: Types.TraceEvents.TraceEventData): void {\n // Because the event has ended, any frames that happened after\n // this event are terminated. Frames that are ancestors to this\n // event are extended to cover its ending.\n const endTime = Types.Timing.MicroSeconds(event.ts + (event.dur || 0));\n this.#truncateJSStack(this.#lockedJsStackDepth.pop() || 0, endTime);\n }\n\n /**\n * Builds the initial calls with no duration from samples. Their\n * purpose is to be merged with the trace event array being parsed so\n * that they can be traversed in order with them and their duration\n * can be updated as the SampleIntegrator callbacks are invoked.\n */\n callsFromProfileSamples(): Types.TraceEvents.TraceEventSyntheticProfileCall[] {\n const samples = this.#profileModel.samples;\n const timestamps = this.#profileModel.timestamps;\n if (!samples) {\n return [];\n }\n const calls: Types.TraceEvents.TraceEventSyntheticProfileCall[] = [];\n let prevNode;\n for (let i = 0; i < samples.length; i++) {\n const node = this.#profileModel.nodeByIndex(i);\n const timestamp = millisecondsToMicroseconds(Types.Timing.MilliSeconds(timestamps[i]));\n if (!node) {\n continue;\n }\n const call = SamplesIntegrator.makeProfileCall(node, timestamp, this.#processId, this.#threadId);\n calls.push(call);\n if (node.id === this.#profileModel.gcNode?.id && prevNode) {\n // GC samples have no stack, so we just put GC node on top of the\n // last recorded sample. Cache the previous sample for future\n // reference.\n this.#nodeForGC.set(call, prevNode);\n continue;\n }\n prevNode = node;\n }\n return calls;\n }\n\n #getStackTraceFromProfileCall(profileCall: Types.TraceEvents.TraceEventSyntheticProfileCall):\n Types.TraceEvents.TraceEventSyntheticProfileCall[] {\n let node = this.#profileModel.nodeById(profileCall.nodeId);\n const isGarbageCollection = Boolean(node?.id === this.#profileModel.gcNode?.id);\n if (isGarbageCollection) {\n // Because GC don't have a stack, we use the stack of the previous\n // sample.\n node = this.#nodeForGC.get(profileCall) || null;\n }\n if (!node) {\n return [];\n }\n // `node.depth` is 0 based, so to set the size of the array we need\n // to add 1 to its value.\n const callFrames =\n new Array<Types.TraceEvents.TraceEventSyntheticProfileCall>(node.depth + 1 + Number(isGarbageCollection));\n // Add the stack trace in reverse order (bottom first).\n let i = callFrames.length - 1;\n if (isGarbageCollection) {\n callFrames[i--] = profileCall;\n }\n while (node) {\n callFrames[i--] = SamplesIntegrator.makeProfileCall(node, profileCall.ts, this.#processId, this.#threadId);\n node = node.parent;\n }\n return callFrames;\n }\n\n /**\n * Update tracked stack using this event's call stack.\n */\n #extractStackTrace(event: Types.TraceEvents.TraceEventData): void {\n const stackTrace =\n Types.TraceEvents.isProfileCall(event) ? this.#getStackTraceFromProfileCall(event) : this.#currentJSStack;\n SamplesIntegrator.filterStackFrames(stackTrace, {\n showNativeFunctionsInJSProfile: this.#showNativeFunctionsInJSProfile,\n });\n\n const endTime = event.ts + (event.dur || 0);\n const minFrames = Math.min(stackTrace.length, this.#currentJSStack.length);\n let i;\n // Merge a sample's stack frames with the stack frames we have\n // so far if we detect they are equivalent.\n // Graphically\n // This:\n // Current stack trace Sample\n // [-------A------] [A]\n // [-------B------] [B]\n // [-------C------] [C]\n // ^ t = x1 ^ t = x2\n\n // Becomes this:\n // New stack trace after merge\n // [--------A-------]\n // [--------B-------]\n // [--------C-------]\n // ^ t = x2\n for (i = this.#lockedJsStackDepth.at(-1) || 0; i < minFrames; ++i) {\n const newFrame = stackTrace[i].callFrame;\n const oldFrame = this.#currentJSStack[i].callFrame;\n if (!SamplesIntegrator.framesAreEqual(newFrame, oldFrame)) {\n break;\n }\n // Scoot the right edge of this callFrame to the right\n this.#currentJSStack[i].dur =\n Types.Timing.MicroSeconds(Math.max(this.#currentJSStack[i].dur || 0, endTime - this.#currentJSStack[i].ts));\n }\n\n // If there are call frames in the sample that differ with the stack\n // we have, update the stack, but keeping the common frames in place\n // Graphically\n // This:\n // Current stack trace Sample\n // [-------A------] [A]\n // [-------B------] [B]\n // [-------C------] [C]\n // [-------D------] [E]\n // ^ t = x1 ^ t = x2\n // Becomes this:\n // New stack trace after merge\n // [--------A-------]\n // [--------B-------]\n // [--------C-------]\n // [E]\n // ^ t = x2\n this.#truncateJSStack(i, event.ts);\n\n for (; i < stackTrace.length; ++i) {\n const call = stackTrace[i];\n this.#currentJSStack.push(call);\n if (call.nodeId === this.#profileModel.programNode?.id || call.nodeId === this.#profileModel.root?.id ||\n call.nodeId === this.#profileModel.idleNode?.id) {\n // Skip (root), (program) and (idle) frames, since this are not\n // relevant for web profiling and we don't want to show them in\n // the timeline.\n continue;\n }\n this.#constructedProfileCalls.push(call);\n }\n }\n\n /**\n * When a call stack that differs from the one we are tracking has\n * been detected in the samples, the latter is \"truncated\" by\n * setting the ending time of its call frames and removing the top\n * call frames that aren't shared with the new call stack. This way,\n * we can update the tracked stack with the new call frames on top.\n * @param depth the amount of call frames from bottom to top that\n * should be kept in the tracking stack trace. AKA amount of shared\n * call frames between two stacks.\n * @param time the new end of the call frames in the stack.\n */\n #truncateJSStack(depth: number, time: Types.Timing.MicroSeconds): void {\n if (this.#lockedJsStackDepth.length) {\n const lockedDepth = this.#lockedJsStackDepth.at(-1);\n if (lockedDepth && depth < lockedDepth) {\n console.error(`Child stack is shallower (${depth}) than the parent stack (${lockedDepth}) at ${time}`);\n depth = lockedDepth;\n }\n }\n if (this.#currentJSStack.length < depth) {\n console.error(`Trying to truncate higher than the current stack size at ${time}`);\n depth = this.#currentJSStack.length;\n }\n for (let k = 0; k < this.#currentJSStack.length; ++k) {\n this.#currentJSStack[k].dur = Types.Timing.MicroSeconds(Math.max(time - this.#currentJSStack[k].ts, 0));\n }\n this.#currentJSStack.length = depth;\n }\n\n /**\n * Generally, before JS is executed, a trace event is dispatched that\n * parents the JS calls. These we call \"invocation\" events. This\n * function determines if an event is one of such.\n */\n static isJSInvocationEvent(event: Types.TraceEvents.TraceEventData): boolean {\n switch (event.name) {\n case Types.TraceEvents.KnownEventName.RunMicrotasks:\n case Types.TraceEvents.KnownEventName.FunctionCall:\n case Types.TraceEvents.KnownEventName.EvaluateScript:\n case Types.TraceEvents.KnownEventName.EvaluateModule:\n case Types.TraceEvents.KnownEventName.EventDispatch:\n case Types.TraceEvents.KnownEventName.V8Execute:\n return true;\n }\n // Also consider any new v8 trace events. (eg 'V8.RunMicrotasks' and 'v8.run')\n if (event.name.startsWith('v8') || event.name.startsWith('V8')) {\n return true;\n }\n return false;\n }\n\n static framesAreEqual(frame1: Protocol.Runtime.CallFrame, frame2: Protocol.Runtime.CallFrame): boolean {\n return frame1.scriptId === frame2.scriptId && frame1.functionName === frame2.functionName &&\n frame1.lineNumber === frame2.lineNumber;\n }\n\n static showNativeName(name: string): boolean {\n return false;\n try {\n // Querying for unregistered experiments will error on debug\n // builds.\n const showRuntimeCallStats = Root.Runtime.experiments.isEnabled('timelineV8RuntimeCallStats');\n return showRuntimeCallStats && Boolean(SamplesIntegrator.nativeGroup(name));\n } catch (error) {\n return false;\n }\n }\n\n static nativeGroup(nativeName: string): 'Parse'|'Compile'|null {\n if (nativeName.startsWith('Parse')) {\n return 'Parse';\n }\n if (nativeName.startsWith('Compile') || nativeName.startsWith('Recompile')) {\n return 'Compile';\n }\n return null;\n }\n\n static isNativeRuntimeFrame(frame: Protocol.Runtime.CallFrame): boolean {\n return frame.url === 'native V8Runtime';\n }\n\n static filterStackFrames(stack: Types.TraceEvents.TraceEventSyntheticProfileCall[], settings: {\n showNativeFunctionsInJSProfile: boolean,\n }): void {\n let showAllEvents = false;\n // try {\n // // Querying for unregistered experiments will error on debug\n // // builds.\n // showAllEvents = Root.Runtime.experiments.isEnabled('timelineShowAllEvents');\n // } catch (_err) {\n // }\n\n if (showAllEvents) {\n return;\n }\n let previousNativeFrameName: string|null = null;\n let j = 0;\n for (let i = 0; i < stack.length; ++i) {\n const frame = stack[i].callFrame;\n const url = frame.url;\n const isNativeFrame = url && url.startsWith('native ');\n if (!settings.showNativeFunctionsInJSProfile && isNativeFrame) {\n continue;\n }\n const nativeRuntimeFrame = SamplesIntegrator.isNativeRuntimeFrame(frame);\n if (nativeRuntimeFrame && !SamplesIntegrator.showNativeName(frame.functionName)) {\n continue;\n }\n const nativeFrameName = nativeRuntimeFrame ? SamplesIntegrator.nativeGroup(frame.functionName) : null;\n if (previousNativeFrameName && previousNativeFrameName === nativeFrameName) {\n continue;\n }\n previousNativeFrameName = nativeFrameName;\n stack[j++] = stack[i];\n }\n stack.length = j;\n }\n\n static makeProfileCall(\n node: CPUProfile.ProfileTreeModel.ProfileNode, ts: Types.Timing.MicroSeconds, pid: Types.TraceEvents.ProcessID,\n tid: Types.TraceEvents.ThreadID): Types.TraceEvents.TraceEventSyntheticProfileCall {\n return {\n cat: '',\n name: 'ProfileCall',\n nodeId: node.id,\n ph: Types.TraceEvents.Phase.COMPLETE,\n pid,\n tid,\n ts,\n dur: Types.Timing.MicroSeconds(0),\n selfTime: Types.Timing.MicroSeconds(0),\n callFrame: node.callFrame,\n };\n }\n}\n", "// Copyright 2020 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../platform/platform.js';\n\nconst queryParamsObject = new URLSearchParams(location.search);\n\nlet runtimePlatform = '';\n\nlet runtimeInstance: Runtime|undefined;\n\nexport function getRemoteBase(location: string = self.location.toString()): {\n base: string,\n version: string,\n}|null {\n const url = new URL(location);\n const remoteBase = url.searchParams.get('remoteBase');\n if (!remoteBase) {\n return null;\n }\n\n const version = /\\/serve_file\\/(@[0-9a-zA-Z]+)\\/?$/.exec(remoteBase);\n if (!version) {\n return null;\n }\n\n return {base: `devtools://devtools/remote/serve_file/${version[1]}/`, version: version[1]};\n}\n\nexport class Runtime {\n private constructor() {\n }\n\n static instance(opts: {\n forceNew: boolean|null,\n }|undefined = {forceNew: null}): Runtime {\n const {forceNew} = opts;\n if (!runtimeInstance || forceNew) {\n runtimeInstance = new Runtime();\n }\n\n return runtimeInstance;\n }\n\n static removeInstance(): void {\n runtimeInstance = undefined;\n }\n\n static queryParam(name: string): string|null {\n return queryParamsObject.get(name);\n }\n\n static setQueryParamForTesting(name: string, value: string): void {\n queryParamsObject.set(name, value);\n }\n\n static experimentsSetting(): {\n [x: string]: boolean,\n } {\n try {\n return JSON.parse(\n self.localStorage && self.localStorage['experiments'] ? self.localStorage['experiments'] : '{}') as {\n [x: string]: boolean,\n };\n } catch (e) {\n console.error('Failed to parse localStorage[\\'experiments\\']');\n return {};\n }\n }\n\n static setPlatform(platform: string): void {\n runtimePlatform = platform;\n }\n\n static platform(): string {\n return runtimePlatform;\n }\n\n static isDescriptorEnabled(descriptor: {\n experiment: ((string | undefined)|null),\n condition: ((string | undefined)|null),\n }): boolean {\n const activatorExperiment = descriptor['experiment'];\n if (activatorExperiment === '*') {\n return true;\n }\n if (activatorExperiment && activatorExperiment.startsWith('!') &&\n experiments.isEnabled(activatorExperiment.substring(1))) {\n return false;\n }\n if (activatorExperiment && !activatorExperiment.startsWith('!') && !experiments.isEnabled(activatorExperiment)) {\n return false;\n }\n const condition = descriptor['condition'];\n if (condition && !condition.startsWith('!') && !Runtime.queryParam(condition)) {\n return false;\n }\n if (condition && condition.startsWith('!') && Runtime.queryParam(condition.substring(1))) {\n return false;\n }\n return true;\n }\n\n loadLegacyModule(modulePath: string): Promise<void> {\n return import(`../../${modulePath}`);\n }\n}\n\nexport interface Option {\n title: string;\n value: string|boolean;\n raw?: boolean;\n text?: string;\n}\n\nexport class ExperimentsSupport {\n #experiments: Experiment[];\n #experimentNames: Set<string>;\n #enabledTransiently: Set<string>;\n readonly #enabledByDefault: Set<string>;\n readonly #serverEnabled: Set<string>;\n // Experiments in this set won't be shown to the user\n readonly #nonConfigurable: Set<string>;\n constructor() {\n this.#experiments = [];\n this.#experimentNames = new Set();\n this.#enabledTransiently = new Set();\n this.#enabledByDefault = new Set();\n this.#serverEnabled = new Set();\n this.#nonConfigurable = new Set();\n }\n\n allConfigurableExperiments(): Experiment[] {\n const result = [];\n for (const experiment of this.#experiments) {\n if (!this.#enabledTransiently.has(experiment.name) && !this.#nonConfigurable.has(experiment.name)) {\n result.push(experiment);\n }\n }\n return result;\n }\n\n private setExperimentsSetting(value: Object): void {\n if (!self.localStorage) {\n return;\n }\n self.localStorage['experiments'] = JSON.stringify(value);\n }\n\n register(\n experimentName: string, experimentTitle: string, unstable?: boolean, docLink?: string,\n feedbackLink?: string): void {\n Platform.DCHECK(\n () => !this.#experimentNames.has(experimentName), 'Duplicate registration of experiment ' + experimentName);\n this.#experimentNames.add(experimentName);\n this.#experiments.push(new Experiment(\n this, experimentName, experimentTitle, Boolean(unstable),\n docLink as Platform.DevToolsPath.UrlString ?? Platform.DevToolsPath.EmptyUrlString,\n feedbackLink as Platform.DevToolsPath.UrlString ?? Platform.DevToolsPath.EmptyUrlString));\n }\n\n isEnabled(experimentName: string): boolean {\n this.checkExperiment(experimentName);\n // Check for explicitly disabled #experiments first - the code could call setEnable(false) on the experiment enabled\n // by default and we should respect that.\n if (Runtime.experimentsSetting()[experimentName] === false) {\n return false;\n }\n if (this.#enabledTransiently.has(experimentName) || this.#enabledByDefault.has(experimentName)) {\n return true;\n }\n if (this.#serverEnabled.has(experimentName)) {\n return true;\n }\n\n return Boolean(Runtime.experimentsSetting()[experimentName]);\n }\n\n setEnabled(experimentName: string, enabled: boolean): void {\n this.checkExperiment(experimentName);\n const experimentsSetting = Runtime.experimentsSetting();\n experimentsSetting[experimentName] = enabled;\n this.setExperimentsSetting(experimentsSetting);\n }\n\n enableExperimentsTransiently(experimentNames: string[]): void {\n for (const experimentName of experimentNames) {\n this.checkExperiment(experimentName);\n this.#enabledTransiently.add(experimentName);\n }\n }\n\n enableExperimentsByDefault(experimentNames: string[]): void {\n for (const experimentName of experimentNames) {\n this.checkExperiment(experimentName);\n this.#enabledByDefault.add(experimentName);\n }\n }\n\n setServerEnabledExperiments(experimentNames: string[]): void {\n for (const experiment of experimentNames) {\n this.checkExperiment(experiment);\n this.#serverEnabled.add(experiment);\n }\n }\n\n setNonConfigurableExperiments(experimentNames: string[]): void {\n for (const experiment of experimentNames) {\n this.checkExperiment(experiment);\n this.#nonConfigurable.add(experiment);\n }\n }\n\n enableForTest(experimentName: string): void {\n this.checkExperiment(experimentName);\n this.#enabledTransiently.add(experimentName);\n }\n\n disableForTest(experimentName: string): void {\n this.checkExperiment(experimentName);\n this.#enabledTransiently.delete(experimentName);\n }\n\n clearForTest(): void {\n this.#experiments = [];\n this.#experimentNames.clear();\n this.#enabledTransiently.clear();\n this.#enabledByDefault.clear();\n this.#serverEnabled.clear();\n }\n\n cleanUpStaleExperiments(): void {\n const experimentsSetting = Runtime.experimentsSetting();\n const cleanedUpExperimentSetting: {\n [x: string]: boolean,\n } = {};\n for (const {name: experimentName} of this.#experiments) {\n if (experimentsSetting.hasOwnProperty(experimentName)) {\n const isEnabled = experimentsSetting[experimentName];\n if (isEnabled || this.#enabledByDefault.has(experimentName)) {\n cleanedUpExperimentSetting[experimentName] = isEnabled;\n }\n }\n }\n this.setExperimentsSetting(cleanedUpExperimentSetting);\n }\n\n private checkExperiment(experimentName: string): void {\n Platform.DCHECK(() => this.#experimentNames.has(experimentName), 'Unknown experiment ' + experimentName);\n }\n}\n\nexport class Experiment {\n name: string;\n title: string;\n unstable: boolean;\n docLink?: Platform.DevToolsPath.UrlString;\n readonly feedbackLink?: Platform.DevToolsPath.UrlString;\n readonly #experiments: ExperimentsSupport;\n constructor(\n experiments: ExperimentsSupport, name: string, title: string, unstable: boolean,\n docLink: Platform.DevToolsPath.UrlString, feedbackLink: Platform.DevToolsPath.UrlString) {\n this.name = name;\n this.title = title;\n this.unstable = unstable;\n this.docLink = docLink;\n this.feedbackLink = feedbackLink;\n this.#experiments = experiments;\n }\n\n isEnabled(): boolean {\n return this.#experiments.isEnabled(this.name);\n }\n\n setEnabled(enabled: boolean): void {\n this.#experiments.setEnabled(this.name, enabled);\n }\n}\n\n// This must be constructed after the query parameters have been parsed.\nexport const experiments = new ExperimentsSupport();\n\n// TODO(crbug.com/1167717): Make this a const enum again\n// eslint-disable-next-line rulesdir/const_enum\nexport enum ExperimentName {\n CAPTURE_NODE_CREATION_STACKS = 'captureNodeCreationStacks',\n CSS_OVERVIEW = 'cssOverview',\n LIVE_HEAP_PROFILE = 'liveHeapProfile',\n DEVELOPER_RESOURCES_VIEW = 'developerResourcesView',\n CSP_VIOLATIONS_VIEW = 'cspViolationsView',\n WASM_DWARF_DEBUGGING = 'wasmDWARFDebugging',\n ALL = '*',\n PROTOCOL_MONITOR = 'protocolMonitor',\n WEBAUTHN_PANE = 'webauthnPane',\n FULL_ACCESSIBILITY_TREE = 'fullAccessibilityTree',\n PRECISE_CHANGES = 'preciseChanges',\n STYLES_PANE_CSS_CHANGES = 'stylesPaneCSSChanges',\n HEADER_OVERRIDES = 'headerOverrides',\n EYEDROPPER_COLOR_PICKER = 'eyedropperColorPicker',\n INSTRUMENTATION_BREAKPOINTS = 'instrumentationBreakpoints',\n AUTHORED_DEPLOYED_GROUPING = 'authoredDeployedGrouping',\n IMPORTANT_DOM_PROPERTIES = 'importantDOMProperties',\n JUST_MY_CODE = 'justMyCode',\n PRELOADING_STATUS_PANEL = 'preloadingStatusPanel',\n DISABLE_COLOR_FORMAT_SETTING = 'disableColorFormatSetting',\n TIMELINE_AS_CONSOLE_PROFILE_RESULT_PANEL = 'timelineAsConsoleProfileResultPanel',\n OUTERMOST_TARGET_SELECTOR = 'outermostTargetSelector',\n JS_PROFILER_TEMP_ENABLE = 'jsProfilerTemporarilyEnable',\n HIGHLIGHT_ERRORS_ELEMENTS_PANEL = 'highlightErrorsElementsPanel',\n SET_ALL_BREAKPOINTS_EAGERLY = 'setAllBreakpointsEagerly',\n SELF_XSS_WARNING = 'selfXssWarning',\n USE_SOURCE_MAP_SCOPES = 'useSourceMapScopes',\n STORAGE_BUCKETS_TREE = 'storageBucketsTree',\n DELETE_OVERRIDES_TEMP_ENABLE = 'deleteOverridesTemporarilyEnable',\n}\n\n// TODO(crbug.com/1167717): Make this a const enum again\n// eslint-disable-next-line rulesdir/const_enum\nexport enum ConditionName {\n CAN_DOCK = 'can_dock',\n NOT_SOURCES_HIDE_ADD_FOLDER = '!sources.hide_add_folder',\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\nimport {getNavigationForTraceEvent} from './Trace.js';\n\nexport const millisecondsToMicroseconds = (value: Types.Timing.MilliSeconds): Types.Timing.MicroSeconds =>\n Types.Timing.MicroSeconds(value * 1000);\n\nexport const secondsToMilliseconds = (value: Types.Timing.Seconds): Types.Timing.MilliSeconds =>\n Types.Timing.MilliSeconds(value * 1000);\n\nexport const secondsToMicroseconds = (value: Types.Timing.Seconds): Types.Timing.MicroSeconds =>\n millisecondsToMicroseconds(secondsToMilliseconds(value));\n\nexport const microSecondsToMilliseconds = (value: Types.Timing.MicroSeconds): Types.Timing.MilliSeconds =>\n Types.Timing.MilliSeconds(value / 1000);\n\nexport const microSecondsToSeconds = (value: Types.Timing.MicroSeconds): Types.Timing.Seconds =>\n Types.Timing.Seconds(value / 1000 / 1000);\n\nexport function detectBestTimeUnit(timeInMicroseconds: Types.Timing.MicroSeconds): Types.Timing.TimeUnit {\n if (timeInMicroseconds < 1000) {\n return Types.Timing.TimeUnit.MICROSECONDS;\n }\n\n const timeInMilliseconds = timeInMicroseconds / 1000;\n if (timeInMilliseconds < 1000) {\n return Types.Timing.TimeUnit.MILLISECONDS;\n }\n\n const timeInSeconds = timeInMilliseconds / 1000;\n if (timeInSeconds < 60) {\n return Types.Timing.TimeUnit.SECONDS;\n }\n\n return Types.Timing.TimeUnit.MINUTES;\n}\n\ninterface FormatOptions extends Intl.NumberFormatOptions {\n format?: Types.Timing.TimeUnit;\n}\n\nconst defaultFormatOptions = {\n style: 'unit',\n unit: 'millisecond',\n unitDisplay: 'narrow',\n};\n\n// Create a bunch of common formatters up front, so that we're not creating\n// them repeatedly during rendering.\nconst serialize = (value: {}): string => JSON.stringify(value);\nconst formatterFactory = (key: string|undefined): Intl.NumberFormat => {\n return new Intl.NumberFormat(navigator.language, key ? JSON.parse(key) : {});\n};\nconst formatters = new Map<string, Intl.NumberFormat>();\n\n// Microsecond Formatter.\nPlatform.MapUtilities.getWithDefault(formatters, serialize({style: 'decimal'}), formatterFactory);\n\n// Millisecond Formatter\nPlatform.MapUtilities.getWithDefault(formatters, serialize(defaultFormatOptions), formatterFactory);\n\n// Second Formatter\nPlatform.MapUtilities.getWithDefault(\n formatters, serialize({...defaultFormatOptions, unit: 'second'}), formatterFactory);\n\n// Minute Formatter\nPlatform.MapUtilities.getWithDefault(\n formatters, serialize({...defaultFormatOptions, unit: 'minute'}), formatterFactory);\n\nexport function formatMicrosecondsTime(\n timeInMicroseconds: Types.Timing.MicroSeconds, opts: FormatOptions = {}): string {\n if (!opts.format) {\n opts.format = detectBestTimeUnit(timeInMicroseconds);\n }\n\n const timeInMilliseconds = timeInMicroseconds / 1000;\n const timeInSeconds = timeInMilliseconds / 1000;\n const formatterOpts = {...defaultFormatOptions, ...opts};\n\n switch (opts.format) {\n case Types.Timing.TimeUnit.MICROSECONDS: {\n const formatter =\n Platform.MapUtilities.getWithDefault(formatters, serialize({style: 'decimal'}), formatterFactory);\n return `${formatter.format(timeInMicroseconds)}\u03BCs`;\n }\n\n case Types.Timing.TimeUnit.MILLISECONDS: {\n const formatter = Platform.MapUtilities.getWithDefault(formatters, serialize(formatterOpts), formatterFactory);\n return formatter.format(timeInMilliseconds);\n }\n\n case Types.Timing.TimeUnit.SECONDS: {\n const formatter = Platform.MapUtilities.getWithDefault(\n formatters, serialize({...formatterOpts, unit: 'second'}), formatterFactory);\n return formatter.format(timeInSeconds);\n }\n\n default: {\n // Switch to mins & seconds.\n const minuteFormatter = Platform.MapUtilities.getWithDefault(\n formatters, serialize({...formatterOpts, unit: 'minute'}), formatterFactory);\n const secondFormatter = Platform.MapUtilities.getWithDefault(\n formatters, serialize({...formatterOpts, unit: 'second'}), formatterFactory);\n const timeInMinutes = timeInSeconds / 60;\n const [mins, divider, fraction] = minuteFormatter.formatToParts(timeInMinutes);\n\n let seconds = 0;\n if (divider && fraction) {\n // Convert the fraction value (a string) to the nearest second.\n seconds = Math.round(Number(`0.${fraction.value}`) * 60);\n }\n return `${minuteFormatter.format(Number(mins.value))} ${secondFormatter.format(seconds)}`;\n }\n }\n}\n\nexport function timeStampForEventAdjustedByClosestNavigation(\n event: Types.TraceEvents.TraceEventData,\n traceBounds: Types.Timing.TraceWindow,\n navigationsByNavigationId: Map<string, Types.TraceEvents.TraceEventNavigationStart>,\n navigationsByFrameId: Map<string, Types.TraceEvents.TraceEventNavigationStart[]>,\n ): Types.Timing.MicroSeconds {\n let eventTimeStamp = event.ts - traceBounds.min;\n if (event.args?.data?.navigationId) {\n const navigationForEvent = navigationsByNavigationId.get(event.args.data.navigationId);\n if (navigationForEvent) {\n eventTimeStamp = event.ts - navigationForEvent.ts;\n }\n } else if (event.args?.data?.frame) {\n const navigationForEvent = getNavigationForTraceEvent(event, event.args.data.frame, navigationsByFrameId);\n if (navigationForEvent) {\n eventTimeStamp = event.ts - navigationForEvent.ts;\n }\n }\n return Types.Timing.MicroSeconds(eventTimeStamp);\n}\n\nexport interface EventTimingsData<\n ValueType extends Types.Timing.MicroSeconds|Types.Timing.MilliSeconds|Types.Timing.Seconds,\n> {\n startTime: ValueType;\n endTime: ValueType;\n duration: ValueType;\n selfTime: ValueType;\n}\n\nexport function eventTimingsMicroSeconds(event: Types.TraceEvents.TraceEventData):\n EventTimingsData<Types.Timing.MicroSeconds> {\n return {\n startTime: event.ts,\n endTime: Types.Timing.MicroSeconds(event.ts + (event.dur || Types.Timing.MicroSeconds(0))),\n duration: Types.Timing.MicroSeconds(event.dur || 0),\n // TODO(crbug.com/1434599): Implement selfTime calculation for events\n // from the new engine.\n selfTime: Types.Timing.MicroSeconds(event.dur || 0),\n };\n}\nexport function eventTimingsMilliSeconds(event: Types.TraceEvents.TraceEventData):\n EventTimingsData<Types.Timing.MilliSeconds> {\n const microTimes = eventTimingsMicroSeconds(event);\n return {\n startTime: microSecondsToMilliseconds(microTimes.startTime),\n endTime: microSecondsToMilliseconds(microTimes.endTime),\n duration: microSecondsToMilliseconds(microTimes.duration),\n selfTime: microSecondsToMilliseconds(microTimes.selfTime),\n };\n}\nexport function eventTimingsSeconds(event: Types.TraceEvents.TraceEventData): EventTimingsData<Types.Timing.Seconds> {\n const microTimes = eventTimingsMicroSeconds(event);\n return {\n startTime: microSecondsToSeconds(microTimes.startTime),\n endTime: microSecondsToSeconds(microTimes.endTime),\n duration: microSecondsToSeconds(microTimes.duration),\n selfTime: microSecondsToSeconds(microTimes.selfTime),\n };\n}\n\nexport function traceBoundsMilliseconds(bounds: Types.Timing.TraceWindow): {\n min: Types.Timing.MilliSeconds,\n max: Types.Timing.MilliSeconds,\n range: Types.Timing.MilliSeconds,\n} {\n return {\n min: microSecondsToMilliseconds(bounds.min),\n max: microSecondsToMilliseconds(bounds.max),\n range: microSecondsToMilliseconds(bounds.range),\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Types from '../types/types.js';\nimport * as Platform from '../../../core/platform/platform.js';\n\nexport function extractOriginFromTrace(firstNavigationURL: string): string|null {\n const url = new URL(firstNavigationURL);\n if (url) {\n // We do this to save some space in the toolbar - seeing the `www` is less\n // useful than seeing `foo.com` if it's truncated at narrow widths\n if (url.host.startsWith('www.')) {\n return url.host.slice(4);\n }\n return url.host;\n }\n return null;\n}\n\nexport type EventsInThread<T extends Types.TraceEvents.TraceEventData> = Map<Types.TraceEvents.ThreadID, T[]>;\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nexport function addEventToProcessThread<T extends Types.TraceEvents.TraceEventData>(\n event: T,\n eventsInProcessThread: Map<Types.TraceEvents.ProcessID, EventsInThread<T>>,\n ): void {\n const {tid, pid} = event;\n let eventsInThread = eventsInProcessThread.get(pid);\n if (!eventsInThread) {\n eventsInThread = new Map<Types.TraceEvents.ThreadID, T[]>();\n }\n\n let events = eventsInThread.get(tid);\n if (!events) {\n events = [];\n }\n\n events.push(event);\n eventsInThread.set(event.tid, events);\n eventsInProcessThread.set(event.pid, eventsInThread);\n}\n\ntype TimeSpan = {\n ts: Types.Timing.MicroSeconds,\n dur?: Types.Timing.MicroSeconds,\n};\nfunction eventTimeComparator(a: TimeSpan, b: TimeSpan): -1|0|1 {\n const aBeginTime = a.ts;\n const bBeginTime = b.ts;\n if (aBeginTime < bBeginTime) {\n return -1;\n }\n if (aBeginTime > bBeginTime) {\n return 1;\n }\n const aDuration = a.dur ?? 0;\n const bDuration = b.dur ?? 0;\n const aEndTime = aBeginTime + aDuration;\n const bEndTime = bBeginTime + bDuration;\n if (aEndTime > bEndTime) {\n return -1;\n }\n if (aEndTime < bEndTime) {\n return 1;\n }\n return 0;\n}\n/**\n * Sorts all the events in place, in order, by their start time. If they have\n * the same start time, orders them by longest first.\n */\nexport function sortTraceEventsInPlace(events: {ts: Types.Timing.MicroSeconds, dur?: Types.Timing.MicroSeconds}[]):\n void {\n events.sort(eventTimeComparator);\n}\n\n/**\n * Returns an array of ordered events that results after merging the two\n * ordered input arrays.\n */\nexport function mergeEventsInOrder<T extends Types.TraceEvents.TraceEventData>(\n eventsArray1: T[], eventsArray2: T[]): T[] {\n const result = [];\n let i = 0;\n let j = 0;\n while (i < eventsArray1.length && j < eventsArray2.length) {\n const event1 = eventsArray1[i];\n const event2 = eventsArray2[j];\n const compareValue = eventTimeComparator(event1, event2);\n if (compareValue <= 0) {\n result.push(event1);\n i++;\n }\n if (compareValue === 1) {\n result.push(event2);\n j++;\n }\n }\n while (i < eventsArray1.length) {\n result.push(eventsArray1[i++]);\n }\n while (j < eventsArray2.length) {\n result.push(eventsArray2[j++]);\n }\n return result;\n}\n\nexport function getNavigationForTraceEvent(\n event: Types.TraceEvents.TraceEventData,\n eventFrameId: string,\n navigationsByFrameId: Map<string, Types.TraceEvents.TraceEventNavigationStart[]>,\n ): Types.TraceEvents.TraceEventNavigationStart|null {\n const navigations = navigationsByFrameId.get(eventFrameId);\n if (!navigations || eventFrameId === '') {\n // This event's navigation has been filtered out by the meta handler as a noise event\n // or contains an empty frameId.\n return null;\n }\n\n const eventNavigationIndex =\n Platform.ArrayUtilities.nearestIndexFromEnd(navigations, navigation => navigation.ts <= event.ts);\n\n if (eventNavigationIndex === null) {\n // This event's navigation has been filtered out by the meta handler as a noise event.\n return null;\n }\n return navigations[eventNavigationIndex];\n}\n\nexport function extractId(event: Types.TraceEvents.TraceEventNestableAsync): string|undefined {\n return event.id || event.id2?.global || event.id2?.local;\n}\n\nexport function activeURLForFrameAtTime(\n frameId: string, time: Types.Timing.MicroSeconds,\n rendererProcessesByFrame: Map<\n string,\n Map<Types.TraceEvents.ProcessID, {frame: Types.TraceEvents.TraceFrame, window: Types.Timing.TraceWindow}[]>>):\n string|null {\n const processData = rendererProcessesByFrame.get(frameId);\n if (!processData) {\n return null;\n }\n for (const processes of processData.values()) {\n for (const processInfo of processes) {\n if (processInfo.window.min > time || processInfo.window.max < time) {\n continue;\n }\n return processInfo.frame.url;\n }\n }\n return null;\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Helpers from '../helpers/helpers.js';\n\nimport {type TraceEventHandlerName, HandlerState} from './types.js';\n\nimport {ScoreClassification} from './PageLoadMetricsHandler.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport {data as screenshotsHandlerData} from './ScreenshotsHandler.js';\nimport * as Platform from '../../../core/platform/platform.js';\n\nimport * as Types from '../types/types.js';\n\n// We start with a score of zero and step through all Layout Shift records from\n// all renderers. Each record not only tells us which renderer it is, but also\n// the unweighted and weighted scores. The unweighted score is the score we would\n// get if the renderer were the only one in the viewport. The weighted score, on\n// the other hand, accounts for how much of the viewport that particular render\n// takes up when the shift happened. An ad frame in the corner of the viewport\n// that shifts is considered less disruptive, therefore, than if it were taking\n// up the whole viewport.\n//\n// Next, we step through all the records from all renderers and add the weighted\n// score to a running total across all of the renderers. We create a new \"cluster\"\n// and reset the running total when:\n//\n// 1. We observe a outermost frame navigation, or\n// 2. When there's a gap between records of > 1s, or\n// 3. When there's more than 5 seconds of continuous layout shifting.\n//\n// Note that for it to be Cumulative Layout Shift in the sense described in the\n// documentation we would need to guarantee that we are tracking from navigation\n// to unload. However, we don't make any such guarantees here (since a developer\n// can record and stop when they please), so we support the cluster approach,\n// and we can give them a score, but it is effectively a \"session\" score, a\n// score for the given recording, and almost certainly not the\n// navigation-to-unload CLS score.\n\ninterface LayoutShifts {\n clusters: LayoutShiftCluster[];\n sessionMaxScore: number;\n // The session window which contains the SessionMaxScore\n clsWindowID: number;\n // We use these to calculate root causes for a given LayoutShift\n prePaintEvents: Types.TraceEvents.TraceEventPrePaint[];\n layoutInvalidationEvents: Types.TraceEvents.TraceEventLayoutInvalidation[];\n styleRecalcInvalidationEvents: Types.TraceEvents.TraceEventStyleRecalcInvalidation[];\n scoreRecords: ScoreRecord[];\n}\n\n// This represents the maximum #time we will allow a cluster to go before we\n// reset it.\nexport const MAX_CLUSTER_DURATION = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(5000));\n\n// This represents the maximum #time we will allow between layout shift events\n// before considering it to be the start of a new cluster.\nexport const MAX_SHIFT_TIME_DELTA = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(1000));\n\n// Layout shifts are reported globally to the developer, irrespective of which\n// frame they originated in. However, each process does have its own individual\n// CLS score, so we need to segment by process. This means Layout Shifts from\n// sites with one process (no subframes, or subframes from the same origin)\n// will be reported together. In the case of multiple renderers (frames across\n// different origins), we offer the developer the ability to switch renderer in\n// the UI.\nconst layoutShiftEvents: Types.TraceEvents.TraceEventLayoutShift[] = [];\n\n// These events denote potential node resizings. We store them to link captured\n// layout shifts to the resizing of unsized elements.\nconst layoutInvalidationEvents: Types.TraceEvents.TraceEventLayoutInvalidation[] = [];\nconst styleRecalcInvalidationEvents: Types.TraceEvents.TraceEventStyleRecalcInvalidation[] = [];\n\n// Layout shifts happen during PrePaint as part of the rendering lifecycle.\n// We determine if a LayoutInvalidation event is a potential root cause of a layout\n// shift if the next PrePaint after the LayoutInvalidation is the parent\n// node of such shift.\nconst prePaintEvents: Types.TraceEvents.TraceEventPrePaint[] = [];\n\nlet sessionMaxScore = 0;\n\nlet clsWindowID = -1;\n\nconst clusters: LayoutShiftCluster[] = [];\n\n// Represents a point in time in which a LS score change\n// was recorded.\ntype ScoreRecord = {\n ts: number,\n score: number,\n};\n\n// The complete timeline of LS score changes in a trace.\n// Includes drops to 0 when session windows end.\nconst scoreRecords: ScoreRecord[] = [];\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('LayoutShifts Handler was not reset');\n }\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function reset(): void {\n handlerState = HandlerState.UNINITIALIZED;\n layoutShiftEvents.length = 0;\n layoutInvalidationEvents.length = 0;\n prePaintEvents.length = 0;\n clusters.length = 0;\n sessionMaxScore = 0;\n scoreRecords.length = 0;\n clsWindowID = -1;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Handler is not initialized');\n }\n\n if (Types.TraceEvents.isTraceEventLayoutShift(event) && !event.args.data?.had_recent_input) {\n layoutShiftEvents.push(event);\n return;\n }\n if (Types.TraceEvents.isTraceEventLayoutInvalidation(event)) {\n layoutInvalidationEvents.push(event);\n return;\n }\n if (Types.TraceEvents.isTraceEventStyleRecalcInvalidation(event)) {\n styleRecalcInvalidationEvents.push(event);\n }\n if (Types.TraceEvents.isTraceEventPrePaint(event)) {\n prePaintEvents.push(event);\n return;\n }\n}\n\nfunction traceWindowFromTime(time: Types.Timing.MicroSeconds): Types.Timing.TraceWindow {\n return {\n min: time,\n max: time,\n range: Types.Timing.MicroSeconds(0),\n };\n}\n\nfunction updateTraceWindowMax(traceWindow: Types.Timing.TraceWindow, newMax: Types.Timing.MicroSeconds): void {\n traceWindow.max = newMax;\n traceWindow.range = Types.Timing.MicroSeconds(traceWindow.max - traceWindow.min);\n}\n\nfunction findNextScreenshotSource(timestamp: Types.Timing.MicroSeconds): string|undefined {\n const screenshots = screenshotsHandlerData();\n const screenshotIndex = findNextScreenshotEventIndex(screenshots, timestamp);\n if (!screenshotIndex) {\n return undefined;\n }\n return `data:img/png;base64,${screenshots[screenshotIndex].args.snapshot}`;\n}\n\nexport function findNextScreenshotEventIndex(\n screenshots: Types.TraceEvents.TraceEventSnapshot[], timestamp: Types.Timing.MicroSeconds): number|null {\n return Platform.ArrayUtilities.nearestIndexFromBeginning(screenshots, frame => frame.ts > timestamp);\n}\n\nfunction buildScoreRecords(): void {\n const {traceBounds} = metaHandlerData();\n scoreRecords.push({ts: traceBounds.min, score: 0});\n\n for (const cluster of clusters) {\n let clusterScore = 0;\n if (cluster.events[0].args.data) {\n scoreRecords.push({ts: cluster.clusterWindow.min, score: cluster.events[0].args.data.weighted_score_delta});\n }\n for (let i = 0; i < cluster.events.length; i++) {\n const event = cluster.events[i];\n if (!event.args.data) {\n continue;\n }\n clusterScore += event.args.data.weighted_score_delta;\n scoreRecords.push({ts: event.ts, score: clusterScore});\n }\n scoreRecords.push({ts: cluster.clusterWindow.max, score: 0});\n }\n}\n\nexport async function finalize(): Promise<void> {\n // Ensure the events are sorted by #time ascending.\n layoutShiftEvents.sort((a, b) => a.ts - b.ts);\n prePaintEvents.sort((a, b) => a.ts - b.ts);\n layoutInvalidationEvents.sort((a, b) => a.ts - b.ts);\n\n // Each function transforms the data used by the next, as such the invoke order\n // is important.\n await buildLayoutShiftsClusters();\n buildScoreRecords();\n handlerState = HandlerState.FINALIZED;\n}\nasync function buildLayoutShiftsClusters(): Promise<void> {\n const {navigationsByFrameId, mainFrameId, traceBounds} = metaHandlerData();\n const navigations = navigationsByFrameId.get(mainFrameId) || [];\n if (layoutShiftEvents.length === 0) {\n return;\n }\n let firstShiftTime = layoutShiftEvents[0].ts;\n let lastShiftTime = layoutShiftEvents[0].ts;\n let lastShiftNavigation = null;\n // Now step through each and create clusters.\n // A cluster is equivalent to a session window (see https://web.dev/cls/#what-is-cls).\n // To make the line chart clear, we explicitly demark the limits of each session window\n // by starting the cumulative score of the window at the time of the first layout shift\n // and ending it (dropping the line back to 0) when the window ends according to the\n // thresholds (MAX_CLUSTER_DURATION, MAX_SHIFT_TIME_DELTA).\n for (const event of layoutShiftEvents) {\n // First detect if either the cluster duration or the #time between this and\n // the last shift has been exceeded.\n const clusterDurationExceeded = event.ts - firstShiftTime > MAX_CLUSTER_DURATION;\n const maxTimeDeltaSinceLastShiftExceeded = event.ts - lastShiftTime > MAX_SHIFT_TIME_DELTA;\n\n // Next take a look at navigations. If between this and the last shift we have navigated,\n // note it.\n const currentShiftNavigation = Platform.ArrayUtilities.nearestIndexFromEnd(navigations, nav => nav.ts < event.ts);\n const hasNavigated = lastShiftNavigation !== currentShiftNavigation && currentShiftNavigation !== null;\n\n // If any of the above criteria are met or if we don't have any cluster yet we should\n // start a new one.\n if (clusterDurationExceeded || maxTimeDeltaSinceLastShiftExceeded || hasNavigated || !clusters.length) {\n // The cluster starts #time should be the timestamp of the first layout shift in it.\n const clusterStartTime = event.ts;\n\n // If the last session window ended because the max delta time between shifts\n // was exceeded set the endtime to MAX_SHIFT_TIME_DELTA microseconds after the\n // last shift in the session.\n const endTimeByMaxSessionDuration = clusterDurationExceeded ? firstShiftTime + MAX_CLUSTER_DURATION : Infinity;\n\n // If the last session window ended because the max session duration was\n // surpassed, set the endtime so that the window length = MAX_CLUSTER_DURATION;\n const endTimeByMaxShiftGap = maxTimeDeltaSinceLastShiftExceeded ? lastShiftTime + MAX_SHIFT_TIME_DELTA : Infinity;\n\n // If there was a navigation during the last window, close it at the time\n // of the navigation.\n const endTimeByNavigation = hasNavigated ? navigations[currentShiftNavigation].ts : Infinity;\n\n // End the previous cluster at the time of the first of the criteria above that was met.\n const previousClusterEndTime = Math.min(endTimeByMaxSessionDuration, endTimeByMaxShiftGap, endTimeByNavigation);\n\n // If there is an existing cluster update its closing time.\n if (clusters.length > 0) {\n const currentCluster = clusters[clusters.length - 1];\n updateTraceWindowMax(currentCluster.clusterWindow, Types.Timing.MicroSeconds(previousClusterEndTime));\n }\n\n clusters.push({\n events: [],\n clusterWindow: traceWindowFromTime(clusterStartTime),\n clusterCumulativeScore: 0,\n scoreWindows: {\n good: traceWindowFromTime(clusterStartTime),\n needsImprovement: null,\n bad: null,\n },\n });\n\n firstShiftTime = clusterStartTime;\n }\n\n // Given the above we should have a cluster available, so pick the most\n // recent one and append the shift, bump its score and window values accordingly.\n const currentCluster = clusters[clusters.length - 1];\n const timeFromNavigation = currentShiftNavigation !== null ?\n Types.Timing.MicroSeconds(event.ts - navigations[currentShiftNavigation].ts) :\n undefined;\n\n currentCluster.clusterCumulativeScore += event.args.data ? event.args.data.weighted_score_delta : 0;\n if (!event.args.data) {\n continue;\n }\n const shift: Types.TraceEvents.SyntheticLayoutShift = {\n ...event,\n args: {\n frame: event.args.frame,\n data: {\n ...event.args.data,\n rawEvent: event,\n },\n },\n parsedData: {\n screenshotSource: findNextScreenshotSource(event.ts),\n timeFromNavigation,\n cumulativeWeightedScoreInWindow: currentCluster.clusterCumulativeScore,\n // The score of the session window is temporarily set to 0 just\n // to initialize it. Since we need to get the score of all shifts\n // in the session window to determine its value, its definite\n // value is set when stepping through the built clusters.\n sessionWindowData: {cumulativeWindowScore: 0, id: clusters.length},\n },\n };\n currentCluster.events.push(shift);\n updateTraceWindowMax(currentCluster.clusterWindow, event.ts);\n\n lastShiftTime = event.ts;\n lastShiftNavigation = currentShiftNavigation;\n }\n\n // Now step through each cluster and set up the times at which the value\n // goes from Good, to needs improvement, to Bad. Note that if there is a\n // large jump we may go from Good to Bad without ever creating a Needs\n // Improvement window at all.\n for (const cluster of clusters) {\n let weightedScore = 0;\n let windowID = -1;\n // If this is the last cluster update its window. The cluster duration is determined\n // by the minimum between: time to next navigation, trace end time, time to maximum\n // cluster duration and time to maximum gap between layout shifts.\n if (cluster === clusters[clusters.length - 1]) {\n const clusterEndByMaxDuration = MAX_CLUSTER_DURATION + cluster.clusterWindow.min;\n const clusterEndByMaxGap = cluster.clusterWindow.max + MAX_SHIFT_TIME_DELTA;\n const nextNavigationIndex =\n Platform.ArrayUtilities.nearestIndexFromBeginning(navigations, nav => nav.ts > cluster.clusterWindow.max);\n const nextNavigationTime = nextNavigationIndex ? navigations[nextNavigationIndex].ts : Infinity;\n const clusterEnd = Math.min(clusterEndByMaxDuration, clusterEndByMaxGap, traceBounds.max, nextNavigationTime);\n updateTraceWindowMax(cluster.clusterWindow, Types.Timing.MicroSeconds(clusterEnd));\n }\n for (const shift of cluster.events) {\n weightedScore += shift.args.data ? shift.args.data.weighted_score_delta : 0;\n windowID = shift.parsedData.sessionWindowData.id;\n const ts = shift.ts;\n // Update the the CLS score of this shift's session window now that\n // we have it.\n shift.parsedData.sessionWindowData.cumulativeWindowScore = cluster.clusterCumulativeScore;\n if (weightedScore < LayoutShiftsThreshold.NEEDS_IMPROVEMENT) {\n // Expand the Good window.\n updateTraceWindowMax(cluster.scoreWindows.good, ts);\n } else if (\n weightedScore >= LayoutShiftsThreshold.NEEDS_IMPROVEMENT && weightedScore < LayoutShiftsThreshold.BAD) {\n if (!cluster.scoreWindows.needsImprovement) {\n // Close the Good window, and open the needs improvement window.\n updateTraceWindowMax(cluster.scoreWindows.good, Types.Timing.MicroSeconds(ts - 1));\n cluster.scoreWindows.needsImprovement = traceWindowFromTime(ts);\n }\n\n // Expand the needs improvement window.\n updateTraceWindowMax(cluster.scoreWindows.needsImprovement, ts);\n } else if (weightedScore >= LayoutShiftsThreshold.BAD) {\n if (!cluster.scoreWindows.bad) {\n // We may jump from Good to Bad here, so update whichever window is open.\n if (cluster.scoreWindows.needsImprovement) {\n updateTraceWindowMax(cluster.scoreWindows.needsImprovement, Types.Timing.MicroSeconds(ts - 1));\n } else {\n updateTraceWindowMax(cluster.scoreWindows.good, Types.Timing.MicroSeconds(ts - 1));\n }\n\n cluster.scoreWindows.bad = traceWindowFromTime(shift.ts);\n }\n\n // Expand the Bad window.\n updateTraceWindowMax(cluster.scoreWindows.bad, ts);\n }\n\n // At this point the windows are set by the timestamps of the events, but the\n // next cluster begins at the timestamp of its first event. As such we now\n // need to expand the score window to the end of the cluster, and we do so\n // by using the Bad widow if it's there, or the NI window, or finally the\n // Good window.\n if (cluster.scoreWindows.bad) {\n updateTraceWindowMax(cluster.scoreWindows.bad, cluster.clusterWindow.max);\n } else if (cluster.scoreWindows.needsImprovement) {\n updateTraceWindowMax(cluster.scoreWindows.needsImprovement, cluster.clusterWindow.max);\n } else {\n updateTraceWindowMax(cluster.scoreWindows.good, cluster.clusterWindow.max);\n }\n }\n if (weightedScore > sessionMaxScore) {\n clsWindowID = windowID;\n sessionMaxScore = weightedScore;\n }\n }\n}\n\nexport function data(): LayoutShifts {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Layout Shifts Handler is not finalized');\n }\n\n return {\n clusters: [...clusters],\n sessionMaxScore: sessionMaxScore,\n clsWindowID,\n prePaintEvents: [...prePaintEvents],\n layoutInvalidationEvents: [...layoutInvalidationEvents],\n styleRecalcInvalidationEvents: [],\n scoreRecords: [...scoreRecords],\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Screenshots', 'Meta'];\n}\n\nexport function stateForLayoutShiftScore(score: number): ScoreClassification {\n let state = ScoreClassification.GOOD;\n if (score >= LayoutShiftsThreshold.NEEDS_IMPROVEMENT) {\n state = ScoreClassification.OK;\n }\n\n if (score >= LayoutShiftsThreshold.BAD) {\n state = ScoreClassification.BAD;\n }\n\n return state;\n}\n\nexport interface LayoutShiftCluster {\n clusterWindow: Types.Timing.TraceWindow;\n clusterCumulativeScore: number;\n events: Types.TraceEvents.SyntheticLayoutShift[];\n // For convenience we split apart the cluster into good, NI, and bad windows.\n // Since a cluster may remain in the good window, we mark NI and bad as being\n // possibly null.\n scoreWindows: {\n good: Types.Timing.TraceWindow,\n needsImprovement: Types.Timing.TraceWindow|null,\n bad: Types.Timing.TraceWindow|null,\n };\n}\n\n// Based on https://web.dev/cls/\nexport const enum LayoutShiftsThreshold {\n GOOD = 0,\n NEEDS_IMPROVEMENT = 0.1,\n BAD = 0.25,\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/**\n * This handler stores page load metrics, including web vitals,\n * and exports them in the shape of a map with the following shape:\n * Map(FrameId -> Map(navigationID -> metrics) )\n *\n * It also exports all markers in a trace in an array.\n *\n * Some metrics are taken directly from a page load events (AKA markers) like DCL.\n * Others require processing multiple events to be determined, like CLS and TBT.\n */\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nimport {type TraceEventHandlerName} from './types.js';\n\nimport * as Types from '../types/types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\n\n/**\n * This represents the metric scores for all navigations, for all frames in a trace.\n * Given a frame id, the map points to another map from navigation id to metric scores.\n * The metric scores include the event related to the metric as well as the data regarding\n * the score itself.\n */\nconst metricScoresByFrameId =\n new Map</* Frame id */ string, Map</* navigation id */ string, Map<MetricName, MetricScore>>>();\n\n/**\n * Page load events with no associated duration that happened in the\n * main frame.\n */\nlet allMarkerEvents: Types.TraceEvents.PageLoadEvent[] = [];\n\nexport function reset(): void {\n metricScoresByFrameId.clear();\n pageLoadEventsArray = [];\n allMarkerEvents = [];\n selectedLCPCandidateEvents.clear();\n}\n\nlet pageLoadEventsArray: Types.TraceEvents.PageLoadEvent[] = [];\n\n// Once we've found the LCP events in the trace we want to fetch their DOM Node\n// from the backend. We could do this by parsing through our Map of frame =>\n// navigation => metric, but it's easier to keep a set of LCP events. As we\n// parse the trace, any time we store an LCP candidate as the potential LCP\n// event, we store the event here. If we later find a new candidate in the\n// trace, we store that and delete the prior event. When we've parsed the\n// entire trace this set will contain all the LCP events that were used - e.g.\n// the candidates that were the actual LCP events.\nconst selectedLCPCandidateEvents = new Set<Types.TraceEvents.TraceEventLargestContentfulPaintCandidate>();\n\nexport const MarkerName =\n ['MarkDOMContent', 'MarkLoad', 'firstPaint', 'firstContentfulPaint', 'largestContentfulPaint::Candidate'] as const;\n\nconst markerTypeGuards = [\n Types.TraceEvents.isTraceEventMarkDOMContent,\n Types.TraceEvents.isTraceEventMarkLoad,\n Types.TraceEvents.isTraceEventFirstPaint,\n Types.TraceEvents.isTraceEventFirstContentfulPaint,\n Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate,\n Types.TraceEvents.isTraceEventNavigationStart,\n];\n\ninterface MakerEvent extends Types.TraceEvents.TraceEventData {\n name: typeof MarkerName[number];\n}\n\nexport function isTraceEventMarkerEvent(event: Types.TraceEvents.TraceEventData): event is MakerEvent {\n return markerTypeGuards.some(fn => fn(event));\n}\n\nconst pageLoadEventTypeGuards = [\n ...markerTypeGuards,\n Types.TraceEvents.isTraceEventInteractiveTime,\n];\n\nexport function eventIsPageLoadEvent(event: Types.TraceEvents.TraceEventData):\n event is Types.TraceEvents.PageLoadEvent {\n return pageLoadEventTypeGuards.some(fn => fn(event));\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (!eventIsPageLoadEvent(event)) {\n return;\n }\n pageLoadEventsArray.push(event);\n}\n\nfunction storePageLoadMetricAgainstNavigationId(\n navigation: Types.TraceEvents.TraceEventNavigationStart, event: Types.TraceEvents.PageLoadEvent): void {\n const navigationId = navigation.args.data?.navigationId;\n if (!navigationId) {\n throw new Error('Navigation event unexpectedly had no navigation ID.');\n }\n const frameId = getFrameIdForPageLoadEvent(event);\n const {rendererProcessesByFrame} = metaHandlerData();\n\n // If either of these pieces of data do not exist, the most likely\n // explanation is that the page load metric we found is for a frame/process\n // combo that the MetaHandler discarded. This typically happens if we get a\n // navigation event with an empty URL. Therefore, we will silently return and\n // drop this metric. If we didn't care about the navigation, we certainly do\n // not need to care about metrics for that navigation.\n const rendererProcessesInFrame = rendererProcessesByFrame.get(frameId);\n if (!rendererProcessesInFrame) {\n return;\n }\n const processData = rendererProcessesInFrame.get(event.pid);\n if (!processData) {\n return;\n }\n\n if (Types.TraceEvents.isTraceEventNavigationStart(event)) {\n return;\n }\n\n // We compare the timestamp of the event to determine if it happened during the\n // time window in which its process was considered active.\n const minTime = processData[0].window.min;\n const maxTime = processData.at(-1)?.window.max || 0;\n const eventBelongsToProcess = event.ts >= minTime && event.ts <= maxTime;\n\n if (!eventBelongsToProcess) {\n // If the event occurred outside its process' active time window we ignore it.\n return;\n }\n\n if (Types.TraceEvents.isTraceEventFirstContentfulPaint(event)) {\n const fcpTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const score = Helpers.Timing.formatMicrosecondsTime(fcpTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const classification = scoreClassificationForFirstContentfulPaint(fcpTime);\n const metricScore = {event, score, metricName: MetricName.FCP, classification, navigation};\n storeMetricScore(frameId, navigationId, metricScore);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventFirstPaint(event)) {\n const paintTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const score = Helpers.Timing.formatMicrosecondsTime(paintTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const classification = ScoreClassification.UNCLASSIFIED;\n const metricScore = {event, score, metricName: MetricName.FP, classification, navigation};\n storeMetricScore(frameId, navigationId, metricScore);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventMarkDOMContent(event)) {\n const dclTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const score = Helpers.Timing.formatMicrosecondsTime(dclTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const metricScore = {\n event,\n score,\n metricName: MetricName.DCL,\n classification: scoreClassificationForDOMContentLoaded(dclTime),\n navigation,\n };\n storeMetricScore(frameId, navigationId, metricScore);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventInteractiveTime(event)) {\n const ttiValue = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const ttiScore = Helpers.Timing.formatMicrosecondsTime(ttiValue, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const tti = {\n event,\n score: ttiScore,\n metricName: MetricName.TTI,\n classification: scoreClassificationForTimeToInteractive(ttiValue),\n navigation,\n };\n storeMetricScore(frameId, navigationId, tti);\n\n const tbtValue =\n Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(event.args.args.total_blocking_time_ms));\n const tbtScore = Helpers.Timing.formatMicrosecondsTime(tbtValue, {\n format: Types.Timing.TimeUnit.MILLISECONDS,\n maximumFractionDigits: 2,\n });\n const tbt = {\n event,\n score: tbtScore,\n metricName: MetricName.TBT,\n classification: scoreClassificationForTotalBlockingTime(tbtValue),\n navigation,\n };\n storeMetricScore(frameId, navigationId, tbt);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventMarkLoad(event)) {\n const loadTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const score = Helpers.Timing.formatMicrosecondsTime(loadTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const metricScore = {\n event,\n score,\n metricName: MetricName.L,\n classification: ScoreClassification.UNCLASSIFIED,\n navigation,\n };\n storeMetricScore(frameId, navigationId, metricScore);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(event)) {\n const candidateIndex = event.args.data?.candidateIndex;\n if (!candidateIndex) {\n throw new Error('Largest Contenful Paint unexpectedly had no candidateIndex.');\n }\n const lcpTime = Types.Timing.MicroSeconds(event.ts - navigation.ts);\n const lcpScore = Helpers.Timing.formatMicrosecondsTime(lcpTime, {\n format: Types.Timing.TimeUnit.SECONDS,\n maximumFractionDigits: 2,\n });\n const lcp = {\n event,\n score: lcpScore,\n metricName: MetricName.LCP,\n classification: scoreClassificationForLargestContentfulPaint(lcpTime),\n navigation,\n };\n const metricsByNavigation = Platform.MapUtilities.getWithDefault(metricScoresByFrameId, frameId, () => new Map());\n const metrics = Platform.MapUtilities.getWithDefault(metricsByNavigation, navigationId, () => new Map());\n const lastLCPCandidate = metrics.get(MetricName.LCP);\n if (lastLCPCandidate === undefined) {\n selectedLCPCandidateEvents.add(lcp.event);\n storeMetricScore(frameId, navigationId, lcp);\n return;\n }\n const lastLCPCandidateEvent = lastLCPCandidate.event;\n\n if (!Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(lastLCPCandidateEvent)) {\n return;\n }\n const lastCandidateIndex = lastLCPCandidateEvent.args.data?.candidateIndex;\n if (!lastCandidateIndex) {\n // lastCandidateIndex cannot be undefined because we don't store candidates with\n // with an undefined candidateIndex value. This check is only to make TypeScript\n // treat the field as not undefined below.\n return;\n }\n if (lastCandidateIndex < candidateIndex) {\n selectedLCPCandidateEvents.delete(lastLCPCandidateEvent);\n selectedLCPCandidateEvents.add(lcp.event);\n storeMetricScore(frameId, navigationId, lcp);\n }\n return;\n }\n if (Types.TraceEvents.isTraceEventLayoutShift(event)) {\n return;\n }\n return Platform.assertNever(event, `Unexpected event type: ${event}`);\n}\n\nfunction storeMetricScore(frameId: string, navigationId: string, metricScore: MetricScore): void {\n const metricsByNavigation = Platform.MapUtilities.getWithDefault(metricScoresByFrameId, frameId, () => new Map());\n const metrics = Platform.MapUtilities.getWithDefault(metricsByNavigation, navigationId, () => new Map());\n // If an entry with that metric name is present, delete it so that the new entry that\n // will replace it is added at the end of the map. This way we guarantee the map entries\n // are ordered in ASC manner by timestamp.\n metrics.delete(metricScore.metricName);\n metrics.set(metricScore.metricName, metricScore);\n}\n\nexport function getFrameIdForPageLoadEvent(event: Types.TraceEvents.PageLoadEvent): string {\n if (Types.TraceEvents.isTraceEventFirstContentfulPaint(event) ||\n Types.TraceEvents.isTraceEventInteractiveTime(event) ||\n Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(event) ||\n Types.TraceEvents.isTraceEventNavigationStart(event) || Types.TraceEvents.isTraceEventLayoutShift(event) ||\n Types.TraceEvents.isTraceEventFirstPaint(event)) {\n return event.args.frame;\n }\n if (Types.TraceEvents.isTraceEventMarkDOMContent(event) || Types.TraceEvents.isTraceEventMarkLoad(event)) {\n const frameId = event.args.data?.frame;\n if (!frameId) {\n throw new Error('MarkDOMContent unexpectedly had no frame ID.');\n }\n return frameId;\n }\n Platform.assertNever(event, `Unexpected event type: ${event}`);\n}\n\nfunction getNavigationForPageLoadEvent(event: Types.TraceEvents.PageLoadEvent):\n Types.TraceEvents.TraceEventNavigationStart|null {\n if (Types.TraceEvents.isTraceEventFirstContentfulPaint(event) ||\n Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(event) ||\n Types.TraceEvents.isTraceEventFirstPaint(event)) {\n const navigationId = event.args.data?.navigationId;\n if (!navigationId) {\n throw new Error('Trace event unexpectedly had no navigation ID.');\n }\n const {navigationsByNavigationId} = metaHandlerData();\n const navigation = navigationsByNavigationId.get(navigationId);\n\n if (!navigation) {\n // This event's navigation has been filtered out by the meta handler as a noise event.\n return null;\n }\n return navigation;\n }\n\n if (Types.TraceEvents.isTraceEventMarkDOMContent(event) || Types.TraceEvents.isTraceEventInteractiveTime(event) ||\n Types.TraceEvents.isTraceEventLayoutShift(event) || Types.TraceEvents.isTraceEventMarkLoad(event)) {\n const frameId = getFrameIdForPageLoadEvent(event);\n const {navigationsByFrameId} = metaHandlerData();\n return Helpers.Trace.getNavigationForTraceEvent(event, frameId, navigationsByFrameId);\n }\n\n if (Types.TraceEvents.isTraceEventNavigationStart(event)) {\n // We don't want to compute metrics of the navigation relative to itself, so we'll avoid avoid all that.\n return null;\n }\n\n return Platform.assertNever(event, `Unexpected event type: ${event}`);\n}\n\n/**\n * Classifications sourced from\n * https://web.dev/fcp/\n */\nexport function scoreClassificationForFirstContentfulPaint(fcpScoreInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n const FCP_GOOD_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(1.8));\n const FCP_MEDIUM_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(3.0));\n let scoreClassification = ScoreClassification.BAD;\n if (fcpScoreInMicroseconds <= FCP_MEDIUM_TIMING) {\n scoreClassification = ScoreClassification.OK;\n }\n if (fcpScoreInMicroseconds <= FCP_GOOD_TIMING) {\n scoreClassification = ScoreClassification.GOOD;\n }\n return scoreClassification;\n}\n\n/**\n * Classifications sourced from\n * https://web.dev/interactive/#how-lighthouse-determines-your-tti-score\n */\n\nexport function scoreClassificationForTimeToInteractive(ttiTimeInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n const TTI_GOOD_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(3.8));\n const TTI_MEDIUM_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(7.3));\n let scoreClassification = ScoreClassification.BAD;\n if (ttiTimeInMicroseconds <= TTI_MEDIUM_TIMING) {\n scoreClassification = ScoreClassification.OK;\n }\n if (ttiTimeInMicroseconds <= TTI_GOOD_TIMING) {\n scoreClassification = ScoreClassification.GOOD;\n }\n return scoreClassification;\n}\n\n/**\n * Classifications sourced from\n * https://web.dev/lcp/#what-is-lcp\n */\n\nexport function scoreClassificationForLargestContentfulPaint(lcpTimeInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n const LCP_GOOD_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(2.5));\n const LCP_MEDIUM_TIMING = Helpers.Timing.secondsToMicroseconds(Types.Timing.Seconds(4));\n let scoreClassification = ScoreClassification.BAD;\n if (lcpTimeInMicroseconds <= LCP_MEDIUM_TIMING) {\n scoreClassification = ScoreClassification.OK;\n }\n if (lcpTimeInMicroseconds <= LCP_GOOD_TIMING) {\n scoreClassification = ScoreClassification.GOOD;\n }\n return scoreClassification;\n}\n\n/**\n * DCL does not have a classification.\n */\nexport function scoreClassificationForDOMContentLoaded(_dclTimeInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n return ScoreClassification.UNCLASSIFIED;\n}\n\n/**\n * Classifications sourced from\n * https://web.dev/lighthouse-total-blocking-#time/\n */\n\nexport function scoreClassificationForTotalBlockingTime(tbtTimeInMicroseconds: Types.Timing.MicroSeconds):\n ScoreClassification {\n const TBT_GOOD_TIMING = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(200));\n const TBT_MEDIUM_TIMING = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(600));\n let scoreClassification = ScoreClassification.BAD;\n if (tbtTimeInMicroseconds <= TBT_MEDIUM_TIMING) {\n scoreClassification = ScoreClassification.OK;\n }\n if (tbtTimeInMicroseconds <= TBT_GOOD_TIMING) {\n scoreClassification = ScoreClassification.GOOD;\n }\n return scoreClassification;\n}\n\n/**\n * Gets all the Largest Contentful Paint scores of all the frames in the\n * trace.\n */\nfunction gatherFinalLCPEvents(): Types.TraceEvents.PageLoadEvent[] {\n const allFinalLCPEvents: Types.TraceEvents.PageLoadEvent[] = [];\n const dataForAllFrames = [...metricScoresByFrameId.values()];\n const dataForAllNavigations = dataForAllFrames.flatMap(frameData => [...frameData.values()]);\n for (let i = 0; i < dataForAllNavigations.length; i++) {\n const navigationData = dataForAllNavigations[i];\n const lcpInNavigation = navigationData.get(MetricName.LCP);\n if (!lcpInNavigation || !lcpInNavigation.event) {\n continue;\n }\n\n allFinalLCPEvents.push(lcpInNavigation.event);\n }\n return allFinalLCPEvents;\n}\n\nexport async function finalize(): Promise<void> {\n pageLoadEventsArray.sort((a, b) => a.ts - b.ts);\n\n for (const pageLoadEvent of pageLoadEventsArray) {\n const navigation = getNavigationForPageLoadEvent(pageLoadEvent);\n if (navigation) {\n // Event's navigation was not filtered out as noise.\n storePageLoadMetricAgainstNavigationId(navigation, pageLoadEvent);\n }\n }\n // NOTE: if you are looking for the TBT calculation, it has temporarily been\n // removed. See crbug.com/1424335 for details.\n const allFinalLCPEvents = gatherFinalLCPEvents();\n const mainFrame = metaHandlerData().mainFrameId;\n // Filter out LCP candidates to use only definitive LCP values\n const allEventsButLCP =\n pageLoadEventsArray.filter(event => !Types.TraceEvents.isTraceEventLargestContentfulPaintCandidate(event));\n const markerEvents = [...allFinalLCPEvents, ...allEventsButLCP].filter(isTraceEventMarkerEvent);\n // Filter by main frame and sort.\n allMarkerEvents =\n markerEvents.filter(event => getFrameIdForPageLoadEvent(event) === mainFrame).sort((a, b) => a.ts - b.ts);\n}\n\nexport type PageLoadMetricsData = {\n metricScoresByFrameId: Map<string, Map<string, Map<MetricName, MetricScore>>>,\n allMarkerEvents: Types.TraceEvents.PageLoadEvent[],\n};\n\nexport function data(): PageLoadMetricsData {\n return {\n /**\n * This represents the metric scores for all navigations, for all frames in a trace.\n * Given a frame id, the map points to another map from navigation id to metric scores.\n * The metric scores include the event related to the metric as well as the data regarding\n * the score itself.\n */\n metricScoresByFrameId: new Map(metricScoresByFrameId),\n\n /**\n * Page load events with no associated duration that happened in the\n * main frame.\n */\n allMarkerEvents: [...allMarkerEvents],\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n\nexport const enum ScoreClassification {\n GOOD = 'good',\n OK = 'ok',\n BAD = 'bad',\n // Some metrics (such as DOMContentLoaded) don't have a Good/OK/Bad classification, hence this additional entry.\n UNCLASSIFIED = 'unclassified',\n}\n\nexport const enum MetricName {\n // First Contentful Paint\n FCP = 'FCP',\n // First Paint\n FP = 'FP',\n // MarkLoad\n L = 'L',\n LCP = 'LCP',\n // Mark DOM Content\n DCL = 'DCL',\n // Time To Interactive\n TTI = 'TTI',\n // Total Blocking Time\n TBT = 'TBT',\n // Cumulative Layout Shift\n CLS = 'CLS',\n}\n\nexport interface MetricScore {\n score: string;\n metricName: MetricName;\n classification: ScoreClassification;\n event?: Types.TraceEvents.PageLoadEvent;\n // The last navigation that occured before this metric score.\n navigation?: Types.TraceEvents.TraceEventNavigationStart;\n estimated?: boolean;\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport {type TraceEventHandlerName} from './types.js';\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nconst eventsInProcessThread =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventSnapshot[]>>();\n\nlet snapshots: Types.TraceEvents.TraceEventSnapshot[] = [];\nexport function reset(): void {\n eventsInProcessThread.clear();\n snapshots.length = 0;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (event.ph !== Types.TraceEvents.Phase.OBJECT_SNAPSHOT || event.name !== 'Screenshot') {\n return;\n }\n\n Helpers.Trace.addEventToProcessThread(event, eventsInProcessThread);\n}\n\nexport async function finalize(): Promise<void> {\n const {browserProcessId, browserThreadId} = metaHandlerData();\n const browserThreads = eventsInProcessThread.get(browserProcessId);\n if (browserThreads) {\n snapshots = browserThreads.get(browserThreadId) || [];\n }\n}\n\nexport function data(): Types.TraceEvents.TraceEventSnapshot[] {\n return [...snapshots];\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\nexport interface MemoryData {\n updateCountersByProcess: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventUpdateCounters[]>;\n}\n\nconst updateCountersByProcess: MemoryData['updateCountersByProcess'] = new Map();\n\nexport function reset(): void {\n updateCountersByProcess.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventUpdateCounters(event)) {\n const countersForProcess = Platform.MapUtilities.getWithDefault(updateCountersByProcess, event.pid, () => []);\n countersForProcess.push(event);\n updateCountersByProcess.set(event.pid, countersForProcess);\n }\n}\n\nexport function data(): MemoryData {\n return {updateCountersByProcess: new Map(updateCountersByProcess)};\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport {type TraceEventHandlerName, HandlerState} from './types.js';\n\nimport {data as metaHandlerData} from './MetaHandler.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nimport * as Types from '../types/types.js';\n\nconst MILLISECONDS_TO_MICROSECONDS = 1000;\nconst SECONDS_TO_MICROSECONDS = 1000000;\n\n// Network requests from traces are actually formed of 5 trace records.\n// This handler tracks all trace records based on the request ID, and\n// then creates a new synthetic trace event for those network requests.\n//\n// This interface, then, defines the shape of the object we intend to\n// keep for each request in the trace. In the finalize we will convert\n// these 5 types of trace records to a synthetic complete event that\n// represents a composite of these trace records.\ninterface TraceEventsForNetworkRequest {\n changePriority?: Types.TraceEvents.TraceEventResourceChangePriority;\n willSendRequests?: Types.TraceEvents.TraceEventResourceWillSendRequest[];\n sendRequests?: Types.TraceEvents.TraceEventResourceSendRequest[];\n receiveResponse?: Types.TraceEvents.TraceEventResourceReceiveResponse;\n resourceFinish?: Types.TraceEvents.TraceEventResourceFinish;\n receivedData?: Types.TraceEvents.TraceEventResourceReceivedData[];\n resourceMarkAsCached?: Types.TraceEvents.TraceEventResourceMarkAsCached;\n}\n\ninterface NetworkRequestData {\n byOrigin: Map<string, {\n renderBlocking: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n nonRenderBlocking: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n all: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n }>;\n byTime: Types.TraceEvents.TraceEventSyntheticNetworkRequest[];\n}\n\nconst requestMap = new Map<string, TraceEventsForNetworkRequest>();\nconst requestsByOrigin = new Map<string, {\n renderBlocking: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n nonRenderBlocking: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n all: Types.TraceEvents.TraceEventSyntheticNetworkRequest[],\n}>();\nconst requestsByTime: Types.TraceEvents.TraceEventSyntheticNetworkRequest[] = [];\n\nfunction storeTraceEventWithRequestId<K extends keyof TraceEventsForNetworkRequest>(\n requestId: string, key: K, value: TraceEventsForNetworkRequest[K]): void {\n if (!requestMap.has(requestId)) {\n requestMap.set(requestId, {});\n }\n\n const traceEvents = requestMap.get(requestId);\n if (!traceEvents) {\n throw new Error(`Unable to locate trace events for request ID ${requestId}`);\n }\n\n if (Array.isArray(traceEvents[key])) {\n const target = traceEvents[key] as Types.TraceEvents.TraceEventData[];\n const values = value as Types.TraceEvents.TraceEventData[];\n target.push(...values);\n } else {\n traceEvents[key] = value;\n }\n}\n\nfunction firstPositiveValueInList(entries: number[]): number {\n for (const entry of entries) {\n if (entry > 0) {\n return entry;\n }\n }\n\n // In the event we don't find a positive value, we return 0 so as to\n // be a mathematical noop. It's typically not correct to return \u2013 say \u2013\n // a -1 here because it would affect the calculation of stats below.\n return 0;\n}\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n requestsByOrigin.clear();\n requestMap.clear();\n requestsByTime.length = 0;\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Network Request handler is not initialized');\n }\n\n if (Types.TraceEvents.isTraceEventResourceChangePriority(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'changePriority', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceWillSendRequest(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'willSendRequests', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceSendRequest(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'sendRequests', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceReceiveResponse(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'receiveResponse', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceReceivedData(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'receivedData', [event]);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceFinish(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'resourceFinish', event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventResourceMarkAsCached(event)) {\n storeTraceEventWithRequestId(event.args.data.requestId, 'resourceMarkAsCached', event);\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Network Request handler is not initialized');\n }\n\n const {rendererProcessesByFrame} = metaHandlerData();\n for (const [requestId, request] of requestMap.entries()) {\n // If we have an incomplete set of events here, we choose to drop the network\n // request rather than attempt to synthesize the missing data.\n if (!request.sendRequests || !request.receiveResponse) {\n continue;\n }\n\n // In the data we may get multiple willSendRequests and sendRequests, which\n // will indicate that there are redirects for a given (sub)resource. In the\n // case of a navigation, e.g., example.com/ we will get willSendRequests,\n // and we should use these to calculate time spent in redirects.\n // In the case of sub-resources, however, e.g., example.com/foo.js we will\n // *only* get sendRequests, and we use these instead of willSendRequests\n // to detect the time in redirects. We always use the sendRequest for the\n // url, priority etc since it contains those values, but we use the\n // willSendRequest (if it exists) to calculate the timestamp and durations\n // of redirects.\n const redirects: Types.TraceEvents.TraceEventSyntheticNetworkRedirect[] = [];\n for (let i = 0; i < request.sendRequests.length - 1; i++) {\n const sendRequest = request.sendRequests[i];\n const nextSendRequest = request.sendRequests[i + 1];\n\n // Use the willSendRequests as the source for redirects if possible.\n // We default to those of the sendRequests, however, since willSendRequest\n // is not guaranteed to be present in the data for every request.\n let ts = sendRequest.ts;\n let dur = Types.Timing.MicroSeconds(nextSendRequest.ts - sendRequest.ts);\n if (request.willSendRequests && request.willSendRequests[i] && request.willSendRequests[i + 1]) {\n const willSendRequest = request.willSendRequests[i];\n const nextWillSendRequest = request.willSendRequests[i + 1];\n ts = willSendRequest.ts;\n dur = Types.Timing.MicroSeconds(nextWillSendRequest.ts - willSendRequest.ts);\n }\n\n redirects.push({\n url: sendRequest.args.data.url,\n priority: sendRequest.args.data.priority,\n requestMethod: sendRequest.args.data.requestMethod,\n ts,\n dur,\n });\n }\n\n // If a ResourceFinish event with an encoded data length is received,\n // then the resource was not cached; it was fetched before it was\n // requested, e.g. because it was pushed in this navigation.\n const isPushedResource = request.resourceFinish?.args.data.encodedDataLength !== 0;\n // This works around crbug.com/998397, which reports pushed resources, and resources served by a service worker as disk cached.\n const isDiskCached = request.receiveResponse.args.data.fromCache &&\n !request.receiveResponse.args.data.fromServiceWorker && !isPushedResource;\n // If the request contains a resourceMarkAsCached event, it was served from memory cache.\n const isMemoryCached = request.resourceMarkAsCached !== undefined;\n\n // The timing data returned is from the original (uncached) request, which\n // means that if we leave the above network record data as-is when the\n // request came from either the disk cache or memory cache, our calculations\n // will be incorrect.\n //\n // Here we add a flag so when we calculate the timestamps of the various\n // events, we can overwrite them.\n // These timestamps may not be perfect (indeed they don't always match\n // the Network CDP domain exactly, which is likely an artifact of the way\n // the data is routed on the backend), but they're the closest we have.\n const isCached = isMemoryCached || isDiskCached;\n\n const timing = request.receiveResponse.args.data.timing;\n // If a non-cached request has no |timing| indicates data URLs, we ignore it.\n if (!timing && !isCached) {\n continue;\n }\n\n const firstSendRequest = request.sendRequests[0];\n const finalSendRequest = request.sendRequests[request.sendRequests.length - 1];\n\n const initialPriority = finalSendRequest.args.data.priority;\n let finalPriority = initialPriority;\n if (request.changePriority) {\n finalPriority = request.changePriority.args.data.priority;\n }\n\n // Start time\n // =======================\n // The time where the request started, which is either the first willSendRequest\n // event if there is one, or, if there is not, the sendRequest.\n const startTime = (request.willSendRequests && request.willSendRequests.length) ?\n Types.Timing.MicroSeconds(request.willSendRequests[0].ts) :\n Types.Timing.MicroSeconds(firstSendRequest.ts);\n\n // End redirect time\n // =======================\n // It's possible that when we start requesting data we will receive redirections.\n // Here we note the time of the *last* willSendRequest / sendRequest event,\n // which is used later on in the calculations for time queueing etc.\n const endRedirectTime = (request.willSendRequests && request.willSendRequests.length) ?\n Types.Timing.MicroSeconds(request.willSendRequests[request.willSendRequests.length - 1].ts) :\n Types.Timing.MicroSeconds(finalSendRequest.ts);\n\n // Finish time and end time\n // =======================\n // The finish time and the end time are subtly different.\n // - Finish time: records the point at which the network stack stopped receiving the data\n // - End time: the timestamp of the finish event itself (if one exists)\n //\n // The end time, then, will be slightly after the finish time.\n const endTime = request.resourceFinish ? request.resourceFinish.ts : endRedirectTime;\n const finishTime = request.resourceFinish?.args.data.finishTime ?\n Types.Timing.MicroSeconds(request.resourceFinish.args.data.finishTime * SECONDS_TO_MICROSECONDS) :\n Types.Timing.MicroSeconds(endTime);\n\n // Network duration\n // =======================\n // Time spent on the network.\n const networkDuration = isCached ? Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((finishTime || endRedirectTime) - endRedirectTime);\n\n // Processing duration\n // =======================\n // Time spent from start to end.\n const processingDuration = Types.Timing.MicroSeconds(endTime - (finishTime || endTime));\n\n // Redirection duration\n // =======================\n // Time between the first willSendRequest / sendRequest and last. This we place in *front* of the\n // queueing, since the queueing time that we know about from the trace data is only the last request,\n // i.e., the one that occurs after all the redirects.\n const redirectionDuration = Types.Timing.MicroSeconds(endRedirectTime - startTime);\n\n // Queueing\n // =======================\n // The amount of time queueing is the time between the request's start time to the requestTime\n // arg recorded in the receiveResponse event. In the cases where the recorded start time is larger\n // that the requestTime we set queueing time to zero.\n const queueing = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds(Platform.NumberUtilities.clamp(\n (timing.requestTime * SECONDS_TO_MICROSECONDS - endRedirectTime), 0, Number.MAX_VALUE));\n\n // Stalled\n // =======================\n // If the request is cached, the amount of time stalled is the time between the start time and\n // receiving a response.\n // Otherwise it is whichever positive number comes first from the following timing info:\n // DNS start, Connection start, Send Start, or the time duration between our start time and\n // receiving a response.\n const stalled = isCached ? Types.Timing.MicroSeconds(request.receiveResponse.ts - startTime) :\n Types.Timing.MicroSeconds(firstPositiveValueInList([\n timing.dnsStart * MILLISECONDS_TO_MICROSECONDS,\n timing.connectStart * MILLISECONDS_TO_MICROSECONDS,\n timing.sendStart * MILLISECONDS_TO_MICROSECONDS,\n (request.receiveResponse.ts - endRedirectTime),\n ]));\n\n // Sending HTTP request\n // =======================\n // Time when the HTTP request is sent.\n const sendStartTime = isCached ?\n startTime :\n Types.Timing.MicroSeconds(\n timing.requestTime * SECONDS_TO_MICROSECONDS + timing.sendStart * MILLISECONDS_TO_MICROSECONDS);\n\n // Waiting\n // =======================\n // Time from when the send finished going to when the headers were received.\n const waiting = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.receiveHeadersEnd - timing.sendEnd) * MILLISECONDS_TO_MICROSECONDS);\n\n // Download\n // =======================\n // Time from receipt of headers to the finish time.\n const downloadStart = isCached ?\n startTime :\n Types.Timing.MicroSeconds(\n timing.requestTime * SECONDS_TO_MICROSECONDS + timing.receiveHeadersEnd * MILLISECONDS_TO_MICROSECONDS);\n const download = isCached ? Types.Timing.MicroSeconds(endTime - request.receiveResponse.ts) :\n Types.Timing.MicroSeconds(((finishTime || downloadStart) - downloadStart));\n\n const totalTime = Types.Timing.MicroSeconds(networkDuration + processingDuration);\n\n // Collect a few values from the timing info.\n // If the Network request is cached, we zero out them.\n const dnsLookup = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.dnsEnd - timing.dnsStart) * MILLISECONDS_TO_MICROSECONDS);\n const ssl = isCached ? Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.sslEnd - timing.sslStart) * MILLISECONDS_TO_MICROSECONDS);\n const proxyNegotiation = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.proxyEnd - timing.proxyStart) * MILLISECONDS_TO_MICROSECONDS);\n const requestSent = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.sendEnd - timing.sendStart) * MILLISECONDS_TO_MICROSECONDS);\n const initialConnection = isCached ?\n Types.Timing.MicroSeconds(0) :\n Types.Timing.MicroSeconds((timing.connectEnd - timing.connectStart) * MILLISECONDS_TO_MICROSECONDS);\n\n // Finally get some of the general data from the trace events.\n const {frame, url, renderBlocking} = finalSendRequest.args.data;\n const {encodedDataLength, decodedBodyLength} =\n request.resourceFinish ? request.resourceFinish.args.data : {encodedDataLength: 0, decodedBodyLength: 0};\n const {host, protocol, pathname, search} = new URL(url);\n const isHttps = protocol === 'https:';\n const requestingFrameUrl =\n Helpers.Trace.activeURLForFrameAtTime(frame, finalSendRequest.ts, rendererProcessesByFrame) || '';\n\n // Construct a synthetic trace event for this network request.\n const networkEvent: Types.TraceEvents.TraceEventSyntheticNetworkRequest = {\n args: {\n data: {\n // All data we create from trace events should be added to |syntheticData|.\n syntheticData: {\n dnsLookup,\n download,\n downloadStart,\n finishTime,\n initialConnection,\n isDiskCached,\n isHttps,\n isMemoryCached,\n isPushedResource,\n networkDuration,\n processingDuration,\n proxyNegotiation,\n queueing,\n redirectionDuration,\n requestSent,\n sendStartTime,\n ssl,\n stalled,\n totalTime,\n waiting,\n },\n // All fields below are from TraceEventsForNetworkRequest.\n decodedBodyLength,\n encodedDataLength,\n frame,\n fromServiceWorker: request.receiveResponse.args.data.fromServiceWorker,\n host,\n mimeType: request.receiveResponse.args.data.mimeType,\n pathname,\n priority: finalPriority,\n initialPriority,\n protocol,\n redirects,\n // In the event the property isn't set, assume non-blocking.\n renderBlocking: renderBlocking ? renderBlocking : 'non_blocking',\n requestId,\n requestingFrameUrl,\n requestMethod: finalSendRequest.args.data.requestMethod,\n search,\n statusCode: request.receiveResponse.args.data.statusCode,\n stackTrace: finalSendRequest.args.data.stackTrace,\n timing,\n url,\n },\n },\n cat: 'loading',\n name: 'SyntheticNetworkRequest',\n ph: Types.TraceEvents.Phase.COMPLETE,\n dur: Types.Timing.MicroSeconds(endTime - startTime),\n tdur: Types.Timing.MicroSeconds(endTime - startTime),\n ts: Types.Timing.MicroSeconds(startTime),\n tts: Types.Timing.MicroSeconds(startTime),\n pid: finalSendRequest.pid,\n tid: finalSendRequest.tid,\n };\n\n const requests = Platform.MapUtilities.getWithDefault(requestsByOrigin, host, () => {\n return {\n renderBlocking: [],\n nonRenderBlocking: [],\n all: [],\n };\n });\n\n // For ease of rendering we sometimes want to differentiate between\n // render-blocking and non-render-blocking, so we divide the data here.\n if (networkEvent.args.data.renderBlocking === 'non_blocking') {\n requests.nonRenderBlocking.push(networkEvent);\n } else {\n requests.renderBlocking.push(networkEvent);\n }\n\n // However, there are also times where we just want to loop through all\n // the captured requests, so here we store all of them together.\n requests.all.push(networkEvent);\n requestsByTime.push(networkEvent);\n }\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): NetworkRequestData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Network Request handler is not finalized');\n }\n\n return {\n byOrigin: new Map(requestsByOrigin),\n byTime: [...requestsByTime],\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\n// This handler serves two purposes. It generates a list of events that are\n// used to show user clicks in the timeline. It is also used to gather\n// EventTimings into Interactions, which we use to show interactions and\n// highlight long interactions to the user, along with INP.\n\n// We don't need to know which process / thread these events occurred in,\n// because they are effectively global, so we just track all that we find.\nconst allEvents: Types.TraceEvents.TraceEventEventTiming[] = [];\n\nexport const LONG_INTERACTION_THRESHOLD = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(200));\n\nexport interface UserInteractionsData {\n /** All the user events we found in the trace */\n allEvents: readonly Types.TraceEvents.TraceEventEventTiming[];\n /** All the interaction events we found in the trace that had an\n * interactionId and a duration > 0\n **/\n interactionEvents: readonly Types.TraceEvents.SyntheticInteractionEvent[];\n /** If the user rapidly generates interaction events (think typing into a\n * text box), in the UI we only really want to show the user the longest\n * interaction in that set.\n * For example picture interactions like this:\n * ===[interaction A]==========\n * =[interaction B]======\n * =[interaction C]=\n *\n * These events all end at the same time, and so in this instance we only want\n * to show the first interaction A on the timeline, as that is the longest one\n * and the one the developer should be focusing on. So this array of events is\n * all the interaction events filtered down, removing any nested interactions\n * entirely.\n **/\n interactionEventsWithNoNesting: readonly Types.TraceEvents.SyntheticInteractionEvent[];\n // The longest duration interaction event. Can be null if the trace has no interaction events.\n longestInteractionEvent: Readonly<Types.TraceEvents.SyntheticInteractionEvent>|null;\n // All interactions that went over the interaction threshold (200ms, see https://web.dev/inp/)\n interactionsOverThreshold: Readonly<Set<Types.TraceEvents.SyntheticInteractionEvent>>;\n}\n\nlet longestInteractionEvent: Types.TraceEvents.SyntheticInteractionEvent|null = null;\n\nconst interactionEvents: Types.TraceEvents.SyntheticInteractionEvent[] = [];\nconst interactionEventsWithNoNesting: Types.TraceEvents.SyntheticInteractionEvent[] = [];\nconst eventTimingEndEventsById = new Map<string, Types.TraceEvents.TraceEventEventTimingEnd>();\nconst eventTimingStartEventsForInteractions: Types.TraceEvents.TraceEventEventTimingBegin[] = [];\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n allEvents.length = 0;\n interactionEvents.length = 0;\n eventTimingStartEventsForInteractions.length = 0;\n eventTimingEndEventsById.clear();\n interactionEventsWithNoNesting.length = 0;\n longestInteractionEvent = null;\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Handler is not initialized');\n }\n\n if (!Types.TraceEvents.isTraceEventEventTiming(event)) {\n return;\n }\n\n if (Types.TraceEvents.isTraceEventEventTimingEnd(event)) {\n // Store the end event; for each start event that is an interaction, we need the matching end event to calculate the duration correctly.\n eventTimingEndEventsById.set(event.id, event);\n }\n\n allEvents.push(event);\n\n // From this point on we want to find events that represent interactions.\n // These events are always start events - those are the ones that contain all\n // the metadata about the interaction.\n if (!event.args.data || !Types.TraceEvents.isTraceEventEventTimingStart(event)) {\n return;\n }\n const {duration, interactionId} = event.args.data;\n // We exclude events for the sake of interactions if:\n // 1. They have no duration.\n // 2. They have no interactionId\n // 3. They have an interactionId of 0: this indicates that it's not an\n // interaction that we care about because it hasn't had its own interactionId\n // set (0 is the default on the backend).\n // See: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/timing/responsiveness_metrics.cc;l=133;drc=40c209a9c365ebb9f16fb99dfe78c7fe768b9594\n\n if (duration < 1 || interactionId === undefined || interactionId === 0) {\n return;\n }\n\n // Store the start event. In the finalize() function we will pair this with\n // its end event and create the synthetic interaction event.\n eventTimingStartEventsForInteractions.push(event);\n}\n\n/**\n * See https://web.dev/better-responsiveness-metric/#interaction-types for the\n * table that defines these sets.\n **/\nconst pointerEventTypes = new Set([\n 'pointerdown',\n 'touchstart',\n 'pointerup',\n 'touchend',\n 'mousedown',\n 'mouseup',\n 'click',\n]);\n\nconst keyboardEventTypes = new Set([\n 'keydown',\n 'keypress',\n 'keyup',\n]);\n\nexport type InteractionCategory = 'KEYBOARD'|'POINTER'|'OTHER';\nexport function categoryOfInteraction(interaction: Types.TraceEvents.SyntheticInteractionEvent): InteractionCategory {\n if (pointerEventTypes.has(interaction.type)) {\n return 'POINTER';\n }\n if (keyboardEventTypes.has(interaction.type)) {\n return 'KEYBOARD';\n }\n\n return 'OTHER';\n}\n\n/**\n * We define a set of interactions as nested where:\n * 1. Their end times align.\n * 2. The longest interaction's start time is earlier than all other\n * interactions with the same end time.\n * 3. The interactions are of the same category [each interaction is either\n * categorised as keyboard, or pointer.]\n *\n * =============A=[pointerup]=\n * ====B=[pointerdown]=\n * ===C=[pointerdown]==\n * ===D=[pointerup]===\n *\n * In this example, B, C and D are all nested and therefore should not be\n * returned from this function.\n *\n * However, in this example we would only consider B nested (under A) and D\n * nested (under C). A and C both stay because they are of different types.\n * ========A=[keydown]====\n * =======B=[keyup]=====\n * ====C=[pointerdown]=\n * =D=[pointerup]=\n **/\nexport function removeNestedInteractions(interactions: readonly Types.TraceEvents.SyntheticInteractionEvent[]):\n readonly Types.TraceEvents.SyntheticInteractionEvent[] {\n /**\n * Because we nest events only that are in the same category, we store the\n * longest event for a given end time by category.\n **/\n const earliestEventForEndTimePerCategory:\n Record<InteractionCategory, Map<Types.Timing.MicroSeconds, Types.TraceEvents.SyntheticInteractionEvent>> = {\n POINTER: new Map(),\n KEYBOARD: new Map(),\n OTHER: new Map(),\n };\n\n function storeEventIfEarliestForCategoryAndEndTime(interaction: Types.TraceEvents.SyntheticInteractionEvent): void {\n const category = categoryOfInteraction(interaction);\n const mapToUse = earliestEventForEndTimePerCategory[category];\n const endTime = Types.Timing.MicroSeconds(interaction.ts + interaction.dur);\n\n const earliestCurrentEvent = mapToUse.get(endTime);\n if (!earliestCurrentEvent) {\n mapToUse.set(endTime, interaction);\n return;\n }\n if (interaction.ts < earliestCurrentEvent.ts) {\n mapToUse.set(endTime, interaction);\n }\n }\n\n for (const interaction of interactions) {\n storeEventIfEarliestForCategoryAndEndTime(interaction);\n }\n\n // Combine all the events that we have kept from all the per-category event\n // maps back into an array and sort them by timestamp.\n const keptEvents = Object.values(earliestEventForEndTimePerCategory)\n .flatMap(eventsByEndTime => Array.from(eventsByEndTime.values()));\n keptEvents.sort((eventA, eventB) => {\n return eventA.ts - eventB.ts;\n });\n return keptEvents;\n}\n\nexport async function finalize(): Promise<void> {\n // For each interaction start event, find the async end event by the ID, and then create the Synthetic Interaction event.\n for (const interactionStartEvent of eventTimingStartEventsForInteractions) {\n const endEvent = eventTimingEndEventsById.get(interactionStartEvent.id);\n if (!endEvent) {\n // If we cannot find an end event, bail and drop this event.\n continue;\n }\n if (!interactionStartEvent.args.data?.type || !interactionStartEvent.args.data?.interactionId) {\n // A valid interaction event that we care about has to have a type (e.g.\n // pointerdown, keyup).\n //\n // We also need to ensure it has an interactionId. We already checked\n // this in the handleEvent() function, but we do it here also to satisfy\n // TypeScript.\n continue;\n }\n\n const interactionEvent: Types.TraceEvents.SyntheticInteractionEvent = {\n // Use the start event to define the common fields.\n cat: interactionStartEvent.cat,\n name: interactionStartEvent.name,\n pid: interactionStartEvent.pid,\n tid: interactionStartEvent.tid,\n ph: interactionStartEvent.ph,\n args: {\n data: {\n beginEvent: interactionStartEvent,\n endEvent: endEvent,\n },\n },\n ts: interactionStartEvent.ts,\n dur: Types.Timing.MicroSeconds(endEvent.ts - interactionStartEvent.ts),\n type: interactionStartEvent.args.data.type,\n interactionId: interactionStartEvent.args.data.interactionId,\n };\n if (!longestInteractionEvent || longestInteractionEvent.dur < interactionEvent.dur) {\n longestInteractionEvent = interactionEvent;\n }\n interactionEvents.push(interactionEvent);\n }\n\n handlerState = HandlerState.FINALIZED;\n interactionEventsWithNoNesting.push(...removeNestedInteractions(interactionEvents));\n}\n\nexport function data(): UserInteractionsData {\n return {\n allEvents: [...allEvents],\n interactionEvents: [...interactionEvents],\n interactionEventsWithNoNesting: [...interactionEventsWithNoNesting],\n longestInteractionEvent,\n interactionsOverThreshold: new Set(interactionEvents.filter(event => {\n return event.dur > LONG_INTERACTION_THRESHOLD;\n })),\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\n/**\n * IMPORTANT!\n * See UserTimings.md in this directory for some handy documentation on\n * UserTimings and the trace events we parse currently.\n **/\nconst syntheticEvents: Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[] = [];\nconst performanceMeasureEvents: (Types.TraceEvents.TraceEventPerformanceMeasureBegin|\n Types.TraceEvents.TraceEventPerformanceMeasureEnd)[] = [];\nconst performanceMarkEvents: Types.TraceEvents.TraceEventPerformanceMark[] = [];\n\nconst consoleTimings: (Types.TraceEvents.TraceEventConsoleTimeBegin|Types.TraceEvents.TraceEventConsoleTimeEnd)[] = [];\n\nconst timestampEvents: Types.TraceEvents.TraceEventTimeStamp[] = [];\n\nexport interface UserTimingsData {\n /**\n * Events triggered with the performance.measure() API.\n * https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure\n */\n performanceMeasures: readonly Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[];\n /**\n * Events triggered with the performance.mark() API.\n * https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark\n */\n performanceMarks: readonly Types.TraceEvents.TraceEventPerformanceMark[];\n /**\n * Events triggered with the console.time(), console.timeEnd() and\n * console.timeLog() API.\n * https://developer.mozilla.org/en-US/docs/Web/API/console/time\n */\n consoleTimings: readonly Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent[];\n /**\n * Events triggered with the console.timeStamp() API\n * https://developer.mozilla.org/en-US/docs/Web/API/console/timeStamp\n */\n timestampEvents: readonly Types.TraceEvents.TraceEventTimeStamp[];\n}\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function reset(): void {\n syntheticEvents.length = 0;\n performanceMeasureEvents.length = 0;\n performanceMarkEvents.length = 0;\n consoleTimings.length = 0;\n timestampEvents.length = 0;\n handlerState = HandlerState.INITIALIZED;\n}\n\nconst resourceTimingNames = [\n 'workerStart',\n 'redirectStart',\n 'redirectEnd',\n 'fetchStart',\n 'domainLookupStart',\n 'domainLookupEnd',\n 'connectStart',\n 'connectEnd',\n 'secureConnectionStart',\n 'requestStart',\n 'responseStart',\n 'responseEnd',\n];\nconst navTimingNames = [\n 'navigationStart',\n 'unloadEventStart',\n 'unloadEventEnd',\n 'redirectStart',\n 'redirectEnd',\n 'fetchStart',\n 'commitNavigationEnd',\n 'domainLookupStart',\n 'domainLookupEnd',\n 'connectStart',\n 'connectEnd',\n 'secureConnectionStart',\n 'requestStart',\n 'responseStart',\n 'responseEnd',\n 'domLoading',\n 'domInteractive',\n 'domContentLoadedEventStart',\n 'domContentLoadedEventEnd',\n 'domComplete',\n 'loadEventStart',\n 'loadEventEnd',\n];\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('UserTimings handler is not initialized');\n }\n\n // These are events dispatched under the blink.user_timing category\n // but that the user didn't add. Filter them out so that they do not\n // Appear in the timings track (they still appear in the main thread\n // flame chart).\n const ignoredNames = [...resourceTimingNames, ...navTimingNames];\n if (ignoredNames.includes(event.name)) {\n return;\n }\n\n if (Types.TraceEvents.isTraceEventPerformanceMeasure(event)) {\n performanceMeasureEvents.push(event);\n return;\n }\n if (Types.TraceEvents.isTraceEventPerformanceMark(event)) {\n performanceMarkEvents.push(event);\n }\n if (Types.TraceEvents.isTraceEventConsoleTime(event)) {\n consoleTimings.push(event);\n }\n if (Types.TraceEvents.isTraceEventTimeStamp(event)) {\n timestampEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('UserTimings handler is not initialized');\n }\n\n const matchedEvents: Map<string, {\n begin: Types.TraceEvents.TraceEventNestableAsyncBegin | null,\n end: Types.TraceEvents.TraceEventNestableAsyncEnd | null,\n }> = new Map();\n\n for (const event of [...performanceMeasureEvents, ...consoleTimings]) {\n const id = Helpers.Trace.extractId(event);\n if (id === undefined) {\n continue;\n }\n // Create a synthetic id to prevent collisions across categories.\n // Console timings can be dispatched with the same id, so use the\n // event name as well to generate unique ids.\n const syntheticId = `${event.cat}:${id}:${event.name}`;\n const otherEventsWithID = Platform.MapUtilities.getWithDefault(matchedEvents, syntheticId, () => {\n return {begin: null, end: null};\n });\n const isStartEvent = event.ph === Types.TraceEvents.Phase.ASYNC_NESTABLE_START;\n const isEndEvent = event.ph === Types.TraceEvents.Phase.ASYNC_NESTABLE_END;\n\n if (isStartEvent) {\n otherEventsWithID.begin = event;\n } else if (isEndEvent) {\n otherEventsWithID.end = event;\n }\n }\n\n for (const [id, eventsPair] of matchedEvents.entries()) {\n if (!eventsPair.begin || !eventsPair.end) {\n // This should never happen, the backend only creates the events once it\n // has them both, so we should never get into this state.\n // If we do, something is very wrong, so let's just drop that problematic event.\n continue;\n }\n\n const event: Types.TraceEvents.TraceEventSyntheticNestableAsyncEvent = {\n cat: eventsPair.end.cat,\n ph: eventsPair.end.ph,\n pid: eventsPair.end.pid,\n tid: eventsPair.end.tid,\n id,\n // Both events have the same name, so it doesn't matter which we pick to\n // use as the description\n name: eventsPair.begin.name,\n dur: Types.Timing.MicroSeconds(eventsPair.end.ts - eventsPair.begin.ts),\n ts: eventsPair.begin.ts,\n args: {\n data: {\n beginEvent: eventsPair.begin,\n endEvent: eventsPair.end,\n },\n },\n };\n\n if (event.dur < 0) {\n // Avoid any pairs that have created a negative duration; this is bad\n // trace data and we should just ignore them.\n continue;\n }\n syntheticEvents.push(event);\n }\n syntheticEvents.sort((a, b) => a.ts - b.ts);\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): UserTimingsData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('UserTimings handler is not finalized');\n }\n\n return {\n performanceMeasures: syntheticEvents.filter(Types.TraceEvents.isTraceEventPerformanceMeasure),\n consoleTimings: syntheticEvents.filter(Types.TraceEvents.isTraceEventConsoleTime),\n performanceMarks: [...performanceMarkEvents],\n timestampEvents: [...timestampEvents],\n };\n}\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nexport interface WarningsData {\n // Tracks warnings keyed by the event.\n perEvent: Map<Types.TraceEvents.TraceEventData, Warning[]>;\n // The same data in reverse: for each type of warning, track the events.\n // Useful if we need to enumerate issues by type of issue\n perWarning: Map<Warning, Types.TraceEvents.TraceEventData[]>;\n}\n\nexport type Warning = 'LONG_TASK'|'IDLE_CALLBACK_OVER_TIME'|'FORCED_LAYOUT'|'FORCED_STYLE';\n\nconst warningsPerEvent: WarningsData['perEvent'] = new Map();\nconst eventsPerWarning: WarningsData['perWarning'] = new Map();\n\nexport const FORCED_LAYOUT_AND_STYLES_THRESHOLD =\n Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(10));\n\nexport const LONG_MAIN_THREAD_TASK_THRESHOLD = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(50));\n\nexport function reset(): void {\n warningsPerEvent.clear();\n eventsPerWarning.clear();\n}\n\nfunction storeWarning(event: Types.TraceEvents.TraceEventData, warning: Warning): void {\n const existingWarnings = Platform.MapUtilities.getWithDefault(warningsPerEvent, event, () => []);\n existingWarnings.push(warning);\n warningsPerEvent.set(event, existingWarnings);\n\n const existingEvents = Platform.MapUtilities.getWithDefault(eventsPerWarning, warning, () => []);\n existingEvents.push(event);\n eventsPerWarning.set(warning, existingEvents);\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (event.name === Types.TraceEvents.KnownEventName.RunTask) {\n const {duration} = Helpers.Timing.eventTimingsMicroSeconds(event);\n if (duration > LONG_MAIN_THREAD_TASK_THRESHOLD) {\n storeWarning(event, 'LONG_TASK');\n }\n return;\n }\n\n if (Types.TraceEvents.isTraceEventFireIdleCallback(event)) {\n const {duration} = Helpers.Timing.eventTimingsMilliSeconds(event);\n if (duration > event.args.data.allottedMilliseconds) {\n storeWarning(event, 'IDLE_CALLBACK_OVER_TIME');\n }\n return;\n }\n\n if (event.name === Types.TraceEvents.KnownEventName.Layout) {\n if (event.dur && event.dur >= FORCED_LAYOUT_AND_STYLES_THRESHOLD) {\n storeWarning(event, 'FORCED_LAYOUT');\n }\n return;\n }\n\n if (event.name === Types.TraceEvents.KnownEventName.RecalculateStyles ||\n event.name === Types.TraceEvents.KnownEventName.UpdateLayoutTree) {\n if (event.dur && event.dur >= FORCED_LAYOUT_AND_STYLES_THRESHOLD) {\n storeWarning(event, 'FORCED_STYLE');\n }\n return;\n }\n}\n\nexport function data(): WarningsData {\n return {\n perEvent: new Map(warningsPerEvent),\n perWarning: new Map(eventsPerWarning),\n };\n}\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\nexport interface WorkersData {\n workerSessionIdEvents: readonly Types.TraceEvents.TraceEventTracingSessionIdForWorker[];\n workerIdByThread: Map<Types.TraceEvents.ThreadID, Types.TraceEvents.WorkerId>;\n workerURLById: Map<Types.TraceEvents.WorkerId, string>;\n}\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst sessionIdEvents: Types.TraceEvents.TraceEventTracingSessionIdForWorker[] = [];\nconst workerIdByThread: Map<Types.TraceEvents.ThreadID, Types.TraceEvents.WorkerId> = new Map();\nconst workerURLById: Map<Types.TraceEvents.WorkerId, string> = new Map();\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Workers Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function reset(): void {\n sessionIdEvents.length = 0;\n workerIdByThread.clear();\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Workers Handler is not initialized');\n }\n if (Types.TraceEvents.isTraceEventTracingSessionIdForWorker(event)) {\n sessionIdEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Handler is not initialized');\n }\n for (const sessionIdEvent of sessionIdEvents) {\n if (!sessionIdEvent.args.data) {\n continue;\n }\n workerIdByThread.set(sessionIdEvent.args.data.workerThreadId, sessionIdEvent.args.data.workerId);\n workerURLById.set(sessionIdEvent.args.data.workerId, sessionIdEvent.args.data.url);\n }\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): WorkersData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Workers Handler is not finalized');\n }\n\n return {\n workerSessionIdEvents: [...sessionIdEvents],\n workerIdByThread: new Map(workerIdByThread),\n workerURLById: new Map(workerURLById),\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as Animations from './AnimationHandler.js';\nexport * as AuctionWorklets from './AuctionWorkletsHandler.js';\nexport * as GPU from './GPUHandler.js';\nexport * as LargestImagePaint from './LargestImagePaintHandler.js';\nexport * as LargestTextPaint from './LargestTextPaintHandler.js';\nexport * as LayoutShifts from './LayoutShiftsHandler.js';\nexport * as Memory from './MemoryHandler.js';\nexport * as Meta from './MetaHandler.js';\nexport * as NetworkRequests from './NetworkRequestsHandler.js';\nexport * as PageLoadMetrics from './PageLoadMetricsHandler.js';\nexport * as Renderer from './RendererHandler.js';\nexport * as Samples from './SamplesHandler.js';\nexport * as Screenshots from './ScreenshotsHandler.js';\nexport * as UserInteractions from './UserInteractionsHandler.js';\nexport * as UserTimings from './UserTimingsHandler.js';\nexport * as Warnings from './WarningsHandler.js';\nexport * as Workers from './WorkersHandler.js';\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\n\n/**\n * There are two metadata events that we care about.\n * => AuctionWorkletRunningInProcess tells us which process the Auction Worklet\n * has taken to run in.\n * => AuctionWorkletDoneWithProcess tells us when the worklet is done with that\n * process. This is less useful - but in the future we might want to surface\n * this information so we still parse and return the event.\n *\n * It is important to note that the top level PID on these events is NOT the\n * PID that the worklet is running on; instead we have to look at its\n * args.data.pid property, which is the PID of the process that it is running\n * on.\n *\n * For any given RunningInProcess event, we would typically expect to see a\n * DoneWithProcess event, however this is not guaranteed, especially as users\n * can record any chunk of time in DevTools.\n *\n * Similarly, it is also possible to see a DoneWithProcess event without a\n * RunningInProcess event, if the user started recording after the auction\n * worklets started. Therefore we are happy to create\n * SyntheticAuctionWorkletEvents as long as we see just one of these events.\n *\n * If we do get two events and need to pair them, we can use the\n * args.data.target property, which is a string ID shared by both\n * events.\n */\nconst runningInProcessEvents:\n Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventAuctionWorkletRunningInProcess> = new Map();\nconst doneWithProcessEvents:\n Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventAuctionWorkletDoneWithProcess> = new Map();\n\n// Keyed by the PID defined in `args.data.pid` on AuctionWorklet trace events..\nconst createdSyntheticEvents: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.SyntheticAuctionWorkletEvent> =\n new Map();\n\n// Each AuctonWorklet takes over a process and has 2 threads (that we care\n// about and want to show as tracks):\n// 1. A CrUtilityMain thread which is known as the \"control process\".\n// 2. A AuctionV8HelperThread which is the actual auction worklet and will be\n// either a \"Seller\" or a \"Bidder\"\n// To detect these we look for the metadata thread_name events. We key these by\n// PID so that we can easily look them up later without having to loop through.\nconst utilityThreads: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventThreadName> = new Map();\nconst v8HelperThreads: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventThreadName> = new Map();\n\nexport function reset(): void {\n runningInProcessEvents.clear();\n doneWithProcessEvents.clear();\n createdSyntheticEvents.clear();\n utilityThreads.clear();\n v8HelperThreads.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventAuctionWorkletRunningInProcess(event)) {\n runningInProcessEvents.set(event.args.data.pid, event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventAuctionWorkletDoneWithProcess(event)) {\n doneWithProcessEvents.set(event.args.data.pid, event);\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event)) {\n if (event.args.name === 'auction_worklet.CrUtilityMain') {\n utilityThreads.set(event.pid, event);\n return;\n }\n if (event.args.name === 'AuctionV8HelperThread') {\n v8HelperThreads.set(event.pid, event);\n }\n }\n}\n\nfunction workletType(input: string): Types.TraceEvents.AuctionWorkletType {\n switch (input) {\n case 'seller':\n return Types.TraceEvents.AuctionWorkletType.SELLER;\n case 'bidder':\n return Types.TraceEvents.AuctionWorkletType.BIDDER;\n default:\n return Types.TraceEvents.AuctionWorkletType.UNKNOWN;\n }\n}\n\n/**\n * We cannot make the full event without knowing the type of event, but we can\n * create everything other than the `args` field, as those are identical\n * regardless of the type of event.\n */\nfunction makeSyntheticEventBase(event: Types.TraceEvents.TraceEventAuctionWorkletDoneWithProcess|\n Types.TraceEvents.TraceEventAuctionWorkletRunningInProcess):\n Omit<Types.TraceEvents.SyntheticAuctionWorkletEvent, 'args'> {\n return {\n name: 'SyntheticAuctionWorkletEvent',\n s: Types.TraceEvents.TraceEventScope.THREAD,\n cat: event.cat,\n tid: event.tid,\n ts: event.ts,\n ph: Types.TraceEvents.Phase.INSTANT,\n pid: event.args.data.pid,\n host: event.args.data.host,\n target: event.args.data.target,\n type: workletType(event.args.data.type),\n };\n}\n\nexport async function finalize(): Promise<void> {\n // Loop through the utility threads we found to create the worklet events. We\n // expect each worklet to have a utility thread, so we can use them as the\n // root of our list of worklets.\n for (const [pid, utilityThreadNameEvent] of utilityThreads) {\n const v8HelperEvent = v8HelperThreads.get(pid);\n if (!v8HelperEvent) {\n // Bad trace data - AuctionWorklets are expected to always have both threads.\n continue;\n }\n\n const runningEvent = runningInProcessEvents.get(pid);\n const doneWithEvent = doneWithProcessEvents.get(pid);\n\n // We can create a worklet from either the runningEvent or doneWithEvent -\n // we do not need both. We cannot express that to TypeScript with an early\n // return here, so instead we set the event initially to null, and then\n // create it from either the running event or the doneWith event. If it is\n // still null after this, that means neither event was found, and we drop\n // the worklet as we do not have enough information to create the synthetic\n // event.\n\n let syntheticEvent: Types.TraceEvents.SyntheticAuctionWorkletEvent|null = null;\n\n if (runningEvent) {\n syntheticEvent = {\n ...makeSyntheticEventBase(runningEvent),\n args: {\n data: {\n runningInProcessEvent: runningEvent,\n utilityThread: utilityThreadNameEvent,\n v8HelperThread: v8HelperEvent,\n },\n },\n };\n if (doneWithEvent) {\n syntheticEvent.args.data.doneWithProcessEvent = doneWithEvent;\n }\n } else if (doneWithEvent) {\n syntheticEvent = {\n ...makeSyntheticEventBase(doneWithEvent),\n args: {\n data: {\n doneWithProcessEvent: doneWithEvent,\n utilityThread: utilityThreadNameEvent,\n v8HelperThread: v8HelperEvent,\n },\n },\n };\n if (runningEvent) {\n syntheticEvent.args.data.runningInProcessEvent = runningEvent;\n }\n }\n if (syntheticEvent === null) {\n continue;\n }\n createdSyntheticEvents.set(pid, syntheticEvent);\n }\n}\n\nexport interface AuctionWorkletsData {\n worklets: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.SyntheticAuctionWorkletEvent>;\n}\n\nexport function data(): AuctionWorkletsData {\n return {\n worklets: new Map(createdSyntheticEvents),\n };\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\nimport type * as Protocol from '../../../generated/protocol.js';\n/**\n * If the LCP resource was an image, and that image was fetched over the\n * network, we want to be able to find the network request in order to construct\n * the critical path for an LCP image.\n * Within the trace file there are `LargestImagePaint::Candidate` events.\n * Within their data object, they contain a `DOMNodeId` property, which maps to\n * the DOM Node ID for that image.\n *\n * This id maps exactly to the `data.nodeId` property that a\n * `LargestContentfulPaint::Candidate` will have. So, when we find an image\n * paint candidate, we can store it, keying it on the node ID.\n * Then, when it comes to finding the network request for an LCP image, we can\n *\n * use the nodeId from the LCP candidate to find the image candidate. That image\n * candidate also contains a `imageUrl` property, which will have the full URL\n * to the image.\n **/\nconst imageByDOMNodeId = new Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestImagePaintCandidate>();\n\nexport function reset(): void {\n imageByDOMNodeId.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (!Types.TraceEvents.isTraceEventLargestImagePaintCandidate(event)) {\n return;\n }\n\n if (!event.args.data) {\n return;\n }\n\n imageByDOMNodeId.set(event.args.data.DOMNodeId, event);\n}\n\nexport function data(): Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestImagePaintCandidate> {\n return new Map(imageByDOMNodeId);\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Protocol from '../../../generated/protocol.js';\nimport * as Types from '../types/types.js';\n/**\n * A trace file will contain all the text paints that were candidates for the\n * LargestTextPaint. If an LCP event is text, it will point to one of these\n * candidates, so we store them by their DOM Node ID.\n **/\nconst textPaintByDOMNodeId =\n new Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestTextPaintCandidate>();\n\nexport function reset(): void {\n textPaintByDOMNodeId.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (!Types.TraceEvents.isTraceEventLargestTextPaintCandidate(event)) {\n return;\n }\n\n if (!event.args.data) {\n return;\n }\n\n textPaintByDOMNodeId.set(event.args.data.DOMNodeId, event);\n}\n\nexport function data(): Map<Protocol.DOM.BackendNodeId, Types.TraceEvents.TraceEventLargestTextPaintCandidate> {\n return new Map(textPaintByDOMNodeId);\n}\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {data as metaHandlerData, type FrameProcessData} from './MetaHandler.js';\nimport {data as samplesHandlerData} from './SamplesHandler.js';\nimport {HandlerState, type TraceEventHandlerName} from './types.js';\n\n/**\n * This handler builds the hierarchy of trace events and profile calls\n * on each thread on each process.\n *\n * Throughout the code, trace events and profile calls are referred to\n * as \"entries\", but note they are different types of data. Trace events\n * come directly from the backend and it's the type the engine commonly\n * refers to. Profile calls on the other hand are built in the frontend,\n * and, for compatibility purposes, typed as an extension to the trace\n * event type.\n */\n\nconst processes = new Map<Types.TraceEvents.ProcessID, RendererProcess>();\n\n// We track the compositor tile worker thread name events so that at the end we\n// can return these keyed by the process ID. These are used in the frontend to\n// show the user the rasterization thread(s) on the main frame as tracks.\nconst compositorTileWorkers = Array<{\n pid: Types.TraceEvents.ProcessID,\n tid: Types.TraceEvents.ThreadID,\n}>();\nconst entryToNode = new Map<RendererEntry, RendererEntryNode>();\nconst allRendererEvents: Types.TraceEvents.TraceEventRendererEvent[] = [];\nlet nodeIdCount = 0;\nconst makeRendererEntrytNodeId = (): RendererEntryNodeId => (++nodeIdCount) as RendererEntryNodeId;\nconst completeEventStack: (Types.TraceEvents.TraceEventSyntheticCompleteEvent)[] = [];\n\nlet handlerState = HandlerState.UNINITIALIZED;\nlet config: Types.Configuration.Configuration = Types.Configuration.DEFAULT;\n\nconst makeRendererProcess = (): RendererProcess => ({\n url: null,\n isOnMainFrame: false,\n threads: new Map(),\n});\n\nconst makeRendererThread = (): RendererThread => ({\n name: null,\n entries: [],\n});\n\nconst makeEmptyRendererTree = (): RendererTree => ({\n nodes: new Map(),\n roots: new Set(),\n maxDepth: 0,\n});\n\nconst makeEmptyRendererEventNode = (entry: RendererEntry, id: RendererEntryNodeId): RendererEntryNode => ({\n entry,\n id,\n parentId: null,\n childrenIds: new Set(),\n depth: 0,\n});\n\nconst getOrCreateRendererProcess =\n (processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, pid: Types.TraceEvents.ProcessID):\n RendererProcess => {\n return Platform.MapUtilities.getWithDefault(processes, pid, makeRendererProcess);\n };\n\nconst getOrCreateRendererThread = (process: RendererProcess, tid: Types.TraceEvents.ThreadID): RendererThread => {\n return Platform.MapUtilities.getWithDefault(process.threads, tid, makeRendererThread);\n};\n\nexport function handleUserConfig(userConfig: Types.Configuration.Configuration): void {\n config = userConfig;\n}\n\nexport function reset(): void {\n processes.clear();\n entryToNode.clear();\n allRendererEvents.length = 0;\n completeEventStack.length = 0;\n compositorTileWorkers.length = 0;\n nodeIdCount = -1;\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Renderer Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Renderer Handler is not initialized');\n }\n\n if (Types.TraceEvents.isThreadName(event) && event.args.name?.startsWith('CompositorTileWorker')) {\n compositorTileWorkers.push({\n pid: event.pid,\n tid: event.tid,\n });\n }\n\n if (Types.TraceEvents.isTraceEventBegin(event) || Types.TraceEvents.isTraceEventEnd(event)) {\n const process = getOrCreateRendererProcess(processes, event.pid);\n const thread = getOrCreateRendererThread(process, event.tid);\n const completeEvent = makeCompleteEvent(event);\n if (!completeEvent) {\n return;\n }\n thread.entries.push(completeEvent);\n allRendererEvents.push(completeEvent);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventInstant(event) || Types.TraceEvents.isTraceEventComplete(event)) {\n const process = getOrCreateRendererProcess(processes, event.pid);\n const thread = getOrCreateRendererThread(process, event.tid);\n thread.entries.push(event);\n allRendererEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Renderer Handler is not initialized');\n }\n\n const {mainFrameId, rendererProcessesByFrame, threadsInProcess} = metaHandlerData();\n assignMeta(processes, mainFrameId, rendererProcessesByFrame, threadsInProcess);\n sanitizeProcesses(processes);\n buildHierarchy(processes);\n sanitizeThreads(processes);\n\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): RendererHandlerData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Renderer Handler is not finalized');\n }\n\n return {\n processes: new Map(processes),\n compositorTileWorkers: new Map(gatherCompositorThreads()),\n entryToNode: new Map(entryToNode),\n allRendererEvents: [...allRendererEvents],\n };\n}\n\nfunction gatherCompositorThreads(): Map<Types.TraceEvents.ProcessID, Types.TraceEvents.ThreadID[]> {\n const threadsByProcess = new Map<Types.TraceEvents.ProcessID, Types.TraceEvents.ThreadID[]>();\n for (const worker of compositorTileWorkers) {\n const byProcess = threadsByProcess.get(worker.pid) || [];\n byProcess.push(worker.tid);\n threadsByProcess.set(worker.pid, byProcess);\n }\n return threadsByProcess;\n}\n\n/**\n * Steps through all the renderer processes we've located so far in the meta\n * handler, obtaining their URL, checking whether they are the main frame, and\n * collecting each one of their threads' name. This meta handler's data is\n * assigned to the renderer handler's data.\n */\nexport function assignMeta(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, mainFrameId: string,\n rendererProcessesByFrame: FrameProcessData,\n threadsInProcess:\n Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>):\n void {\n assignOrigin(processes, rendererProcessesByFrame);\n assignIsMainFrame(processes, mainFrameId, rendererProcessesByFrame);\n assignThreadName(processes, rendererProcessesByFrame, threadsInProcess);\n}\n\n/**\n * Assigns origins to all threads in all processes.\n * @see assignMeta\n */\nexport function assignOrigin(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, rendererProcessesByFrame: FrameProcessData): void {\n for (const renderProcessesByPid of rendererProcessesByFrame.values()) {\n for (const [pid, processWindows] of renderProcessesByPid) {\n for (const processInfo of processWindows.flat()) {\n const process = getOrCreateRendererProcess(processes, pid);\n // Sometimes a single process is responsible with rendering multiple\n // frames at the same time. For example, see https://crbug.com/1334563.\n // When this happens, we'd still like to assign a single url per process\n // so: 1) use the first frame rendered by this process as the url source\n // and 2) if the last url is \"about:blank\", use the next frame's url,\n // data from about:blank is irrelevant.\n if (process.url === null || process.url === 'about:blank') {\n // If we are here, it's because we care about this process and the URL. But before we store\n // it, we check if it is a valid URL by trying to create a URL object. If it isn't, we won't\n // set it, and this process will be filtered out later.\n try {\n new URL(processInfo.frame.url);\n process.url = processInfo.frame.url;\n } catch (e) {\n process.url = null;\n }\n }\n }\n }\n }\n}\n\n/**\n * Assigns whether or not a thread is the main frame to all threads in all processes.\n * @see assignMeta\n */\nexport function assignIsMainFrame(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, mainFrameId: string,\n rendererProcessesByFrame: FrameProcessData): void {\n for (const [frameId, renderProcessesByPid] of rendererProcessesByFrame) {\n for (const [pid] of renderProcessesByPid) {\n const process = getOrCreateRendererProcess(processes, pid);\n // We have this go in one direction; once a renderer has been flagged as\n // being on the main frame, we don't unset it to false if were to show up\n // in a subframe. Equally, if we already saw this renderer in a subframe,\n // but it becomes the main frame, the flag would get updated.\n if (frameId === mainFrameId) {\n process.isOnMainFrame = true;\n }\n }\n }\n}\n\n/**\n * Assigns the thread name to all threads in all processes.\n * @see assignMeta\n */\nexport function assignThreadName(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>, rendererProcessesByFrame: FrameProcessData,\n threadsInProcess:\n Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventThreadName>>):\n void {\n for (const [, renderProcessesByPid] of rendererProcessesByFrame) {\n for (const [pid] of renderProcessesByPid) {\n const process = getOrCreateRendererProcess(processes, pid);\n for (const [tid, threadInfo] of threadsInProcess.get(pid) ?? []) {\n const thread = getOrCreateRendererThread(process, tid);\n thread.name = threadInfo?.args.name ?? `${tid}`;\n }\n }\n }\n}\n\n/**\n * Removes unneeded trace data opportunistically stored while handling events.\n * This currently does the following:\n * - Deletes processes with an unkonwn origin.\n */\nexport function sanitizeProcesses(processes: Map<Types.TraceEvents.ProcessID, RendererProcess>): void {\n for (const [pid, process] of processes) {\n // If the process had no url, or if it had a malformed url that could not be\n // parsed for some reason, or if it's an \"about:\" origin, delete it.\n // This is done because we don't really care about processes for which we\n // can't provide actionable insights to the user (e.g. about:blank pages).\n if (process.url === null) {\n processes.delete(pid);\n continue;\n }\n const asUrl = new URL(process.url);\n if (asUrl.protocol === 'about:') {\n processes.delete(pid);\n }\n }\n}\n\n/**\n * Removes unneeded trace data opportunistically stored while handling events.\n * This currently does the following:\n * - Deletes threads with no roots.\n */\nexport function sanitizeThreads(processes: Map<Types.TraceEvents.ProcessID, RendererProcess>): void {\n for (const [, process] of processes) {\n for (const [tid, thread] of process.threads) {\n // If the thread has no roots, delete it. Otherwise, there's going to\n // be space taken, even though nothing is rendered in the track manager.\n if (!thread.tree?.roots.size) {\n process.threads.delete(tid);\n }\n }\n }\n}\n\n/**\n * Creates a hierarchical structure from the trace events. Each thread in each\n * process will contribute to their own individual hierarchy.\n *\n * The trace data comes in as a contiguous array of events, against which we\n * make a couple of assumptions:\n *\n * 1. Events are temporally-ordered in terms of start time (though they're\n * not necessarily ordered as such in the data stream).\n * 2. If event B's start and end times are within event A's time boundaries\n * we assume that A is the parent of B.\n *\n * Therefore we expect to reformulate something like:\n *\n * [ Task A ][ Task B ][ Task C ][ Task D ][ Task E ]\n *\n * Into something hierarchically-arranged like below:\n *\n * |------------- Task A -------------||-- Task E --|\n * |-- Task B --||-- Task D --|\n * |- Task C -|\n */\nexport function buildHierarchy(\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>,\n options?: {filter: {has: (name: Types.TraceEvents.KnownEventName) => boolean}}): void {\n for (const [pid, process] of processes) {\n for (const [tid, thread] of process.threads) {\n if (!thread.entries.length) {\n thread.tree = makeEmptyRendererTree();\n continue;\n }\n // Step 1. Massage the data.\n Helpers.Trace.sortTraceEventsInPlace(thread.entries);\n // Step 2. Inject profile calls from samples\n const cpuProfile = samplesHandlerData().profilesInProcess.get(pid)?.get(tid)?.parsedProfile;\n const samplesIntegrator = cpuProfile && new Helpers.SamplesIntegrator.SamplesIntegrator(cpuProfile, pid, tid, {\n showNativeFunctionsInJSProfile: config.settings.showNativeFunctionsInJSProfile,\n });\n const profileCalls = samplesIntegrator?.buildProfileCalls(thread.entries);\n if (profileCalls) {\n thread.entries = Helpers.Trace.mergeEventsInOrder(thread.entries, profileCalls);\n }\n // Step 3. Build the tree.\n thread.tree = treify(thread.entries, options);\n }\n }\n}\n\n/**\n * Builds a hierarchy of the entries (trace events and profile calls) in\n * a particular thread of a particular process, assuming that they're\n * sorted, by iterating through all of the events in order.\n *\n * The approach is analogous to how a parser would be implemented. A\n * stack maintains local context. A scanner peeks and pops from the data\n * stream. Various \"tokens\" (events) are treated as \"whitespace\"\n * (ignored).\n *\n * The tree starts out empty and is populated as the hierarchy is built.\n * The nodes are also assumed to be created empty, with no known parent\n * or children.\n *\n * Complexity: O(n), where n = number of events\n */\nexport function treify(\n entries: RendererEntry[],\n options?: {filter: {has: (name: Types.TraceEvents.KnownEventName) => boolean}}): RendererTree {\n const stack = [];\n // Reset the node id counter for every new renderer.\n nodeIdCount = -1;\n const tree = makeEmptyRendererTree();\n for (let i = 0; i < entries.length; i++) {\n const event = entries[i];\n // If the current event should not be part of the tree, then simply proceed\n // with the next event.\n if (options && !options.filter.has(event.name as Types.TraceEvents.KnownEventName)) {\n continue;\n }\n\n const duration = event.dur || 0;\n const nodeId = makeRendererEntrytNodeId();\n const node = makeEmptyRendererEventNode(event, nodeId);\n\n // If the parent stack is empty, then the current event is a root. Create a\n // node for it, mark it as a root, then proceed with the next event.\n if (stack.length === 0) {\n tree.nodes.set(nodeId, node);\n tree.roots.add(nodeId);\n event.selfTime = Types.Timing.MicroSeconds(duration);\n stack.push(node);\n tree.maxDepth = Math.max(tree.maxDepth, stack.length);\n entryToNode.set(event, node);\n continue;\n }\n\n const parentNode = stack.at(-1);\n if (parentNode === undefined) {\n throw new Error('Impossible: no parent node found in the stack');\n }\n\n const parentEvent = parentNode.entry;\n\n const begin = event.ts;\n const parentBegin = parentEvent.ts;\n const parentDuration = parentEvent.dur || 0;\n const end = begin + duration;\n const parentEnd = parentBegin + parentDuration;\n // Check the relationship between the parent event at the top of the stack,\n // and the current event being processed. There are only 4 distinct\n // possiblities, only 2 of them actually valid, given the assumed sorting:\n // 1. Current event starts before the parent event, ends whenever. (invalid)\n // 2. Current event starts after the parent event, ends whenever. (valid)\n // 3. Current event starts during the parent event, ends after. (invalid)\n // 4. Current event starts and ends during the parent event. (valid)\n\n // 1. If the current event starts before the parent event, then the data is\n // not sorted properly, messed up some way, or this logic is incomplete.\n const startsBeforeParent = begin < parentBegin;\n if (startsBeforeParent) {\n throw new Error('Impossible: current event starts before the parent event');\n }\n\n // 2. If the current event starts after the parent event, then it's a new\n // parent. Pop, then handle current event again.\n const startsAfterParent = begin >= parentEnd;\n if (startsAfterParent) {\n stack.pop();\n i--;\n // The last created node has been discarded, so discard this id.\n nodeIdCount--;\n continue;\n }\n // 3. If the current event starts during the parent event, but ends\n // after it, then the data is messed up some way, for example a\n // profile call was sampled too late after its start, ignore the\n // problematic event.\n const endsAfterParent = end > parentEnd;\n if (endsAfterParent) {\n continue;\n }\n\n // 4. The only remaining case is the common case, where the current event is\n // contained within the parent event. Create a node for the current\n // event, establish the parent/child relationship, then proceed with the\n // next event.\n tree.nodes.set(nodeId, node);\n node.depth = stack.length;\n node.parentId = parentNode.id;\n parentNode.childrenIds.add(nodeId);\n event.selfTime = Types.Timing.MicroSeconds(duration);\n if (parentEvent.selfTime !== undefined) {\n parentEvent.selfTime = Types.Timing.MicroSeconds(parentEvent.selfTime - (event.dur || 0));\n }\n stack.push(node);\n tree.maxDepth = Math.max(tree.maxDepth, stack.length);\n entryToNode.set(event, node);\n }\n return tree;\n}\n\nexport function makeCompleteEvent(event: Types.TraceEvents.TraceEventBegin|Types.TraceEvents.TraceEventEnd):\n Types.TraceEvents.TraceEventSyntheticCompleteEvent|null {\n if (Types.TraceEvents.isTraceEventEnd(event)) {\n // Quietly ignore unbalanced close events, they're legit (we could\n // have missed start one).\n const beginEvent = completeEventStack.pop();\n if (!beginEvent) {\n return null;\n }\n if (beginEvent.name !== event.name || beginEvent.cat !== event.cat) {\n console.error(\n 'Begin/End events mismatch at ' + beginEvent.ts + ' (' + beginEvent.name + ') vs. ' + event.ts + ' (' +\n event.name + ')');\n return null;\n }\n // Update the begin event's duration using the timestamp of the end\n // event.\n beginEvent.dur = Types.Timing.MicroSeconds(event.ts - beginEvent.ts);\n return null;\n }\n\n // Create a synthetic event using the begin event, when we find the\n // matching end event later we will update its duration.\n const syntheticComplete: Types.TraceEvents.TraceEventSyntheticCompleteEvent = {\n ...event,\n ph: Types.TraceEvents.Phase.COMPLETE,\n dur: Types.Timing.MicroSeconds(0),\n };\n\n completeEventStack.push(syntheticComplete);\n return syntheticComplete;\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta', 'Samples'];\n}\n\nexport interface RendererHandlerData {\n processes: Map<Types.TraceEvents.ProcessID, RendererProcess>;\n /**\n * A map of all compositor workers (which we show in the UI as Rasterizers)\n * by the process ID.\n */\n compositorTileWorkers: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.ThreadID[]>;\n entryToNode: Map<RendererEntry, RendererEntryNode>;\n /**\n * All trace events and synthetic profile calls made from\n * samples.\n */\n allRendererEvents: Types.TraceEvents.TraceEventRendererEvent[];\n}\n\nexport interface RendererProcess {\n // In an ideal world this would be modelled as a URL, but URLs cannot be sent\n // between the main thread and workers, so we have to store it as a string.\n url: string|null;\n isOnMainFrame: boolean;\n threads: Map<Types.TraceEvents.ThreadID, RendererThread>;\n}\n\nexport interface RendererThread {\n name: string|null;\n /**\n * Contains trace events and synthetic profile calls made from\n * samples.\n */\n entries: RendererEntry[];\n tree?: RendererTree;\n}\n\nexport type RendererEntry = Types.TraceEvents.SyntheticRendererEvent|Types.TraceEvents.TraceEventSyntheticProfileCall;\n\nexport interface RendererTree {\n nodes: Map<RendererEntryNodeId, RendererEntryNode>;\n roots: Set<RendererEntryNodeId>;\n maxDepth: number;\n}\n\nexport interface RendererEntryNode {\n entry: RendererEntry;\n depth: number;\n id: RendererEntryNodeId;\n parentId?: RendererEntryNodeId|null;\n childrenIds: Set<RendererEntryNodeId>;\n}\n\nclass RendererEventNodeIdTag {\n /* eslint-disable-next-line no-unused-private-class-members */\n readonly #tag: (symbol|undefined);\n}\nexport type RendererEntryNodeId = number&RendererEventNodeIdTag;\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\nimport type * as Protocol from '../../../generated/protocol.js';\nimport {HandlerState} from './types.js';\nimport * as CPUProfile from '../../cpu_profile/cpu_profile.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nconst events =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventComplete[]>>();\n\nconst profilesInProcess = new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, ProfileData>>();\n\n// The profile head, containing its metadata like its start\n// time, comes in a \"Profile\" event. The sample data comes in\n// \"ProfileChunk\" events. We match these ProfileChunks with their head\n// using process and profile ids. However, in order to integrate sample\n// data with trace data, we need the thread id that owns each profile.\n// This thread id is extracted from the head event.\n// For this reason, we have a preprocessed data structure, where events\n// are matched by profile id, which we then finish processing to export\n// events matched by thread id.\nconst preprocessedData = new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ProfileID, PreprocessedData>>();\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nexport function buildProfileCalls(): void {\n for (const [processId, profiles] of preprocessedData) {\n for (const [profileId, preProcessedData] of profiles) {\n const threadId = preProcessedData.threadId;\n if (!preProcessedData.rawProfile.nodes.length || !threadId) {\n continue;\n }\n const trackingStack: Partial<Types.TraceEvents.TraceEventSyntheticProfileCall>[] = [];\n\n const profileModel = new CPUProfile.CPUProfileDataModel.CPUProfileDataModel(preProcessedData.rawProfile);\n\n const finalizedData:\n ProfileData = {rawProfile: preProcessedData.rawProfile, parsedProfile: profileModel, profileCalls: []};\n\n profileModel.forEachFrame(openFrameCallback, closeFrameCallback);\n Helpers.Trace.sortTraceEventsInPlace(finalizedData.profileCalls);\n const dataByThread = Platform.MapUtilities.getWithDefault(profilesInProcess, processId, () => new Map());\n dataByThread.set(threadId, finalizedData);\n\n function openFrameCallback(\n _depth: number, node: CPUProfile.ProfileTreeModel.ProfileNode, timeStampMs: number): void {\n const ts = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(timeStampMs));\n trackingStack.push({callFrame: node.callFrame, ts, pid: processId, children: [], tid: threadId});\n }\n function closeFrameCallback(\n depth: number, node: CPUProfile.ProfileTreeModel.ProfileNode, _timeStamp: number, durMs: number,\n selfTimeMs: number): void {\n const partialProfileCall = trackingStack.pop();\n if (!partialProfileCall) {\n return;\n }\n const {callFrame, ts, pid, children, tid} = partialProfileCall;\n if (callFrame === undefined || ts === undefined || pid === undefined || profileId === undefined ||\n children === undefined || tid === undefined) {\n return;\n }\n const dur = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(durMs));\n const selfTime = Helpers.Timing.millisecondsToMicroseconds(Types.Timing.MilliSeconds(selfTimeMs));\n const completeProfileCall: Types.TraceEvents.TraceEventSyntheticProfileCall = {\n callFrame,\n ts,\n pid,\n dur,\n selfTime,\n children,\n ph: Types.TraceEvents.Phase.COMPLETE,\n cat: '',\n name: 'ProfileCall',\n tid,\n nodeId: node.id,\n };\n const parent = trackingStack.at(-1);\n const calls = finalizedData.profileCalls;\n calls.push(completeProfileCall);\n if (!parent) {\n return;\n }\n parent.children = parent.children || [];\n parent.children.push(completeProfileCall);\n if (parent.selfTime) {\n parent.selfTime = Types.Timing.MicroSeconds(parent.selfTime - dur);\n }\n }\n }\n }\n}\n\nexport function reset(): void {\n events.clear();\n preprocessedData.clear();\n profilesInProcess.clear();\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Samples Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Samples Handler is not initialized');\n }\n\n if (Types.TraceEvents.isTraceEventProfile(event)) {\n // Do not use event.args.data.startTime as it is in CLOCK_MONOTONIC domain,\n // but use profileEvent.ts which has been translated to Perfetto's clock\n // domain. Also convert from ms to us.\n // Note: events are collected on a different thread than what's sampled.\n // The correct process and thread ids are specified by the profile.\n const profileData = getOrCreatePreProcessedData(event.pid, event.id);\n profileData.rawProfile.startTime = event.ts;\n profileData.threadId = event.tid;\n return;\n }\n if (Types.TraceEvents.isTraceEventProfileChunk(event)) {\n const profileData = getOrCreatePreProcessedData(event.pid, event.id);\n const cdpProfile = profileData.rawProfile;\n const nodesAndSamples: Types.TraceEvents.TraceEventPartialProfile|undefined =\n event.args?.data?.cpuProfile || {samples: []};\n const samples = nodesAndSamples?.samples || [];\n const nodes: CPUProfile.CPUProfileDataModel.ExtendedProfileNode[] = [];\n for (const n of nodesAndSamples?.nodes || []) {\n const lineNumber = n.callFrame.lineNumber || -1;\n const columnNumber = n.callFrame.columnNumber || -1;\n const scriptId = String(n.callFrame.scriptId) as Protocol.Runtime.ScriptId;\n const url = n.callFrame.url || '';\n const node = {\n ...n,\n callFrame: {\n ...n.callFrame,\n url,\n lineNumber,\n columnNumber,\n scriptId,\n },\n };\n nodes.push(node);\n }\n\n const timeDeltas = event.args.data?.timeDeltas || [];\n const lines = event.args.data?.lines || Array(samples.length).fill(0);\n cdpProfile.nodes.push(...nodes);\n cdpProfile.samples?.push(...samples);\n cdpProfile.timeDeltas?.push(...timeDeltas);\n cdpProfile.lines?.push(...lines);\n if (cdpProfile.samples && cdpProfile.timeDeltas && cdpProfile.samples.length !== cdpProfile.timeDeltas.length) {\n console.error('Failed to parse CPU profile.');\n return;\n }\n if (!cdpProfile.endTime && cdpProfile.timeDeltas) {\n const timeDeltas: number[] = cdpProfile.timeDeltas;\n cdpProfile.endTime = timeDeltas.reduce((x, y) => x + y, cdpProfile.startTime);\n }\n return;\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Samples Handler is not initialized');\n }\n buildProfileCalls();\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): SamplesHandlerData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Samples Handler is not finalized');\n }\n\n return {\n profilesInProcess: new Map(profilesInProcess),\n };\n}\n\nfunction getOrCreatePreProcessedData(\n processId: Types.TraceEvents.ProcessID, profileId: Types.TraceEvents.ProfileID): PreprocessedData {\n const profileById = Platform.MapUtilities.getWithDefault(preprocessedData, processId, () => new Map());\n return Platform.MapUtilities.getWithDefault<Types.TraceEvents.ProfileID, PreprocessedData>(\n profileById, profileId, () => ({\n rawProfile: {\n startTime: 0,\n endTime: 0,\n nodes: [],\n samples: [],\n timeDeltas: [],\n lines: [],\n },\n profileId,\n }));\n}\n\nexport interface SamplesHandlerData {\n profilesInProcess: typeof profilesInProcess;\n}\n\nexport type ProfileData = {\n rawProfile: CPUProfile.CPUProfileDataModel.ExtendedProfile,\n parsedProfile: CPUProfile.CPUProfileDataModel.CPUProfileDataModel,\n profileCalls: Types.TraceEvents.TraceEventSyntheticProfileCall[],\n};\n\ntype PreprocessedData = {\n rawProfile: CPUProfile.CPUProfileDataModel.ExtendedProfile,\n threadId?: Types.TraceEvents.ThreadID, profileId: Types.TraceEvents.ProfileID,\n};\n", "// Copyright 2014 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../core/platform/platform.js';\nimport type * as Protocol from '../../generated/protocol.js';\n\nimport {ProfileNode, ProfileTreeModel} from './ProfileTreeModel.js';\n\nexport class CPUProfileNode extends ProfileNode {\n override id: number;\n override self: number;\n // Position ticks are available in profile nodes coming from CDP\n // profiles and not in those coming from tracing. They are used to\n // calculate the line level execution time shown in the Sources panel\n // after recording a profile. For trace CPU profiles we use the\n // `lines` array instead.\n positionTicks: Protocol.Profiler.PositionTickInfo[]|undefined;\n override deoptReason: string|null;\n\n constructor(node: Protocol.Profiler.ProfileNode, samplingInterval: number /* milliseconds */) {\n const callFrame = node.callFrame || ({\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n functionName: node['functionName'],\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n scriptId: node['scriptId'],\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n url: node['url'],\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n lineNumber: node['lineNumber'] - 1,\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // @ts-expect-error\n columnNumber: node['columnNumber'] - 1,\n } as Protocol.Runtime.CallFrame);\n super(callFrame);\n this.id = node.id;\n this.self = (node.hitCount || 0) * samplingInterval;\n this.positionTicks = node.positionTicks;\n // Compatibility: legacy backends could provide \"no reason\" for optimized functions.\n this.deoptReason = node.deoptReason && node.deoptReason !== 'no reason' ? node.deoptReason : null;\n }\n}\n\nexport class CPUProfileDataModel extends ProfileTreeModel {\n profileStartTime: number /* milliseconds */;\n profileEndTime: number /* milliseconds */;\n timestamps: number[];\n samples: number[]|undefined;\n lines?: number[];\n totalHitCount: number;\n profileHead: CPUProfileNode;\n /**\n * A cache for the nodes we have parsed.\n * Note: \"Parsed\" nodes are different from the \"Protocol\" nodes, the\n * latter being the raw data we receive from the backend.\n */\n #idToParsedNode!: Map<number, ProfileNode>;\n gcNode?: ProfileNode;\n programNode?: ProfileNode;\n idleNode?: ProfileNode;\n #stackStartTimes?: number[];\n #stackChildrenDuration?: number[];\n constructor(profile: ExtendedProfile) {\n super();\n // @ts-ignore Legacy types\n const isLegacyFormat = Boolean(profile['head']);\n if (isLegacyFormat) {\n // Legacy format contains raw timestamps and start/stop times are in seconds.\n this.profileStartTime = profile.startTime * 1000;\n this.profileEndTime = profile.endTime * 1000;\n // @ts-ignore Legacy types\n this.timestamps = profile.timestamps;\n this.compatibilityConversionHeadToNodes(profile);\n } else {\n // Current format encodes timestamps as deltas. Start/stop times are in microseconds.\n this.profileStartTime = profile.startTime / 1000;\n this.profileEndTime = profile.endTime / 1000;\n this.timestamps = this.convertTimeDeltas(profile);\n }\n this.samples = profile.samples;\n\n // Lines are available only in profiles coming from tracing.\n // Elements in the lines array have a 1 to 1 correspondance with\n // samples, by array position. They can be 1 or 0 and indicate if\n // there is line data for a given sample, i.e. if a given sample\n // needs to be included to calculate the line level execution time\n // data, which we show in the sources panel after recording a\n // profile.\n this.lines = profile.lines;\n this.totalHitCount = 0;\n this.profileHead = this.translateProfileTree(profile.nodes);\n this.initialize(this.profileHead);\n this.extractMetaNodes();\n if (this.samples) {\n this.sortSamples();\n this.normalizeTimestamps();\n this.fixMissingSamples();\n }\n }\n\n private compatibilityConversionHeadToNodes(profile: Protocol.Profiler.Profile): void {\n // @ts-ignore Legacy types\n if (!profile.head || profile.nodes) {\n return;\n }\n const nodes: Protocol.Profiler.ProfileNode[] = [];\n // @ts-ignore Legacy types\n convertNodesTree(profile.head);\n profile.nodes = nodes;\n // @ts-ignore Legacy types\n delete profile.head;\n function convertNodesTree(node: Protocol.Profiler.ProfileNode): number {\n nodes.push(node);\n // @ts-ignore Legacy types\n node.children = (node.children as Protocol.Profiler.ProfileNode[]).map(convertNodesTree);\n return node.id;\n }\n }\n\n /**\n * Calculate timestamps using timeDeltas. Some CPU profile formats,\n * like the ones contained in traces have timeDeltas instead of\n * timestamps.\n */\n private convertTimeDeltas(profile: Protocol.Profiler.Profile): number[] {\n if (!profile.timeDeltas) {\n return [];\n }\n let lastTimeMicroSec = profile.startTime;\n const timestamps = new Array(profile.timeDeltas.length);\n for (let i = 0; i < profile.timeDeltas.length; ++i) {\n lastTimeMicroSec += profile.timeDeltas[i];\n timestamps[i] = lastTimeMicroSec;\n }\n return timestamps;\n }\n\n /**\n * Creates a Tree of CPUProfileNodes using the Protocol.Profiler.ProfileNodes.\n * As the tree is built, samples of native code (prefixed with \"native \") are\n * filtered out. Samples of filtered nodes are replaced with the parent of the\n * node being filtered.\n *\n * This function supports legacy and new definitions of the CDP Profiler.Profile\n * type.\n */\n private translateProfileTree(nodes: Protocol.Profiler.ProfileNode[]): CPUProfileNode {\n function isNativeNode(node: Protocol.Profiler.ProfileNode): boolean {\n if (node.callFrame) {\n return Boolean(node.callFrame.url) && node.callFrame.url.startsWith('native ');\n }\n // @ts-ignore Legacy types\n return Boolean(node['url']) && node['url'].startsWith('native ');\n }\n\n function buildChildrenFromParents(nodes: Protocol.Profiler.ProfileNode[]): void {\n if (nodes[0].children) {\n return;\n }\n nodes[0].children = [];\n for (let i = 1; i < nodes.length; ++i) {\n const node = nodes[i];\n // @ts-ignore Legacy types\n const parentNode = protocolNodeById.get(node.parent);\n // @ts-ignore Legacy types\n if (parentNode.children) {\n // @ts-ignore Legacy types\n parentNode.children.push(node.id);\n } else {\n // @ts-ignore Legacy types\n parentNode.children = [node.id];\n }\n }\n }\n\n /**\n * Calculate how many times each node was sampled in the profile, if\n * not available in the profile data.\n */\n function buildHitCountFromSamples(nodes: Protocol.Profiler.ProfileNode[], samples: number[]|undefined): void {\n // If hit count is available, this profile has the new format, so\n // no need to continue.`\n if (typeof (nodes[0].hitCount) === 'number') {\n return;\n }\n if (!samples) {\n throw new Error('Error: Neither hitCount nor samples are present in profile.');\n }\n for (let i = 0; i < nodes.length; ++i) {\n nodes[i].hitCount = 0;\n }\n for (let i = 0; i < samples.length; ++i) {\n const node = protocolNodeById.get(samples[i]);\n if (!node || node.hitCount === undefined) {\n continue;\n }\n node.hitCount++;\n }\n }\n\n // A cache for the raw nodes received from the traces / CDP.\n const protocolNodeById = new Map<number, Protocol.Profiler.ProfileNode>();\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n protocolNodeById.set(node.id, node);\n }\n\n buildHitCountFromSamples(nodes, this.samples);\n buildChildrenFromParents(nodes);\n this.totalHitCount = nodes.reduce((acc, node) => acc + (node.hitCount || 0), 0);\n const sampleTime = (this.profileEndTime - this.profileStartTime) / this.totalHitCount;\n const keepNatives = true;\n const root = nodes[0];\n // If a node is filtered out, its samples are replaced with its parent,\n // so we keep track of the which id to use in the samples data.\n const idToUseForRemovedNode = new Map<number, number>([[root.id, root.id]]);\n this.#idToParsedNode = new Map();\n\n const resultRoot = new CPUProfileNode(root, sampleTime);\n this.#idToParsedNode.set(root.id, resultRoot);\n if (!root.children) {\n throw new Error('Missing children for root');\n }\n const parentNodeStack = root.children.map(() => resultRoot);\n const sourceNodeStack = root.children.map(id => protocolNodeById.get(id));\n while (sourceNodeStack.length) {\n let parentNode = parentNodeStack.pop();\n const sourceNode = sourceNodeStack.pop();\n if (!sourceNode || !parentNode) {\n continue;\n }\n if (!sourceNode.children) {\n sourceNode.children = [];\n }\n const targetNode = new CPUProfileNode(sourceNode, sampleTime);\n if (keepNatives || !isNativeNode(sourceNode)) {\n parentNode.children.push(targetNode);\n parentNode = targetNode;\n } else {\n parentNode.self += targetNode.self;\n }\n\n idToUseForRemovedNode.set(sourceNode.id, parentNode.id);\n parentNodeStack.push.apply(parentNodeStack, sourceNode.children.map(() => parentNode as CPUProfileNode));\n sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children.map(id => protocolNodeById.get(id)));\n this.#idToParsedNode.set(sourceNode.id, targetNode);\n }\n if (this.samples) {\n this.samples = this.samples.map(id => idToUseForRemovedNode.get(id) as number);\n }\n return resultRoot;\n }\n\n /**\n * Sorts the samples array using the timestamps array (there is a one\n * to one matching by index between the two).\n */\n private sortSamples(): void {\n if (!this.timestamps || !this.samples) {\n return;\n }\n\n const timestamps = this.timestamps;\n const samples = this.samples;\n const orderedIndices = timestamps.map((_x, index) => index);\n orderedIndices.sort((a, b) => timestamps[a] - timestamps[b]);\n\n this.timestamps = [];\n this.samples = [];\n\n for (let i = 0; i < orderedIndices.length; i++) {\n const orderedIndex = orderedIndices[i];\n this.timestamps.push(timestamps[orderedIndex]);\n this.samples.push(samples[orderedIndex]);\n }\n }\n\n /**\n * Fills in timestamps and/or time deltas from legacy profiles where\n * they could be missing.\n */\n private normalizeTimestamps(): void {\n if (!this.samples) {\n return;\n }\n let timestamps: number[] = this.timestamps;\n if (!timestamps) {\n // Support loading CPU profiles that are missing timestamps and\n // timedeltas\n const profileStartTime = this.profileStartTime;\n const interval = (this.profileEndTime - profileStartTime) / this.samples.length;\n // Add an extra timestamp used to calculate the last sample duration.\n timestamps = new Array(this.samples.length + 1);\n for (let i = 0; i < timestamps.length; ++i) {\n timestamps[i] = profileStartTime + i * interval;\n }\n this.timestamps = timestamps;\n return;\n }\n\n // Convert samples from micro to milliseconds\n for (let i = 0; i < timestamps.length; ++i) {\n timestamps[i] /= 1000;\n }\n if (this.samples.length === timestamps.length) {\n // Add an extra timestamp used to calculate the last sample duration.\n const lastTimestamp = timestamps.at(-1) || 0;\n const averageIntervalTime = (lastTimestamp - timestamps[0]) / (timestamps.length - 1);\n this.timestamps.push(lastTimestamp + averageIntervalTime);\n }\n this.profileStartTime = timestamps.at(0) || this.profileStartTime;\n this.profileEndTime = timestamps.at(-1) || this.profileEndTime;\n }\n\n /**\n * Some nodes do not refer to JS samples but to V8 system tasks, AKA\n * \"meta\" nodes. This function extracts those nodes from the profile.\n */\n private extractMetaNodes(): void {\n const topLevelNodes = this.profileHead.children;\n for (let i = 0; i < topLevelNodes.length && !(this.gcNode && this.programNode && this.idleNode); i++) {\n const node = topLevelNodes[i];\n if (node.functionName === '(garbage collector)') {\n this.gcNode = node;\n } else if (node.functionName === '(program)') {\n this.programNode = node;\n } else if (node.functionName === '(idle)') {\n this.idleNode = node;\n }\n }\n }\n\n private fixMissingSamples(): void {\n // Sometimes the V8 sampler is not able to parse the JS stack and returns\n // a (program) sample instead. The issue leads to call frames being split\n // apart when they shouldn't.\n // Here's a workaround for that. When there's a single (program) sample\n // between two call stacks sharing the same bottom node, it is replaced\n // with the preceeding sample.\n const samples = this.samples;\n if (!samples) {\n return;\n }\n const samplesCount = samples.length;\n if (!this.programNode || samplesCount < 3) {\n return;\n }\n const idToNode = this.#idToParsedNode;\n const programNodeId = this.programNode.id;\n const gcNodeId = this.gcNode ? this.gcNode.id : -1;\n const idleNodeId = this.idleNode ? this.idleNode.id : -1;\n let prevNodeId: number = samples[0];\n let nodeId: number = samples[1];\n for (let sampleIndex = 1; sampleIndex < samplesCount - 1; sampleIndex++) {\n const nextNodeId = samples[sampleIndex + 1];\n const prevNode = idToNode.get(prevNodeId);\n const nextNode = idToNode.get(nextNodeId);\n if (prevNodeId === undefined || nextNodeId === undefined || !prevNode || !nextNode) {\n console.error(`Unexpectedly found undefined nodes: ${prevNodeId} ${nextNodeId}`);\n continue;\n }\n if (nodeId === programNodeId && !isSystemNode(prevNodeId) && !isSystemNode(nextNodeId) &&\n bottomNode(prevNode) === bottomNode(nextNode)) {\n samples[sampleIndex] = prevNodeId;\n }\n prevNodeId = nodeId;\n nodeId = nextNodeId;\n }\n function bottomNode(node: ProfileNode): ProfileNode {\n while (node.parent && node.parent.parent) {\n node = node.parent;\n }\n return node;\n }\n function isSystemNode(nodeId: number): boolean {\n return nodeId === programNodeId || nodeId === gcNodeId || nodeId === idleNodeId;\n }\n }\n\n /**\n * Traverses the call tree derived from the samples calling back when a call is opened\n * and when it's closed\n */\n forEachFrame(\n openFrameCallback: (depth: number, node: ProfileNode, timestamp: number) => void,\n closeFrameCallback: (depth: number, node: ProfileNode, timestamp: number, dur: number, selfTime: number) => void,\n startTime?: number, stopTime?: number): void {\n if (!this.profileHead || !this.samples) {\n return;\n }\n\n startTime = startTime || 0;\n stopTime = stopTime || Infinity;\n const samples = this.samples;\n const timestamps = this.timestamps;\n const idToNode = this.#idToParsedNode;\n const gcNode = this.gcNode;\n const samplesCount = samples.length;\n const startIndex =\n Platform.ArrayUtilities.lowerBound(timestamps, startTime, Platform.ArrayUtilities.DEFAULT_COMPARATOR);\n let stackTop = 0;\n const stackNodes: ProfileNode[] = [];\n let prevId: number = this.profileHead.id;\n let sampleTime;\n let gcParentNode: ProfileNode|null = null;\n\n // Extra slots for gc being put on top,\n // and one at the bottom to allow safe stackTop-1 access.\n const stackDepth = this.maxDepth + 3;\n if (!this.#stackStartTimes) {\n this.#stackStartTimes = new Array(stackDepth);\n }\n const stackStartTimes = this.#stackStartTimes;\n if (!this.#stackChildrenDuration) {\n this.#stackChildrenDuration = new Array(stackDepth);\n }\n const stackChildrenDuration = this.#stackChildrenDuration;\n\n let node;\n let sampleIndex;\n for (sampleIndex = startIndex; sampleIndex < samplesCount; sampleIndex++) {\n sampleTime = timestamps[sampleIndex];\n if (sampleTime >= stopTime) {\n break;\n }\n const id = samples[sampleIndex];\n if (id === prevId) {\n continue;\n }\n node = idToNode.get(id);\n let prevNode: ProfileNode|null = idToNode.get(prevId) || null;\n if (!prevNode) {\n continue;\n }\n\n if (gcNode && node === gcNode) {\n // GC samples have no stack, so we just put GC node on top of the last recorded sample.\n gcParentNode = prevNode;\n openFrameCallback(gcParentNode.depth + 1, gcNode, sampleTime);\n stackStartTimes[++stackTop] = sampleTime;\n stackChildrenDuration[stackTop] = 0;\n prevId = id;\n continue;\n }\n if (gcNode && prevNode === gcNode && gcParentNode) {\n // end of GC frame\n const start = stackStartTimes[stackTop];\n const duration = sampleTime - start;\n stackChildrenDuration[stackTop - 1] += duration;\n closeFrameCallback(gcParentNode.depth + 1, gcNode, start, duration, duration - stackChildrenDuration[stackTop]);\n --stackTop;\n prevNode = gcParentNode;\n prevId = prevNode.id;\n gcParentNode = null;\n }\n\n // If the depth of this node is greater than the depth of the\n // previous one, new calls happened in between and we need to open\n // them, so track all of them in stackNodes.\n while (node && node.depth > prevNode.depth) {\n stackNodes.push(node);\n node = node.parent;\n }\n\n // If `prevNode` differs from `node`, the current sample was taken\n // after a change in the call stack, meaning that frames in the\n // path of `prevNode` that differ from those in the path of `node`\n // can be closed. So go down to the lowest common ancestor and\n // close current intervals.\n //\n // For example:\n //\n // prevNode node\n // | |\n // v v\n // [---D--]\n // [---C--][--E--]\n // [------B------] <- LCA\n // [------A------]\n //\n // Because a sample was taken with A, B and E in the stack, it\n // means C and D finished and we can close them.\n while (prevNode && prevNode !== node) {\n const start = stackStartTimes[stackTop];\n const duration = sampleTime - start;\n stackChildrenDuration[stackTop - 1] += duration;\n closeFrameCallback(prevNode.depth, prevNode, start, duration, duration - stackChildrenDuration[stackTop]);\n --stackTop;\n // Track calls to open after previous calls were closed\n // In the example above, this would add E to the tracking stack.\n if (node && node.depth === prevNode.depth) {\n stackNodes.push(node);\n node = node.parent;\n }\n prevNode = prevNode.parent;\n }\n\n // Go up the nodes stack and open new intervals.\n while (stackNodes.length) {\n const currentNode = stackNodes.pop();\n if (!currentNode) {\n break;\n }\n node = currentNode;\n openFrameCallback(currentNode.depth, currentNode, sampleTime);\n stackStartTimes[++stackTop] = sampleTime;\n stackChildrenDuration[stackTop] = 0;\n }\n\n prevId = id;\n }\n\n // Close remaining intervals.\n sampleTime = timestamps[sampleIndex] || this.profileEndTime;\n if (node && gcParentNode && idToNode.get(prevId) === gcNode) {\n const start = stackStartTimes[stackTop];\n const duration = sampleTime - start;\n stackChildrenDuration[stackTop - 1] += duration;\n closeFrameCallback(gcParentNode.depth + 1, node, start, duration, duration - stackChildrenDuration[stackTop]);\n --stackTop;\n prevId = gcParentNode.id;\n }\n for (let node = idToNode.get(prevId); node && node.parent; node = node.parent) {\n const start = stackStartTimes[stackTop];\n const duration = sampleTime - start;\n stackChildrenDuration[stackTop - 1] += duration;\n closeFrameCallback(node.depth, node, start, duration, duration - stackChildrenDuration[stackTop]);\n --stackTop;\n }\n }\n /**\n * Returns the node that corresponds to a given index of a sample.\n */\n nodeByIndex(index: number): ProfileNode|null {\n return this.samples && this.#idToParsedNode.get(this.samples[index]) || null;\n }\n /**\n * Returns the node that corresponds to a given node id.\n */\n nodeById(nodeId: number): ProfileNode|null {\n return this.#idToParsedNode.get(nodeId) || null;\n }\n\n nodes(): ProfileNode[]|null {\n if (!this.#idToParsedNode) {\n return null;\n }\n return [...this.#idToParsedNode.values()];\n }\n}\n\n// Format used by profiles coming from traces.\nexport type ExtendedProfileNode = Protocol.Profiler.ProfileNode&{parent?: number};\nexport type ExtendedProfile =\n Protocol.Profiler.Profile&{nodes: Protocol.Profiler.ProfileNode[] | ExtendedProfileNode[], lines?: number[]};\n", "// Copyright 2016 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Protocol from '../../generated/protocol.js';\nimport type * as Platform from '../../core/platform/platform.js';\n\nexport class ProfileNode {\n callFrame: Protocol.Runtime.CallFrame;\n callUID: string;\n self: number;\n total: number;\n id: number;\n parent: ProfileNode|null;\n children: ProfileNode[];\n functionName: string;\n depth!: number;\n deoptReason!: string|null;\n constructor(callFrame: Protocol.Runtime.CallFrame) {\n this.callFrame = callFrame;\n this.callUID = `${callFrame.functionName}@${callFrame.scriptId}:${callFrame.lineNumber}:${callFrame.columnNumber}`;\n this.self = 0;\n this.total = 0;\n this.id = 0;\n this.functionName = callFrame.functionName;\n this.parent = null;\n this.children = [];\n }\n\n get scriptId(): Protocol.Runtime.ScriptId {\n return String(this.callFrame.scriptId) as Protocol.Runtime.ScriptId;\n }\n\n get url(): Platform.DevToolsPath.UrlString {\n return this.callFrame.url as Platform.DevToolsPath.UrlString;\n }\n\n get lineNumber(): number {\n return this.callFrame.lineNumber;\n }\n\n get columnNumber(): number {\n return this.callFrame.columnNumber;\n }\n\n setFunctionName(name: string|null): void {\n if (name === null) {\n return;\n }\n this.functionName = name;\n }\n}\n\nexport class ProfileTreeModel {\n root!: ProfileNode;\n total!: number;\n maxDepth!: number;\n constructor() {\n }\n\n initialize(root: ProfileNode): void {\n this.root = root;\n this.assignDepthsAndParents();\n this.total = this.calculateTotals(this.root);\n }\n\n private assignDepthsAndParents(): void {\n const root = this.root;\n // TODO(crbug.com/1354548): start depth from 0 once profiler\n // panel dependencies are gone.\n root.depth = -1;\n root.parent = null;\n this.maxDepth = 0;\n const nodesToTraverse = [root];\n while (nodesToTraverse.length) {\n const parent = (nodesToTraverse.pop() as ProfileNode);\n const depth = parent.depth + 1;\n if (depth > this.maxDepth) {\n this.maxDepth = depth;\n }\n const children = parent.children;\n for (const child of children) {\n child.depth = depth;\n child.parent = parent;\n nodesToTraverse.push(child);\n }\n }\n }\n\n private calculateTotals(root: ProfileNode): number {\n const nodesToTraverse = [root];\n const dfsList = [];\n while (nodesToTraverse.length) {\n const node = (nodesToTraverse.pop() as ProfileNode);\n node.total = node.self;\n dfsList.push(node);\n nodesToTraverse.push(...node.children);\n }\n while (dfsList.length > 1) {\n const node = (dfsList.pop() as ProfileNode);\n if (node.parent) {\n node.parent.total += node.total;\n }\n }\n return root.total;\n }\n}\n", "// Copyright 2014 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n//\n// This is what was SDK.TracingModel moved into models/trace to avoid circular dependency issues. Our ultimate goal is to remove this model entirely once the migration to the new model is done\n\n\n\nimport * as Helpers from './helpers/helpers.js';\nimport {type EventPayload} from './TracingManager.js';\nimport * as Types from './types/types.js';\n\ntype IgnoreListArgs = {\n [key: string]: string|number|ObjectSnapshot,\n};\n\nexport class TracingModel {\n readonly #title: string|undefined;\n readonly #processById: Map<string|number, Process>;\n readonly #processByName: Map<string, Process>;\n #minimumRecordTimeInternal: number;\n #maximumRecordTimeInternal: number;\n readonly #devToolsMetadataEventsInternal: Event[];\n #asyncEvents: AsyncEvent[];\n readonly #openAsyncEvents: Map<string, AsyncEvent>;\n readonly #openNestableAsyncEvents: Map<string, AsyncEvent[]>;\n readonly #profileGroups: Map<string, ProfileEventsGroup>;\n readonly #parsedCategories: Map<string, Set<string>>;\n readonly #allEventsPayload: EventPayload[] = [];\n\n constructor(title?: string) {\n this.#title = title;\n this.#processById = new Map();\n this.#processByName = new Map();\n this.#minimumRecordTimeInternal = Number(Infinity);\n this.#maximumRecordTimeInternal = Number(-Infinity);\n this.#devToolsMetadataEventsInternal = [];\n this.#asyncEvents = [];\n this.#openAsyncEvents = new Map();\n this.#openNestableAsyncEvents = new Map();\n this.#profileGroups = new Map();\n this.#parsedCategories = new Map();\n }\n\n static isTopLevelEvent(event: CompatibleTraceEvent): boolean {\n return eventHasCategory(event, DevToolsTimelineEventCategory) && event.name === 'RunTask' ||\n eventHasCategory(event, LegacyTopLevelEventCategory) ||\n eventHasCategory(event, DevToolsMetadataEventCategory) &&\n event.name === 'Program'; // Older timelines may have this instead of toplevel.\n }\n\n static extractId(payload: EventPayload): string|undefined {\n const scope = payload.scope || '';\n if (typeof payload.id2 === 'undefined') {\n return scope && payload.id ? `${scope}@${payload.id}` : payload.id;\n }\n const id2 = payload.id2;\n if (typeof id2 === 'object' && ('global' in id2) !== ('local' in id2)) {\n return typeof id2['global'] !== 'undefined' ? `:${scope}:${id2['global']}` :\n `:${scope}:${payload.pid}:${id2['local']}`;\n }\n console.error(\n `Unexpected id2 field at ${payload.ts / 1000}, one and only one of 'local' and 'global' should be present.`);\n return undefined;\n }\n\n static browserMainThread(tracingModel: TracingModel): Thread|null {\n const processes = tracingModel.sortedProcesses();\n // Avoid warning for an empty #model.\n if (!processes.length) {\n return null;\n }\n const browserMainThreadName = 'CrBrowserMain';\n const browserProcesses = [];\n const browserMainThreads = [];\n for (const process of processes) {\n if (process.name().toLowerCase().endsWith('browser')) {\n browserProcesses.push(process);\n }\n browserMainThreads.push(...process.sortedThreads().filter(t => t.name() === browserMainThreadName));\n }\n if (browserMainThreads.length === 1) {\n return browserMainThreads[0];\n }\n if (browserProcesses.length === 1) {\n return browserProcesses[0].threadByName(browserMainThreadName);\n }\n const tracingStartedInBrowser =\n tracingModel.devToolsMetadataEvents().filter(e => e.name === 'TracingStartedInBrowser');\n if (tracingStartedInBrowser.length === 1) {\n return tracingStartedInBrowser[0].thread;\n }\n console.error(\n 'Failed to find browser main thread in trace, some timeline features may be unavailable');\n return null;\n }\n\n allRawEvents(): readonly EventPayload[] {\n return this.#allEventsPayload;\n }\n\n devToolsMetadataEvents(): Event[] {\n return this.#devToolsMetadataEventsInternal;\n }\n\n addEvents(events: readonly EventPayload[]): void {\n for (let i = 0; i < events.length; ++i) {\n this.addEvent(events[i]);\n }\n }\n\n tracingComplete(): void {\n this.processPendingAsyncEvents();\n for (const process of this.#processById.values()) {\n for (const thread of process.threads.values()) {\n thread.tracingComplete();\n }\n }\n }\n\n private addEvent(payload: EventPayload): void {\n this.#allEventsPayload.push(payload);\n let process = this.#processById.get(payload.pid);\n if (!process) {\n process = new Process(this, payload.pid);\n this.#processById.set(payload.pid, process);\n }\n\n const timestamp = payload.ts / 1000;\n // We do allow records for unrelated threads to arrive out-of-order,\n // so there's a chance we're getting records from the past.\n if (timestamp && timestamp < this.#minimumRecordTimeInternal &&\n eventPhasesOfInterestForTraceBounds.has(payload.ph as Types.TraceEvents.Phase) &&\n // UMA related events are ignored when calculating the minimumRecordTime because they might\n // be related to previous navigations that happened before the current trace started and\n // will currently not be displayed anyways.\n // See crbug.com/1201198\n (!payload.name.endsWith('::UMA'))) {\n this.#minimumRecordTimeInternal = timestamp;\n }\n\n if (payload.name === 'TracingStartedInBrowser') {\n // If we received a timestamp for tracing start, use that for minimumRecordTime.\n this.#minimumRecordTimeInternal = timestamp;\n }\n\n if (eventPhasesOfInterestForTraceBounds.has(payload.ph as Types.TraceEvents.Phase)) {\n const endTimeStamp = (payload.ts + (payload.dur || 0)) / 1000;\n this.#maximumRecordTimeInternal = Math.max(this.#maximumRecordTimeInternal, endTimeStamp);\n }\n const event = process.addEvent(payload);\n if (!event) {\n return;\n }\n if (payload.ph === Types.TraceEvents.Phase.SAMPLE) {\n this.addSampleEvent(event);\n return;\n }\n // Build async event when we've got events from all threads & processes, so we can sort them and process in the\n // chronological order. However, also add individual async events to the thread flow (above), so we can easily\n // display them on the same chart as other events, should we choose so.\n if (Types.TraceEvents.isAsyncPhase(payload.ph)) {\n this.#asyncEvents.push((event as AsyncEvent));\n }\n if (event.hasCategory(DevToolsMetadataEventCategory)) {\n this.#devToolsMetadataEventsInternal.push(event);\n }\n\n if (payload.ph !== Types.TraceEvents.Phase.METADATA) {\n return;\n }\n\n switch (payload.name) {\n case MetadataEvent.ProcessSortIndex: {\n process.setSortIndex(payload.args['sort_index']);\n break;\n }\n case MetadataEvent.ProcessName: {\n const processName = payload.args['name'];\n process.setName(processName);\n this.#processByName.set(processName, process);\n break;\n }\n case MetadataEvent.ThreadSortIndex: {\n process.threadById(payload.tid).setSortIndex(payload.args['sort_index']);\n break;\n }\n case MetadataEvent.ThreadName: {\n process.threadById(payload.tid).setName(payload.args['name']);\n break;\n }\n }\n }\n\n private addSampleEvent(event: Event): void {\n const id = `${event.thread.process().id()}:${event.id}`;\n const group = this.#profileGroups.get(id);\n if (group) {\n group.addChild(event);\n } else {\n this.#profileGroups.set(id, new ProfileEventsGroup(event));\n }\n }\n\n profileGroup(event: Event): ProfileEventsGroup|null {\n return this.#profileGroups.get(`${event.thread.process().id()}:${event.id}`) || null;\n }\n\n minimumRecordTime(): number {\n return this.#minimumRecordTimeInternal;\n }\n\n maximumRecordTime(): number {\n return this.#maximumRecordTimeInternal;\n }\n\n sortedProcesses(): Process[] {\n return NamedObject.sort([...this.#processById.values()]);\n }\n\n getProcessByName(name: string): Process|null {\n return this.#processByName.get(name) ?? null;\n }\n\n getProcessById(pid: number): Process|null {\n return this.#processById.get(pid) || null;\n }\n\n getThreadByName(processName: string, threadName: string): Thread|null {\n const process = this.getProcessByName(processName);\n return process && process.threadByName(threadName);\n }\n\n private processPendingAsyncEvents(): void {\n this.#asyncEvents.sort(Event.compareStartTime);\n for (let i = 0; i < this.#asyncEvents.length; ++i) {\n const event = this.#asyncEvents[i];\n if (Types.TraceEvents.isNestableAsyncPhase(event.phase)) {\n this.addNestableAsyncEvent(event);\n } else {\n this.addAsyncEvent(event);\n }\n }\n this.#asyncEvents = [];\n this.closeOpenAsyncEvents();\n }\n\n private closeOpenAsyncEvents(): void {\n for (const event of this.#openAsyncEvents.values()) {\n event.setEndTime(this.#maximumRecordTimeInternal);\n // FIXME: remove this once we figure a better way to convert async console\n // events to sync [waterfall] timeline records.\n event.steps[0].setEndTime(this.#maximumRecordTimeInternal);\n }\n this.#openAsyncEvents.clear();\n\n for (const eventStack of this.#openNestableAsyncEvents.values()) {\n while (eventStack.length) {\n const event = eventStack.pop();\n if (!event) {\n continue;\n }\n event.setEndTime(this.#maximumRecordTimeInternal);\n }\n }\n this.#openNestableAsyncEvents.clear();\n }\n\n private addNestableAsyncEvent(event: Event): void {\n const key = event.categoriesString + '.' + event.id;\n let openEventsStack = this.#openNestableAsyncEvents.get(key);\n\n switch (event.phase) {\n case Types.TraceEvents.Phase.ASYNC_NESTABLE_START: {\n if (!openEventsStack) {\n openEventsStack = [];\n this.#openNestableAsyncEvents.set(key, openEventsStack);\n }\n const asyncEvent = new AsyncEvent(event);\n openEventsStack.push(asyncEvent);\n event.thread.addAsyncEvent(asyncEvent);\n break;\n }\n\n case Types.TraceEvents.Phase.ASYNC_NESTABLE_INSTANT: {\n if (openEventsStack && openEventsStack.length) {\n const event = openEventsStack[openEventsStack.length - 1];\n if (event) {\n event.addStep(event);\n }\n }\n break;\n }\n\n case Types.TraceEvents.Phase.ASYNC_NESTABLE_END: {\n if (!openEventsStack || !openEventsStack.length) {\n break;\n }\n const top = openEventsStack.pop();\n if (!top) {\n break;\n }\n if (top.name !== event.name) {\n console.error(\n `Begin/end event mismatch for nestable async event, ${top.name} vs. ${event.name}, key: ${key}`);\n break;\n }\n top.addStep(event);\n }\n }\n }\n\n private addAsyncEvent(event: Event): void {\n const key = event.categoriesString + '.' + event.name + '.' + event.id;\n let asyncEvent = this.#openAsyncEvents.get(key);\n\n if (event.phase === Types.TraceEvents.Phase.ASYNC_BEGIN) {\n if (asyncEvent) {\n console.error(`Event ${event.name} has already been started`);\n return;\n }\n asyncEvent = new AsyncEvent(event);\n this.#openAsyncEvents.set(key, asyncEvent);\n event.thread.addAsyncEvent(asyncEvent);\n return;\n }\n if (!asyncEvent) {\n // Quietly ignore stray async events, we're probably too late for the start.\n return;\n }\n if (event.phase === Types.TraceEvents.Phase.ASYNC_END) {\n asyncEvent.addStep(event);\n this.#openAsyncEvents.delete(key);\n return;\n }\n if (event.phase === Types.TraceEvents.Phase.ASYNC_STEP_INTO ||\n event.phase === Types.TraceEvents.Phase.ASYNC_STEP_PAST) {\n const lastStep = asyncEvent.steps[asyncEvent.steps.length - 1];\n if (lastStep && lastStep.phase !== Types.TraceEvents.Phase.ASYNC_BEGIN && lastStep.phase !== event.phase) {\n console.assert(\n false,\n 'Async event step phase mismatch: ' + lastStep.phase + ' at ' + lastStep.startTime + ' vs. ' + event.phase +\n ' at ' + event.startTime);\n return;\n }\n asyncEvent.addStep(event);\n return;\n }\n console.assert(false, 'Invalid async event phase');\n }\n\n title(): string|undefined {\n return this.#title;\n }\n\n parsedCategoriesForString(str: string): Set<string> {\n let parsedCategories = this.#parsedCategories.get(str);\n if (!parsedCategories) {\n parsedCategories = new Set(str ? str.split(',') : []);\n this.#parsedCategories.set(str, parsedCategories);\n }\n return parsedCategories;\n }\n}\n\nexport const eventPhasesOfInterestForTraceBounds: Set<Types.TraceEvents.Phase> = new Set([\n Types.TraceEvents.Phase.BEGIN,\n Types.TraceEvents.Phase.END,\n Types.TraceEvents.Phase.COMPLETE,\n Types.TraceEvents.Phase.INSTANT,\n]);\n\nexport const MetadataEvent = {\n ProcessSortIndex: 'process_sort_index',\n ProcessName: 'process_name',\n ThreadSortIndex: 'thread_sort_index',\n ThreadName: 'thread_name',\n};\n\n// TODO(alph): LegacyTopLevelEventCategory is not recorded since M74 and used for loading\n// legacy profiles. Drop at some point.\nexport const LegacyTopLevelEventCategory = 'toplevel';\n\nexport const DevToolsMetadataEventCategory = 'disabled-by-default-devtools.timeline';\nexport const DevToolsTimelineEventCategory = 'disabled-by-default-devtools.timeline';\n\nexport function eventHasPayload(event: Event): event is PayloadEvent {\n return 'rawPayload' in event;\n}\n\nexport class Event {\n categoriesString: string;\n readonly #parsedCategories: Set<string>;\n name: string;\n phase: Types.TraceEvents.Phase;\n startTime: number;\n thread: Thread;\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any;\n id!: string|null;\n ordinal: number;\n selfTime: number;\n endTime?: number;\n duration?: number;\n\n // The constructor is protected so that we ensure that only classes or\n // subclasses can directly instantiate events. All other callers should\n // either create ConstructedEvent instances, which have a public constructor,\n // or use the static fromPayload method which can create an event instance\n // from the trace payload.\n protected constructor(\n categories: string|undefined, name: string, phase: Types.TraceEvents.Phase, startTime: number, thread: Thread) {\n this.categoriesString = categories || '';\n this.#parsedCategories = thread.getModel().parsedCategoriesForString(this.categoriesString);\n this.name = name;\n this.phase = phase;\n this.startTime = startTime;\n this.thread = thread;\n this.args = {};\n this.ordinal = 0;\n\n this.selfTime = 0;\n }\n\n static compareStartTime(a: Event|null, b: Event|null): number {\n if (!a || !b) {\n return 0;\n }\n\n return a.startTime - b.startTime;\n }\n\n static orderedCompareStartTime(a: Event, b: Event): number {\n // Array.mergeOrdered coalesces objects if comparator returns 0.\n // To change this behavior this comparator return -1 in the case events\n // startTime's are equal, so both events got placed into the result array.\n return a.startTime - b.startTime || a.ordinal - b.ordinal || -1;\n }\n\n hasCategory(categoryName: string): boolean {\n return this.#parsedCategories.has(categoryName);\n }\n\n setEndTime(endTime: number): void {\n if (endTime < this.startTime) {\n console.assert(false, 'Event out of order: ' + this.name);\n return;\n }\n this.endTime = endTime;\n this.duration = endTime - this.startTime;\n }\n\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n addArgs(args: any): void {\n // Shallow copy args to avoid modifying original #payload which may be saved to file.\n for (const name in args) {\n if (name in this.args) {\n console.error('Same argument name (' + name + ') is used for begin and end phases of ' + this.name);\n }\n\n (this.args as IgnoreListArgs)[name] = (args as IgnoreListArgs)[name];\n }\n }\n\n complete(endEvent: Event): void {\n if (endEvent.args) {\n this.addArgs(endEvent.args);\n } else {\n console.error('Missing mandatory event argument \\'args\\' at ' + endEvent.startTime);\n }\n this.setEndTime(endEvent.startTime);\n }\n}\n\n/**\n * Represents a tracing event that is not directly linked to an individual\n * object in the trace. We construct these events at times, particularly when\n * building up the CPU profile data for JS Profiling.\n **/\nexport class ConstructedEvent extends Event {\n // Because the constructor of Event is marked as protected, but we want\n // people to be able to create constructed events, we override the\n // constructor here, even though we are only calling super, in order to mark\n // it as public.\n constructor(\n categories: string|undefined, name: string, phase: Types.TraceEvents.Phase, startTime: number, thread: Thread) {\n super(categories, name, phase, startTime, thread);\n }\n}\n\n/**\n * Represents a tracing event that has been created directly from an object in\n * the trace file and therefore is guaranteed to have a payload associated with\n * it. The only way to create these events is to use the static fromPayload\n * method, which you must call with a payload.\n **/\nexport class PayloadEvent extends Event {\n #rawPayload: EventPayload;\n\n /**\n * Returns the raw payload that was used to create this event instance.\n **/\n rawLegacyPayload(): EventPayload {\n return this.#rawPayload;\n }\n\n /**\n * Returns the raw payload that was used to create this event instance, but\n * returns it typed as the new engine's TraceEventArgs option.\n **/\n rawPayload(): Types.TraceEvents.TraceEventData {\n return this.#rawPayload as unknown as Types.TraceEvents.TraceEventData;\n }\n\n protected constructor(\n categories: string|undefined, name: string, phase: Types.TraceEvents.Phase, startTime: number, thread: Thread,\n rawPayload: EventPayload) {\n super(categories, name, phase, startTime, thread);\n this.#rawPayload = rawPayload;\n }\n\n static fromPayload(payload: EventPayload, thread: Thread): PayloadEvent {\n const event = new PayloadEvent(payload.cat, payload.name, payload.ph, payload.ts / 1000, thread, payload);\n event.#rawPayload = payload;\n if (payload.args) {\n event.addArgs(payload.args);\n }\n if (typeof payload.dur === 'number') {\n event.setEndTime((payload.ts + payload.dur) / 1000);\n }\n const id = TracingModel.extractId(payload);\n if (typeof id !== 'undefined') {\n event.id = id;\n }\n\n return event;\n }\n}\n\nexport class ObjectSnapshot extends PayloadEvent {\n private constructor(\n category: string|undefined, name: string, startTime: number, thread: Thread, rawPayload: EventPayload) {\n super(category, name, Types.TraceEvents.Phase.OBJECT_SNAPSHOT, startTime, thread, rawPayload);\n }\n\n static override fromPayload(payload: EventPayload, thread: Thread): ObjectSnapshot {\n const snapshot = new ObjectSnapshot(payload.cat, payload.name, payload.ts / 1000, thread, payload);\n const id = TracingModel.extractId(payload);\n if (typeof id !== 'undefined') {\n snapshot.id = id;\n }\n if (!payload.args || !payload.args['snapshot']) {\n console.error('Missing mandatory \\'snapshot\\' argument at ' + payload.ts / 1000);\n return snapshot;\n }\n if (payload.args) {\n snapshot.addArgs(payload.args);\n }\n return snapshot;\n }\n\n getSnapshot(): ObjectSnapshot {\n const snapshot = this.args['snapshot'];\n if (!snapshot) {\n throw new Error('ObjectSnapshot has no snapshot argument.');\n }\n return snapshot;\n }\n}\n\nexport class AsyncEvent extends ConstructedEvent {\n steps: Event[];\n causedFrame: boolean;\n\n constructor(startEvent: Event) {\n super(startEvent.categoriesString, startEvent.name, startEvent.phase, startEvent.startTime, startEvent.thread);\n this.addArgs(startEvent.args);\n this.steps = [startEvent];\n this.causedFrame = false;\n }\n\n addStep(event: Event): void {\n this.steps.push(event);\n if (event.phase === Types.TraceEvents.Phase.ASYNC_END ||\n event.phase === Types.TraceEvents.Phase.ASYNC_NESTABLE_END) {\n this.setEndTime(event.startTime);\n // FIXME: ideally, we shouldn't do this, but this makes the logic of converting\n // async console events to sync ones much simpler.\n this.steps[0].setEndTime(event.startTime);\n }\n }\n}\n\nclass ProfileEventsGroup {\n children: Event[];\n constructor(event: Event) {\n this.children = [event];\n }\n\n addChild(event: Event): void {\n this.children.push(event);\n }\n}\n\nclass NamedObject {\n model: TracingModel;\n readonly idInternal: number;\n #nameInternal: string;\n #sortIndex: number;\n constructor(model: TracingModel, id: number) {\n this.model = model;\n this.idInternal = id;\n this.#nameInternal = '';\n this.#sortIndex = 0;\n }\n\n static sort<Item extends NamedObject>(array: Item[]): Item[] {\n return array.sort((a, b) => {\n return a.#sortIndex !== b.#sortIndex ? a.#sortIndex - b.#sortIndex : a.name().localeCompare(b.name());\n });\n }\n\n setName(name: string): void {\n this.#nameInternal = name;\n }\n\n name(): string {\n return this.#nameInternal;\n }\n\n id(): number {\n return this.idInternal;\n }\n\n setSortIndex(sortIndex: number): void {\n this.#sortIndex = sortIndex;\n }\n\n getModel(): TracingModel {\n return this.model;\n }\n}\n\nexport class Process extends NamedObject {\n readonly threads: Map<number, Thread>;\n readonly #threadByNameInternal: Map<string, Thread|null>;\n constructor(model: TracingModel, id: number) {\n super(model, id);\n this.threads = new Map();\n this.#threadByNameInternal = new Map();\n }\n\n threadById(id: number): Thread {\n let thread = this.threads.get(id);\n if (!thread) {\n thread = new Thread(this, id);\n this.threads.set(id, thread);\n }\n return thread;\n }\n\n threadByName(name: string): Thread|null {\n return this.#threadByNameInternal.get(name) || null;\n }\n\n setThreadByName(name: string, thread: Thread): void {\n this.#threadByNameInternal.set(name, thread);\n }\n\n addEvent(payload: EventPayload): Event|null {\n return this.threadById(payload.tid).addEvent(payload);\n }\n\n sortedThreads(): Thread[] {\n return NamedObject.sort([...this.threads.values()]);\n }\n}\n\nexport class Thread extends NamedObject {\n readonly #processInternal: Process;\n #eventsInternal: Event[];\n readonly #asyncEventsInternal: AsyncEvent[];\n #lastTopLevelEvent: Event|null;\n constructor(process: Process, id: number) {\n super(process.getModel(), id);\n this.#processInternal = process;\n\n this.#eventsInternal = [];\n this.#asyncEventsInternal = [];\n this.#lastTopLevelEvent = null;\n }\n\n /**\n * Whilst we are in the middle of migrating to the new Phase enum, we need to\n * be able to compare events with the legacy phase to the new enum. This method\n * does this by casting the event phase to a string, ensuring we can compare it\n * against either enum. Once the migration is complete (crbug.com/1417587), we\n * will be able to use === to compare with no TS errors and this method can be\n * removed.\n */\n #eventMatchesPhase(event: Event, phase: Types.TraceEvents.Phase): boolean {\n return (event.phase as string) === phase;\n }\n\n tracingComplete(): void {\n this.#asyncEventsInternal.sort(Event.compareStartTime);\n this.#eventsInternal.sort(Event.compareStartTime);\n const stack: Event[] = [];\n const toDelete = new Set<number>();\n for (let i = 0; i < this.#eventsInternal.length; ++i) {\n const e = this.#eventsInternal[i];\n e.ordinal = i;\n if (this.#eventMatchesPhase(e, Types.TraceEvents.Phase.END)) {\n toDelete.add(i); // Mark for removal.\n // Quietly ignore unbalanced close events, they're legit (we could have missed start one).\n if (!stack.length) {\n continue;\n }\n const top = stack.pop();\n if (!top) {\n continue;\n }\n if (top.name !== e.name || top.categoriesString !== e.categoriesString) {\n console.error(\n 'B/E events mismatch at ' + top.startTime + ' (' + top.name + ') vs. ' + e.startTime + ' (' + e.name +\n ')');\n } else {\n top.complete(e);\n }\n } else if (this.#eventMatchesPhase(e, Types.TraceEvents.Phase.BEGIN)) {\n stack.push(e);\n }\n }\n\n // Handle Begin events with no matching End.\n // This commonly happens due to a bug in the trace machinery. See crbug.com/982252\n while (stack.length) {\n const event = stack.pop();\n if (event) {\n // Masquerade the event as Instant, so it's rendered to the user.\n // The ideal fix is resolving crbug.com/1021571, but handling that without a perfetto migration appears prohibitive\n event.phase = Types.TraceEvents.Phase.INSTANT;\n }\n }\n this.#eventsInternal = this.#eventsInternal.filter((_, idx) => !toDelete.has(idx));\n }\n\n addEvent(payload: EventPayload): Event|null {\n const event = payload.ph === Types.TraceEvents.Phase.OBJECT_SNAPSHOT ? ObjectSnapshot.fromPayload(payload, this) :\n PayloadEvent.fromPayload(payload, this);\n if (TracingModel.isTopLevelEvent(event)) {\n // Discard nested \"top-level\" events.\n const lastTopLevelEvent = this.#lastTopLevelEvent;\n if (lastTopLevelEvent && (lastTopLevelEvent.endTime || 0) > event.startTime) {\n return null;\n }\n this.#lastTopLevelEvent = event;\n }\n this.#eventsInternal.push(event);\n return event;\n }\n\n addAsyncEvent(asyncEvent: AsyncEvent): void {\n this.#asyncEventsInternal.push(asyncEvent);\n }\n\n override setName(name: string): void {\n super.setName(name);\n this.#processInternal.setThreadByName(name, this);\n }\n\n process(): Process {\n return this.#processInternal;\n }\n\n events(): Event[] {\n return this.#eventsInternal;\n }\n\n asyncEvents(): AsyncEvent[] {\n return this.#asyncEventsInternal;\n }\n\n removeEventsByName(name: string): Event[] {\n const extracted: Event[] = [];\n this.#eventsInternal = this.#eventsInternal.filter(e => {\n if (!e) {\n return false;\n }\n\n if (e.name !== name) {\n return true;\n }\n\n extracted.push(e);\n return false;\n });\n\n return extracted;\n }\n}\n\nexport interface TimesForEventMs {\n startTime: Types.Timing.MilliSeconds;\n endTime?: Types.Timing.MilliSeconds;\n selfTime: Types.Timing.MilliSeconds;\n duration: Types.Timing.MilliSeconds;\n}\n\nexport function timesForEventInMilliseconds(event: Event|Types.TraceEvents.TraceEventData): TimesForEventMs {\n if (event instanceof Event) {\n return {\n startTime: Types.Timing.MilliSeconds(event.startTime),\n endTime: event.endTime ? Types.Timing.MilliSeconds(event.endTime) : undefined,\n duration: Types.Timing.MilliSeconds(event.duration || 0),\n selfTime: Types.Timing.MilliSeconds(event.selfTime),\n };\n }\n return Helpers.Timing.eventTimingsMilliSeconds(event);\n}\n// Parsed categories are cached to prevent calling cat.split() multiple\n// times on the same categories string.\nconst parsedCategories = new Map<string, Set<string>>();\nexport function eventHasCategory(event: CompatibleTraceEvent, category: string): boolean {\n if (event instanceof Event) {\n return event.hasCategory(category);\n }\n let parsedCategoriesForEvent = parsedCategories.get(event.cat);\n if (!parsedCategoriesForEvent) {\n parsedCategoriesForEvent = new Set(event.cat.split(',') || []);\n }\n return parsedCategoriesForEvent.has(category);\n}\n\nexport function phaseForEvent(event: Event|Types.TraceEvents.TraceEventData): Types.TraceEvents.Phase {\n if (event instanceof Event) {\n return event.phase;\n }\n return event.ph;\n}\n\nexport function threadIDForEvent(event: Event|Types.TraceEvents.TraceEventData): Types.TraceEvents.ThreadID {\n if (event instanceof Event) {\n return event.thread.idInternal as Types.TraceEvents.ThreadID;\n }\n return event.tid;\n}\n\nexport function eventIsFromNewEngine(event: CompatibleTraceEvent|null): event is Types.TraceEvents.TraceEventData {\n return event !== null && !(event instanceof Event);\n}\n\nexport type CompatibleTraceEvent = Event|Types.TraceEvents.TraceEventData;\n", "// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../core/platform/platform.js';\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport {TraceParseProgressEvent, TraceProcessor} from './Processor.js';\nimport * as Types from './types/types.js';\n\n// Note: this model is implemented in a way that can support multiple trace\n// processors. Currently there is only one implemented, but you will see\n// references to \"processors\" plural because it can easily be extended in the future.\n\nexport interface ParseConfig {\n metadata?: Types.File.MetaData;\n // Unused but will eventually be consumed by UIUtils Linkifier, etc.\n isFreshRecording?: boolean;\n}\n\n/**\n * The new trace engine model we are migrating to. The Model is responsible for\n * parsing arrays of raw trace events and storing the resulting data. It can\n * store multiple traces at once, and can return the data for any of them.\n * Currently as we migrate from the old engine to this, we are turning on the\n * model handlers incrementally as we need the data, to save performance costs\n * of running handlers that we do not use. Therefore, when the model is\n * constructed we pass through a set of handlers that should be used. Once we\n * have migrated all tracks in the Performance Panel to this model, we can\n * remove this ability to run a subset of handlers, as we will need all handlers\n * to be used at that point. For tests, if you want to construct a model with\n * all handlers, you can use the static `Model.createWithAllHandlers` method.\n **/\nexport class Model<EnabledModelHandlers extends {[key: string]: Handlers.Types.TraceEventHandler}> extends EventTarget {\n readonly #traces: ParsedTraceFile<EnabledModelHandlers>[] = [];\n readonly #nextNumberByDomain = new Map<string, number>();\n\n readonly #recordingsAvailable: string[] = [];\n #lastRecordingIndex = 0;\n #processor: TraceProcessor<Handlers.Types.HandlersWithMeta<EnabledModelHandlers>>;\n #config: Types.Configuration.Configuration = Types.Configuration.DEFAULT;\n\n static createWithAllHandlers(): Model<typeof Handlers.ModelHandlers> {\n return new Model(Handlers.ModelHandlers);\n }\n\n static createWithRequiredHandlersForMigration(config?: Types.Configuration.Configuration): Model<{\n [K in keyof typeof Handlers.Migration.ENABLED_TRACE_HANDLERS]: typeof Handlers.Migration.ENABLED_TRACE_HANDLERS[K];\n }> {\n return new Model(Handlers.Migration.ENABLED_TRACE_HANDLERS, config);\n }\n\n constructor(handlers: EnabledModelHandlers, config?: Types.Configuration.Configuration) {\n super();\n if (config) {\n this.#config = config;\n }\n this.#processor = new TraceProcessor(handlers, {/* Settings for how event processing is chunked */}, this.#config);\n }\n\n /**\n * Updates the configuration. Useful if a user changes a setting - this lets\n * us update the model without having to destroy it and recreate it with the\n * new settings.\n */\n updateConfiguration(config: Types.Configuration.Configuration): void {\n this.#config = config;\n this.#processor.updateConfiguration(config);\n }\n\n /**\n * Parses an array of trace events into a structured object containing all the\n * information parsed by the trace handlers.\n * You can `await` this function to pause execution until parsing is complete,\n * or instead rely on the `ModuleUpdateEvent` that is dispatched when the\n * parsing is finished.\n *\n * Once parsed, you then have to call the `traceParsedData` method, providing an\n * index of the trace you want to have the data for. This is because any model\n * can store a number of traces. Each trace is given an index, which starts at 0\n * and increments by one as a new trace is parsed.\n *\n * @example\n * // Awaiting the parse method() to block until parsing complete\n * await this.traceModel.parse(events);\n * const data = this.traceModel.traceParsedData(0)\n *\n * @example\n * // Using an event listener to be notified when tracing is complete.\n * this.traceModel.addEventListener(Trace.ModelUpdateEvent.eventName, (event) => {\n * if(event.data.data === 'done') {\n * // trace complete\n * const data = this.traceModel.traceParsedData(0);\n * }\n * });\n * void this.traceModel.parse(events);\n **/\n async parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], config?: ParseConfig): Promise<void> {\n const metadata = config?.metadata || {};\n const isFreshRecording = config?.isFreshRecording || false;\n // During parsing, periodically update any listeners on each processors'\n // progress (if they have any updates).\n const onTraceUpdate = (event: Event): void => {\n const {data} = event as TraceParseProgressEvent;\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.PROGRESS_UPDATE, data: data}));\n };\n\n this.#processor.addEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n\n // Create a parsed trace file. It will be populated with data from the processor.\n const file: ParsedTraceFile<EnabledModelHandlers> = {\n traceEvents,\n metadata,\n traceParsedData: null,\n };\n\n try {\n // Wait for all outstanding promises before finishing the async execution,\n // but perform all tasks in parallel.\n await this.#processor.parse(traceEvents, isFreshRecording);\n this.#storeParsedFileData(file, this.#processor.data);\n // We only push the file onto this.#traces here once we know it's valid\n // and there's been no errors in the parsing.\n this.#traces.push(file);\n } catch (e) {\n throw e;\n } finally {\n // All processors have finished parsing, no more updates are expected.\n this.#processor.removeEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n // Finally, update any listeners that all processors are 'done'.\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.COMPLETE, data: 'done'}));\n }\n }\n\n #storeParsedFileData(\n file: ParsedTraceFile<EnabledModelHandlers>,\n data: Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null): void {\n file.traceParsedData = data;\n this.#lastRecordingIndex++;\n let recordingName = `Trace ${this.#lastRecordingIndex}`;\n let origin: string|null = null;\n if (file.traceParsedData) {\n origin = Helpers.Trace.extractOriginFromTrace(file.traceParsedData.Meta.mainFrameURL);\n if (origin) {\n const nextSequenceForDomain = Platform.MapUtilities.getWithDefault(this.#nextNumberByDomain, origin, () => 1);\n recordingName = `${origin} (${nextSequenceForDomain})`;\n this.#nextNumberByDomain.set(origin, nextSequenceForDomain + 1);\n }\n }\n this.#recordingsAvailable.push(recordingName);\n }\n\n /**\n * Returns the parsed trace data indexed by the order in which it was stored.\n * If no index is given, the last stored parsed data is returned.\n */\n traceParsedData(index: number = this.#traces.length - 1):\n Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].traceParsedData;\n }\n\n metadata(index: number): Types.File.MetaData|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].metadata;\n }\n\n traceEvents(index: number): readonly Types.TraceEvents.TraceEventData[]|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].traceEvents;\n }\n\n size(): number {\n return this.#traces.length;\n }\n\n deleteTraceByIndex(recordingIndex: number): void {\n this.#traces.splice(recordingIndex, 1);\n this.#recordingsAvailable.splice(recordingIndex, 1);\n }\n\n getRecordingsAvailable(): string[] {\n return this.#recordingsAvailable;\n }\n\n resetProcessor(): void {\n this.#processor.reset();\n }\n}\n\n/**\n * This parsed trace file is used by the Model. It keeps multiple instances\n * of these so that the user can swap between them. The key is that it is\n * essentially the TraceFile plus whatever the model has parsed from it.\n */\nexport type ParsedTraceFile<Handlers extends {[key: string]: Handlers.Types.TraceEventHandler}> = Types.File.TraceFile&{\n traceParsedData: Handlers.Types.EnabledHandlerDataWithMeta<Handlers>| null,\n};\n\nexport const enum ModelUpdateType {\n COMPLETE = 'COMPLETE',\n PROGRESS_UPDATE = 'PROGRESS_UPDATE',\n}\n\nexport type ModelUpdateEventData = ModelUpdateEventComplete|ModelUpdateEventProgress;\n\nexport type ModelUpdateEventComplete = {\n type: ModelUpdateType.COMPLETE,\n data: 'done',\n};\nexport type ModelUpdateEventProgress = {\n type: ModelUpdateType.PROGRESS_UPDATE,\n data: TraceParseEventProgressData,\n};\n\nexport type TraceParseEventProgressData = {\n index: number,\n total: number,\n};\n\nexport class ModelUpdateEvent extends Event {\n static readonly eventName = 'modelupdate';\n constructor(public data: ModelUpdateEventData) {\n super(ModelUpdateEvent.eventName);\n }\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [ModelUpdateEvent.eventName]: ModelUpdateEvent;\n }\n}\n\nexport function isModelUpdateDataComplete(eventData: ModelUpdateEventData): eventData is ModelUpdateEventComplete {\n return eventData.type === ModelUpdateType.COMPLETE;\n}\n\nexport function isModelUpdateDataProgress(eventData: ModelUpdateEventData): eventData is ModelUpdateEventProgress {\n return eventData.type === ModelUpdateType.PROGRESS_UPDATE;\n}\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\nimport * as Handlers from './handlers/handlers.js';\nimport * as Types from './types/types.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport type TraceParseEventProgressData = {\n index: number,\n total: number,\n};\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport class TraceProcessor<EnabledModelHandlers extends {[key: string]: Handlers.Types.TraceEventHandler}> extends\n EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n readonly #traceHandlers: Handlers.Types.HandlersWithMeta<EnabledModelHandlers>;\n #pauseDuration: number;\n #eventsPerChunk: number;\n #status = Status.IDLE;\n #modelConfiguration = Types.Configuration.DEFAULT;\n\n static createWithAllHandlers(): TraceProcessor<typeof Handlers.ModelHandlers> {\n return new TraceProcessor(Handlers.ModelHandlers, {}, Types.Configuration.DEFAULT);\n }\n\n constructor(\n traceHandlers: EnabledModelHandlers, {pauseDuration = 1, eventsPerChunk = 15_000} = {},\n modelConfiguration?: Types.Configuration.Configuration) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n this.#pauseDuration = pauseDuration;\n this.#eventsPerChunk = eventsPerChunk;\n if (modelConfiguration) {\n this.#modelConfiguration = modelConfiguration;\n }\n this.#passConfigToHandlers();\n }\n\n updateConfiguration(config: Types.Configuration.Configuration): void {\n this.#modelConfiguration = config;\n this.#passConfigToHandlers();\n }\n\n #passConfigToHandlers(): void {\n for (const handler of Object.values(this.#traceHandlers)) {\n // Bit of an odd double check, but without this TypeScript refuses to let\n // you call the function as it thinks it might be undefined.\n if ('handleUserConfig' in handler && handler.handleUserConfig) {\n handler.handleUserConfig(this.#modelConfiguration);\n }\n }\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: EnabledModelHandlers): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys: Set<Handlers.Types.TraceEventHandlerName> = new Set();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.TraceEventHandlerName);\n for (const depName of (handler.deps?.() || [])) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], freshRecording = false): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n try {\n this.#status = Status.PARSING;\n await this.#parse(traceEvents, freshRecording);\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n }\n }\n\n async #parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], freshRecording: boolean): Promise<void> {\n // This iterator steps through all events, periodically yielding back to the\n // main thread to avoid blocking execution. It uses `dispatchEvent` to\n // provide status update events, and other various bits of config like the\n // pause duration and frequency.\n const traceEventIterator = new TraceEventIterator(traceEvents, this.#pauseDuration, this.#eventsPerChunk);\n\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];\n // Reset.\n for (const handler of sortedHandlers) {\n handler.reset();\n }\n\n // Initialize.\n for (const handler of sortedHandlers) {\n handler.initialize?.(freshRecording);\n }\n\n // Handle each event.\n for await (const item of traceEventIterator) {\n if (item.kind === IteratorItemType.STATUS_UPDATE) {\n this.dispatchEvent(new TraceParseProgressEvent(item.data));\n continue;\n }\n for (const handler of sortedHandlers) {\n handler.handleEvent(item.data);\n }\n }\n\n // Finalize.\n for (const handler of sortedHandlers) {\n await handler.finalize?.();\n }\n }\n\n get data(): Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n const data = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n Object.assign(data, {[name]: handler.data()});\n }\n\n return data as Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>;\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event hander whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(\n traceHandlers: Partial<{[key in Handlers.Types.TraceEventHandlerName]: Handlers.Types.TraceEventHandler}>):\n Map<Handlers.Types.TraceEventHandlerName, Handlers.Types.TraceEventHandler> {\n const sortedMap = new Map<Handlers.Types.TraceEventHandlerName, Handlers.Types.TraceEventHandler>();\n const visited = new Set<Handlers.Types.TraceEventHandlerName>();\n const visitHandler = (handlerName: Handlers.Types.TraceEventHandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.TraceEventHandlerName);\n }\n return sortedMap;\n}\n\nconst enum IteratorItemType {\n TRACE_EVENT = 1,\n STATUS_UPDATE = 2,\n}\n\ntype IteratorItem = IteratorTraceEventItem|IteratorStatusUpdateItem;\n\ntype IteratorTraceEventItem = {\n kind: IteratorItemType.TRACE_EVENT,\n data: Types.TraceEvents.TraceEventData,\n};\n\ntype IteratorStatusUpdateItem = {\n kind: IteratorItemType.STATUS_UPDATE,\n data: TraceParseEventProgressData,\n};\n\nclass TraceEventIterator {\n #eventCount: number;\n\n constructor(\n private traceEvents: readonly Types.TraceEvents.TraceEventData[], private pauseDuration: number,\n private eventsPerChunk: number) {\n this.#eventCount = 0;\n }\n\n async * [Symbol.asyncIterator](): AsyncGenerator<IteratorItem, void, void> {\n for (let i = 0, length = this.traceEvents.length; i < length; i++) {\n // Every so often we take a break just to render.\n if (++this.#eventCount % this.eventsPerChunk === 0) {\n // Take the opportunity to provide status update events.\n yield {kind: IteratorItemType.STATUS_UPDATE, data: {index: i, total: length}};\n // Wait for rendering before resuming.\n await new Promise(resolve => setTimeout(resolve, this.pauseDuration));\n }\n\n yield {kind: IteratorItemType.TRACE_EVENT, data: this.traceEvents[i]};\n }\n }\n}\n", "// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\nimport * as Platform from '../../core/platform/platform.js';\n\nimport type * as Handlers from './handlers/handlers.js';\nimport type * as Types from './types/types.js';\n\ntype EntryToNodeMap =\n Map<Handlers.ModelHandlers.Renderer.RendererEntry, Handlers.ModelHandlers.Renderer.RendererEntryNode>;\n\nexport interface UserTreeAction {\n type: 'MERGE_FUNCTION'|'COLLAPSE_FUNCTION';\n entry: Handlers.ModelHandlers.Renderer.RendererEntry;\n}\n\n/**\n * This class can take in a thread that has been generated by the\n * RendererHandler and apply certain actions to it in order to modify what is\n * shown to the user. These actions can be automatically applied by DevTools or\n * applied by the user.\n *\n * Once actions are applied, the visibleEntries() method will return only the\n * entries that are still visible, and this is the list of entries that can\n * then be used to render the resulting thread on the timeline.\n **/\nexport class TreeManipulator {\n readonly #thread: Handlers.ModelHandlers.Renderer.RendererThread;\n // Maps from an individual TraceEvent entry to its representation as a\n // RendererEntryNode. We need this so we can then parse the tree structure\n // generated by the RendererHandler.\n #entryToNode: EntryToNodeMap;\n\n // Track the last calculated set of visible entries. This means we can avoid\n // re-generating this if the set of actions that have been applied has not\n // changed.\n #lastVisibleEntries: readonly Handlers.ModelHandlers.Renderer.RendererEntry[]|null = null;\n #activeActions: UserTreeAction[] = [];\n\n constructor(\n thread: Handlers.ModelHandlers.Renderer.RendererThread,\n entryToNode: EntryToNodeMap,\n ) {\n this.#thread = thread;\n this.#entryToNode = entryToNode;\n }\n\n /**\n * Applies an action to the visible tree. This will also clear the cache of\n * visible entries, ensuring that it will be recalculated with the latest set\n * of actions.\n **/\n applyAction(action: UserTreeAction): void {\n if (this.#actionIsActive(action)) {\n // If the action is already active there is no reason to apply it again.\n return;\n }\n\n this.#activeActions.push(action);\n // Clear the last list of visible entries - this invalidates the cache and\n // ensures that the visible list will be recalculated, which we have to do\n // now we have changed the list of actions.\n this.#lastVisibleEntries = null;\n }\n\n /**\n * Removes a matching action, if one is found, from the active actions set.\n * Note that we do not match on action equality and instead search through\n * the set of active actions for one that is of the same type, and has the\n * same entry associated with it.\n *\n * This is a no-op if the action is not active.\n **/\n removeActiveAction(action: UserTreeAction): void {\n let removedAction = false;\n this.#activeActions = this.#activeActions.filter(activeAction => {\n if (activeAction.type === action.type && activeAction.entry === action.entry) {\n removedAction = true;\n return false;\n }\n return true;\n });\n\n if (removedAction) {\n // If we found and removed an action, we need to clear the cache to force\n // the set of visible entries to be recalculcated.\n this.#lastVisibleEntries = null;\n }\n }\n\n #actionIsActive(action: UserTreeAction): boolean {\n return this.#activeActions.some(activeAction => {\n return action.entry === activeAction.entry && action.type === activeAction.type;\n });\n }\n\n /**\n * The set of entries that are visible given the set of applied actions. If\n * no actions are applied, this will return all entries in the thread.\n *\n * This method is cached, so it is safe to call multiple times.\n **/\n visibleEntries(): readonly Types.TraceEvents.TraceEventData[] {\n if (this.#activeActions.length === 0) {\n return this.#thread.entries;\n }\n return this.#calculateVisibleEntries();\n }\n\n #calculateVisibleEntries(): readonly Types.TraceEvents.TraceEventData[] {\n // When an action is added, we clear this cache. So if this cache is\n // present it means that the set of active actions has not changed, and so\n // we do not need to recalculate anything.\n if (this.#lastVisibleEntries) {\n return this.#lastVisibleEntries;\n }\n\n if (!this.#thread.tree) {\n // We need a tree to be able to calculate user actions, if we do not have\n // it, just return all the entries.\n return this.#thread.entries;\n }\n\n // We apply each user action in turn to the set of all entries, and mark\n // any that should be hidden by adding them to this set. We do this to\n // ensure we minimise the amount of passes through the list of all entries.\n // Another approach would be to use splice() to remove items from the\n // array, but doing this would be a mutation of the arry for every hidden\n // event. Instead, we add entries to this set, and at the very end loop\n // through the entries array once to filter out any that should be hidden.\n const entriesToHide = new Set<Handlers.ModelHandlers.Renderer.RendererEntry>();\n\n const entries = [...this.#thread.entries];\n for (const action of this.#activeActions) {\n switch (action.type) {\n case 'MERGE_FUNCTION': {\n // The entry that was clicked on is merged into its parent. All its\n // children remain visible, so we just have to hide the entry that was\n // selected.\n entriesToHide.add(action.entry);\n break;\n }\n\n case 'COLLAPSE_FUNCTION': {\n // The entry itself remains visible, but all of its ancestors are hidden.\n const entryNode = this.#entryToNode.get(action.entry);\n if (!entryNode) {\n // Invalid node was given, just ignore and move on.\n continue;\n }\n const allAncestors = this.#findAllAncestorsOfNode(this.#thread.tree, entryNode);\n allAncestors.forEach(ancestor => entriesToHide.add(ancestor));\n break;\n }\n default:\n Platform.assertNever(action.type, `Unknown TreeManipulator action: ${action.type}`);\n }\n }\n\n // Now we have applied all actions, loop through the list of entries and\n // remove any that are marked as hidden.\n // We cache this under lastVisibleEntries - if this function is called\n // again and the user actions have not changed, we can avoid recalculating\n // this and just return the last one. This cache is automatically cleared\n // when the user actions are changed.\n this.#lastVisibleEntries = entries.filter(entry => {\n return entriesToHide.has(entry) === false;\n });\n\n return this.#lastVisibleEntries;\n }\n\n #findAllAncestorsOfNode(\n tree: Handlers.ModelHandlers.Renderer.RendererTree,\n root: Handlers.ModelHandlers.Renderer.RendererEntryNode): Handlers.ModelHandlers.Renderer.RendererEntry[] {\n const ancestors: Handlers.ModelHandlers.Renderer.RendererEntry[] = [];\n\n // Walk through all the ancestors, starting at the root node.\n const childIds: Handlers.ModelHandlers.Renderer.RendererEntryNodeId[] = Array.from(root.childrenIds);\n while (childIds.length > 0) {\n const id = childIds.shift();\n if (!id) {\n break;\n }\n const childNode = tree.nodes.get(id);\n if (childNode) {\n ancestors.push(childNode.entry);\n const newChildIds = Array.from(childNode.childrenIds);\n childIds.push(...newChildIds);\n }\n }\n\n return ancestors;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }