@launchdarkly/browser-telemetry 1.0.11 → 1.0.13

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/collectors/dom/getTarget.ts","../src/collectors/dom/toSelector.ts","../src/collectors/dom/ClickCollector.ts","../src/collectors/dom/KeypressCollector.ts","../src/collectors/error.ts","../src/filters/filterUrl.ts","../src/filters/filterHttpBreadcrumb.ts","../src/collectors/http/fetchDecorator.ts","../src/collectors/http/fetch.ts","../src/collectors/http/xhrDecorator.ts","../src/collectors/http/xhr.ts","../src/filters/defaultUrlFilter.ts","../src/inspectors.ts","../src/logging.ts","../src/randomUuidV4.ts","../src/vendor/TraceKit.ts","../src/stack/StackParser.ts","../src/BrowserTelemetryImpl.ts","../src/options.ts","../src/singleton/singletonInstance.ts","../src/singleton/singletonMethods.ts"],"sourcesContent":["import { BrowserTelemetry } from './api/BrowserTelemetry';\nimport { Options } from './api/Options';\nimport BrowserTelemetryImpl from './BrowserTelemetryImpl';\nimport { safeMinLogger } from './logging';\nimport parse from './options';\n\nexport * from './api';\n\nexport * from './singleton';\n\n/**\n * Initialize a new telemetry instance.\n *\n * This instance is not global. Generally developers should use {@link initTelemetry} instead.\n *\n * If for some reason multiple telemetry instances are needed, this method can be used to create a new instance.\n * Instances are not aware of each other and may send duplicate data from automatically captured events.\n *\n * @param options The options to use for the telemetry instance.\n * @returns A telemetry instance.\n */\nexport function initTelemetryInstance(options?: Options): BrowserTelemetry {\n const parsedOptions = parse(options || {}, safeMinLogger(options?.logger));\n return new BrowserTelemetryImpl(parsedOptions);\n}\n","/**\n * Get the event target. This is wrapped because in some situations a browser may throw when\n * accessing the event target.\n *\n * @param event The event to get the target from.\n * @returns The event target, or undefined if one is not available.\n */\nexport default function getTarget(event: { target: any }): Element | undefined {\n try {\n return event.target as Element;\n } catch {\n return undefined;\n }\n}\n","// https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator\nconst CHILD_COMBINATOR = '>';\n// Spacing around the combinator is optional, but it increases readability.\nconst CHILD_SEPARATOR = ` ${CHILD_COMBINATOR} `;\n\n/**\n * The elements of a node we need for traversal.\n */\ninterface NodeWithParent {\n parentNode?: NodeWithParent;\n}\n\n/**\n * The elements of a node we need to generate a string representation.\n *\n * All element fields are optional, so a type guard is not required to use this typing.\n */\ninterface BasicElement {\n tagName?: string;\n id?: string;\n className?: string;\n}\n\n/**\n * Type guard that verifies that an element complies with {@link NodeWithParent}.\n */\nfunction isNode(element: unknown): element is NodeWithParent {\n const anyElement = element as any;\n // Parent node being null or undefined fill be falsy.\n // The type of `null` is object, so check for null as well.\n return typeof anyElement === 'object' && anyElement != null && anyElement.parentNode;\n}\n\n/**\n * Given an element produce a class name in CSS selector format.\n *\n * Exported for testing.\n *\n * @param element The element to get a class name for.\n * @returns The class name, or undefined if there is no class name.\n */\nexport function getClassName(element: BasicElement): string | undefined {\n if (typeof element.className !== `string`) {\n return undefined;\n }\n let value = element.className;\n // Elements should be space separated in a class attribute. If there are other kinds of\n // whitespace, then this code could need adjustment.\n if (element.className.includes(' ')) {\n value = element.className.replace(' ', '.');\n }\n\n if (value !== '') {\n return `.${value}`;\n }\n // There was no class name.\n return undefined;\n}\n\n/**\n * Produce a string representation for a single DOM element. Does not produce the full selector.\n *\n * Exported for testing.\n *\n * @param element The element to produce a text representation for.\n * @returns A text representation of the element, or an empty string if one cannot be produced.\n */\nexport function elementToString(element: BasicElement): string {\n if (!element.tagName) {\n return '';\n }\n\n const components: string[] = [];\n\n components.push(element.tagName.toLowerCase());\n if (element.id) {\n components.push(`#${element.id}`);\n }\n\n const className = getClassName(element);\n if (className) {\n components.push(className);\n }\n\n return components.join('');\n}\n\n/**\n * Given an HTML element produce a CSS selector.\n *\n * Defaults to a maximum depth of 10 components.\n *\n * Example:\n * ```\n * <html>\n * <body>\n * <div>\n * <ul>\n * <li class=\"some-class\">\n * <p id=\"some-id\">toaster</p>\n * </li>\n * </ul>\n * </div>\n * </body>\n * </html>\n * ```\n * The <p> element in the above HTML would produce:\n * `body > div > ul > li.some-class > p#some-id`\n *\n * @param element The element to generate a selector from.\n * @param options Options which control selector generation.\n * @returns The generated selector.\n */\nexport default function toSelector(\n element: unknown,\n options: {\n maxDepth: number;\n } = { maxDepth: 10 },\n): string {\n // For production we may want to consider if we additionally limit the maximum selector length.\n // Limiting the components should generate reasonable selectors in most cases.\n const components: string[] = [];\n let ptr = element;\n while (isNode(ptr) && ptr.parentNode && components.length < options.maxDepth) {\n const asString = elementToString(ptr as BasicElement);\n // We do not need to include the 'html' component in the selector.\n // The HTML element can be assumed to be the top. If there are more elements\n // we would not want to include them (they would be something non-standard).\n if (asString === 'html') {\n break;\n }\n\n components.push(asString);\n ptr = ptr.parentNode;\n }\n return components.reverse().join(CHILD_SEPARATOR);\n}\n","import { UiBreadcrumb } from '../../api/Breadcrumb';\nimport { Collector } from '../../api/Collector';\nimport { Recorder } from '../../api/Recorder';\nimport getTarget from './getTarget';\nimport toSelector from './toSelector';\n\n/**\n * Collects mouse click events and adds them as breadcrumbs.\n */\nexport default class ClickCollector implements Collector {\n private _destination?: Recorder;\n\n constructor() {\n window.addEventListener(\n 'click',\n (event: MouseEvent) => {\n const target = getTarget(event);\n if (target) {\n const breadcrumb: UiBreadcrumb = {\n class: 'ui',\n type: 'click',\n level: 'info',\n timestamp: Date.now(),\n message: toSelector(target),\n };\n this._destination?.addBreadcrumb(breadcrumb);\n }\n },\n true,\n );\n }\n\n register(recorder: Recorder, _sessionId: string): void {\n this._destination = recorder;\n }\n unregister(): void {\n this._destination = undefined;\n }\n}\n","import { Breadcrumb, UiBreadcrumb } from '../../api/Breadcrumb';\nimport { Collector } from '../../api/Collector';\nimport { Recorder } from '../../api/Recorder';\nimport getTarget from './getTarget';\nimport toSelector from './toSelector';\n\nconst THROTTLE_TIME_MS = 1000;\n\nconst INPUT_TAG_NAMES = ['INPUT', 'TEXTAREA'];\n\n/**\n * Collects key press events and adds them as breadcrumbs.\n */\nexport default class KeypressCollector implements Collector {\n private _destination?: Recorder;\n private _lastEvent?: UiBreadcrumb;\n\n constructor() {\n // Currently we use the keypress event, but it is technically deprecated.\n // It is the simplest way to currently get the most broad coverage.\n // In the future we may want to consider some check to attempt to selectively use a more\n // targetted event.\n window.addEventListener(\n 'keypress',\n (event: KeyboardEvent) => {\n const target = getTarget(event);\n const htmlElement = target as HTMLElement;\n // An example of `isContentEditable` would be an editable <p> tag.\n // Input and textarea tags do not have the isContentEditable property.\n if (\n target &&\n (INPUT_TAG_NAMES.includes(target.tagName) || htmlElement?.isContentEditable)\n ) {\n const breadcrumb: UiBreadcrumb = {\n class: 'ui',\n type: 'input',\n level: 'info',\n timestamp: Date.now(),\n message: toSelector(target),\n };\n\n if (!this._shouldDeduplicate(breadcrumb)) {\n this._destination?.addBreadcrumb(breadcrumb);\n this._lastEvent = breadcrumb;\n }\n }\n },\n true,\n );\n }\n\n register(recorder: Recorder, _sessionId: string): void {\n this._destination = recorder;\n }\n unregister(): void {\n this._destination = undefined;\n }\n\n private _shouldDeduplicate(crumb: Breadcrumb): boolean {\n // If this code every is demonstrably a performance issue, then we may be able to implement\n // some scheme to de-duplicate these via some DOM mechanism. Like adding a debounce annotation\n // of some kind.\n if (this._lastEvent) {\n const timeDiff = Math.abs(crumb.timestamp - this._lastEvent.timestamp);\n return timeDiff <= THROTTLE_TIME_MS && this._lastEvent.message === crumb.message;\n }\n return false;\n }\n}\n","import { Collector } from '../api/Collector';\nimport { Recorder } from '../api/Recorder';\n\nexport default class ErrorCollector implements Collector {\n private _destination?: Recorder;\n\n constructor() {\n window.addEventListener(\n 'error',\n (event: ErrorEvent) => {\n this._destination?.captureErrorEvent(event);\n },\n true,\n );\n window.addEventListener(\n 'unhandledrejection',\n (event: PromiseRejectionEvent) => {\n if (event.reason) {\n this._destination?.captureError(event.reason);\n }\n },\n true,\n );\n }\n\n register(recorder: Recorder): void {\n this._destination = recorder;\n }\n unregister(): void {\n this._destination = undefined;\n }\n}\n","import { UrlFilter } from '../api/Options';\n\nexport default function filterUrl(filters: UrlFilter[], url?: string): string {\n if (!url) {\n return '';\n }\n return filters.reduce((filtered, filter) => filter(filtered), url);\n}\n","import { HttpBreadcrumb } from '../api/Breadcrumb';\nimport HttpCollectorOptions from '../collectors/http/HttpCollectorOptions';\nimport filterUrl from './filterUrl';\n\n/**\n * This function does in-place filtering of http breadcrumbs.\n *\n * @param crumb The breadcrumb to filter.\n */\nexport default function filterHttpBreadcrumb(\n crumb: HttpBreadcrumb,\n options: HttpCollectorOptions,\n): void {\n if (crumb.data?.url) {\n // Re-assigning for performance. The contract of the function is clear that the input\n // data is modified.\n // eslint-disable-next-line no-param-reassign\n crumb.data.url = filterUrl(options.urlFilters, crumb.data.url);\n }\n}\n","import { HttpBreadcrumb } from '../../api/Breadcrumb';\n\nconst LD_ORIGINAL_FETCH = '__LaunchDarkly_original_fetch';\n\nconst originalFetch = window.fetch;\n\n/**\n * Given fetch arguments produce a URL and method.\n *\n * Exposed for testing.\n *\n * @param input First parameter to fetch.\n * @param init Second, optional, parameter to fetch.\n * @returns Return the URL and method. If not method or url can be accessed, then 'GET' will be the\n * method and the url will be an empty string.\n */\nexport function processFetchArgs(\n input: RequestInfo | URL,\n init?: RequestInit | undefined,\n): { url: string; method: string } {\n let url = '';\n let method = 'GET';\n\n if (typeof input === 'string') {\n url = input;\n }\n // We may want to consider prop checks if this ends up being a problem for people.\n // `instanceof` was not added to Edge until 2015.\n if (typeof Request !== 'undefined' && input instanceof Request) {\n url = input.url;\n method = input.method;\n }\n if (typeof URL !== 'undefined' && input instanceof URL) {\n url = input.toString();\n }\n\n if (init) {\n method = init.method ?? method;\n }\n return { url, method };\n}\n\n/**\n * Decorate fetch and execute the callback whenever a fetch is completed providing a breadcrumb.\n *\n * @param callback Function which handles a breadcrumb.\n */\nexport default function decorateFetch(callback: (breadcrumb: HttpBreadcrumb) => void) {\n // TODO (SDK-884): Check if already wrapped?\n // TODO (SDK-884): Centralized mechanism to wrapping?\n\n // In this function we add type annotations for `this`. In this case we are telling the compiler\n // we don't care about the typing.\n\n // This is a function instead of an arrow function in order to preserve the original `this`.\n // Arrow functions capture the enclosing `this`.\n function wrapper(this: any, ...args: any[]): Promise<Response> {\n const timestamp = Date.now();\n // We are taking the original parameters and passing them through. We are not specifying their\n // type information and the number of parameters could be changed over time and the wrapper\n // would still function.\n return originalFetch.apply(this, args as any).then((response: Response) => {\n const crumb: HttpBreadcrumb = {\n class: 'http',\n timestamp,\n level: response.ok ? 'info' : 'error',\n type: 'fetch',\n data: {\n // We know these will be fetch args. We only can take 2 of them, one of which may be\n // undefined. We still use all the ars to apply to the original function.\n ...processFetchArgs(args[0], args[1]),\n statusCode: response.status,\n statusText: response.statusText,\n },\n };\n callback(crumb);\n return response;\n });\n }\n\n wrapper.prototype = originalFetch?.prototype;\n\n try {\n // Use defineProperty to prevent this value from being enumerable.\n Object.defineProperty(wrapper, LD_ORIGINAL_FETCH, {\n // Defaults to non-enumerable.\n value: originalFetch,\n writable: true,\n configurable: true,\n });\n } catch {\n // Intentional ignore.\n // TODO: If we add debug logging, then this should be logged.\n }\n\n window.fetch = wrapper;\n}\n","import { Collector } from '../../api/Collector';\nimport { Recorder } from '../../api/Recorder';\nimport filterHttpBreadcrumb from '../../filters/filterHttpBreadcrumb';\nimport decorateFetch from './fetchDecorator';\nimport HttpCollectorOptions from './HttpCollectorOptions';\n\n/**\n * Instrument fetch requests and generate a breadcrumb for each request.\n */\nexport default class FetchCollector implements Collector {\n private _destination?: Recorder;\n private _loggedIssue: boolean = false;\n\n constructor(options: HttpCollectorOptions) {\n decorateFetch((breadcrumb) => {\n let filtersExecuted = false;\n try {\n filterHttpBreadcrumb(breadcrumb, options);\n filtersExecuted = true;\n } catch (err) {\n if (!this._loggedIssue) {\n options.getLogger?.()?.warn('Error filtering http breadcrumb', err);\n this._loggedIssue = true;\n }\n }\n // Only add the breadcrumb if the filter didn't throw. We don't want to\n // report a breadcrumb that may have not have had the correct information redacted.\n if (filtersExecuted) {\n this._destination?.addBreadcrumb(breadcrumb);\n }\n });\n }\n\n register(recorder: Recorder, _sessionId: string): void {\n this._destination = recorder;\n }\n\n unregister(): void {\n this._destination = undefined;\n }\n}\n","import { HttpBreadcrumb } from '../../api/Breadcrumb';\n\nconst LD_ORIGINAL_XHR = '__LaunchDarkly_original_xhr';\nconst LD_ORIGINAL_XHR_OPEN = `${LD_ORIGINAL_XHR}_open`;\nconst LD_ORIGINAL_XHR_SEND = `${LD_ORIGINAL_XHR}_send`;\n\n// Key used to store data inside the xhr.\nconst LD_DATA_XHR = '__LaunchDarkly_data_xhr';\n\n// We want to monitor open to collect the URL and method.\nconst originalOpen = window.XMLHttpRequest.prototype.open;\n// We want to monitor send in order to generate an accurate timestamp.\nconst originalSend = window.XMLHttpRequest.prototype.send;\n\ninterface LDXhrData {\n method?: string;\n url?: string;\n timestamp?: number;\n error?: boolean;\n}\n\n/**\n * Decorate XMLHttpRequest and execute the callback whenever a request is completed.\n *\n * @param callback Function which handles a breadcrumb.\n */\nexport default function decorateXhr(callback: (breadcrumb: HttpBreadcrumb) => void) {\n // In these functions we add type annotations for `this`. The impact here should just\n // be that we get correct typing for typescript. They should not affect the output.\n\n // We are using functions instead of an arrow functions in order to preserve the original `this`.\n // Arrow functions capture the enclosing `this`.\n\n function wrappedOpen(this: XMLHttpRequest, ...args: any[]) {\n // Listen to error so we can tag this request as having an error. If there is no error event\n // then the request will assume to not have errored.\n // eslint-disable-next-line func-names\n this.addEventListener('error', function (_event: ProgressEvent<XMLHttpRequestEventTarget>) {\n // We know, if the data is present, that it has this shape, as we injected it.\n const data: LDXhrData = (this as any)[LD_DATA_XHR];\n data.error = true;\n });\n\n this.addEventListener(\n 'loadend',\n // eslint-disable-next-line func-names\n function (_event: ProgressEvent<XMLHttpRequestEventTarget>) {\n // We know, if the data is present, that it has this shape, as we injected it.\n const data: LDXhrData = (this as any)[LD_DATA_XHR];\n // Timestamp could be falsy for 0, but obviously that isn't a good timestamp, so we are ok.\n if (data && data.timestamp) {\n callback({\n class: 'http',\n timestamp: data.timestamp,\n level: data.error ? 'error' : 'info',\n type: 'xhr',\n data: {\n url: data.url,\n method: data.method,\n statusCode: this.status,\n statusText: this.statusText,\n },\n });\n }\n },\n true,\n );\n\n // We know these will be open arguments.\n originalOpen.apply(this, args as any);\n\n try {\n const xhrData: LDXhrData = {\n method: args?.[0],\n url: args?.[1],\n };\n // Use defineProperty to prevent this value from being enumerable.\n Object.defineProperty(this, LD_DATA_XHR, {\n // Defaults to non-enumerable.\n value: xhrData,\n writable: true,\n configurable: true,\n });\n } catch {\n // Intentional ignore.\n // TODO: If we add debug logging, then this should be logged.\n }\n }\n\n function wrappedSend(this: XMLHttpRequest, ...args: any[]) {\n // We know these will be open arguments.\n originalSend.apply(this, args as any);\n\n // We know, if the data is present, that it has this shape, as we injected it.\n const data: LDXhrData = (this as any)[LD_DATA_XHR];\n if (data) {\n data.timestamp = Date.now();\n }\n }\n\n window.XMLHttpRequest.prototype.open = wrappedOpen;\n window.XMLHttpRequest.prototype.send = wrappedSend;\n\n try {\n // Use defineProperties to prevent these values from being enumerable.\n // The properties default to non-enumerable.\n Object.defineProperties(window.XMLHttpRequest, {\n [LD_ORIGINAL_XHR_OPEN]: {\n value: originalOpen,\n writable: true,\n configurable: true,\n },\n [LD_ORIGINAL_XHR_SEND]: {\n value: originalSend,\n writable: true,\n configurable: true,\n },\n });\n } catch {\n // Intentional ignore.\n // TODO: If we add debug logging, then this should be logged.\n }\n}\n","import { Collector } from '../../api/Collector';\nimport { Recorder } from '../../api/Recorder';\nimport filterHttpBreadcrumb from '../../filters/filterHttpBreadcrumb';\nimport HttpCollectorOptions from './HttpCollectorOptions';\nimport decorateXhr from './xhrDecorator';\n\n/**\n * Instrument XMLHttpRequest and provide a breadcrumb for every XMLHttpRequest\n * which is completed.\n */\nexport default class XhrCollector implements Collector {\n private _destination?: Recorder;\n private _loggedIssue: boolean = false;\n\n constructor(options: HttpCollectorOptions) {\n decorateXhr((breadcrumb) => {\n let filtersExecuted = false;\n try {\n filterHttpBreadcrumb(breadcrumb, options);\n filtersExecuted = true;\n } catch (err) {\n if (!this._loggedIssue) {\n options.getLogger?.()?.warn('Error filtering http breadcrumb', err);\n this._loggedIssue = true;\n }\n }\n // Only add the breadcrumb if the filter didn't throw. We don't want to\n // report a breadcrumb that may have not have had the correct information redacted.\n if (filtersExecuted) {\n this._destination?.addBreadcrumb(breadcrumb);\n }\n });\n }\n\n register(recorder: Recorder, _sessionId: string): void {\n this._destination = recorder;\n }\n\n unregister(): void {\n this._destination = undefined;\n }\n}\n","const pollingRegex = /sdk\\/evalx\\/[^/]+\\/contexts\\/(?<context>[^/?]*)\\??.*?/;\nconst streamingREgex = /\\/eval\\/[^/]+\\/(?<context>[^/?]*)\\??.*?/;\n\n/**\n * Filter which redacts user information (auth) from a URL.\n *\n * If a username/password is present, then they are replaced with 'redacted'.\n * Authority reference: https://developer.mozilla.org/en-US/docs/Web/URI/Authority\n *\n * @param url URL to filter.\n * @returns A filtered URL.\n */\nfunction authorityUrlFilter(url: string): string {\n // This will work in browser environments, but in the future we may want to consider an approach\n // which doesn't rely on the browser's URL parsing. This is because other environments we may\n // want to target, such as ReactNative, may not have as robust URL parsing.\n // We first check if the URL can be parsed, because it may not include the base URL.\n try {\n // If the URL includes a protocol, if so, then it can probably be parsed.\n // Credentials require a full URL.\n if (url.includes('://')) {\n const urlObj = new URL(url);\n let hadAuth = false;\n if (urlObj.username) {\n urlObj.username = 'redacted';\n hadAuth = true;\n }\n if (urlObj.password) {\n urlObj.password = 'redacted';\n hadAuth = true;\n }\n if (hadAuth) {\n return urlObj.toString();\n }\n }\n } catch {\n // Could not parse the URL.\n }\n // If there was no auth information, then we don't need to modify the URL.\n return url;\n}\n\n/**\n * Filter which removes context information for browser JavaScript endpoints.\n *\n * @param url URL to filter.\n * @returns A filtered URL.\n */\nfunction ldUrlFilter(url: string): string {\n // TODO: Maybe we consider a way to identify LD requests so they can be filtered without\n // regular expressions.\n\n if (url.includes('/sdk/evalx')) {\n const regexMatch = url.match(pollingRegex);\n const context = regexMatch?.groups?.context;\n if (context) {\n return url.replace(context, '*'.repeat(context.length));\n }\n }\n if (url.includes('/eval/')) {\n const regexMatch = url.match(streamingREgex);\n const context = regexMatch?.groups?.context;\n if (context) {\n return url.replace(context, '*'.repeat(context.length));\n }\n }\n return url;\n}\n\n/**\n * Filter which redacts user information and removes context information for browser JavaScript endpoints.\n *\n * @param url URL to filter.\n * @returns A filtered URL.\n */\nexport default function defaultUrlFilter(url: string): string {\n return ldUrlFilter(authorityUrlFilter(url));\n}\n","import type { LDContext, LDEvaluationDetail } from '@launchdarkly/js-client-sdk';\n\nimport { BrowserTelemetryInspector } from './api/client/BrowserTelemetryInspector.js';\nimport BrowserTelemetryImpl from './BrowserTelemetryImpl.js';\nimport { ParsedOptions } from './options.js';\n\n/**\n * Create inspectors to register with an LDClient instance.\n *\n * @param options Optiont which determine which inspectors are created.\n * @param inspectors Inspectors will be added to this array.\n * @param telemetry The telemetry instance which inspectors will forward data to.\n */\nexport default function makeInspectors(\n options: ParsedOptions,\n inspectors: BrowserTelemetryInspector[],\n telemetry: BrowserTelemetryImpl,\n) {\n if (options.breadcrumbs.evaluations) {\n inspectors.push({\n type: 'flag-used',\n name: 'launchdarkly-browser-telemetry-flag-used',\n synchronous: true,\n method(flagKey: string, flagDetail: LDEvaluationDetail, context?: LDContext): void {\n telemetry.handleFlagUsed(flagKey, flagDetail, context);\n },\n });\n }\n\n if (options.breadcrumbs.flagChange) {\n inspectors.push({\n type: 'flag-detail-changed',\n name: 'launchdarkly-browser-telemetry-flag-used',\n synchronous: true,\n method(flagKey: string, detail: LDEvaluationDetail): void {\n telemetry.handleFlagDetailChanged(flagKey, detail);\n },\n });\n }\n}\n","import { MinLogger } from './api';\n\nexport const fallbackLogger: MinLogger = {\n // Intentionally using console.warn as a fallback logger.\n // eslint-disable-next-line no-console\n warn: console.warn,\n};\n\nconst loggingPrefix = 'LaunchDarkly - Browser Telemetry:';\n\nexport function prefixLog(message: string) {\n return `${loggingPrefix} ${message}`;\n}\n\nexport function safeMinLogger(logger: MinLogger | undefined): MinLogger {\n return {\n warn: (...args: any[]) => {\n if (!logger) {\n fallbackLogger.warn(...args);\n return;\n }\n\n try {\n logger.warn(...args);\n } catch {\n fallbackLogger.warn(...args);\n fallbackLogger.warn(\n prefixLog('The provided logger threw an exception, using fallback logger.'),\n );\n }\n },\n };\n}\n","// This implementation is the same as in the browser package. Eventually we\n// will want a common package for this type of code. (SDK-905)\n\n// The implementation in this file generates UUIDs in v4 format and is suitable\n// for use as a UUID in LaunchDarkly events. It is not a rigorous implementation.\n\n// It uses crypto.randomUUID when available.\n// If crypto.randomUUID is not available, then it uses random values and forms\n// the UUID itself.\n// When possible it uses crypto.getRandomValues, but it can use Math.random\n// if crypto.getRandomValues is not available.\n\n// UUIDv4 Struct definition.\n// https://www.rfc-archive.org/getrfc.php?rfc=4122\n// Appendix A. Appendix A - Sample Implementation\nconst timeLow = {\n start: 0,\n end: 3,\n};\nconst timeMid = {\n start: 4,\n end: 5,\n};\nconst timeHiAndVersion = {\n start: 6,\n end: 7,\n};\nconst clockSeqHiAndReserved = {\n start: 8,\n end: 8,\n};\nconst clockSeqLow = {\n start: 9,\n end: 9,\n};\nconst nodes = {\n start: 10,\n end: 15,\n};\n\nfunction getRandom128bit(): number[] {\n if (crypto && crypto.getRandomValues) {\n const typedArray = new Uint8Array(16);\n crypto.getRandomValues(typedArray);\n return [...typedArray.values()];\n }\n const values = [];\n for (let index = 0; index < 16; index += 1) {\n // Math.random is 0-1 with inclusive min and exclusive max.\n values.push(Math.floor(Math.random() * 256));\n }\n return values;\n}\n\nfunction hex(bytes: number[], range: { start: number; end: number }): string {\n let strVal = '';\n for (let index = range.start; index <= range.end; index += 1) {\n strVal += bytes[index].toString(16).padStart(2, '0');\n }\n return strVal;\n}\n\n/**\n * Given a list of 16 random bytes generate a UUID in v4 format.\n *\n * Note: The input bytes are modified to conform to the requirements of UUID v4.\n *\n * @param bytes A list of 16 bytes.\n * @returns A UUID v4 string.\n */\nexport function formatDataAsUuidV4(bytes: number[]): string {\n // https://www.rfc-archive.org/getrfc.php?rfc=4122\n // 4.4. Algorithms for Creating a UUID from Truly Random or\n // Pseudo-Random Numbers\n\n // Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and\n // one, respectively.\n // eslint-disable-next-line no-bitwise, no-param-reassign\n bytes[clockSeqHiAndReserved.start] = (bytes[clockSeqHiAndReserved.start] | 0x80) & 0xbf;\n // Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to\n // the 4-bit version number from Section 4.1.3.\n // eslint-disable-next-line no-bitwise, no-param-reassign\n bytes[timeHiAndVersion.start] = (bytes[timeHiAndVersion.start] & 0x0f) | 0x40;\n\n return (\n `${hex(bytes, timeLow)}-${hex(bytes, timeMid)}-${hex(bytes, timeHiAndVersion)}-` +\n `${hex(bytes, clockSeqHiAndReserved)}${hex(bytes, clockSeqLow)}-${hex(bytes, nodes)}`\n );\n}\n\nexport function fallbackUuidV4(): string {\n const bytes = getRandom128bit();\n return formatDataAsUuidV4(bytes);\n}\n\nexport default function randomUuidV4(): string {\n if (typeof crypto !== undefined && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n\n return fallbackUuidV4();\n}\n","/**\n * https://github.com/csnover/TraceKit\n * @license MIT\n * @namespace TraceKit\n */\n\n/**\n * This file has been vendored to make it compatible with ESM and to any potential window\n * level TraceKit instance.\n *\n * Functionality unused by this SDK has been removed to minimize size.\n *\n * It has additionally been converted to typescript.\n *\n * The functionality of computeStackTrace has been extended to allow for easier use of the context\n * information in stack frames.\n */\n\n/**\n * Currently the conversion to typescript is minimal, so the following eslint\n * rules are disabled.\n */\n\n/* eslint-disable func-names */\n/* eslint-disable no-shadow-restricted-names */\n/* eslint-disable prefer-destructuring */\n/* eslint-disable no-param-reassign */\n/* eslint-disable no-cond-assign */\n/* eslint-disable consistent-return */\n/* eslint-disable no-empty */\n/* eslint-disable no-plusplus */\n/* eslint-disable prefer-rest-params */\n/* eslint-disable no-useless-escape */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable no-continue */\n/* eslint-disable no-underscore-dangle */\n\n/**\n * Source context information.\n *\n * This was not present in the original source, but helps to easily identify which line in the\n * context is the original line.\n *\n * Without this knowledge of the source file is requires for a consumer to know the position\n * of the original source line within the context.\n */\nexport interface SourceContext {\n /**\n * The starting location in the source code. This is 1-based.\n */\n startFromSource?: number;\n contextLines: string[] | null;\n}\n\nexport interface TraceKitStatic {\n computeStackTrace: {\n (ex: Error, depth?: number): StackTrace;\n augmentStackTraceWithInitialElement: (\n stackInfo: StackTrace,\n url: string,\n lineNo: number | string,\n message: string,\n ) => boolean;\n computeStackTraceFromStackProp: (ex: Error) => StackTrace | null;\n guessFunctionName: (url: string, lineNo: number | string) => string;\n gatherContext: (url: string, line: number | string) => SourceContext | null;\n ofCaller: (depth?: number) => StackTrace;\n getSource: (url: string) => string[];\n };\n remoteFetching: boolean;\n collectWindowErrors: boolean;\n linesOfContext: number;\n debug: boolean;\n}\n\nconst TraceKit: any = {};\n\nexport interface StackFrame {\n url: string;\n func: string;\n args?: string[];\n /**\n * The line number of source code.\n * This is 1-based.\n */\n line?: number | null;\n column?: number | null;\n context?: string[] | null;\n /**\n * The source line number that is the first line of the context.\n * This is 1-based.\n */\n srcStart?: number;\n}\n\nexport type Mode = 'stack' | 'stacktrace' | 'multiline' | 'callers' | 'onerror' | 'failed';\n\nexport interface StackTrace {\n name: string;\n message: string;\n stack: StackFrame[];\n mode: Mode;\n incomplete?: boolean;\n partial?: boolean;\n}\n\n(function (window, undefined) {\n if (!window) {\n return;\n }\n\n // global reference to slice\n const _slice = [].slice;\n const UNKNOWN_FUNCTION = '?';\n\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types\n const ERROR_TYPES_RE =\n /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/;\n\n /**\n * A better form of hasOwnProperty<br/>\n * Example: `_has(MainHostObject, property) === true/false`\n *\n * @param {Object} object to check property\n * @param {string} key to check\n * @return {Boolean} true if the object has the key and it is not inherited\n */\n function _has(object: any, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(object, key);\n }\n\n /**\n * Returns true if the parameter is undefined<br/>\n * Example: `_isUndefined(val) === true/false`\n *\n * @param {*} what Value to check\n * @return {Boolean} true if undefined and false otherwise\n */\n function _isUndefined(what: any): boolean {\n return typeof what === 'undefined';\n }\n\n /**\n * Wrap any function in a TraceKit reporter<br/>\n * Example: `func = TraceKit.wrap(func);`\n *\n * @param {Function} func Function to be wrapped\n * @return {Function} The wrapped func\n * @memberof TraceKit\n */\n TraceKit.wrap = function traceKitWrapper(func: Function): Function {\n function wrapped(this: any) {\n try {\n return func.apply(this, arguments);\n } catch (e) {\n TraceKit.report(e);\n throw e;\n }\n }\n return wrapped;\n };\n\n /**\n * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript\n *\n * Syntax:\n * ```js\n * s = TraceKit.computeStackTrace.ofCaller([depth])\n * s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below)\n * ```\n *\n * Supports:\n * - Firefox: full stack trace with line numbers and unreliable column\n * number on top frame\n * - Opera 10: full stack trace with line and column numbers\n * - Opera 9-: full stack trace with line numbers\n * - Chrome: full stack trace with line and column numbers\n * - Safari: line and column number for the topmost stacktrace element\n * only\n * - IE: no line numbers whatsoever\n *\n * Tries to guess names of anonymous functions by looking for assignments\n * in the source code. In IE and Safari, we have to guess source file names\n * by searching for function bodies inside all page scripts. This will not\n * work for scripts that are loaded cross-domain.\n * Here be dragons: some function names may be guessed incorrectly, and\n * duplicate functions may be mismatched.\n *\n * TraceKit.computeStackTrace should only be used for tracing purposes.\n * Logging of unhandled exceptions should be done with TraceKit.report,\n * which builds on top of TraceKit.computeStackTrace and provides better\n * IE support by utilizing the window.onerror event to retrieve information\n * about the top of the stack.\n *\n * Note: In IE and Safari, no stack trace is recorded on the Error object,\n * so computeStackTrace instead walks its *own* chain of callers.\n * This means that:\n * * in Safari, some methods may be missing from the stack trace;\n * * in IE, the topmost function in the stack trace will always be the\n * caller of computeStackTrace.\n *\n * This is okay for tracing (because you are likely to be calling\n * computeStackTrace from the function you want to be the topmost element\n * of the stack trace anyway), but not okay for logging unhandled\n * exceptions (because your catch block will likely be far away from the\n * inner function that actually caused the exception).\n *\n * Tracing example:\n * ```js\n * function trace(message) {\n * var stackInfo = TraceKit.computeStackTrace.ofCaller();\n * var data = message + \"\\n\";\n * for(var i in stackInfo.stack) {\n * var item = stackInfo.stack[i];\n * data += (item.func || '[anonymous]') + \"() in \" + item.url + \":\" + (item.line || '0') + \"\\n\";\n * }\n * if (window.console)\n * console.info(data);\n * else\n * alert(data);\n * }\n * ```\n * @memberof TraceKit\n * @namespace\n */\n TraceKit.computeStackTrace = (function computeStackTraceWrapper() {\n const debug = false;\n const sourceCache: Record<string, string[]> = {};\n\n /**\n * Attempts to retrieve source code via XMLHttpRequest, which is used\n * to look up anonymous function names.\n * @param {string} url URL of source code.\n * @return {string} Source contents.\n * @memberof TraceKit.computeStackTrace\n */\n function loadSource(url: string): string {\n if (!TraceKit.remoteFetching) {\n // Only attempt request if remoteFetching is on.\n return '';\n }\n try {\n const getXHR = function () {\n try {\n return new window.XMLHttpRequest();\n } catch (e) {\n // explicitly bubble up the exception if not found\n // @ts-ignore\n return new window.ActiveXObject('Microsoft.XMLHTTP');\n }\n };\n\n const request = getXHR();\n request.open('GET', url, false);\n request.send('');\n return request.responseText;\n } catch (e) {\n return '';\n }\n }\n\n /**\n * Retrieves source code from the source code cache.\n * @param {string} url URL of source code.\n * @return {Array.<string>} Source contents.\n * @memberof TraceKit.computeStackTrace\n */\n function getSource(url: string): string[] {\n if (typeof url !== 'string') {\n return [];\n }\n\n if (!_has(sourceCache, url)) {\n // URL needs to be able to fetched within the acceptable domain. Otherwise,\n // cross-domain errors will be triggered.\n /*\n Regex matches:\n 0 - Full Url\n 1 - Protocol\n 2 - Domain\n 3 - Port (Useful for internal applications)\n 4 - Path\n */\n let source = '';\n let domain = '';\n try {\n domain = window.document.domain;\n } catch (e) {}\n const match = /(.*)\\:\\/\\/([^:\\/]+)([:\\d]*)\\/{0,1}([\\s\\S]*)/.exec(url);\n if (match && match[2] === domain) {\n source = loadSource(url);\n }\n sourceCache[url] = source ? source.split('\\n') : [];\n }\n\n return sourceCache[url];\n }\n\n /**\n * Tries to use an externally loaded copy of source code to determine\n * the name of a function by looking at the name of the variable it was\n * assigned to, if any.\n * @param {string} url URL of source code.\n * @param {(string|number)} lineNo Line number in source code.\n * @return {string} The function name, if discoverable.\n * @memberof TraceKit.computeStackTrace\n */\n function guessFunctionName(url: string, lineNo: string | number) {\n if (typeof lineNo !== 'number') {\n lineNo = Number(lineNo);\n }\n const reFunctionArgNames = /function ([^(]*)\\(([^)]*)\\)/;\n const reGuessFunction = /['\"]?([0-9A-Za-z$_]+)['\"]?\\s*[:=]\\s*(function|eval|new Function)/;\n let line = '';\n const maxLines = 10;\n const source = getSource(url);\n let m;\n\n if (!source.length) {\n return UNKNOWN_FUNCTION;\n }\n\n // Walk backwards from the first line in the function until we find the line which\n // matches the pattern above, which is the function definition\n for (let i = 0; i < maxLines; ++i) {\n line = source[lineNo - i] + line;\n\n if (!_isUndefined(line)) {\n if ((m = reGuessFunction.exec(line))) {\n return m[1];\n }\n if ((m = reFunctionArgNames.exec(line))) {\n return m[1];\n }\n }\n }\n\n return UNKNOWN_FUNCTION;\n }\n\n /**\n * Retrieves the surrounding lines from where an exception occurred.\n * @param {string} url URL of source code.\n * @param {(string|number)} line Line number in source code to center around for context.\n * @return {SourceContext} Lines of source code and line the source context starts on.\n * @memberof TraceKit.computeStackTrace\n */\n function gatherContext(url: string, line: string | number): SourceContext | null {\n if (typeof line !== 'number') {\n line = Number(line);\n }\n const source = getSource(url);\n\n if (!source.length) {\n return null;\n }\n\n const context = [];\n // linesBefore & linesAfter are inclusive with the offending line.\n // if linesOfContext is even, there will be one extra line\n // *before* the offending line.\n const linesBefore = Math.floor(TraceKit.linesOfContext / 2);\n // Add one extra line if linesOfContext is odd\n const linesAfter = linesBefore + (TraceKit.linesOfContext % 2);\n const start = Math.max(0, line - linesBefore - 1);\n const end = Math.min(source.length, line + linesAfter - 1);\n\n line -= 1; // convert to 0-based index\n\n for (let i = start; i < end; ++i) {\n if (!_isUndefined(source[i])) {\n context.push(source[i]);\n }\n }\n\n return context.length > 0\n ? {\n contextLines: context,\n // Source lines are in base-1.\n startFromSource: start + 1,\n }\n : null;\n }\n /**\n * Escapes special characters, except for whitespace, in a string to be\n * used inside a regular expression as a string literal.\n * @param {string} text The string.\n * @return {string} The escaped string literal.\n * @memberof TraceKit.computeStackTrace\n */\n function escapeRegExp(text: string): string {\n return text.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#]/g, '\\\\$&');\n }\n\n /**\n * Escapes special characters in a string to be used inside a regular\n * expression as a string literal. Also ensures that HTML entities will\n * be matched the same as their literal friends.\n * @param {string} body The string.\n * @return {string} The escaped string.\n * @memberof TraceKit.computeStackTrace\n */\n function escapeCodeAsRegExpForMatchingInsideHTML(body: string): string {\n return escapeRegExp(body)\n .replace('<', '(?:<|&lt;)')\n .replace('>', '(?:>|&gt;)')\n .replace('&', '(?:&|&amp;)')\n .replace('\"', '(?:\"|&quot;)')\n .replace(/\\s+/g, '\\\\s+');\n }\n\n /**\n * Determines where a code fragment occurs in the source code.\n * @param {RegExp} re The function definition.\n * @param {Array.<string>} urls A list of URLs to search.\n * @return {?Object.<string, (string|number)>} An object containing\n * the url, line, and column number of the defined function.\n * @memberof TraceKit.computeStackTrace\n */\n function findSourceInUrls(\n re: RegExp,\n urls: string[],\n ): {\n url: string;\n line: number;\n column: number;\n } | null {\n let source: any;\n let m: any;\n for (let i = 0, j = urls.length; i < j; ++i) {\n if ((source = getSource(urls[i])).length) {\n source = source.join('\\n');\n if ((m = re.exec(source))) {\n return {\n url: urls[i],\n line: source.substring(0, m.index).split('\\n').length,\n column: m.index - source.lastIndexOf('\\n', m.index) - 1,\n };\n }\n }\n }\n\n return null;\n }\n\n /**\n * Determines at which column a code fragment occurs on a line of the\n * source code.\n * @param {string} fragment The code fragment.\n * @param {string} url The URL to search.\n * @param {(string|number)} line The line number to examine.\n * @return {?number} The column number.\n * @memberof TraceKit.computeStackTrace\n */\n function findSourceInLine(fragment: string, url: string, line: string | number): number | null {\n if (typeof line !== 'number') {\n line = Number(line);\n }\n const source = getSource(url);\n const re = new RegExp(`\\\\b${escapeRegExp(fragment)}\\\\b`);\n let m: any;\n\n line -= 1;\n\n if (source && source.length > line && (m = re.exec(source[line]))) {\n return m.index;\n }\n\n return null;\n }\n\n /**\n * Determines where a function was defined within the source code.\n * @param {(Function|string)} func A function reference or serialized\n * function definition.\n * @return {?Object.<string, (string|number)>} An object containing\n * the url, line, and column number of the defined function.\n * @memberof TraceKit.computeStackTrace\n */\n function findSourceByFunctionBody(func: Function | string) {\n if (_isUndefined(window && window.document)) {\n return;\n }\n\n const urls = [window.location.href];\n const scripts = window.document.getElementsByTagName('script');\n let body;\n const code = `${func}`;\n const codeRE = /^function(?:\\s+([\\w$]+))?\\s*\\(([\\w\\s,]*)\\)\\s*\\{\\s*(\\S[\\s\\S]*\\S)\\s*\\}\\s*$/;\n const eventRE = /^function on([\\w$]+)\\s*\\(event\\)\\s*\\{\\s*(\\S[\\s\\S]*\\S)\\s*\\}\\s*$/;\n let re;\n let parts;\n let result;\n\n for (let i = 0; i < scripts.length; ++i) {\n const script = scripts[i];\n if (script.src) {\n urls.push(script.src);\n }\n }\n\n if (!(parts = codeRE.exec(code))) {\n re = new RegExp(escapeRegExp(code).replace(/\\s+/g, '\\\\s+'));\n }\n\n // not sure if this is really necessary, but I don’t have a test\n // corpus large enough to confirm that and it was in the original.\n else {\n const name = parts[1] ? `\\\\s+${parts[1]}` : '';\n const args = parts[2].split(',').join('\\\\s*,\\\\s*');\n\n body = escapeRegExp(parts[3]).replace(/;$/, ';?'); // semicolon is inserted if the function ends with a comment.replace(/\\s+/g, '\\\\s+');\n re = new RegExp(`function${name}\\\\s*\\\\(\\\\s*${args}\\\\s*\\\\)\\\\s*{\\\\s*${body}\\\\s*}`);\n }\n\n // look for a normal function definition\n if ((result = findSourceInUrls(re, urls))) {\n return result;\n }\n\n // look for an old-school event handler function\n if ((parts = eventRE.exec(code))) {\n const event = parts[1];\n body = escapeCodeAsRegExpForMatchingInsideHTML(parts[2]);\n\n // look for a function defined in HTML as an onXXX handler\n re = new RegExp(`on${event}=[\\\\'\"]\\\\s*${body}\\\\s*[\\\\'\"]`, 'i');\n\n // The below line is as it appears in the original code.\n // @ts-expect-error TODO (SDK-1037): Determine if this is a bug or handling for some unexpected case.\n if ((result = findSourceInUrls(re, urls[0]))) {\n return result;\n }\n\n // look for ???\n re = new RegExp(body);\n\n if ((result = findSourceInUrls(re, urls))) {\n return result;\n }\n }\n\n return null;\n }\n\n // Contents of Exception in various browsers.\n //\n // SAFARI:\n // ex.message = Can't find variable: qq\n // ex.line = 59\n // ex.sourceId = 580238192\n // ex.sourceURL = http://...\n // ex.expressionBeginOffset = 96\n // ex.expressionCaretOffset = 98\n // ex.expressionEndOffset = 98\n // ex.name = ReferenceError\n //\n // FIREFOX:\n // ex.message = qq is not defined\n // ex.fileName = http://...\n // ex.lineNumber = 59\n // ex.columnNumber = 69\n // ex.stack = ...stack trace... (see the example below)\n // ex.name = ReferenceError\n //\n // CHROME:\n // ex.message = qq is not defined\n // ex.name = ReferenceError\n // ex.type = not_defined\n // ex.arguments = ['aa']\n // ex.stack = ...stack trace...\n //\n // INTERNET EXPLORER:\n // ex.message = ...\n // ex.name = ReferenceError\n //\n // OPERA:\n // ex.message = ...message... (see the example below)\n // ex.name = ReferenceError\n // ex.opera#sourceloc = 11 (pretty much useless, duplicates the info in ex.message)\n // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace'\n\n /**\n * Computes stack trace information from the stack property.\n * Chrome and Gecko use this property.\n * @param {Error} ex\n * @return {?TraceKit.StackTrace} Stack trace information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceFromStackProp(ex: any): StackTrace | null {\n if (!ex.stack) {\n return null;\n }\n\n const chrome =\n /^\\s*at (.*?) ?\\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|\\/).*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\n const gecko =\n /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\\[native).*?|[^@]*bundle)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\n const winjs =\n /^\\s*at (?:((?:\\[object object\\])?.+) )?\\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\\d+)(?::(\\d+))?\\)?\\s*$/i;\n\n // Used to additionally parse URL/line/column from eval frames\n let isEval;\n const geckoEval = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\n const chromeEval = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\n\n const lines = ex.stack.split('\\n');\n const stack: StackFrame[] = [];\n let submatch: any;\n let parts: any;\n let element: StackFrame;\n const reference: any = /^(.*) is undefined$/.exec(ex.message);\n\n for (let i = 0, j = lines.length; i < j; ++i) {\n if ((parts = chrome.exec(lines[i]))) {\n const isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line\n isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line\n if (isEval && (submatch = chromeEval.exec(parts[2]))) {\n // throw out eval line/column and use top-most line/column number\n parts[2] = submatch[1]; // url\n parts[3] = submatch[2]; // line\n parts[4] = submatch[3]; // column\n }\n element = {\n url: !isNative ? parts[2] : null,\n func: parts[1] || UNKNOWN_FUNCTION,\n args: isNative ? [parts[2]] : [],\n line: parts[3] ? +parts[3] : null,\n column: parts[4] ? +parts[4] : null,\n };\n } else if ((parts = winjs.exec(lines[i]))) {\n element = {\n url: parts[2],\n func: parts[1] || UNKNOWN_FUNCTION,\n args: [],\n line: +parts[3],\n column: parts[4] ? +parts[4] : null,\n };\n } else if ((parts = gecko.exec(lines[i]))) {\n isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n if (isEval && (submatch = geckoEval.exec(parts[3]))) {\n // throw out eval line/column and use top-most line number\n parts[3] = submatch[1];\n parts[4] = submatch[2];\n parts[5] = null; // no column when eval\n } else if (i === 0 && !parts[5] && !_isUndefined(ex.columnNumber)) {\n // FireFox uses this awesome columnNumber property for its top frame\n // Also note, Firefox's column number is 0-based and everything else expects 1-based,\n // so adding 1\n // NOTE: this hack doesn't work if top-most frame is eval\n stack[0].column = ex.columnNumber + 1;\n }\n element = {\n url: parts[3],\n func: parts[1] || UNKNOWN_FUNCTION,\n args: parts[2] ? parts[2].split(',') : [],\n line: parts[4] ? +parts[4] : null,\n column: parts[5] ? +parts[5] : null,\n };\n } else {\n continue;\n }\n\n if (!element.func && element.line) {\n element.func = guessFunctionName(element.url, element.line);\n }\n\n const srcContext = gatherContext(element.url, element.line!);\n element.context = element.line ? (srcContext?.contextLines ?? null) : null;\n element.srcStart = srcContext?.startFromSource;\n stack.push(element);\n }\n\n if (!stack.length) {\n return null;\n }\n\n if (stack[0] && stack[0].line && !stack[0].column && reference) {\n stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line);\n }\n\n return {\n mode: 'stack',\n name: ex.name,\n message: ex.message,\n stack,\n };\n }\n\n /**\n * Computes stack trace information from the stacktrace property.\n * Opera 10+ uses this property.\n * @param {Error} ex\n * @return {?TraceKit.StackTrace} Stack trace information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceFromStacktraceProp(ex: any): StackTrace | null {\n // Access and store the stacktrace property before doing ANYTHING\n // else to it because Opera is not very good at providing it\n // reliably in other circumstances.\n const { stacktrace } = ex;\n if (!stacktrace) {\n return null;\n }\n\n const opera10Regex = / line (\\d+).*script (?:in )?(\\S+)(?:: in function (\\S+))?$/i;\n const opera11Regex =\n / line (\\d+), column (\\d+)\\s*(?:in (?:<anonymous function: ([^>]+)>|([^\\)]+))\\((.*)\\))? in (.*):\\s*$/i;\n const lines = stacktrace.split('\\n');\n const stack = [];\n let parts;\n\n for (let line = 0; line < lines.length; line += 2) {\n let element: StackFrame | null = null;\n if ((parts = opera10Regex.exec(lines[line]))) {\n element = {\n url: parts[2],\n line: +parts[1],\n column: null,\n func: parts[3],\n args: [],\n };\n } else if ((parts = opera11Regex.exec(lines[line]))) {\n element = {\n url: parts[6],\n line: +parts[1],\n column: +parts[2],\n func: parts[3] || parts[4],\n args: parts[5] ? parts[5].split(',') : [],\n };\n }\n\n if (element) {\n if (!element.func && element.line) {\n element.func = guessFunctionName(element.url, element.line);\n }\n if (element.line) {\n try {\n const srcContext = gatherContext(element.url, element.line);\n element.srcStart = srcContext?.startFromSource;\n element.context = element.line ? (srcContext?.contextLines ?? null) : null;\n } catch (exc) {}\n }\n\n if (!element.context) {\n element.context = [lines[line + 1]];\n }\n\n stack.push(element);\n }\n }\n\n if (!stack.length) {\n return null;\n }\n\n return {\n mode: 'stacktrace',\n name: ex.name,\n message: ex.message,\n stack,\n };\n }\n\n /**\n * NOT TESTED.\n * Computes stack trace information from an error message that includes\n * the stack trace.\n * Opera 9 and earlier use this method if the option to show stack\n * traces is turned on in opera:config.\n * @param {Error} ex\n * @return {?TraceKit.StackTrace} Stack information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceFromOperaMultiLineMessage(ex: Error): StackTrace | null {\n // TODO: Clean this function up\n // Opera includes a stack trace into the exception message. An example is:\n //\n // Statement on line 3: Undefined variable: undefinedFunc\n // Backtrace:\n // Line 3 of linked script file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.js: In function zzz\n // undefinedFunc(a);\n // Line 7 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function yyy\n // zzz(x, y, z);\n // Line 3 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function xxx\n // yyy(a, a, a);\n // Line 1 of function script\n // try { xxx('hi'); return false; } catch(ex) { TraceKit.report(ex); }\n // ...\n\n const lines = ex.message.split('\\n');\n if (lines.length < 4) {\n return null;\n }\n\n const lineRE1 =\n /^\\s*Line (\\d+) of linked script ((?:file|https?|blob)\\S+)(?:: in function (\\S+))?\\s*$/i;\n const lineRE2 =\n /^\\s*Line (\\d+) of inline#(\\d+) script in ((?:file|https?|blob)\\S+)(?:: in function (\\S+))?\\s*$/i;\n const lineRE3 = /^\\s*Line (\\d+) of function script\\s*$/i;\n const stack = [];\n const scripts = window && window.document && window.document.getElementsByTagName('script');\n const inlineScriptBlocks = [];\n let parts: any;\n\n for (const s in scripts) {\n if (_has(scripts, s) && !scripts[s].src) {\n inlineScriptBlocks.push(scripts[s]);\n }\n }\n\n for (let line = 2; line < lines.length; line += 2) {\n let item: any = null;\n if ((parts = lineRE1.exec(lines[line]))) {\n item = {\n url: parts[2],\n func: parts[3],\n args: [],\n line: +parts[1],\n column: null,\n };\n } else if ((parts = lineRE2.exec(lines[line]))) {\n item = {\n url: parts[3],\n func: parts[4],\n args: [],\n line: +parts[1],\n column: null, // TODO: Check to see if inline#1 (+parts[2]) points to the script number or column number.\n };\n const relativeLine = +parts[1]; // relative to the start of the <SCRIPT> block\n const script = inlineScriptBlocks[parts[2] - 1];\n if (script) {\n let source: any = getSource(item.url);\n if (source) {\n source = source.join('\\n');\n const pos = source.indexOf(script.innerText);\n if (pos >= 0) {\n item.line = relativeLine + source.substring(0, pos).split('\\n').length;\n }\n }\n }\n } else if ((parts = lineRE3.exec(lines[line]))) {\n const url = window.location.href.replace(/#.*$/, '');\n const re = new RegExp(escapeCodeAsRegExpForMatchingInsideHTML(lines[line + 1]));\n const src = findSourceInUrls(re, [url]);\n item = {\n url,\n func: '',\n args: [],\n line: src ? src.line : parts[1],\n column: null,\n };\n }\n\n if (item) {\n if (!item.func) {\n item.func = guessFunctionName(item.url, item.line);\n }\n const srcContext = gatherContext(item.url, item.line);\n item.srcStart = srcContext?.startFromSource;\n const context = srcContext?.contextLines;\n const midline = context ? context[Math.floor(context.length / 2)] : null;\n if (\n context &&\n midline &&\n midline.replace(/^\\s*/, '') === lines[line + 1].replace(/^\\s*/, '')\n ) {\n item.context = context;\n } else {\n // if (context) alert(\"Context mismatch. Correct midline:\\n\" + lines[i+1] + \"\\n\\nMidline:\\n\" + midline + \"\\n\\nContext:\\n\" + context.join(\"\\n\") + \"\\n\\nURL:\\n\" + item.url);\n item.context = [lines[line + 1]];\n }\n stack.push(item);\n }\n }\n if (!stack.length) {\n return null; // could not parse multiline exception message as Opera stack trace\n }\n\n return {\n mode: 'multiline',\n name: ex.name,\n message: lines[0],\n stack,\n };\n }\n\n /**\n * Adds information about the first frame to incomplete stack traces.\n * Safari and IE require this to get complete data on the first frame.\n * @param {TraceKit.StackTrace} stackInfo Stack trace information from\n * one of the compute* methods.\n * @param {string} url The URL of the script that caused an error.\n * @param {(number|string)} lineNo The line number of the script that\n * caused an error.\n * @param {string=} message The error generated by the browser, which\n * hopefully contains the name of the object that caused the error.\n * @return {boolean} Whether or not the stack information was\n * augmented.\n * @memberof TraceKit.computeStackTrace\n */\n function augmentStackTraceWithInitialElement(\n stackInfo: StackTrace,\n url: string,\n lineNo: number | string,\n message: string,\n ): boolean {\n const initial: any = {\n url,\n line: lineNo,\n };\n\n if (initial.url && initial.line) {\n stackInfo.incomplete = false;\n\n if (!initial.func) {\n initial.func = guessFunctionName(initial.url, initial.line);\n }\n\n if (!initial.context) {\n const srcContext = gatherContext(initial.url, initial.line);\n initial.context = srcContext?.contextLines ?? null;\n initial.srcStart = srcContext?.startFromSource;\n }\n\n const reference = / '([^']+)' /.exec(message);\n if (reference) {\n initial.column = findSourceInLine(reference[1], initial.url, initial.line);\n }\n\n if (stackInfo.stack.length > 0) {\n if (stackInfo.stack[0].url === initial.url) {\n if (stackInfo.stack[0].line === initial.line) {\n return false; // already in stack trace\n }\n if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) {\n stackInfo.stack[0].line = initial.line;\n stackInfo.stack[0].context = initial.context;\n return false;\n }\n }\n }\n\n stackInfo.stack.unshift(initial);\n stackInfo.partial = true;\n return true;\n }\n stackInfo.incomplete = true;\n\n return false;\n }\n\n /**\n * Computes stack trace information by walking the arguments.caller\n * chain at the time the exception occurred. This will cause earlier\n * frames to be missed but is the only way to get any stack trace in\n * Safari and IE. The top frame is restored by\n * {@link augmentStackTraceWithInitialElement}.\n * @param {Error} ex\n * @return {TraceKit.StackTrace=} Stack trace information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceByWalkingCallerChain(ex: any, depth: number) {\n const functionName = /function\\s+([_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*)?\\s*\\(/i;\n const stack = [];\n const funcs = {};\n let recursion = false;\n let parts: any;\n let item: any;\n let source;\n\n for (\n let curr = computeStackTraceByWalkingCallerChain.caller;\n curr && !recursion;\n curr = curr.caller\n ) {\n if (curr === computeStackTrace || curr === TraceKit.report) {\n continue;\n }\n\n item = {\n url: null,\n func: UNKNOWN_FUNCTION,\n args: [],\n line: null,\n column: null,\n };\n\n if (curr.name) {\n item.func = curr.name;\n } else if ((parts = functionName.exec(curr.toString()))) {\n item.func = parts[1];\n }\n\n if (typeof item.func === 'undefined') {\n try {\n item.func = parts.input.substring(0, parts.input.indexOf('{'));\n } catch (e) {}\n }\n\n if ((source = findSourceByFunctionBody(curr))) {\n item.url = source.url;\n item.line = source.line;\n\n if (item.func === UNKNOWN_FUNCTION) {\n item.func = guessFunctionName(item.url, item.line);\n }\n\n const reference = / '([^']+)' /.exec(ex.message || ex.description);\n if (reference) {\n item.column = findSourceInLine(reference[1], source.url, source.line);\n }\n }\n\n // @ts-ignore\n if (funcs[`${curr}`]) {\n recursion = true;\n } else {\n // @ts-ignore\n funcs[`${curr}`] = true;\n }\n\n stack.push(item);\n }\n\n if (depth) {\n stack.splice(0, depth);\n }\n\n const result: StackTrace = {\n mode: 'callers',\n name: ex.name,\n message: ex.message,\n stack,\n };\n augmentStackTraceWithInitialElement(\n result,\n ex.sourceURL || ex.fileName,\n ex.line || ex.lineNumber,\n ex.message || ex.description,\n );\n return result;\n }\n\n /**\n * Computes a stack trace for an exception.\n * @param {Error} ex\n * @param {(string|number)=} depth\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTrace(ex: any, depth: number): StackTrace {\n let stack: StackTrace | null = null;\n depth = depth == null ? 0 : +depth;\n\n try {\n // This must be tried first because Opera 10 *destroys*\n // its stacktrace property if you try to access the stack\n // property first!!\n stack = computeStackTraceFromStacktraceProp(ex);\n if (stack) {\n return stack;\n }\n } catch (e) {\n if (debug) {\n throw e;\n }\n }\n\n try {\n stack = computeStackTraceFromStackProp(ex);\n if (stack) {\n return stack;\n }\n } catch (e) {\n if (debug) {\n throw e;\n }\n }\n\n try {\n stack = computeStackTraceFromOperaMultiLineMessage(ex);\n if (stack) {\n return stack;\n }\n } catch (e) {\n if (debug) {\n throw e;\n }\n }\n\n try {\n stack = computeStackTraceByWalkingCallerChain(ex, depth + 1);\n if (stack) {\n return stack;\n }\n } catch (e) {\n if (debug) {\n throw e;\n }\n }\n\n return {\n name: ex.name,\n message: ex.message,\n mode: 'failed',\n stack: [],\n };\n }\n\n /**\n * Logs a stacktrace starting from the previous call and working down.\n * @param {(number|string)=} depth How many frames deep to trace.\n * @return {TraceKit.StackTrace} Stack trace information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceOfCaller(depth: number): StackTrace {\n depth = (depth == null ? 0 : +depth) + 1; // \"+ 1\" because \"ofCaller\" should drop one frame\n try {\n throw new Error();\n } catch (ex) {\n return computeStackTrace(ex, depth + 1);\n }\n }\n\n computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement;\n computeStackTrace.computeStackTraceFromStackProp = computeStackTraceFromStackProp;\n computeStackTrace.guessFunctionName = guessFunctionName;\n computeStackTrace.gatherContext = gatherContext;\n computeStackTrace.ofCaller = computeStackTraceOfCaller;\n computeStackTrace.getSource = getSource;\n\n return computeStackTrace;\n })();\n\n // Default options:\n if (!TraceKit.remoteFetching) {\n TraceKit.remoteFetching = true;\n }\n if (!TraceKit.collectWindowErrors) {\n TraceKit.collectWindowErrors = true;\n }\n if (!TraceKit.linesOfContext || TraceKit.linesOfContext < 1) {\n // 5 lines before, the offending line, 5 lines after\n TraceKit.linesOfContext = 11;\n }\n})(typeof window !== 'undefined' ? window : global);\n\nexport function getTraceKit(): TraceKitStatic {\n return TraceKit as TraceKitStatic;\n}\n","import { StackFrame } from '../api/stack/StackFrame';\nimport { StackTrace } from '../api/stack/StackTrace';\nimport { ParsedStackOptions } from '../options';\nimport { getTraceKit } from '../vendor/TraceKit';\n\n/**\n * In the browser we will not always be able to determine the source file that code originates\n * from. When you access a route it may just return HTML with embedded source, or just source,\n * in which case there may not be a file name.\n *\n * There will also be cases where there is no source file, such as when running with various\n * dev servers.\n *\n * In these situations we use this constant in place of the file name.\n */\nconst INDEX_SPECIFIER = '(index)';\n\n/**\n * For files hosted on the origin attempt to reduce to just a filename.\n * If the origin matches the source file, then the special identifier `(index)` will\n * be used.\n *\n * @param input The input URL.\n * @returns The output file name.\n */\nexport function processUrlToFileName(input: string, origin: string): string {\n let cleaned = input;\n if (input.startsWith(origin)) {\n cleaned = input.slice(origin.length);\n // If the input is a single `/` then it would get removed and we would\n // be left with an empty string. That empty string would get replaced with\n // the INDEX_SPECIFIER. In cases where a `/` remains, either singular\n // or at the end of a path, then we will append the index specifier.\n // For instance the route `/test/` would ultimately be `test/(index)`.\n if (cleaned.startsWith('/')) {\n cleaned = cleaned.slice(1);\n }\n\n if (cleaned === '') {\n return INDEX_SPECIFIER;\n }\n\n if (cleaned.endsWith('/')) {\n cleaned += INDEX_SPECIFIER;\n }\n }\n return cleaned;\n}\n\n/**\n * Clamp a value to be between an inclusive max an minimum.\n *\n * @param min The inclusive minimum value.\n * @param max The inclusive maximum value.\n * @param value The value to clamp.\n * @returns The clamped value in range [min, max].\n */\nfunction clamp(min: number, max: number, value: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nexport interface TrimOptions {\n /**\n * The maximum length of the trimmed line.\n */\n maxLength: number;\n\n /**\n * If the line needs to be trimmed, then this is the number of character to retain before the\n * originating character of the frame.\n */\n beforeColumnCharacters: number;\n}\n\n/**\n * Trim a source string to a reasonable size.\n *\n * @param options Configuration which affects trimming.\n * @param line The source code line to trim.\n * @param column The column which the stack frame originates from.\n * @returns A trimmed source string.\n */\nexport function trimSourceLine(options: TrimOptions, line: string, column: number): string {\n if (line.length <= options.maxLength) {\n return line;\n }\n const captureStart = Math.max(0, column - options.beforeColumnCharacters);\n const captureEnd = Math.min(line.length, captureStart + options.maxLength);\n return line.slice(captureStart, captureEnd);\n}\n\n/**\n * Given a context get trimmed source lines within the specified range.\n *\n * The context is a list of source code lines, this function returns a subset of\n * lines which have been trimmed.\n *\n * If an error is on a specific line of source code we want to be able to get\n * lines before and after that line. This is done relative to the originating\n * line of source.\n *\n * If you wanted to get 3 lines before the origin line, then this function would\n * need to be called with `start: originLine - 3, end: originLine`.\n *\n * If the `start` would underflow the context, then the start is set to 0.\n * If the `end` would overflow the context, then the end is set to the context\n * length.\n *\n * Exported for testing.\n *\n * @param start The inclusive start index.\n * @param end The exclusive end index.\n * @param trimmer Method which will trim individual lines.\n */\nexport function getLines(\n start: number,\n end: number,\n context: string[],\n trimmer: (val: string) => string,\n): string[] {\n const adjustedStart = start < 0 ? 0 : start;\n const adjustedEnd = end > context.length ? context.length : end;\n if (adjustedStart < adjustedEnd) {\n return context.slice(adjustedStart, adjustedEnd).map(trimmer);\n }\n return [];\n}\n\n/**\n * Given a stack frame produce source context about that stack frame.\n *\n * The source context includes the source line of the stack frame, some number\n * of lines before the line of the stack frame, and some number of lines\n * after the stack frame. The amount of context can be controlled by the\n * provided options.\n *\n * Exported for testing.\n */\nexport function getSrcLines(\n inFrame: {\n // Tracekit returns null potentially. We accept undefined as well to be as lenient here\n // as we can.\n context?: string[] | null;\n column?: number | null;\n srcStart?: number | null;\n line?: number | null;\n },\n options: ParsedStackOptions,\n): {\n srcBefore?: string[];\n srcLine?: string;\n srcAfter?: string[];\n} {\n const { context } = inFrame;\n // It should be present, but we don't want to trust that it is.\n if (!context) {\n return {};\n }\n const { maxLineLength } = options.source;\n const beforeColumnCharacters = Math.floor(maxLineLength / 2);\n\n // The before and after lines will not be precise while we use TraceKit.\n // By forking it we should be able to achieve a more optimal result.\n // We only need to do this if we are not getting sufficient quality using this\n // method.\n\n // Trimmer for non-origin lines. Starts at column 0.\n // Non-origin lines are lines which are not the line for a specific stack\n // frame, but instead the lines before or after that frame.\n // ```\n // console.log(\"before origin\"); // non-origin line\n // throw new Error(\"this is the origin\"); // origin line\n // console.log(\"after origin); // non-origin line\n // ```\n const trimmer = (input: string) =>\n trimSourceLine(\n {\n maxLength: options.source.maxLineLength,\n beforeColumnCharacters,\n },\n input,\n 0,\n );\n\n const origin = clamp(0, context.length - 1, (inFrame?.line ?? 0) - (inFrame.srcStart ?? 0));\n\n return {\n // The lines immediately preceeding the origin line.\n srcBefore: getLines(origin - options.source.beforeLines, origin, context, trimmer),\n srcLine: trimSourceLine(\n {\n maxLength: maxLineLength,\n beforeColumnCharacters,\n },\n context[origin],\n inFrame.column || 0,\n ),\n // The lines immediately following the origin line.\n srcAfter: getLines(origin + 1, origin + 1 + options.source.afterLines, context, trimmer),\n };\n}\n\n/**\n * Parse the browser stack trace into a StackTrace which contains frames with specific fields parsed\n * from the free-form stack. Browser stack traces are not standardized, so implementations handling\n * the output should be resilient to missing fields.\n *\n * @param error The error to generate a StackTrace for.\n * @returns The stack trace for the given error.\n */\nexport default function parse(error: Error, options: ParsedStackOptions): StackTrace {\n if (!options.enabled) {\n return {\n frames: [],\n };\n }\n\n const parsed = getTraceKit().computeStackTrace(error);\n const frames: StackFrame[] = parsed.stack.reverse().map((inFrame) => ({\n fileName: processUrlToFileName(inFrame.url, window.location.origin),\n function: inFrame.func,\n // Strip the nulls so we only ever return undefined.\n line: inFrame.line ?? undefined,\n col: inFrame.column ?? undefined,\n ...getSrcLines(inFrame, options),\n }));\n return {\n frames,\n };\n}\n","/**\n * A limited selection of type information is provided by the browser client SDK.\n * This is only a type dependency and these types should be compatible between\n * SDKs.\n */\nimport type { LDContext, LDEvaluationDetail } from '@launchdarkly/js-client-sdk';\n\nimport { LDClientInitialization, LDClientLogging, LDClientTracking, MinLogger } from './api';\nimport { Breadcrumb, FeatureManagementBreadcrumb } from './api/Breadcrumb';\nimport { BrowserTelemetry } from './api/BrowserTelemetry';\nimport { BrowserTelemetryInspector } from './api/client/BrowserTelemetryInspector';\nimport { Collector } from './api/Collector';\nimport { ErrorData } from './api/ErrorData';\nimport { EventData } from './api/EventData';\nimport ClickCollector from './collectors/dom/ClickCollector';\nimport KeypressCollector from './collectors/dom/KeypressCollector';\nimport ErrorCollector from './collectors/error';\nimport FetchCollector from './collectors/http/fetch';\nimport XhrCollector from './collectors/http/xhr';\nimport defaultUrlFilter from './filters/defaultUrlFilter';\nimport makeInspectors from './inspectors';\nimport { fallbackLogger, prefixLog } from './logging';\nimport { ParsedOptions, ParsedStackOptions } from './options';\nimport randomUuidV4 from './randomUuidV4';\nimport parse from './stack/StackParser';\nimport { getTraceKit } from './vendor/TraceKit';\n\n// TODO: Use a ring buffer for the breadcrumbs/pending events instead of shifting. (SDK-914)\n\nconst CUSTOM_KEY_PREFIX = '$ld:telemetry';\nconst ERROR_KEY = `${CUSTOM_KEY_PREFIX}:error`;\nconst SESSION_INIT_KEY = `${CUSTOM_KEY_PREFIX}:session:init`;\nconst GENERIC_EXCEPTION = 'generic';\nconst NULL_EXCEPTION_MESSAGE = 'exception was null or undefined';\nconst MISSING_MESSAGE = 'exception had no message';\n\n// Timeout for client initialization. The telemetry SDK doesn't require that the client be initialized, but it does\n// require that the context processing that happens during initialization complete. This is some subset of the total\n// initialization time, but we don't care if initialization actually completes within the, just that the context\n// is available for event sending.\nconst INITIALIZATION_TIMEOUT = 5;\n\n/**\n * Given a flag value ensure it is safe for analytics.\n *\n * If the parameter is not safe, then return undefined.\n *\n * TODO: Add limited JSON support. (SDK-916)\n * @param u The value to check.\n * @returns Either the value or undefined.\n */\nfunction safeValue(u: unknown): string | boolean | number | undefined {\n switch (typeof u) {\n case 'string':\n case 'boolean':\n case 'number':\n return u;\n default:\n return undefined;\n }\n}\n\nfunction applyFilter<T>(item: T | undefined, filter: (item: T) => T | undefined): T | undefined {\n return item === undefined ? undefined : filter(item);\n}\n\nfunction configureTraceKit(options: ParsedStackOptions) {\n if (!options.enabled) {\n return;\n }\n\n const TraceKit = getTraceKit();\n // Include before + after + source line.\n // TraceKit only takes a total context size, so we have to over capture and then reduce the lines.\n // So, for instance if before is 3 and after is 4 we need to capture 4 and 4 and then drop a line\n // from the before context.\n // The typing for this is a bool, but it accepts a number.\n const beforeAfterMax = Math.max(options.source.afterLines, options.source.beforeLines);\n // The assignment here has bene split to prevent esbuild from complaining about an assignment to\n // an import. TraceKit exports a single object and the interface requires modifying an exported\n // var.\n const anyObj = TraceKit as any;\n anyObj.linesOfContext = beforeAfterMax * 2 + 1;\n}\n\n/**\n * Check if the client supports LDClientLogging.\n *\n * @param client The client to check.\n * @returns True if the client is an instance of LDClientLogging.\n */\nfunction isLDClientLogging(client: unknown): client is LDClientLogging {\n return (client as any).logger !== undefined;\n}\n\nfunction isLDClientInitialization(client: unknown): client is LDClientInitialization {\n return (client as any).waitForInitialization !== undefined;\n}\n\nexport default class BrowserTelemetryImpl implements BrowserTelemetry {\n private _maxPendingEvents: number;\n private _maxBreadcrumbs: number;\n\n private _pendingEvents: { type: string; data: EventData }[] = [];\n private _client?: LDClientTracking;\n\n private _breadcrumbs: Breadcrumb[] = [];\n\n private _inspectorInstances: BrowserTelemetryInspector[] = [];\n private _collectors: Collector[] = [];\n private _sessionId: string = randomUuidV4();\n\n private _logger: MinLogger;\n\n private _registrationComplete: boolean = false;\n\n // Used to ensure we only log the event dropped message once.\n private _eventsDropped: boolean = false;\n // Used to ensure we only log the breadcrumb filter error once.\n private _breadcrumbFilterError: boolean = false;\n // Used to ensure we only log the error filter error once.\n private _errorFilterError: boolean = false;\n\n constructor(private _options: ParsedOptions) {\n configureTraceKit(_options.stack);\n\n // Error collector is always required.\n this._collectors.push(new ErrorCollector());\n this._collectors.push(..._options.collectors);\n\n this._maxPendingEvents = _options.maxPendingEvents;\n this._maxBreadcrumbs = _options.breadcrumbs.maxBreadcrumbs;\n\n // Set the initial logger, it may be replaced when the client is registered.\n // For typescript purposes, we need the logger to be directly set in the constructor.\n this._logger = this._options.logger ?? fallbackLogger;\n\n const urlFilters = [defaultUrlFilter];\n if (_options.breadcrumbs.http.customUrlFilter) {\n urlFilters.push(_options.breadcrumbs.http.customUrlFilter);\n }\n\n if (_options.breadcrumbs.http.instrumentFetch) {\n this._collectors.push(\n new FetchCollector({\n urlFilters,\n getLogger: () => this._logger,\n }),\n );\n }\n\n if (_options.breadcrumbs.http.instrumentXhr) {\n this._collectors.push(\n new XhrCollector({\n urlFilters,\n getLogger: () => this._logger,\n }),\n );\n }\n\n if (_options.breadcrumbs.click) {\n this._collectors.push(new ClickCollector());\n }\n\n if (_options.breadcrumbs.keyboardInput) {\n this._collectors.push(new KeypressCollector());\n }\n\n this._collectors.forEach((collector) =>\n collector.register(this as BrowserTelemetry, this._sessionId),\n );\n\n const impl = this;\n const inspectors: BrowserTelemetryInspector[] = [];\n makeInspectors(_options, inspectors, impl);\n this._inspectorInstances.push(...inspectors);\n }\n\n register(client: LDClientTracking): void {\n if (this._client !== undefined) {\n return;\n }\n\n this._client = client;\n\n // When the client is registered, we need to set the logger again, because we may be able to use the client's\n // logger.\n this._setLogger();\n\n const completeRegistration = () => {\n this._client?.track(SESSION_INIT_KEY, { sessionId: this._sessionId });\n\n this._pendingEvents.forEach((event) => {\n this._client?.track(event.type, event.data);\n });\n this._pendingEvents = [];\n this._registrationComplete = true;\n };\n\n if (isLDClientInitialization(client)) {\n // We don't actually need the client initialization to complete, but we do need the context processing that\n // happens during initialization to complete. This time will be some time greater than that, but we don't\n // care if initialization actually completes within the timeout.\n\n // An immediately invoked async function is used to ensure that the registration method can be called synchronously.\n // Making the `register` method async would increase the complexity for application developers.\n (async () => {\n try {\n await client.waitForInitialization(INITIALIZATION_TIMEOUT);\n } catch {\n // We don't care if the initialization fails.\n }\n completeRegistration();\n })();\n } else {\n // TODO(EMSR-36): Figure out how to handle the 4.x implementation.\n completeRegistration();\n }\n }\n\n private _setLogger() {\n // If the user has provided a logger, then we want to prioritize that over the client's logger.\n // If the client supports LDClientLogging, then we to prioritize that over the fallback logger.\n if (this._options.logger) {\n this._logger = this._options.logger;\n } else if (isLDClientLogging(this._client)) {\n this._logger = this._client.logger;\n } else {\n this._logger = fallbackLogger;\n }\n }\n\n inspectors(): BrowserTelemetryInspector[] {\n return this._inspectorInstances;\n }\n\n /**\n * Capture an event.\n *\n * If the LaunchDarkly client SDK is not yet registered, then the event\n * will be buffered until the client is registered.\n * @param type The type of event to capture.\n * @param event The event data.\n */\n private _capture(type: string, event: EventData) {\n const filteredEvent = this._applyFilters(event, this._options.errorFilters, (e: unknown) => {\n if (!this._errorFilterError) {\n this._errorFilterError = true;\n this._logger.warn(prefixLog(`Error applying error filters: ${e}`));\n }\n });\n if (filteredEvent === undefined) {\n return;\n }\n\n if (this._registrationComplete) {\n this._client?.track(type, filteredEvent);\n } else {\n this._pendingEvents.push({ type, data: filteredEvent });\n if (this._pendingEvents.length > this._maxPendingEvents) {\n if (!this._eventsDropped) {\n this._eventsDropped = true;\n this._logger.warn(\n prefixLog(\n `Maximum pending events reached. Old events will be dropped until the SDK client is registered.`,\n ),\n );\n }\n this._pendingEvents.shift();\n }\n }\n }\n\n captureError(exception: Error): void {\n const validException = exception !== undefined && exception !== null;\n\n const data: ErrorData = validException\n ? {\n type: exception.name || exception.constructor?.name || GENERIC_EXCEPTION,\n // Only coalesce null/undefined, not empty.\n message: exception.message ?? MISSING_MESSAGE,\n stack: parse(exception, this._options.stack),\n breadcrumbs: [...this._breadcrumbs],\n sessionId: this._sessionId,\n }\n : {\n type: GENERIC_EXCEPTION,\n message: NULL_EXCEPTION_MESSAGE,\n stack: { frames: [] },\n breadcrumbs: [...this._breadcrumbs],\n sessionId: this._sessionId,\n };\n this._capture(ERROR_KEY, data);\n }\n\n captureErrorEvent(errorEvent: ErrorEvent): void {\n this.captureError(errorEvent.error);\n }\n\n private _applyFilters<T>(\n item: T,\n filters: ((item: T) => T | undefined)[],\n handleError: (e: unknown) => void,\n ): T | undefined {\n try {\n return filters.reduce(\n (itemToFilter: T | undefined, filter: (item: T) => T | undefined) =>\n applyFilter(itemToFilter, filter),\n item,\n );\n } catch (e) {\n handleError(e);\n return undefined;\n }\n }\n\n addBreadcrumb(breadcrumb: Breadcrumb): void {\n const filtered = this._applyFilters(\n breadcrumb,\n this._options.breadcrumbs.filters,\n (e: unknown) => {\n if (!this._breadcrumbFilterError) {\n this._breadcrumbFilterError = true;\n this._logger.warn(prefixLog(`Error applying breadcrumb filters: ${e}`));\n }\n },\n );\n if (filtered !== undefined) {\n this._breadcrumbs.push(filtered);\n if (this._breadcrumbs.length > this._maxBreadcrumbs) {\n this._breadcrumbs.shift();\n }\n }\n }\n\n close(): void {\n this._collectors.forEach((collector) => collector.unregister());\n }\n\n /**\n * Used to automatically collect flag usage for breadcrumbs.\n *\n * When session replay is in use the data is also forwarded to the session\n * replay collector.\n *\n * @internal\n */\n handleFlagUsed(flagKey: string, detail: LDEvaluationDetail, _context?: LDContext): void {\n const breadcrumb: FeatureManagementBreadcrumb = {\n type: 'flag-evaluated',\n data: {\n key: flagKey,\n value: safeValue(detail.value),\n },\n timestamp: new Date().getTime(),\n class: 'feature-management',\n level: 'info',\n };\n this.addBreadcrumb(breadcrumb);\n }\n\n /**\n * Used to automatically collect flag detail changes.\n *\n * When session replay is in use the data is also forwarded to the session\n * replay collector.\n *\n * @internal\n */\n handleFlagDetailChanged(flagKey: string, detail: LDEvaluationDetail): void {\n const breadcrumb: FeatureManagementBreadcrumb = {\n type: 'flag-detail-changed',\n data: {\n key: flagKey,\n value: safeValue(detail.value),\n },\n timestamp: new Date().getTime(),\n class: 'feature-management',\n level: 'info',\n };\n\n this.addBreadcrumb(breadcrumb);\n }\n}\n","import { Collector } from './api/Collector';\nimport { MinLogger } from './api/MinLogger';\nimport {\n BreadcrumbFilter,\n BreadcrumbsOptions,\n ErrorDataFilter,\n HttpBreadcrumbOptions,\n Options,\n StackOptions,\n UrlFilter,\n} from './api/Options';\nimport { fallbackLogger, prefixLog, safeMinLogger } from './logging';\n\nconst disabledBreadcrumbs: ParsedBreadcrumbsOptions = {\n maxBreadcrumbs: 0,\n evaluations: false,\n flagChange: false,\n click: false,\n keyboardInput: false,\n http: {\n instrumentFetch: false,\n instrumentXhr: false,\n customUrlFilter: undefined,\n },\n filters: [],\n};\n\nconst disabledStack: ParsedStackOptions = {\n enabled: false,\n source: {\n beforeLines: 0,\n afterLines: 0,\n maxLineLength: 0,\n },\n};\n\nexport function defaultOptions(): ParsedOptions {\n return {\n breadcrumbs: {\n maxBreadcrumbs: 50,\n evaluations: true,\n flagChange: true,\n click: true,\n keyboardInput: true,\n http: {\n instrumentFetch: true,\n instrumentXhr: true,\n },\n filters: [],\n },\n stack: {\n enabled: true,\n source: {\n beforeLines: 3,\n afterLines: 3,\n maxLineLength: 280,\n },\n },\n maxPendingEvents: 100,\n collectors: [],\n errorFilters: [],\n };\n}\n\nfunction wrongOptionType(name: string, expectedType: string, actualType: string): string {\n return prefixLog(\n `Config option \"${name}\" should be of type ${expectedType}, got ${actualType}, using default value`,\n );\n}\n\nfunction checkBasic<T>(type: string, name: string, logger?: MinLogger): (item: T) => boolean {\n return (item: T) => {\n const actualType = typeof item;\n if (actualType === type) {\n return true;\n }\n logger?.warn(wrongOptionType(name, type, actualType));\n return false;\n };\n}\n\nfunction itemOrDefault<T>(item: T | undefined, defaultValue: T, checker?: (item: T) => boolean): T {\n if (item !== undefined && item !== null) {\n if (!checker) {\n return item;\n }\n if (checker(item)) {\n return item;\n }\n }\n return defaultValue;\n}\n\nfunction parseHttp(\n options: HttpBreadcrumbOptions | false | undefined,\n defaults: ParsedHttpOptions,\n logger?: MinLogger,\n): ParsedHttpOptions {\n if (options !== undefined && options !== false && typeof options !== 'object') {\n logger?.warn(\n wrongOptionType('breadcrumbs.http', 'HttpBreadCrumbOptions | false', typeof options),\n );\n return defaults;\n }\n\n if (options === false) {\n return {\n instrumentFetch: false,\n instrumentXhr: false,\n };\n }\n\n // Make sure that the custom filter is at least a function.\n if (options?.customUrlFilter) {\n if (typeof options.customUrlFilter !== 'function') {\n logger?.warn(\n prefixLog(\n `The \"breadcrumbs.http.customUrlFilter\" must be a function. Received ${typeof options.customUrlFilter}`,\n ),\n );\n }\n }\n const customUrlFilter =\n options?.customUrlFilter && typeof options?.customUrlFilter === 'function'\n ? options.customUrlFilter\n : undefined;\n\n return {\n instrumentFetch: itemOrDefault(\n options?.instrumentFetch,\n defaults.instrumentFetch,\n checkBasic('boolean', 'breadcrumbs.http.instrumentFetch', logger),\n ),\n instrumentXhr: itemOrDefault(\n options?.instrumentXhr,\n defaults.instrumentXhr,\n checkBasic('boolean', 'breadcrumbs.http.instrumentXhr', logger),\n ),\n customUrlFilter,\n };\n}\n\nfunction parseLogger(options: Options): MinLogger | undefined {\n if (options.logger) {\n const { logger } = options;\n if (typeof logger === 'object' && logger !== null && 'warn' in logger) {\n return safeMinLogger(logger);\n }\n // Using console.warn here because the logger is not suitable to log with.\n fallbackLogger.warn(wrongOptionType('logger', 'MinLogger or LDLogger', typeof logger));\n }\n return undefined;\n}\n\nfunction parseStack(\n options: StackOptions | false | undefined,\n defaults: ParsedStackOptions,\n logger?: MinLogger,\n): ParsedStackOptions {\n if (options === false) {\n return disabledStack;\n }\n return {\n // Internal option not parsed from the options object.\n enabled: true,\n source: {\n beforeLines: itemOrDefault(\n options?.source?.beforeLines,\n defaults.source.beforeLines,\n checkBasic('number', 'stack.beforeLines', logger),\n ),\n afterLines: itemOrDefault(\n options?.source?.afterLines,\n defaults.source.afterLines,\n checkBasic('number', 'stack.afterLines', logger),\n ),\n maxLineLength: itemOrDefault(\n options?.source?.maxLineLength,\n defaults.source.maxLineLength,\n checkBasic('number', 'stack.maxLineLength', logger),\n ),\n },\n };\n}\n\nfunction parseBreadcrumbs(\n options: BreadcrumbsOptions | false | undefined,\n defaults: ParsedBreadcrumbsOptions,\n logger: MinLogger | undefined,\n): ParsedBreadcrumbsOptions {\n if (options === false) {\n return disabledBreadcrumbs;\n }\n return {\n maxBreadcrumbs: itemOrDefault(\n options?.maxBreadcrumbs,\n defaults.maxBreadcrumbs,\n checkBasic('number', 'breadcrumbs.maxBreadcrumbs', logger),\n ),\n evaluations: itemOrDefault(\n options?.evaluations,\n defaults.evaluations,\n checkBasic('boolean', 'breadcrumbs.evaluations', logger),\n ),\n flagChange: itemOrDefault(\n options?.flagChange,\n defaults.flagChange,\n checkBasic('boolean', 'breadcrumbs.flagChange', logger),\n ),\n click: itemOrDefault(\n options?.click,\n defaults.click,\n checkBasic('boolean', 'breadcrumbs.click', logger),\n ),\n keyboardInput: itemOrDefault(\n options?.keyboardInput,\n defaults.keyboardInput,\n checkBasic('boolean', 'breadcrumbs.keyboardInput', logger),\n ),\n http: parseHttp(options?.http, defaults.http, logger),\n filters: itemOrDefault(options?.filters, defaults.filters, (item) => {\n if (Array.isArray(item)) {\n return true;\n }\n logger?.warn(wrongOptionType('breadcrumbs.filters', 'BreadcrumbFilter[]', typeof item));\n return false;\n }),\n };\n}\n\nexport default function parse(options: Options, logger?: MinLogger): ParsedOptions {\n const defaults = defaultOptions();\n if (options.breadcrumbs) {\n checkBasic('object', 'breadcrumbs', logger)(options.breadcrumbs);\n }\n if (options.stack) {\n checkBasic('object', 'stack', logger)(options.stack);\n }\n return {\n breadcrumbs: parseBreadcrumbs(options.breadcrumbs, defaults.breadcrumbs, logger),\n stack: parseStack(options.stack, defaults.stack, logger),\n maxPendingEvents: itemOrDefault(\n options.maxPendingEvents,\n defaults.maxPendingEvents,\n checkBasic('number', 'maxPendingEvents', logger),\n ),\n collectors: [\n ...itemOrDefault(options.collectors, defaults.collectors, (item) => {\n if (Array.isArray(item)) {\n return true;\n }\n logger?.warn(wrongOptionType('collectors', 'Collector[]', typeof item));\n return false;\n }),\n ],\n logger: parseLogger(options),\n errorFilters: itemOrDefault(options.errorFilters, defaults.errorFilters, (item) => {\n if (Array.isArray(item)) {\n return true;\n }\n logger?.warn(wrongOptionType('errorFilters', 'ErrorDataFilter[]', typeof item));\n return false;\n }),\n };\n}\n\n/**\n * Internal type for parsed http options.\n * @internal\n */\nexport interface ParsedHttpOptions {\n /**\n * True to instrument fetch and enable fetch breadcrumbs.\n */\n instrumentFetch: boolean;\n\n /**\n * True to instrument XMLHttpRequests and enable XMLHttpRequests breadcrumbs.\n */\n instrumentXhr: boolean;\n\n /**\n * Optional custom URL filter.\n */\n customUrlFilter?: UrlFilter;\n}\n\n/**\n * Internal type for parsed stack options.\n * @internal\n */\nexport interface ParsedStackOptions {\n enabled: boolean;\n source: {\n /**\n * The number of lines captured before the originating line.\n */\n beforeLines: number;\n\n /**\n * The number of lines captured after the originating line.\n */\n afterLines: number;\n\n /**\n * The maximum length of source line to include. Lines longer than this will be\n * trimmed.\n */\n maxLineLength: number;\n };\n}\n\n/**\n * Internal type for parsed breadcrumbs options.\n * @internal\n */\nexport interface ParsedBreadcrumbsOptions {\n /**\n * Set the maximum number of breadcrumbs. Defaults to 50.\n */\n maxBreadcrumbs: number;\n\n /**\n * True to enable automatic evaluation breadcrumbs. Defaults to true.\n */\n evaluations: boolean;\n\n /**\n * True to enable flag change breadcrumbs. Defaults to true.\n */\n flagChange: boolean;\n\n /**\n * True to enable click breadcrumbs. Defaults to true.\n */\n click: boolean;\n\n /**\n * True to enable input breadcrumbs for keypresses. Defaults to true.\n */\n keyboardInput?: boolean;\n\n /**\n * Settings for http instrumentation and breadcrumbs.\n */\n http: ParsedHttpOptions;\n\n /**\n * Custom breadcrumb filters.\n */\n filters: BreadcrumbFilter[];\n}\n\n/**\n * Internal type for parsed options.\n * @internal\n */\nexport interface ParsedOptions {\n /**\n * The maximum number of pending events. Events may be captured before the LaunchDarkly\n * SDK is initialized and these are stored until they can be sent. This only affects the\n * events captured during initialization.\n */\n maxPendingEvents: number;\n\n /**\n * Properties related to automatic breadcrumb collection, or `false` to disable automatic breadcrumbs.\n */\n breadcrumbs: ParsedBreadcrumbsOptions;\n\n /**\n * Settings which affect call stack capture, or `false` to exclude stack frames from error events .\n */\n stack: ParsedStackOptions;\n\n /**\n * Additional, or custom, collectors.\n */\n collectors: Collector[];\n\n /**\n * Logger to use for warnings.\n */\n logger?: MinLogger;\n\n /**\n * Custom error data filters.\n */\n errorFilters: ErrorDataFilter[];\n}\n","import { Options } from '../api';\nimport { BrowserTelemetry } from '../api/BrowserTelemetry';\nimport BrowserTelemetryImpl from '../BrowserTelemetryImpl';\nimport { fallbackLogger, prefixLog, safeMinLogger } from '../logging';\nimport parse from '../options';\n\nlet telemetryInstance: BrowserTelemetry | undefined;\nlet warnedClientNotInitialized: boolean = false;\n\n/**\n * Initialize the LaunchDarkly telemetry client\n *\n * This method should be called one time as early as possible in the application lifecycle.\n *\n * @example\n * ```\n * import { initTelemetry } from '@launchdarkly/browser-telemetry';\n *\n * initTelemetry();\n * ```\n *\n * After initialization the telemetry client must be registered with the LaunchDarkly SDK client.\n *\n * @example\n * ```\n * import { initTelemetry, register } from '@launchdarkly/browser-telemetry';\n *\n * initTelemetry();\n *\n * // Create your LaunchDarkly client following the LaunchDarkly SDK documentation.\n *\n * register(ldClient);\n * ```\n *\n * If using the 3.x version of the LaunchDarkly SDK, then you must also add inspectors when initializing your LaunchDarkly client.\n * This allows for integration with feature flag data.\n *\n * @example\n * ```\n * import { initTelemetry, register, inspectors } from '@launchdarkly/browser-telemetry';\n * import { init } from 'launchdarkly-js-client-sdk';\n *\n * initTelemetry();\n *\n * const ldClient = init('YOUR_CLIENT_SIDE_ID', {\n * inspectors: inspectors()\n * });\n *\n * register(ldClient);\n * ```\n *\n * @param options The options to use for the telemetry instance. Refer to {@link Options} for more information.\n */\nexport function initTelemetry(options?: Options) {\n const logger = safeMinLogger(options?.logger);\n\n if (telemetryInstance) {\n logger.warn(prefixLog('Telemetry has already been initialized. Ignoring new options.'));\n return;\n }\n\n const parsedOptions = parse(options || {}, logger);\n telemetryInstance = new BrowserTelemetryImpl(parsedOptions);\n}\n\n/**\n * Get the telemetry instance.\n *\n * In typical operation this method doesn't need to be called. Instead the functions exported by this package directly\n * use the telemetry instance.\n *\n * This function can be used when the telemetry instance needs to be injected into code instead of accessed globally.\n *\n * @returns The telemetry instance, or undefined if it has not been initialized.\n */\nexport function getTelemetryInstance(): BrowserTelemetry | undefined {\n if (!telemetryInstance) {\n if (warnedClientNotInitialized) {\n return undefined;\n }\n\n fallbackLogger.warn(prefixLog('Telemetry has not been initialized'));\n warnedClientNotInitialized = true;\n return undefined;\n }\n\n return telemetryInstance;\n}\n\n/**\n * Reset the telemetry instance to its initial state.\n *\n * This method is intended to be used in tests.\n *\n * @internal\n */\nexport function resetTelemetryInstance() {\n telemetryInstance = undefined;\n warnedClientNotInitialized = false;\n}\n","import { LDClientTracking } from '../api';\nimport { Breadcrumb } from '../api/Breadcrumb';\nimport { BrowserTelemetryInspector } from '../api/client/BrowserTelemetryInspector';\nimport { getTelemetryInstance } from './singletonInstance';\n\n/**\n * Returns an array of active SDK inspectors to use with SDK versions that do\n * not support hooks.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, this method will return an empty array.\n *\n * @returns An array of {@link BrowserTelemetryInspector} objects.\n */\nexport function inspectors(): BrowserTelemetryInspector[] {\n return getTelemetryInstance()?.inspectors() || [];\n}\n\n/**\n * Captures an Error object for telemetry purposes.\n *\n * Use this method to manually capture errors during application operation.\n * Unhandled errors are automatically captured, but this method can be used\n * to capture errors which were handled, but are still useful for telemetry.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, then the exception will be discarded.\n *\n * @param exception The Error object to capture\n */\nexport function captureError(exception: Error): void {\n getTelemetryInstance()?.captureError(exception);\n}\n\n/**\n * Captures a browser ErrorEvent for telemetry purposes.\n *\n * This method can be used to capture a manually created error event. Use this\n * function to represent application specific errors which cannot be captured\n * automatically or are not `Error` types.\n *\n * For most errors {@link captureError} should be used.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, then the error event will be discarded.\n *\n * @param errorEvent The ErrorEvent to capture\n */\nexport function captureErrorEvent(errorEvent: ErrorEvent): void {\n getTelemetryInstance()?.captureErrorEvent(errorEvent);\n}\n\n/**\n * Add a breadcrumb which will be included with telemetry events.\n *\n * Many breadcrumbs can be automatically captured, but this method can be\n * used for capturing manual breadcrumbs. For application specific breadcrumbs\n * the {@link CustomBreadcrumb} type can be used.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, then the breadcrumb will be discarded.\n *\n * @param breadcrumb The breadcrumb to add.\n */\nexport function addBreadcrumb(breadcrumb: Breadcrumb): void {\n getTelemetryInstance()?.addBreadcrumb(breadcrumb);\n}\n\n/**\n * Registers a LaunchDarkly client instance for telemetry tracking.\n *\n * This method connects the telemetry system to the specific LaunchDarkly\n * client instance. The client instance will be used to report telemetry\n * to LaunchDarkly and also for collecting flag and context data.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, then the client will not be registered, and no events will be sent to LaunchDarkly.\n *\n * @param client The {@link LDClientTracking} instance to register for\n * telemetry.\n */\nexport function register(client: LDClientTracking): void {\n getTelemetryInstance()?.register(client);\n}\n\n/**\n * Closes the telemetry system and stops data collection.\n *\n * In general usage this method is not required, but it can be used in cases\n * where collection needs to be stopped independent of application\n * lifecycle.\n *\n * If telemetry is not initialized, using {@link initTelemetry}, then this method will do nothing.\n */\nexport function close(): void {\n getTelemetryInstance()?.close();\n}\n"],"mappings":"ubAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,mBAAAE,GAAA,iBAAAC,GAAA,sBAAAC,GAAA,UAAAC,GAAA,yBAAAC,EAAA,kBAAAC,GAAA,0BAAAC,GAAA,eAAAC,GAAA,aAAAC,GAAA,2BAAAC,KAAA,eAAAC,GAAAZ,ICOe,SAARa,EAA2BC,EAA6C,CAC7E,GAAI,CACF,OAAOA,EAAM,MACf,OAAQC,EAAA,CACN,MACF,CACF,CCaA,SAASC,GAAOC,EAA6C,CAC3D,IAAMC,EAAaD,EAGnB,OAAO,OAAOC,GAAe,UAAYA,GAAc,MAAQA,EAAW,UAC5E,CAUO,SAASC,GAAaF,EAA2C,CACtE,GAAI,OAAOA,EAAQ,WAAc,SAC/B,OAEF,IAAIG,EAAQH,EAAQ,UAOpB,GAJIA,EAAQ,UAAU,SAAS,GAAG,IAChCG,EAAQH,EAAQ,UAAU,QAAQ,IAAK,GAAG,GAGxCG,IAAU,GACZ,MAAO,IAAIA,CAAK,EAIpB,CAUO,SAASC,GAAgBJ,EAA+B,CAC7D,GAAI,CAACA,EAAQ,QACX,MAAO,GAGT,IAAMK,EAAuB,CAAC,EAE9BA,EAAW,KAAKL,EAAQ,QAAQ,YAAY,CAAC,EACzCA,EAAQ,IACVK,EAAW,KAAK,IAAIL,EAAQ,EAAE,EAAE,EAGlC,IAAMM,EAAYJ,GAAaF,CAAO,EACtC,OAAIM,GACFD,EAAW,KAAKC,CAAS,EAGpBD,EAAW,KAAK,EAAE,CAC3B,CA4Be,SAARE,EACLP,EACAQ,EAEI,CAAE,SAAU,EAAG,EACX,CAGR,IAAMH,EAAuB,CAAC,EAC1BI,EAAMT,EACV,KAAOD,GAAOU,CAAG,GAAKA,EAAI,YAAcJ,EAAW,OAASG,EAAQ,UAAU,CAC5E,IAAME,EAAWN,GAAgBK,CAAmB,EAIpD,GAAIC,IAAa,OACf,MAGFL,EAAW,KAAKK,CAAQ,EACxBD,EAAMA,EAAI,UACZ,CACA,OAAOJ,EAAW,QAAQ,EAAE,KAAK,KAAe,CAClD,CC/HA,IAAqBM,EAArB,KAAyD,CAGvD,aAAc,CACZ,OAAO,iBACL,QACCC,GAAsB,CAf7B,IAAAC,EAgBQ,IAAMC,EAASC,EAAUH,CAAK,EAC9B,GAAIE,EAAQ,CACV,IAAME,EAA2B,CAC/B,MAAO,KACP,KAAM,QACN,MAAO,OACP,UAAW,KAAK,IAAI,EACpB,QAASC,EAAWH,CAAM,CAC5B,GACAD,EAAA,KAAK,eAAL,MAAAA,EAAmB,cAAcG,EACnC,CACF,EACA,EACF,CACF,CAEA,SAASE,EAAoBC,EAA0B,CACrD,KAAK,aAAeD,CACtB,CACA,YAAmB,CACjB,KAAK,aAAe,MACtB,CACF,EChCA,IAAME,GAAmB,IAEnBC,GAAkB,CAAC,QAAS,UAAU,EAKvBC,EAArB,KAA4D,CAI1D,aAAc,CAKZ,OAAO,iBACL,WACCC,GAAyB,CAxBhC,IAAAC,EAyBQ,IAAMC,EAASC,EAAUH,CAAK,EACxBI,EAAcF,EAGpB,GACEA,IACCJ,GAAgB,SAASI,EAAO,OAAO,GAAKE,GAAA,MAAAA,EAAa,mBAC1D,CACA,IAAMC,EAA2B,CAC/B,MAAO,KACP,KAAM,QACN,MAAO,OACP,UAAW,KAAK,IAAI,EACpB,QAASC,EAAWJ,CAAM,CAC5B,EAEK,KAAK,mBAAmBG,CAAU,KACrCJ,EAAA,KAAK,eAAL,MAAAA,EAAmB,cAAcI,GACjC,KAAK,WAAaA,EAEtB,CACF,EACA,EACF,CACF,CAEA,SAASE,EAAoBC,EAA0B,CACrD,KAAK,aAAeD,CACtB,CACA,YAAmB,CACjB,KAAK,aAAe,MACtB,CAEQ,mBAAmBE,EAA4B,CAIrD,OAAI,KAAK,WACU,KAAK,IAAIA,EAAM,UAAY,KAAK,WAAW,SAAS,GAClDZ,IAAoB,KAAK,WAAW,UAAYY,EAAM,QAEpE,EACT,CACF,ECjEA,IAAqBC,EAArB,KAAyD,CAGvD,aAAc,CACZ,OAAO,iBACL,QACCC,GAAsB,CAT7B,IAAAC,GAUQA,EAAA,KAAK,eAAL,MAAAA,EAAmB,kBAAkBD,EACvC,EACA,EACF,EACA,OAAO,iBACL,qBACCA,GAAiC,CAhBxC,IAAAC,EAiBYD,EAAM,UACRC,EAAA,KAAK,eAAL,MAAAA,EAAmB,aAAaD,EAAM,QAE1C,EACA,EACF,CACF,CAEA,SAASE,EAA0B,CACjC,KAAK,aAAeA,CACtB,CACA,YAAmB,CACjB,KAAK,aAAe,MACtB,CACF,EC7Be,SAARC,GAA2BC,EAAsBC,EAAsB,CAC5E,OAAKA,EAGED,EAAQ,OAAO,CAACE,EAAUC,IAAWA,EAAOD,CAAQ,EAAGD,CAAG,EAFxD,EAGX,CCEe,SAARG,EACLC,EACAC,EACM,CAZR,IAAAC,GAaMA,EAAAF,EAAM,OAAN,MAAAE,EAAY,MAIdF,EAAM,KAAK,IAAMG,GAAUF,EAAQ,WAAYD,EAAM,KAAK,GAAG,EAEjE,CCjBA,IAAMI,GAAoB,gCAEpBC,EAAgB,OAAO,MAYtB,SAASC,GACdC,EACAC,EACiC,CAnBnC,IAAAC,EAoBE,IAAIC,EAAM,GACNC,EAAS,MAEb,OAAI,OAAOJ,GAAU,WACnBG,EAAMH,GAIJ,OAAO,SAAY,aAAeA,aAAiB,UACrDG,EAAMH,EAAM,IACZI,EAASJ,EAAM,QAEb,OAAO,KAAQ,aAAeA,aAAiB,MACjDG,EAAMH,EAAM,SAAS,GAGnBC,IACFG,GAASF,EAAAD,EAAK,SAAL,KAAAC,EAAeE,GAEnB,CAAE,IAAAD,EAAK,OAAAC,CAAO,CACvB,CAOe,SAARC,GAA+BC,EAAgD,CASpF,SAASC,KAAsBC,EAAgC,CAC7D,IAAMC,EAAY,KAAK,IAAI,EAI3B,OAAOX,EAAc,MAAM,KAAMU,CAAW,EAAE,KAAME,GAAuB,CACzE,IAAMC,EAAwB,CAC5B,MAAO,OACP,UAAAF,EACA,MAAOC,EAAS,GAAK,OAAS,QAC9B,KAAM,QACN,KAAM,CAGJ,GAAGX,GAAiBS,EAAK,CAAC,EAAGA,EAAK,CAAC,CAAC,EACpC,WAAYE,EAAS,OACrB,WAAYA,EAAS,UACvB,CACF,EACA,OAAAJ,EAASK,CAAK,EACPD,CACT,CAAC,CACH,CAEAH,EAAQ,UAAYT,GAAA,YAAAA,EAAe,UAEnC,GAAI,CAEF,OAAO,eAAeS,EAASV,GAAmB,CAEhD,MAAOC,EACP,SAAU,GACV,aAAc,EAChB,CAAC,CACH,OAAQc,EAAA,CAGR,CAEA,OAAO,MAAQL,CACjB,CCvFA,IAAqBM,EAArB,KAAyD,CAIvD,YAAYC,EAA+B,CAF3C,KAAQ,aAAwB,GAG9BC,GAAeC,GAAe,CAdlC,IAAAC,EAAAC,EAAAC,EAeM,IAAIC,EAAkB,GACtB,GAAI,CACFC,EAAqBL,EAAYF,CAAO,EACxCM,EAAkB,EACpB,OAASE,EAAK,CACP,KAAK,gBACRJ,GAAAD,EAAAH,EAAQ,YAAR,YAAAG,EAAA,KAAAH,KAAA,MAAAI,EAAuB,KAAK,kCAAmCI,GAC/D,KAAK,aAAe,GAExB,CAGIF,KACFD,EAAA,KAAK,eAAL,MAAAA,EAAmB,cAAcH,GAErC,CAAC,CACH,CAEA,SAASO,EAAoBC,EAA0B,CACrD,KAAK,aAAeD,CACtB,CAEA,YAAmB,CACjB,KAAK,aAAe,MACtB,CACF,ECtCA,IAAME,GAAkB,8BAClBC,GAAuB,GAAGD,EAAe,QACzCE,GAAuB,GAAGF,EAAe,QAGzCG,GAAc,0BAGdC,GAAe,OAAO,eAAe,UAAU,KAE/CC,GAAe,OAAO,eAAe,UAAU,KActC,SAARC,GAA6BC,EAAgD,CAOlF,SAASC,KAAqCC,EAAa,CAIzD,KAAK,iBAAiB,QAAS,SAAUC,EAAkD,CAEzF,IAAMC,EAAmB,KAAaR,EAAW,EACjDQ,EAAK,MAAQ,EACf,CAAC,EAED,KAAK,iBACH,UAEA,SAAUD,EAAkD,CAE1D,IAAMC,EAAmB,KAAaR,EAAW,EAE7CQ,GAAQA,EAAK,WACfJ,EAAS,CACP,MAAO,OACP,UAAWI,EAAK,UAChB,MAAOA,EAAK,MAAQ,QAAU,OAC9B,KAAM,MACN,KAAM,CACJ,IAAKA,EAAK,IACV,OAAQA,EAAK,OACb,WAAY,KAAK,OACjB,WAAY,KAAK,UACnB,CACF,CAAC,CAEL,EACA,EACF,EAGAP,GAAa,MAAM,KAAMK,CAAW,EAEpC,GAAI,CACF,IAAMG,EAAqB,CACzB,OAAQH,GAAA,YAAAA,EAAO,GACf,IAAKA,GAAA,YAAAA,EAAO,EACd,EAEA,OAAO,eAAe,KAAMN,GAAa,CAEvC,MAAOS,EACP,SAAU,GACV,aAAc,EAChB,CAAC,CACH,OAAQC,EAAA,CAGR,CACF,CAEA,SAASC,KAAqCL,EAAa,CAEzDJ,GAAa,MAAM,KAAMI,CAAW,EAGpC,IAAME,EAAmB,KAAaR,EAAW,EAC7CQ,IACFA,EAAK,UAAY,KAAK,IAAI,EAE9B,CAEA,OAAO,eAAe,UAAU,KAAOH,EACvC,OAAO,eAAe,UAAU,KAAOM,EAEvC,GAAI,CAGF,OAAO,iBAAiB,OAAO,eAAgB,CAC7C,CAACb,EAAoB,EAAG,CACtB,MAAOG,GACP,SAAU,GACV,aAAc,EAChB,EACA,CAACF,EAAoB,EAAG,CACtB,MAAOG,GACP,SAAU,GACV,aAAc,EAChB,CACF,CAAC,CACH,OAAQQ,EAAA,CAGR,CACF,CChHA,IAAqBE,EAArB,KAAuD,CAIrD,YAAYC,EAA+B,CAF3C,KAAQ,aAAwB,GAG9BC,GAAaC,GAAe,CAfhC,IAAAC,EAAAC,EAAAC,EAgBM,IAAIC,EAAkB,GACtB,GAAI,CACFC,EAAqBL,EAAYF,CAAO,EACxCM,EAAkB,EACpB,OAASE,EAAK,CACP,KAAK,gBACRJ,GAAAD,EAAAH,EAAQ,YAAR,YAAAG,EAAA,KAAAH,KAAA,MAAAI,EAAuB,KAAK,kCAAmCI,GAC/D,KAAK,aAAe,GAExB,CAGIF,KACFD,EAAA,KAAK,eAAL,MAAAA,EAAmB,cAAcH,GAErC,CAAC,CACH,CAEA,SAASO,EAAoBC,EAA0B,CACrD,KAAK,aAAeD,CACtB,CAEA,YAAmB,CACjB,KAAK,aAAe,MACtB,CACF,ECzCA,IAAME,GAAe,wDACfC,GAAiB,0CAWvB,SAASC,GAAmBC,EAAqB,CAK/C,GAAI,CAGF,GAAIA,EAAI,SAAS,KAAK,EAAG,CACvB,IAAMC,EAAS,IAAI,IAAID,CAAG,EACtBE,EAAU,GASd,GARID,EAAO,WACTA,EAAO,SAAW,WAClBC,EAAU,IAERD,EAAO,WACTA,EAAO,SAAW,WAClBC,EAAU,IAERA,EACF,OAAOD,EAAO,SAAS,CAE3B,CACF,OAAQE,EAAA,CAER,CAEA,OAAOH,CACT,CAQA,SAASI,GAAYJ,EAAqB,CAhD1C,IAAAK,EAAAC,EAoDE,GAAIN,EAAI,SAAS,YAAY,EAAG,CAC9B,IAAMO,EAAaP,EAAI,MAAMH,EAAY,EACnCW,GAAUH,EAAAE,GAAA,YAAAA,EAAY,SAAZ,YAAAF,EAAoB,QACpC,GAAIG,EACF,OAAOR,EAAI,QAAQQ,EAAS,IAAI,OAAOA,EAAQ,MAAM,CAAC,CAE1D,CACA,GAAIR,EAAI,SAAS,QAAQ,EAAG,CAC1B,IAAMO,EAAaP,EAAI,MAAMF,EAAc,EACrCU,GAAUF,EAAAC,GAAA,YAAAA,EAAY,SAAZ,YAAAD,EAAoB,QACpC,GAAIE,EACF,OAAOR,EAAI,QAAQQ,EAAS,IAAI,OAAOA,EAAQ,MAAM,CAAC,CAE1D,CACA,OAAOR,CACT,CAQe,SAARS,GAAkCT,EAAqB,CAC5D,OAAOI,GAAYL,GAAmBC,CAAG,CAAC,CAC5C,CChEe,SAARU,GACLC,EACAC,EACAC,EACA,CACIF,EAAQ,YAAY,aACtBC,EAAW,KAAK,CACd,KAAM,YACN,KAAM,2CACN,YAAa,GACb,OAAOE,EAAiBC,EAAgCC,EAA2B,CACjFH,EAAU,eAAeC,EAASC,EAAYC,CAAO,CACvD,CACF,CAAC,EAGCL,EAAQ,YAAY,YACtBC,EAAW,KAAK,CACd,KAAM,sBACN,KAAM,2CACN,YAAa,GACb,OAAOE,EAAiBG,EAAkC,CACxDJ,EAAU,wBAAwBC,EAASG,CAAM,CACnD,CACF,CAAC,CAEL,CCrCO,IAAMC,EAA4B,CAGvC,KAAM,QAAQ,IAChB,EAEMC,GAAgB,oCAEf,SAASC,EAAUC,EAAiB,CACzC,MAAO,GAAGF,EAAa,IAAIE,CAAO,EACpC,CAEO,SAASC,EAAcC,EAA0C,CACtE,MAAO,CACL,KAAM,IAAIC,IAAgB,CACxB,GAAI,CAACD,EAAQ,CACXL,EAAe,KAAK,GAAGM,CAAI,EAC3B,MACF,CAEA,GAAI,CACFD,EAAO,KAAK,GAAGC,CAAI,CACrB,OAAQC,EAAA,CACNP,EAAe,KAAK,GAAGM,CAAI,EAC3BN,EAAe,KACbE,EAAU,gEAAgE,CAC5E,CACF,CACF,CACF,CACF,CCjBA,IAAMM,GAAU,CACd,MAAO,EACP,IAAK,CACP,EACMC,GAAU,CACd,MAAO,EACP,IAAK,CACP,EACMC,GAAmB,CACvB,MAAO,EACP,IAAK,CACP,EACMC,GAAwB,CAC5B,MAAO,EACP,IAAK,CACP,EACMC,GAAc,CAClB,MAAO,EACP,IAAK,CACP,EACMC,GAAQ,CACZ,MAAO,GACP,IAAK,EACP,EAEA,SAASC,IAA4B,CACnC,GAAI,QAAU,OAAO,gBAAiB,CACpC,IAAMC,EAAa,IAAI,WAAW,EAAE,EACpC,cAAO,gBAAgBA,CAAU,EAC1B,CAAC,GAAGA,EAAW,OAAO,CAAC,CAChC,CACA,IAAMC,EAAS,CAAC,EAChB,QAASC,EAAQ,EAAGA,EAAQ,GAAIA,GAAS,EAEvCD,EAAO,KAAK,KAAK,MAAM,KAAK,OAAO,EAAI,GAAG,CAAC,EAE7C,OAAOA,CACT,CAEA,SAASE,EAAIC,EAAiBC,EAA+C,CAC3E,IAAIC,EAAS,GACb,QAASJ,EAAQG,EAAM,MAAOH,GAASG,EAAM,IAAKH,GAAS,EACzDI,GAAUF,EAAMF,CAAK,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,EAErD,OAAOI,CACT,CAUO,SAASC,GAAmBH,EAAyB,CAQ1D,OAAAA,EAAMR,GAAsB,KAAK,GAAKQ,EAAMR,GAAsB,KAAK,EAAI,KAAQ,IAInFQ,EAAMT,GAAiB,KAAK,EAAKS,EAAMT,GAAiB,KAAK,EAAI,GAAQ,GAGvE,GAAGQ,EAAIC,EAAOX,EAAO,CAAC,IAAIU,EAAIC,EAAOV,EAAO,CAAC,IAAIS,EAAIC,EAAOT,EAAgB,CAAC,IAC1EQ,EAAIC,EAAOR,EAAqB,CAAC,GAAGO,EAAIC,EAAOP,EAAW,CAAC,IAAIM,EAAIC,EAAON,EAAK,CAAC,EAEvF,CAEO,SAASU,IAAyB,CACvC,IAAMJ,EAAQL,GAAgB,EAC9B,OAAOQ,GAAmBH,CAAK,CACjC,CAEe,SAARK,IAAwC,CAC7C,OAAI,OAAO,SAAW,QAAa,OAAO,OAAO,YAAe,WACvD,OAAO,WAAW,EAGpBD,GAAe,CACxB,CCxBA,IAAME,EAAgB,CAAC,GA+BtB,SAAUC,EAAQC,EAAW,CAC5B,GAAI,CAACD,EACH,OAIF,IAAME,EAAS,CAAC,EAAE,MACZC,EAAmB,IAGnBC,EACJ,0GAUF,SAASC,EAAKC,EAAaC,EAAsB,CAC/C,OAAO,OAAO,UAAU,eAAe,KAAKD,EAAQC,CAAG,CACzD,CASA,SAASC,EAAaC,EAAoB,CACxC,OAAO,OAAOA,GAAS,WACzB,CAUAV,EAAS,KAAO,SAAyBW,EAA0B,CACjE,SAASC,GAAmB,CAC1B,GAAI,CACF,OAAOD,EAAK,MAAM,KAAM,SAAS,CACnC,OAASE,EAAG,CACV,MAAAb,EAAS,OAAOa,CAAC,EACXA,CACR,CACF,CACA,OAAOD,CACT,EAiEAZ,EAAS,kBAAqB,UAAoC,CAEhE,IAAMc,EAAwC,CAAC,EAS/C,SAASC,EAAWC,EAAqB,CACvC,GAAI,CAAChB,EAAS,eAEZ,MAAO,GAET,GAAI,CAWF,IAAMiB,EAVS,UAAY,CACzB,GAAI,CACF,OAAO,IAAIhB,EAAO,cACpB,OAASY,EAAG,CAGV,OAAO,IAAIZ,EAAO,cAAc,mBAAmB,CACrD,CACF,EAEuB,EACvB,OAAAgB,EAAQ,KAAK,MAAOD,EAAK,EAAK,EAC9BC,EAAQ,KAAK,EAAE,EACRA,EAAQ,YACjB,OAASJ,EAAG,CACV,MAAO,EACT,CACF,CAQA,SAASK,EAAUF,EAAuB,CACxC,GAAI,OAAOA,GAAQ,SACjB,MAAO,CAAC,EAGV,GAAI,CAACV,EAAKQ,EAAaE,CAAG,EAAG,CAW3B,IAAIG,EAAS,GACTC,EAAS,GACb,GAAI,CACFA,EAASnB,EAAO,SAAS,MAC3B,OAASY,EAAG,CAAC,CACb,IAAMQ,EAAQ,8CAA8C,KAAKL,CAAG,EAChEK,GAASA,EAAM,CAAC,IAAMD,IACxBD,EAASJ,EAAWC,CAAG,GAEzBF,EAAYE,CAAG,EAAIG,EAASA,EAAO,MAAM;AAAA,CAAI,EAAI,CAAC,CACpD,CAEA,OAAOL,EAAYE,CAAG,CACxB,CAWA,SAASM,EAAkBN,EAAaO,EAAyB,CAC3D,OAAOA,GAAW,WACpBA,EAAS,OAAOA,CAAM,GAExB,IAAMC,EAAqB,8BACrBC,EAAkB,mEACpBC,EAAO,GACLC,EAAW,GACXR,EAASD,EAAUF,CAAG,EACxBY,EAEJ,GAAI,CAACT,EAAO,OACV,OAAOf,EAKT,QAASyB,EAAI,EAAGA,EAAIF,EAAU,EAAEE,EAG9B,GAFAH,EAAOP,EAAOI,EAASM,CAAC,EAAIH,EAExB,CAACjB,EAAaiB,CAAI,KACfE,EAAIH,EAAgB,KAAKC,CAAI,KAG7BE,EAAIJ,EAAmB,KAAKE,CAAI,IACnC,OAAOE,EAAE,CAAC,EAKhB,OAAOxB,CACT,CASA,SAAS0B,EAAcd,EAAaU,EAA6C,CAC3E,OAAOA,GAAS,WAClBA,EAAO,OAAOA,CAAI,GAEpB,IAAMP,EAASD,EAAUF,CAAG,EAE5B,GAAI,CAACG,EAAO,OACV,OAAO,KAGT,IAAMY,EAAU,CAAC,EAIXC,EAAc,KAAK,MAAMhC,EAAS,eAAiB,CAAC,EAEpDiC,EAAaD,EAAehC,EAAS,eAAiB,EACtDkC,EAAQ,KAAK,IAAI,EAAGR,EAAOM,EAAc,CAAC,EAC1CG,EAAM,KAAK,IAAIhB,EAAO,OAAQO,EAAOO,EAAa,CAAC,EAEzDP,GAAQ,EAER,QAASG,EAAIK,EAAOL,EAAIM,EAAK,EAAEN,EACxBpB,EAAaU,EAAOU,CAAC,CAAC,GACzBE,EAAQ,KAAKZ,EAAOU,CAAC,CAAC,EAI1B,OAAOE,EAAQ,OAAS,EACpB,CACE,aAAcA,EAEd,gBAAiBG,EAAQ,CAC3B,EACA,IACN,CAQA,SAASE,EAAaC,EAAsB,CAC1C,OAAOA,EAAK,QAAQ,4BAA6B,MAAM,CACzD,CAUA,SAASC,GAAwCC,EAAsB,CACrE,OAAOH,EAAaG,CAAI,EACrB,QAAQ,IAAK,YAAY,EACzB,QAAQ,IAAK,YAAY,EACzB,QAAQ,IAAK,aAAa,EAC1B,QAAQ,IAAK,cAAc,EAC3B,QAAQ,OAAQ,MAAM,CAC3B,CAUA,SAASC,EACPC,EACAC,EAKO,CACP,IAAIvB,EACAS,EACJ,QAASC,EAAI,EAAGc,EAAID,EAAK,OAAQb,EAAIc,EAAG,EAAEd,EACxC,IAAKV,EAASD,EAAUwB,EAAKb,CAAC,CAAC,GAAG,SAChCV,EAASA,EAAO,KAAK;AAAA,CAAI,EACpBS,EAAIa,EAAG,KAAKtB,CAAM,GACrB,MAAO,CACL,IAAKuB,EAAKb,CAAC,EACX,KAAMV,EAAO,UAAU,EAAGS,EAAE,KAAK,EAAE,MAAM;AAAA,CAAI,EAAE,OAC/C,OAAQA,EAAE,MAAQT,EAAO,YAAY;AAAA,EAAMS,EAAE,KAAK,EAAI,CACxD,EAKN,OAAO,IACT,CAWA,SAASgB,GAAiBC,EAAkB7B,EAAaU,EAAsC,CACzF,OAAOA,GAAS,WAClBA,EAAO,OAAOA,CAAI,GAEpB,IAAMP,EAASD,EAAUF,CAAG,EACtByB,EAAK,IAAI,OAAO,MAAML,EAAaS,CAAQ,CAAC,KAAK,EACnDjB,EAIJ,OAFAF,GAAQ,EAEJP,GAAUA,EAAO,OAASO,IAASE,EAAIa,EAAG,KAAKtB,EAAOO,CAAI,CAAC,GACtDE,EAAE,MAGJ,IACT,CAUA,SAASkB,GAAyBnC,EAAyB,CACzD,GAAIF,EAAaR,GAAUA,EAAO,QAAQ,EACxC,OAGF,IAAMyC,EAAO,CAACzC,EAAO,SAAS,IAAI,EAC5B8C,EAAU9C,EAAO,SAAS,qBAAqB,QAAQ,EACzDsC,EACES,EAAO,GAAGrC,CAAI,GACdsC,EAAS,2EACTC,EAAU,iEACZT,EACAU,EACAC,EAEJ,QAASvB,EAAI,EAAGA,EAAIkB,EAAQ,OAAQ,EAAElB,EAAG,CACvC,IAAMwB,EAASN,EAAQlB,CAAC,EACpBwB,EAAO,KACTX,EAAK,KAAKW,EAAO,GAAG,CAExB,CAEA,GAAI,EAAEF,EAAQF,EAAO,KAAKD,CAAI,GAC5BP,EAAK,IAAI,OAAOL,EAAaY,CAAI,EAAE,QAAQ,OAAQ,MAAM,CAAC,MAKvD,CACH,IAAMM,EAAOH,EAAM,CAAC,EAAI,OAAOA,EAAM,CAAC,CAAC,GAAK,GACtCI,EAAOJ,EAAM,CAAC,EAAE,MAAM,GAAG,EAAE,KAAK,WAAW,EAEjDZ,EAAOH,EAAae,EAAM,CAAC,CAAC,EAAE,QAAQ,KAAM,IAAI,EAChDV,EAAK,IAAI,OAAO,WAAWa,CAAI,cAAcC,CAAI,mBAAmBhB,CAAI,OAAO,CACjF,CAGA,GAAKa,EAASZ,EAAiBC,EAAIC,CAAI,EACrC,OAAOU,EAIT,GAAKD,EAAQD,EAAQ,KAAKF,CAAI,EAAI,CAChC,IAAMQ,EAAQL,EAAM,CAAC,EAerB,GAdAZ,EAAOD,GAAwCa,EAAM,CAAC,CAAC,EAGvDV,EAAK,IAAI,OAAO,KAAKe,CAAK,cAAcjB,CAAI,aAAc,GAAG,GAIxDa,EAASZ,EAAiBC,EAAIC,EAAK,CAAC,CAAC,KAK1CD,EAAK,IAAI,OAAOF,CAAI,EAEfa,EAASZ,EAAiBC,EAAIC,CAAI,GACrC,OAAOU,CAEX,CAEA,OAAO,IACT,CA8CA,SAASK,GAA+BC,EAA4B,CA/kBxE,IAAAC,EAglBM,GAAI,CAACD,EAAG,MACN,OAAO,KAGT,IAAME,EACJ,8HACIC,EACJ,kIACIC,EACJ,gHAGEC,EACEC,EAAY,gDACZC,EAAa,gCAEbC,EAAQR,EAAG,MAAM,MAAM;AAAA,CAAI,EAC3BS,EAAsB,CAAC,EACzBC,EACAjB,EACAkB,EACEC,EAAiB,sBAAsB,KAAKZ,EAAG,OAAO,EAE5D,QAAS7B,EAAI,EAAGc,GAAIuB,EAAM,OAAQrC,EAAIc,GAAG,EAAEd,EAAG,CAC5C,GAAKsB,EAAQS,EAAO,KAAKM,EAAMrC,CAAC,CAAC,EAAI,CACnC,IAAM0C,GAAWpB,EAAM,CAAC,GAAKA,EAAM,CAAC,EAAE,QAAQ,QAAQ,IAAM,EAC5DY,EAASZ,EAAM,CAAC,GAAKA,EAAM,CAAC,EAAE,QAAQ,MAAM,IAAM,EAC9CY,IAAWK,EAAWH,EAAW,KAAKd,EAAM,CAAC,CAAC,KAEhDA,EAAM,CAAC,EAAIiB,EAAS,CAAC,EACrBjB,EAAM,CAAC,EAAIiB,EAAS,CAAC,EACrBjB,EAAM,CAAC,EAAIiB,EAAS,CAAC,GAEvBC,EAAU,CACR,IAAME,GAAsB,KAAXpB,EAAM,CAAC,EACxB,KAAMA,EAAM,CAAC,GAAK/C,EAClB,KAAMmE,GAAW,CAACpB,EAAM,CAAC,CAAC,EAAI,CAAC,EAC/B,KAAMA,EAAM,CAAC,EAAI,CAACA,EAAM,CAAC,EAAI,KAC7B,OAAQA,EAAM,CAAC,EAAI,CAACA,EAAM,CAAC,EAAI,IACjC,CACF,SAAYA,EAAQW,EAAM,KAAKI,EAAMrC,CAAC,CAAC,EACrCwC,EAAU,CACR,IAAKlB,EAAM,CAAC,EACZ,KAAMA,EAAM,CAAC,GAAK/C,EAClB,KAAM,CAAC,EACP,KAAM,CAAC+C,EAAM,CAAC,EACd,OAAQA,EAAM,CAAC,EAAI,CAACA,EAAM,CAAC,EAAI,IACjC,UACUA,EAAQU,EAAM,KAAKK,EAAMrC,CAAC,CAAC,EACrCkC,EAASZ,EAAM,CAAC,GAAKA,EAAM,CAAC,EAAE,QAAQ,SAAS,EAAI,GAC/CY,IAAWK,EAAWJ,EAAU,KAAKb,EAAM,CAAC,CAAC,IAE/CA,EAAM,CAAC,EAAIiB,EAAS,CAAC,EACrBjB,EAAM,CAAC,EAAIiB,EAAS,CAAC,EACrBjB,EAAM,CAAC,EAAI,MACFtB,IAAM,GAAK,CAACsB,EAAM,CAAC,GAAK,CAAC1C,EAAaiD,EAAG,YAAY,IAK9DS,EAAM,CAAC,EAAE,OAAST,EAAG,aAAe,GAEtCW,EAAU,CACR,IAAKlB,EAAM,CAAC,EACZ,KAAMA,EAAM,CAAC,GAAK/C,EAClB,KAAM+C,EAAM,CAAC,EAAIA,EAAM,CAAC,EAAE,MAAM,GAAG,EAAI,CAAC,EACxC,KAAMA,EAAM,CAAC,EAAI,CAACA,EAAM,CAAC,EAAI,KAC7B,OAAQA,EAAM,CAAC,EAAI,CAACA,EAAM,CAAC,EAAI,IACjC,MAEA,UAGE,CAACkB,EAAQ,MAAQA,EAAQ,OAC3BA,EAAQ,KAAO/C,EAAkB+C,EAAQ,IAAKA,EAAQ,IAAI,GAG5D,IAAMG,EAAa1C,EAAcuC,EAAQ,IAAKA,EAAQ,IAAK,EAC3DA,EAAQ,QAAUA,EAAQ,OAAQV,EAAAa,GAAA,YAAAA,EAAY,eAAZ,KAAAb,EAAoC,KACtEU,EAAQ,SAAWG,GAAA,YAAAA,EAAY,gBAC/BL,EAAM,KAAKE,CAAO,CACpB,CAEA,OAAKF,EAAM,QAIPA,EAAM,CAAC,GAAKA,EAAM,CAAC,EAAE,MAAQ,CAACA,EAAM,CAAC,EAAE,QAAUG,IACnDH,EAAM,CAAC,EAAE,OAASvB,GAAiB0B,EAAU,CAAC,EAAGH,EAAM,CAAC,EAAE,IAAKA,EAAM,CAAC,EAAE,IAAI,GAGvE,CACL,KAAM,QACN,KAAMT,EAAG,KACT,QAASA,EAAG,QACZ,MAAAS,CACF,GAZS,IAaX,CASA,SAASM,GAAoCf,EAA4B,CA1rB7E,IAAAC,EA8rBM,GAAM,CAAE,WAAAe,CAAW,EAAIhB,EACvB,GAAI,CAACgB,EACH,OAAO,KAGT,IAAMC,EAAe,8DACfC,EACJ,uGACIV,EAAQQ,EAAW,MAAM;AAAA,CAAI,EAC7BP,EAAQ,CAAC,EACXhB,EAEJ,QAASzB,EAAO,EAAGA,EAAOwC,EAAM,OAAQxC,GAAQ,EAAG,CACjD,IAAI2C,EAA6B,KAmBjC,IAlBKlB,EAAQwB,EAAa,KAAKT,EAAMxC,CAAI,CAAC,GACxC2C,EAAU,CACR,IAAKlB,EAAM,CAAC,EACZ,KAAM,CAACA,EAAM,CAAC,EACd,OAAQ,KACR,KAAMA,EAAM,CAAC,EACb,KAAM,CAAC,CACT,GACUA,EAAQyB,EAAa,KAAKV,EAAMxC,CAAI,CAAC,KAC/C2C,EAAU,CACR,IAAKlB,EAAM,CAAC,EACZ,KAAM,CAACA,EAAM,CAAC,EACd,OAAQ,CAACA,EAAM,CAAC,EAChB,KAAMA,EAAM,CAAC,GAAKA,EAAM,CAAC,EACzB,KAAMA,EAAM,CAAC,EAAIA,EAAM,CAAC,EAAE,MAAM,GAAG,EAAI,CAAC,CAC1C,GAGEkB,EAAS,CAIX,GAHI,CAACA,EAAQ,MAAQA,EAAQ,OAC3BA,EAAQ,KAAO/C,EAAkB+C,EAAQ,IAAKA,EAAQ,IAAI,GAExDA,EAAQ,KACV,GAAI,CACF,IAAMG,EAAa1C,EAAcuC,EAAQ,IAAKA,EAAQ,IAAI,EAC1DA,EAAQ,SAAWG,GAAA,YAAAA,EAAY,gBAC/BH,EAAQ,QAAUA,EAAQ,OAAQV,EAAAa,GAAA,YAAAA,EAAY,eAAZ,KAAAb,EAAoC,IACxE,OAASkB,EAAK,CAAC,CAGZR,EAAQ,UACXA,EAAQ,QAAU,CAACH,EAAMxC,EAAO,CAAC,CAAC,GAGpCyC,EAAM,KAAKE,CAAO,CACpB,CACF,CAEA,OAAKF,EAAM,OAIJ,CACL,KAAM,aACN,KAAMT,EAAG,KACT,QAASA,EAAG,QACZ,MAAAS,CACF,EARS,IASX,CAYA,SAASW,GAA2CpB,EAA8B,CAgBhF,IAAMQ,EAAQR,EAAG,QAAQ,MAAM;AAAA,CAAI,EACnC,GAAIQ,EAAM,OAAS,EACjB,OAAO,KAGT,IAAMa,EACJ,yFACIC,EACJ,kGACIC,EAAU,yCACVd,EAAQ,CAAC,EACTpB,EAAU9C,GAAUA,EAAO,UAAYA,EAAO,SAAS,qBAAqB,QAAQ,EACpFiF,EAAqB,CAAC,EACxB/B,EAEJ,QAAWgC,KAAKpC,EACVzC,EAAKyC,EAASoC,CAAC,GAAK,CAACpC,EAAQoC,CAAC,EAAE,KAClCD,EAAmB,KAAKnC,EAAQoC,CAAC,CAAC,EAItC,QAASzD,EAAO,EAAGA,EAAOwC,EAAM,OAAQxC,GAAQ,EAAG,CACjD,IAAI0D,EAAY,KAChB,GAAKjC,EAAQ4B,EAAQ,KAAKb,EAAMxC,CAAI,CAAC,EACnC0D,EAAO,CACL,IAAKjC,EAAM,CAAC,EACZ,KAAMA,EAAM,CAAC,EACb,KAAM,CAAC,EACP,KAAM,CAACA,EAAM,CAAC,EACd,OAAQ,IACV,UACUA,EAAQ6B,EAAQ,KAAKd,EAAMxC,CAAI,CAAC,EAAI,CAC9C0D,EAAO,CACL,IAAKjC,EAAM,CAAC,EACZ,KAAMA,EAAM,CAAC,EACb,KAAM,CAAC,EACP,KAAM,CAACA,EAAM,CAAC,EACd,OAAQ,IACV,EACA,IAAMkC,EAAe,CAAClC,EAAM,CAAC,EACvBE,EAAS6B,EAAmB/B,EAAM,CAAC,EAAI,CAAC,EAC9C,GAAIE,EAAQ,CACV,IAAIlC,EAAcD,EAAUkE,EAAK,GAAG,EACpC,GAAIjE,EAAQ,CACVA,EAASA,EAAO,KAAK;AAAA,CAAI,EACzB,IAAMmE,EAAMnE,EAAO,QAAQkC,EAAO,SAAS,EACvCiC,GAAO,IACTF,EAAK,KAAOC,EAAelE,EAAO,UAAU,EAAGmE,CAAG,EAAE,MAAM;AAAA,CAAI,EAAE,OAEpE,CACF,CACF,SAAYnC,EAAQ8B,EAAQ,KAAKf,EAAMxC,CAAI,CAAC,EAAI,CAC9C,IAAMV,EAAMf,EAAO,SAAS,KAAK,QAAQ,OAAQ,EAAE,EAC7CwC,EAAK,IAAI,OAAOH,GAAwC4B,EAAMxC,EAAO,CAAC,CAAC,CAAC,EACxE6D,EAAM/C,EAAiBC,EAAI,CAACzB,CAAG,CAAC,EACtCoE,EAAO,CACL,IAAApE,EACA,KAAM,GACN,KAAM,CAAC,EACP,KAAMuE,EAAMA,EAAI,KAAOpC,EAAM,CAAC,EAC9B,OAAQ,IACV,CACF,CAEA,GAAIiC,EAAM,CACHA,EAAK,OACRA,EAAK,KAAO9D,EAAkB8D,EAAK,IAAKA,EAAK,IAAI,GAEnD,IAAMZ,EAAa1C,EAAcsD,EAAK,IAAKA,EAAK,IAAI,EACpDA,EAAK,SAAWZ,GAAA,YAAAA,EAAY,gBAC5B,IAAMzC,EAAUyC,GAAA,YAAAA,EAAY,aACtBgB,EAAUzD,EAAUA,EAAQ,KAAK,MAAMA,EAAQ,OAAS,CAAC,CAAC,EAAI,KAElEA,GACAyD,GACAA,EAAQ,QAAQ,OAAQ,EAAE,IAAMtB,EAAMxC,EAAO,CAAC,EAAE,QAAQ,OAAQ,EAAE,EAElE0D,EAAK,QAAUrD,EAGfqD,EAAK,QAAU,CAAClB,EAAMxC,EAAO,CAAC,CAAC,EAEjCyC,EAAM,KAAKiB,CAAI,CACjB,CACF,CACA,OAAKjB,EAAM,OAIJ,CACL,KAAM,YACN,KAAMT,EAAG,KACT,QAASQ,EAAM,CAAC,EAChB,MAAAC,CACF,EARS,IASX,CAgBA,SAASsB,GACPC,EACA1E,EACAO,EACAoE,EACS,CA54Bf,IAAAhC,EA64BM,IAAMiC,EAAe,CACnB,IAAA5E,EACA,KAAMO,CACR,EAEA,GAAIqE,EAAQ,KAAOA,EAAQ,KAAM,CAO/B,GANAF,EAAU,WAAa,GAElBE,EAAQ,OACXA,EAAQ,KAAOtE,EAAkBsE,EAAQ,IAAKA,EAAQ,IAAI,GAGxD,CAACA,EAAQ,QAAS,CACpB,IAAMpB,EAAa1C,EAAc8D,EAAQ,IAAKA,EAAQ,IAAI,EAC1DA,EAAQ,SAAUjC,EAAAa,GAAA,YAAAA,EAAY,eAAZ,KAAAb,EAA4B,KAC9CiC,EAAQ,SAAWpB,GAAA,YAAAA,EAAY,eACjC,CAEA,IAAMF,EAAY,cAAc,KAAKqB,CAAO,EAK5C,GAJIrB,IACFsB,EAAQ,OAAShD,GAAiB0B,EAAU,CAAC,EAAGsB,EAAQ,IAAKA,EAAQ,IAAI,GAGvEF,EAAU,MAAM,OAAS,GACvBA,EAAU,MAAM,CAAC,EAAE,MAAQE,EAAQ,IAAK,CAC1C,GAAIF,EAAU,MAAM,CAAC,EAAE,OAASE,EAAQ,KACtC,MAAO,GAET,GAAI,CAACF,EAAU,MAAM,CAAC,EAAE,MAAQA,EAAU,MAAM,CAAC,EAAE,OAASE,EAAQ,KAClE,OAAAF,EAAU,MAAM,CAAC,EAAE,KAAOE,EAAQ,KAClCF,EAAU,MAAM,CAAC,EAAE,QAAUE,EAAQ,QAC9B,EAEX,CAGF,OAAAF,EAAU,MAAM,QAAQE,CAAO,EAC/BF,EAAU,QAAU,GACb,EACT,CACA,OAAAA,EAAU,WAAa,GAEhB,EACT,CAYA,SAASG,GAAsCnC,EAASoC,EAAe,CACrE,IAAMC,EAAe,qEACf5B,EAAQ,CAAC,EACT6B,EAAQ,CAAC,EACXC,EAAY,GACZ9C,EACAiC,EACAjE,EAEJ,QACM+E,EAAOL,GAAsC,OACjDK,GAAQ,CAACD,EACTC,EAAOA,EAAK,OAEZ,GAAI,EAAAA,IAASC,GAAqBD,IAASlG,EAAS,QAkBpD,IAdAoF,EAAO,CACL,IAAK,KACL,KAAMhF,EACN,KAAM,CAAC,EACP,KAAM,KACN,OAAQ,IACV,EAEI8F,EAAK,KACPd,EAAK,KAAOc,EAAK,MACP/C,EAAQ4C,EAAa,KAAKG,EAAK,SAAS,CAAC,KACnDd,EAAK,KAAOjC,EAAM,CAAC,GAGjB,OAAOiC,EAAK,MAAS,YACvB,GAAI,CACFA,EAAK,KAAOjC,EAAM,MAAM,UAAU,EAAGA,EAAM,MAAM,QAAQ,GAAG,CAAC,CAC/D,OAAStC,EAAG,CAAC,CAGf,GAAKM,EAAS2B,GAAyBoD,CAAI,EAAI,CAC7Cd,EAAK,IAAMjE,EAAO,IAClBiE,EAAK,KAAOjE,EAAO,KAEfiE,EAAK,OAAShF,IAChBgF,EAAK,KAAO9D,EAAkB8D,EAAK,IAAKA,EAAK,IAAI,GAGnD,IAAMd,EAAY,cAAc,KAAKZ,EAAG,SAAWA,EAAG,WAAW,EAC7DY,IACFc,EAAK,OAASxC,GAAiB0B,EAAU,CAAC,EAAGnD,EAAO,IAAKA,EAAO,IAAI,EAExE,CAGI6E,EAAM,GAAGE,CAAI,EAAE,EACjBD,EAAY,GAGZD,EAAM,GAAGE,CAAI,EAAE,EAAI,GAGrB/B,EAAM,KAAKiB,CAAI,EAGbU,GACF3B,EAAM,OAAO,EAAG2B,CAAK,EAGvB,IAAM1C,EAAqB,CACzB,KAAM,UACN,KAAMM,EAAG,KACT,QAASA,EAAG,QACZ,MAAAS,CACF,EACA,OAAAsB,GACErC,EACAM,EAAG,WAAaA,EAAG,SACnBA,EAAG,MAAQA,EAAG,WACdA,EAAG,SAAWA,EAAG,WACnB,EACON,CACT,CAQA,SAAS+C,EAAkBzC,EAASoC,EAA2B,CAC7D,IAAI3B,EAA2B,KAC/B2B,EAAQA,GAAS,KAAO,EAAI,CAACA,EAE7B,GAAI,CAKF,GADA3B,EAAQM,GAAoCf,CAAE,EAC1CS,EACF,OAAOA,CAEX,OAAStD,EAAG,CAIZ,CAEA,GAAI,CAEF,GADAsD,EAAQV,GAA+BC,CAAE,EACrCS,EACF,OAAOA,CAEX,OAAStD,EAAG,CAIZ,CAEA,GAAI,CAEF,GADAsD,EAAQW,GAA2CpB,CAAE,EACjDS,EACF,OAAOA,CAEX,OAAStD,EAAG,CAIZ,CAEA,GAAI,CAEF,GADAsD,EAAQ0B,GAAsCnC,EAAIoC,EAAQ,CAAC,EACvD3B,EACF,OAAOA,CAEX,OAAStD,EAAG,CAIZ,CAEA,MAAO,CACL,KAAM6C,EAAG,KACT,QAASA,EAAG,QACZ,KAAM,SACN,MAAO,CAAC,CACV,CACF,CAQA,SAAS0C,GAA0BN,EAA2B,CAC5DA,GAASA,GAAS,KAAO,EAAI,CAACA,GAAS,EACvC,GAAI,CACF,MAAM,IAAI,KACZ,OAASpC,EAAI,CACX,OAAOyC,EAAkBzC,EAAIoC,EAAQ,CAAC,CACxC,CACF,CAEA,OAAAK,EAAkB,oCAAsCV,GACxDU,EAAkB,+BAAiC1C,GACnD0C,EAAkB,kBAAoB7E,EACtC6E,EAAkB,cAAgBrE,EAClCqE,EAAkB,SAAWC,GAC7BD,EAAkB,UAAYjF,EAEvBiF,CACT,EAAG,EAGEnG,EAAS,iBACZA,EAAS,eAAiB,IAEvBA,EAAS,sBACZA,EAAS,oBAAsB,KAE7B,CAACA,EAAS,gBAAkBA,EAAS,eAAiB,KAExDA,EAAS,eAAiB,GAE9B,GAAG,OAAO,QAAW,YAAc,OAAS,MAAM,EAE3C,SAASqG,IAA8B,CAC5C,OAAOrG,CACT,CChnCA,IAAMsG,GAAkB,UAUjB,SAASC,GAAqBC,EAAeC,EAAwB,CAC1E,IAAIC,EAAUF,EACd,GAAIA,EAAM,WAAWC,CAAM,EAAG,CAW5B,GAVAC,EAAUF,EAAM,MAAMC,EAAO,MAAM,EAM/BC,EAAQ,WAAW,GAAG,IACxBA,EAAUA,EAAQ,MAAM,CAAC,GAGvBA,IAAY,GACd,OAAOJ,GAGLI,EAAQ,SAAS,GAAG,IACtBA,GAAWJ,GAEf,CACA,OAAOI,CACT,CAUA,SAASC,GAAMC,EAAaC,EAAaC,EAAuB,CAC9D,OAAO,KAAK,IAAID,EAAK,KAAK,IAAID,EAAKE,CAAK,CAAC,CAC3C,CAuBO,SAASC,GAAeC,EAAsBC,EAAcC,EAAwB,CACzF,GAAID,EAAK,QAAUD,EAAQ,UACzB,OAAOC,EAET,IAAME,EAAe,KAAK,IAAI,EAAGD,EAASF,EAAQ,sBAAsB,EAClEI,EAAa,KAAK,IAAIH,EAAK,OAAQE,EAAeH,EAAQ,SAAS,EACzE,OAAOC,EAAK,MAAME,EAAcC,CAAU,CAC5C,CAyBO,SAASC,GACdC,EACAC,EACAC,EACAC,EACU,CACV,IAAMC,EAAgBJ,EAAQ,EAAI,EAAIA,EAChCK,EAAcJ,EAAMC,EAAQ,OAASA,EAAQ,OAASD,EAC5D,OAAIG,EAAgBC,EACXH,EAAQ,MAAME,EAAeC,CAAW,EAAE,IAAIF,CAAO,EAEvD,CAAC,CACV,CAYO,SAASG,GACdC,EAQAb,EAKA,CAxJF,IAAAc,EAAAC,EAyJE,GAAM,CAAE,QAAAP,CAAQ,EAAIK,EAEpB,GAAI,CAACL,EACH,MAAO,CAAC,EAEV,GAAM,CAAE,cAAAQ,CAAc,EAAIhB,EAAQ,OAC5BiB,EAAyB,KAAK,MAAMD,EAAgB,CAAC,EAerDP,EAAWjB,GACfO,GACE,CACE,UAAWC,EAAQ,OAAO,cAC1B,uBAAAiB,CACF,EACAzB,EACA,CACF,EAEIC,EAASE,GAAM,EAAGa,EAAQ,OAAS,IAAIM,EAAAD,GAAA,YAAAA,EAAS,OAAT,KAAAC,EAAiB,KAAMC,EAAAF,EAAQ,WAAR,KAAAE,EAAoB,EAAE,EAE1F,MAAO,CAEL,UAAWV,GAASZ,EAASO,EAAQ,OAAO,YAAaP,EAAQe,EAASC,CAAO,EACjF,QAASV,GACP,CACE,UAAWiB,EACX,uBAAAC,CACF,EACAT,EAAQf,CAAM,EACdoB,EAAQ,QAAU,CACpB,EAEA,SAAUR,GAASZ,EAAS,EAAGA,EAAS,EAAIO,EAAQ,OAAO,WAAYQ,EAASC,CAAO,CACzF,CACF,CAUe,SAARS,GAAuBC,EAAcnB,EAAyC,CACnF,OAAKA,EAAQ,QAeN,CACL,OAVaoB,GAAY,EAAE,kBAAkBD,CAAK,EAChB,MAAM,QAAQ,EAAE,IAAKN,GAAS,CA1NpE,IAAAC,EAAAC,EA0NwE,OACpE,SAAUxB,GAAqBsB,EAAQ,IAAK,OAAO,SAAS,MAAM,EAClE,SAAUA,EAAQ,KAElB,MAAMC,EAAAD,EAAQ,OAAR,KAAAC,EAAgB,OACtB,KAAKC,EAAAF,EAAQ,SAAR,KAAAE,EAAkB,OACvB,GAAGH,GAAYC,EAASb,CAAO,CACjC,EAAE,CAGF,EAhBS,CACL,OAAQ,CAAC,CACX,CAeJ,CCxMA,IAAMqB,GAAoB,gBACpBC,GAAY,GAAGD,EAAiB,SAChCE,GAAmB,GAAGF,EAAiB,gBACvCG,GAAoB,UACpBC,GAAyB,kCACzBC,GAAkB,2BAMlBC,GAAyB,EAW/B,SAASC,GAAUC,EAAmD,CACpE,OAAQ,OAAOA,EAAG,CAChB,IAAK,SACL,IAAK,UACL,IAAK,SACH,OAAOA,EACT,QACE,MACJ,CACF,CAEA,SAASC,GAAeC,EAAqBC,EAAmD,CAC9F,OAAOD,IAAS,OAAY,OAAYC,EAAOD,CAAI,CACrD,CAEA,SAASE,GAAkBC,EAA6B,CACtD,GAAI,CAACA,EAAQ,QACX,OAGF,IAAMC,EAAWC,GAAY,EAMvBC,EAAiB,KAAK,IAAIH,EAAQ,OAAO,WAAYA,EAAQ,OAAO,WAAW,EAI/EI,EAASH,EACfG,EAAO,eAAiBD,EAAiB,EAAI,CAC/C,CAQA,SAASE,GAAkBC,EAA4C,CACrE,OAAQA,EAAe,SAAW,MACpC,CAEA,SAASC,GAAyBD,EAAmD,CACnF,OAAQA,EAAe,wBAA0B,MACnD,CAEA,IAAqBE,EAArB,KAAsE,CAwBpE,YAAoBC,EAAyB,CAAzB,cAAAA,EApBpB,KAAQ,eAAsD,CAAC,EAG/D,KAAQ,aAA6B,CAAC,EAEtC,KAAQ,oBAAmD,CAAC,EAC5D,KAAQ,YAA2B,CAAC,EACpC,KAAQ,WAAqBC,GAAa,EAI1C,KAAQ,sBAAiC,GAGzC,KAAQ,eAA0B,GAElC,KAAQ,uBAAkC,GAE1C,KAAQ,kBAA6B,GAzHvC,IAAAC,EA4HIZ,GAAkBU,EAAS,KAAK,EAGhC,KAAK,YAAY,KAAK,IAAIG,CAAgB,EAC1C,KAAK,YAAY,KAAK,GAAGH,EAAS,UAAU,EAE5C,KAAK,kBAAoBA,EAAS,iBAClC,KAAK,gBAAkBA,EAAS,YAAY,eAI5C,KAAK,SAAUE,EAAA,KAAK,SAAS,SAAd,KAAAA,EAAwBE,EAEvC,IAAMC,EAAa,CAACC,EAAgB,EAChCN,EAAS,YAAY,KAAK,iBAC5BK,EAAW,KAAKL,EAAS,YAAY,KAAK,eAAe,EAGvDA,EAAS,YAAY,KAAK,iBAC5B,KAAK,YAAY,KACf,IAAIO,EAAe,CACjB,WAAAF,EACA,UAAW,IAAM,KAAK,OACxB,CAAC,CACH,EAGEL,EAAS,YAAY,KAAK,eAC5B,KAAK,YAAY,KACf,IAAIQ,EAAa,CACf,WAAAH,EACA,UAAW,IAAM,KAAK,OACxB,CAAC,CACH,EAGEL,EAAS,YAAY,OACvB,KAAK,YAAY,KAAK,IAAIS,CAAgB,EAGxCT,EAAS,YAAY,eACvB,KAAK,YAAY,KAAK,IAAIU,CAAmB,EAG/C,KAAK,YAAY,QAASC,GACxBA,EAAU,SAAS,KAA0B,KAAK,UAAU,CAC9D,EAEA,IAAMC,EAAO,KACPC,EAA0C,CAAC,EACjDC,GAAed,EAAUa,EAAYD,CAAI,EACzC,KAAK,oBAAoB,KAAK,GAAGC,CAAU,CAC7C,CAEA,SAAShB,EAAgC,CACvC,GAAI,KAAK,UAAY,OACnB,OAGF,KAAK,QAAUA,EAIf,KAAK,WAAW,EAEhB,IAAMkB,EAAuB,IAAM,CA7LvC,IAAAb,GA8LMA,EAAA,KAAK,UAAL,MAAAA,EAAc,MAAMtB,GAAkB,CAAE,UAAW,KAAK,UAAW,GAEnE,KAAK,eAAe,QAASoC,GAAU,CAhM7C,IAAAd,GAiMQA,EAAA,KAAK,UAAL,MAAAA,EAAc,MAAMc,EAAM,KAAMA,EAAM,KACxC,CAAC,EACD,KAAK,eAAiB,CAAC,EACvB,KAAK,sBAAwB,EAC/B,EAEIlB,GAAyBD,CAAM,GAOhC,SAAY,CACX,GAAI,CACF,MAAMA,EAAO,sBAAsBb,EAAsB,CAC3D,OAAQiC,EAAA,CAER,CACAF,EAAqB,CACvB,GAAG,EAGHA,EAAqB,CAEzB,CAEQ,YAAa,CAGf,KAAK,SAAS,OAChB,KAAK,QAAU,KAAK,SAAS,OACpBnB,GAAkB,KAAK,OAAO,EACvC,KAAK,QAAU,KAAK,QAAQ,OAE5B,KAAK,QAAUQ,CAEnB,CAEA,YAA0C,CACxC,OAAO,KAAK,mBACd,CAUQ,SAASc,EAAcF,EAAkB,CApPnD,IAAAd,EAqPI,IAAMiB,EAAgB,KAAK,cAAcH,EAAO,KAAK,SAAS,aAAeC,GAAe,CACrF,KAAK,oBACR,KAAK,kBAAoB,GACzB,KAAK,QAAQ,KAAKG,EAAU,iCAAiCH,CAAC,EAAE,CAAC,EAErE,CAAC,EACGE,IAAkB,SAIlB,KAAK,uBACPjB,EAAA,KAAK,UAAL,MAAAA,EAAc,MAAMgB,EAAMC,IAE1B,KAAK,eAAe,KAAK,CAAE,KAAAD,EAAM,KAAMC,CAAc,CAAC,EAClD,KAAK,eAAe,OAAS,KAAK,oBAC/B,KAAK,iBACR,KAAK,eAAiB,GACtB,KAAK,QAAQ,KACXC,EACE,gGACF,CACF,GAEF,KAAK,eAAe,MAAM,IAGhC,CAEA,aAAaC,EAAwB,CAjRvC,IAAAnB,EAAAoB,EAoRI,IAAMC,EAF4CF,GAAc,KAG5D,CACE,KAAMA,EAAU,QAAQnB,EAAAmB,EAAU,cAAV,YAAAnB,EAAuB,OAAQrB,GAEvD,SAASyC,EAAAD,EAAU,UAAV,KAAAC,EAAqBvC,GAC9B,MAAOyC,GAAMH,EAAW,KAAK,SAAS,KAAK,EAC3C,YAAa,CAAC,GAAG,KAAK,YAAY,EAClC,UAAW,KAAK,UAClB,EACA,CACE,KAAMxC,GACN,QAASC,GACT,MAAO,CAAE,OAAQ,CAAC,CAAE,EACpB,YAAa,CAAC,GAAG,KAAK,YAAY,EAClC,UAAW,KAAK,UAClB,EACJ,KAAK,SAASH,GAAW4C,CAAI,CAC/B,CAEA,kBAAkBE,EAA8B,CAC9C,KAAK,aAAaA,EAAW,KAAK,CACpC,CAEQ,cACNrC,EACAsC,EACAC,EACe,CACf,GAAI,CACF,OAAOD,EAAQ,OACb,CAACE,EAA6BvC,IAC5BF,GAAYyC,EAAcvC,CAAM,EAClCD,CACF,CACF,OAAS6B,EAAG,CACVU,EAAYV,CAAC,EACb,MACF,CACF,CAEA,cAAcY,EAA8B,CAC1C,IAAMC,EAAW,KAAK,cACpBD,EACA,KAAK,SAAS,YAAY,QACzBZ,GAAe,CACT,KAAK,yBACR,KAAK,uBAAyB,GAC9B,KAAK,QAAQ,KAAKG,EAAU,sCAAsCH,CAAC,EAAE,CAAC,EAE1E,CACF,EACIa,IAAa,SACf,KAAK,aAAa,KAAKA,CAAQ,EAC3B,KAAK,aAAa,OAAS,KAAK,iBAClC,KAAK,aAAa,MAAM,EAG9B,CAEA,OAAc,CACZ,KAAK,YAAY,QAASnB,GAAcA,EAAU,WAAW,CAAC,CAChE,CAUA,eAAeoB,EAAiBC,EAA4BC,EAA4B,CACtF,IAAMJ,EAA0C,CAC9C,KAAM,iBACN,KAAM,CACJ,IAAKE,EACL,MAAO9C,GAAU+C,EAAO,KAAK,CAC/B,EACA,UAAW,IAAI,KAAK,EAAE,QAAQ,EAC9B,MAAO,qBACP,MAAO,MACT,EACA,KAAK,cAAcH,CAAU,CAC/B,CAUA,wBAAwBE,EAAiBC,EAAkC,CACzE,IAAMH,EAA0C,CAC9C,KAAM,sBACN,KAAM,CACJ,IAAKE,EACL,MAAO9C,GAAU+C,EAAO,KAAK,CAC/B,EACA,UAAW,IAAI,KAAK,EAAE,QAAQ,EAC9B,MAAO,qBACP,MAAO,MACT,EAEA,KAAK,cAAcH,CAAU,CAC/B,CACF,EClXA,IAAMK,GAAgD,CACpD,eAAgB,EAChB,YAAa,GACb,WAAY,GACZ,MAAO,GACP,cAAe,GACf,KAAM,CACJ,gBAAiB,GACjB,cAAe,GACf,gBAAiB,MACnB,EACA,QAAS,CAAC,CACZ,EAEMC,GAAoC,CACxC,QAAS,GACT,OAAQ,CACN,YAAa,EACb,WAAY,EACZ,cAAe,CACjB,CACF,EAEO,SAASC,IAAgC,CAC9C,MAAO,CACL,YAAa,CACX,eAAgB,GAChB,YAAa,GACb,WAAY,GACZ,MAAO,GACP,cAAe,GACf,KAAM,CACJ,gBAAiB,GACjB,cAAe,EACjB,EACA,QAAS,CAAC,CACZ,EACA,MAAO,CACL,QAAS,GACT,OAAQ,CACN,YAAa,EACb,WAAY,EACZ,cAAe,GACjB,CACF,EACA,iBAAkB,IAClB,WAAY,CAAC,EACb,aAAc,CAAC,CACjB,CACF,CAEA,SAASC,EAAgBC,EAAcC,EAAsBC,EAA4B,CACvF,OAAOC,EACL,kBAAkBH,CAAI,uBAAuBC,CAAY,SAASC,CAAU,uBAC9E,CACF,CAEA,SAASE,EAAcC,EAAcL,EAAcM,EAA0C,CAC3F,OAAQC,GAAY,CAClB,IAAML,EAAa,OAAOK,EAC1B,OAAIL,IAAeG,EACV,IAETC,GAAA,MAAAA,EAAQ,KAAKP,EAAgBC,EAAMK,EAAMH,CAAU,GAC5C,GACT,CACF,CAEA,SAASM,EAAiBD,EAAqBE,EAAiBC,EAAmC,CACjG,OAA0BH,GAAS,OAC7B,CAACG,GAGDA,EAAQH,CAAI,GACPA,EAGJE,CACT,CAEA,SAASE,GACPC,EACAC,EACAP,EACmB,CACnB,GAAIM,IAAY,QAAaA,IAAY,IAAS,OAAOA,GAAY,SACnE,OAAAN,GAAA,MAAAA,EAAQ,KACNP,EAAgB,mBAAoB,gCAAiC,OAAOa,CAAO,GAE9EC,EAGT,GAAID,IAAY,GACd,MAAO,CACL,gBAAiB,GACjB,cAAe,EACjB,EAIEA,GAAA,MAAAA,EAAS,iBACP,OAAOA,EAAQ,iBAAoB,aACrCN,GAAA,MAAAA,EAAQ,KACNH,EACE,uEAAuE,OAAOS,EAAQ,eAAe,EACvG,IAIN,IAAME,EACJF,GAAA,MAAAA,EAAS,iBAAmB,OAAOA,GAAA,YAAAA,EAAS,kBAAoB,WAC5DA,EAAQ,gBACR,OAEN,MAAO,CACL,gBAAiBJ,EACfI,GAAA,YAAAA,EAAS,gBACTC,EAAS,gBACTT,EAAW,UAAW,mCAAoCE,CAAM,CAClE,EACA,cAAeE,EACbI,GAAA,YAAAA,EAAS,cACTC,EAAS,cACTT,EAAW,UAAW,iCAAkCE,CAAM,CAChE,EACA,gBAAAQ,CACF,CACF,CAEA,SAASC,GAAYH,EAAyC,CAC5D,GAAIA,EAAQ,OAAQ,CAClB,GAAM,CAAE,OAAAN,CAAO,EAAIM,EACnB,GAAI,OAAON,GAAW,UAAYA,IAAW,MAAQ,SAAUA,EAC7D,OAAOU,EAAcV,CAAM,EAG7BW,EAAe,KAAKlB,EAAgB,SAAU,wBAAyB,OAAOO,CAAM,CAAC,CACvF,CAEF,CAEA,SAASY,GACPN,EACAC,EACAP,EACoB,CA9JtB,IAAAa,EAAAC,EAAAC,EA+JE,OAAIT,IAAY,GACPf,GAEF,CAEL,QAAS,GACT,OAAQ,CACN,YAAaW,GACXW,EAAAP,GAAA,YAAAA,EAAS,SAAT,YAAAO,EAAiB,YACjBN,EAAS,OAAO,YAChBT,EAAW,SAAU,oBAAqBE,CAAM,CAClD,EACA,WAAYE,GACVY,EAAAR,GAAA,YAAAA,EAAS,SAAT,YAAAQ,EAAiB,WACjBP,EAAS,OAAO,WAChBT,EAAW,SAAU,mBAAoBE,CAAM,CACjD,EACA,cAAeE,GACba,EAAAT,GAAA,YAAAA,EAAS,SAAT,YAAAS,EAAiB,cACjBR,EAAS,OAAO,cAChBT,EAAW,SAAU,sBAAuBE,CAAM,CACpD,CACF,CACF,CACF,CAEA,SAASgB,GACPV,EACAC,EACAP,EAC0B,CAC1B,OAAIM,IAAY,GACPhB,GAEF,CACL,eAAgBY,EACdI,GAAA,YAAAA,EAAS,eACTC,EAAS,eACTT,EAAW,SAAU,6BAA8BE,CAAM,CAC3D,EACA,YAAaE,EACXI,GAAA,YAAAA,EAAS,YACTC,EAAS,YACTT,EAAW,UAAW,0BAA2BE,CAAM,CACzD,EACA,WAAYE,EACVI,GAAA,YAAAA,EAAS,WACTC,EAAS,WACTT,EAAW,UAAW,yBAA0BE,CAAM,CACxD,EACA,MAAOE,EACLI,GAAA,YAAAA,EAAS,MACTC,EAAS,MACTT,EAAW,UAAW,oBAAqBE,CAAM,CACnD,EACA,cAAeE,EACbI,GAAA,YAAAA,EAAS,cACTC,EAAS,cACTT,EAAW,UAAW,4BAA6BE,CAAM,CAC3D,EACA,KAAMK,GAAUC,GAAA,YAAAA,EAAS,KAAMC,EAAS,KAAMP,CAAM,EACpD,QAASE,EAAcI,GAAA,YAAAA,EAAS,QAASC,EAAS,QAAUN,GACtD,MAAM,QAAQA,CAAI,EACb,IAETD,GAAA,MAAAA,EAAQ,KAAKP,EAAgB,sBAAuB,qBAAsB,OAAOQ,CAAI,GAC9E,GACR,CACH,CACF,CAEe,SAARgB,EAAuBX,EAAkBN,EAAmC,CACjF,IAAMO,EAAWf,GAAe,EAChC,OAAIc,EAAQ,aACVR,EAAW,SAAU,cAAeE,CAAM,EAAEM,EAAQ,WAAW,EAE7DA,EAAQ,OACVR,EAAW,SAAU,QAASE,CAAM,EAAEM,EAAQ,KAAK,EAE9C,CACL,YAAaU,GAAiBV,EAAQ,YAAaC,EAAS,YAAaP,CAAM,EAC/E,MAAOY,GAAWN,EAAQ,MAAOC,EAAS,MAAOP,CAAM,EACvD,iBAAkBE,EAChBI,EAAQ,iBACRC,EAAS,iBACTT,EAAW,SAAU,mBAAoBE,CAAM,CACjD,EACA,WAAY,CACV,GAAGE,EAAcI,EAAQ,WAAYC,EAAS,WAAaN,GACrD,MAAM,QAAQA,CAAI,EACb,IAETD,GAAA,MAAAA,EAAQ,KAAKP,EAAgB,aAAc,cAAe,OAAOQ,CAAI,GAC9D,GACR,CACH,EACA,OAAQQ,GAAYH,CAAO,EAC3B,aAAcJ,EAAcI,EAAQ,aAAcC,EAAS,aAAeN,GACpE,MAAM,QAAQA,CAAI,EACb,IAETD,GAAA,MAAAA,EAAQ,KAAKP,EAAgB,eAAgB,oBAAqB,OAAOQ,CAAI,GACtE,GACR,CACH,CACF,CClQA,IAAIiB,EACAC,GAAsC,GA8CnC,SAASC,GAAcC,EAAmB,CAC/C,IAAMC,EAASC,EAAcF,GAAA,YAAAA,EAAS,MAAM,EAE5C,GAAIH,EAAmB,CACrBI,EAAO,KAAKE,EAAU,+DAA+D,CAAC,EACtF,MACF,CAEA,IAAMC,EAAgBC,EAAML,GAAW,CAAC,EAAGC,CAAM,EACjDJ,EAAoB,IAAIS,EAAqBF,CAAa,CAC5D,CAYO,SAASG,GAAqD,CACnE,GAAI,CAACV,EAAmB,CACtB,GAAIC,GACF,OAGFU,EAAe,KAAKL,EAAU,oCAAoC,CAAC,EACnEL,GAA6B,GAC7B,MACF,CAEA,OAAOD,CACT,CASO,SAASY,IAAyB,CACvCZ,EAAoB,OACpBC,GAA6B,EAC/B,CCrFO,SAASY,IAA0C,CAd1D,IAAAC,EAeE,QAAOA,EAAAC,EAAqB,IAArB,YAAAD,EAAwB,eAAgB,CAAC,CAClD,CAcO,SAASE,GAAaC,EAAwB,CA9BrD,IAAAH,GA+BEA,EAAAC,EAAqB,IAArB,MAAAD,EAAwB,aAAaG,EACvC,CAgBO,SAASC,GAAkBC,EAA8B,CAhDhE,IAAAL,GAiDEA,EAAAC,EAAqB,IAArB,MAAAD,EAAwB,kBAAkBK,EAC5C,CAcO,SAASC,GAAcC,EAA8B,CAhE5D,IAAAP,GAiEEA,EAAAC,EAAqB,IAArB,MAAAD,EAAwB,cAAcO,EACxC,CAeO,SAASC,GAASC,EAAgC,CAjFzD,IAAAT,GAkFEA,EAAAC,EAAqB,IAArB,MAAAD,EAAwB,SAASS,EACnC,CAWO,SAASC,IAAc,CA9F9B,IAAAV,GA+FEA,EAAAC,EAAqB,IAArB,MAAAD,EAAwB,OAC1B,CrB3EO,SAASW,GAAsBC,EAAqC,CACzE,IAAMC,EAAgBC,EAAMF,GAAW,CAAC,EAAGG,EAAcH,GAAA,YAAAA,EAAS,MAAM,CAAC,EACzE,OAAO,IAAII,EAAqBH,CAAa,CAC/C","names":["src_exports","__export","addBreadcrumb","captureError","captureErrorEvent","close","getTelemetryInstance","initTelemetry","initTelemetryInstance","inspectors","register","resetTelemetryInstance","__toCommonJS","getTarget","event","e","isNode","element","anyElement","getClassName","value","elementToString","components","className","toSelector","options","ptr","asString","ClickCollector","event","_a","target","getTarget","breadcrumb","toSelector","recorder","_sessionId","THROTTLE_TIME_MS","INPUT_TAG_NAMES","KeypressCollector","event","_a","target","getTarget","htmlElement","breadcrumb","toSelector","recorder","_sessionId","crumb","ErrorCollector","event","_a","recorder","filterUrl","filters","url","filtered","filter","filterHttpBreadcrumb","crumb","options","_a","filterUrl","LD_ORIGINAL_FETCH","originalFetch","processFetchArgs","input","init","_a","url","method","decorateFetch","callback","wrapper","args","timestamp","response","crumb","e","FetchCollector","options","decorateFetch","breadcrumb","_a","_b","_c","filtersExecuted","filterHttpBreadcrumb","err","recorder","_sessionId","LD_ORIGINAL_XHR","LD_ORIGINAL_XHR_OPEN","LD_ORIGINAL_XHR_SEND","LD_DATA_XHR","originalOpen","originalSend","decorateXhr","callback","wrappedOpen","args","_event","data","xhrData","e","wrappedSend","XhrCollector","options","decorateXhr","breadcrumb","_a","_b","_c","filtersExecuted","filterHttpBreadcrumb","err","recorder","_sessionId","pollingRegex","streamingREgex","authorityUrlFilter","url","urlObj","hadAuth","e","ldUrlFilter","_a","_b","regexMatch","context","defaultUrlFilter","makeInspectors","options","inspectors","telemetry","flagKey","flagDetail","context","detail","fallbackLogger","loggingPrefix","prefixLog","message","safeMinLogger","logger","args","e","timeLow","timeMid","timeHiAndVersion","clockSeqHiAndReserved","clockSeqLow","nodes","getRandom128bit","typedArray","values","index","hex","bytes","range","strVal","formatDataAsUuidV4","fallbackUuidV4","randomUuidV4","TraceKit","window","undefined","_slice","UNKNOWN_FUNCTION","ERROR_TYPES_RE","_has","object","key","_isUndefined","what","func","wrapped","e","sourceCache","loadSource","url","request","getSource","source","domain","match","guessFunctionName","lineNo","reFunctionArgNames","reGuessFunction","line","maxLines","m","i","gatherContext","context","linesBefore","linesAfter","start","end","escapeRegExp","text","escapeCodeAsRegExpForMatchingInsideHTML","body","findSourceInUrls","re","urls","j","findSourceInLine","fragment","findSourceByFunctionBody","scripts","code","codeRE","eventRE","parts","result","script","name","args","event","computeStackTraceFromStackProp","ex","_a","chrome","gecko","winjs","isEval","geckoEval","chromeEval","lines","stack","submatch","element","reference","isNative","srcContext","computeStackTraceFromStacktraceProp","stacktrace","opera10Regex","opera11Regex","exc","computeStackTraceFromOperaMultiLineMessage","lineRE1","lineRE2","lineRE3","inlineScriptBlocks","s","item","relativeLine","pos","src","midline","augmentStackTraceWithInitialElement","stackInfo","message","initial","computeStackTraceByWalkingCallerChain","depth","functionName","funcs","recursion","curr","computeStackTrace","computeStackTraceOfCaller","getTraceKit","INDEX_SPECIFIER","processUrlToFileName","input","origin","cleaned","clamp","min","max","value","trimSourceLine","options","line","column","captureStart","captureEnd","getLines","start","end","context","trimmer","adjustedStart","adjustedEnd","getSrcLines","inFrame","_a","_b","maxLineLength","beforeColumnCharacters","parse","error","getTraceKit","CUSTOM_KEY_PREFIX","ERROR_KEY","SESSION_INIT_KEY","GENERIC_EXCEPTION","NULL_EXCEPTION_MESSAGE","MISSING_MESSAGE","INITIALIZATION_TIMEOUT","safeValue","u","applyFilter","item","filter","configureTraceKit","options","TraceKit","getTraceKit","beforeAfterMax","anyObj","isLDClientLogging","client","isLDClientInitialization","BrowserTelemetryImpl","_options","randomUuidV4","_a","ErrorCollector","fallbackLogger","urlFilters","defaultUrlFilter","FetchCollector","XhrCollector","ClickCollector","KeypressCollector","collector","impl","inspectors","makeInspectors","completeRegistration","event","e","type","filteredEvent","prefixLog","exception","_b","data","parse","errorEvent","filters","handleError","itemToFilter","breadcrumb","filtered","flagKey","detail","_context","disabledBreadcrumbs","disabledStack","defaultOptions","wrongOptionType","name","expectedType","actualType","prefixLog","checkBasic","type","logger","item","itemOrDefault","defaultValue","checker","parseHttp","options","defaults","customUrlFilter","parseLogger","safeMinLogger","fallbackLogger","parseStack","_a","_b","_c","parseBreadcrumbs","parse","telemetryInstance","warnedClientNotInitialized","initTelemetry","options","logger","safeMinLogger","prefixLog","parsedOptions","parse","BrowserTelemetryImpl","getTelemetryInstance","fallbackLogger","resetTelemetryInstance","inspectors","_a","getTelemetryInstance","captureError","exception","captureErrorEvent","errorEvent","addBreadcrumb","breadcrumb","register","client","close","initTelemetryInstance","options","parsedOptions","parse","safeMinLogger","BrowserTelemetryImpl"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/collectors/dom/getTarget.ts","../src/collectors/dom/toSelector.ts","../src/collectors/dom/ClickCollector.ts","../src/collectors/dom/KeypressCollector.ts","../src/collectors/error.ts","../src/filters/filterUrl.ts","../src/filters/filterHttpBreadcrumb.ts","../src/collectors/http/fetchDecorator.ts","../src/collectors/http/fetch.ts","../src/collectors/http/xhrDecorator.ts","../src/collectors/http/xhr.ts","../src/filters/defaultUrlFilter.ts","../src/inspectors.ts","../src/logging.ts","../src/randomUuidV4.ts","../src/vendor/TraceKit.ts","../src/stack/StackParser.ts","../src/BrowserTelemetryImpl.ts","../src/options.ts","../src/singleton/singletonInstance.ts","../src/singleton/singletonMethods.ts"],"sourcesContent":["import { BrowserTelemetry } from './api/BrowserTelemetry';\nimport { Options } from './api/Options';\nimport BrowserTelemetryImpl from './BrowserTelemetryImpl';\nimport { safeMinLogger } from './logging';\nimport parse from './options';\n\nexport * from './api';\n\nexport * from './singleton';\n\n/**\n * Initialize a new telemetry instance.\n *\n * This instance is not global. Generally developers should use {@link initTelemetry} instead.\n *\n * If for some reason multiple telemetry instances are needed, this method can be used to create a new instance.\n * Instances are not aware of each other and may send duplicate data from automatically captured events.\n *\n * @param options The options to use for the telemetry instance.\n * @returns A telemetry instance.\n */\nexport function initTelemetryInstance(options?: Options): BrowserTelemetry {\n const parsedOptions = parse(options || {}, safeMinLogger(options?.logger));\n return new BrowserTelemetryImpl(parsedOptions);\n}\n","/**\n * Get the event target. This is wrapped because in some situations a browser may throw when\n * accessing the event target.\n *\n * @param event The event to get the target from.\n * @returns The event target, or undefined if one is not available.\n */\nexport default function getTarget(event: { target: any }): Element | undefined {\n try {\n return event.target as Element;\n } catch {\n return undefined;\n }\n}\n","// https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator\nconst CHILD_COMBINATOR = '>';\n// Spacing around the combinator is optional, but it increases readability.\nconst CHILD_SEPARATOR = ` ${CHILD_COMBINATOR} `;\n\n/**\n * The elements of a node we need for traversal.\n */\ninterface NodeWithParent {\n parentNode?: NodeWithParent;\n}\n\n/**\n * The elements of a node we need to generate a string representation.\n *\n * All element fields are optional, so a type guard is not required to use this typing.\n */\ninterface BasicElement {\n tagName?: string;\n id?: string;\n className?: string;\n}\n\n/**\n * Type guard that verifies that an element complies with {@link NodeWithParent}.\n */\nfunction isNode(element: unknown): element is NodeWithParent {\n const anyElement = element as any;\n // Parent node being null or undefined fill be falsy.\n // The type of `null` is object, so check for null as well.\n return typeof anyElement === 'object' && anyElement != null && anyElement.parentNode;\n}\n\n/**\n * Given an element produce a class name in CSS selector format.\n *\n * Exported for testing.\n *\n * @param element The element to get a class name for.\n * @returns The class name, or undefined if there is no class name.\n */\nexport function getClassName(element: BasicElement): string | undefined {\n if (typeof element.className !== `string`) {\n return undefined;\n }\n let value = element.className;\n // Elements should be space separated in a class attribute. If there are other kinds of\n // whitespace, then this code could need adjustment.\n if (element.className.includes(' ')) {\n value = element.className.replace(' ', '.');\n }\n\n if (value !== '') {\n return `.${value}`;\n }\n // There was no class name.\n return undefined;\n}\n\n/**\n * Produce a string representation for a single DOM element. Does not produce the full selector.\n *\n * Exported for testing.\n *\n * @param element The element to produce a text representation for.\n * @returns A text representation of the element, or an empty string if one cannot be produced.\n */\nexport function elementToString(element: BasicElement): string {\n if (!element.tagName) {\n return '';\n }\n\n const components: string[] = [];\n\n components.push(element.tagName.toLowerCase());\n if (element.id) {\n components.push(`#${element.id}`);\n }\n\n const className = getClassName(element);\n if (className) {\n components.push(className);\n }\n\n return components.join('');\n}\n\n/**\n * Given an HTML element produce a CSS selector.\n *\n * Defaults to a maximum depth of 10 components.\n *\n * Example:\n * ```\n * <html>\n * <body>\n * <div>\n * <ul>\n * <li class=\"some-class\">\n * <p id=\"some-id\">toaster</p>\n * </li>\n * </ul>\n * </div>\n * </body>\n * </html>\n * ```\n * The <p> element in the above HTML would produce:\n * `body > div > ul > li.some-class > p#some-id`\n *\n * @param element The element to generate a selector from.\n * @param options Options which control selector generation.\n * @returns The generated selector.\n */\nexport default function toSelector(\n element: unknown,\n options: {\n maxDepth: number;\n } = { maxDepth: 10 },\n): string {\n // For production we may want to consider if we additionally limit the maximum selector length.\n // Limiting the components should generate reasonable selectors in most cases.\n const components: string[] = [];\n let ptr = element;\n while (isNode(ptr) && ptr.parentNode && components.length < options.maxDepth) {\n const asString = elementToString(ptr as BasicElement);\n // We do not need to include the 'html' component in the selector.\n // The HTML element can be assumed to be the top. If there are more elements\n // we would not want to include them (they would be something non-standard).\n if (asString === 'html') {\n break;\n }\n\n components.push(asString);\n ptr = ptr.parentNode;\n }\n return components.reverse().join(CHILD_SEPARATOR);\n}\n","import { UiBreadcrumb } from '../../api/Breadcrumb';\nimport { Collector } from '../../api/Collector';\nimport { Recorder } from '../../api/Recorder';\nimport getTarget from './getTarget';\nimport toSelector from './toSelector';\n\n/**\n * Collects mouse click events and adds them as breadcrumbs.\n */\nexport default class ClickCollector implements Collector {\n private _destination?: Recorder;\n\n constructor() {\n window.addEventListener(\n 'click',\n (event: MouseEvent) => {\n const target = getTarget(event);\n if (target) {\n const breadcrumb: UiBreadcrumb = {\n class: 'ui',\n type: 'click',\n level: 'info',\n timestamp: Date.now(),\n message: toSelector(target),\n };\n this._destination?.addBreadcrumb(breadcrumb);\n }\n },\n true,\n );\n }\n\n register(recorder: Recorder, _sessionId: string): void {\n this._destination = recorder;\n }\n unregister(): void {\n this._destination = undefined;\n }\n}\n","import { Breadcrumb, UiBreadcrumb } from '../../api/Breadcrumb';\nimport { Collector } from '../../api/Collector';\nimport { Recorder } from '../../api/Recorder';\nimport getTarget from './getTarget';\nimport toSelector from './toSelector';\n\nconst THROTTLE_TIME_MS = 1000;\n\nconst INPUT_TAG_NAMES = ['INPUT', 'TEXTAREA'];\n\n/**\n * Collects key press events and adds them as breadcrumbs.\n */\nexport default class KeypressCollector implements Collector {\n private _destination?: Recorder;\n private _lastEvent?: UiBreadcrumb;\n\n constructor() {\n // Currently we use the keypress event, but it is technically deprecated.\n // It is the simplest way to currently get the most broad coverage.\n // In the future we may want to consider some check to attempt to selectively use a more\n // targetted event.\n window.addEventListener(\n 'keypress',\n (event: KeyboardEvent) => {\n const target = getTarget(event);\n const htmlElement = target as HTMLElement;\n // An example of `isContentEditable` would be an editable <p> tag.\n // Input and textarea tags do not have the isContentEditable property.\n if (\n target &&\n (INPUT_TAG_NAMES.includes(target.tagName) || htmlElement?.isContentEditable)\n ) {\n const breadcrumb: UiBreadcrumb = {\n class: 'ui',\n type: 'input',\n level: 'info',\n timestamp: Date.now(),\n message: toSelector(target),\n };\n\n if (!this._shouldDeduplicate(breadcrumb)) {\n this._destination?.addBreadcrumb(breadcrumb);\n this._lastEvent = breadcrumb;\n }\n }\n },\n true,\n );\n }\n\n register(recorder: Recorder, _sessionId: string): void {\n this._destination = recorder;\n }\n unregister(): void {\n this._destination = undefined;\n }\n\n private _shouldDeduplicate(crumb: Breadcrumb): boolean {\n // If this code every is demonstrably a performance issue, then we may be able to implement\n // some scheme to de-duplicate these via some DOM mechanism. Like adding a debounce annotation\n // of some kind.\n if (this._lastEvent) {\n const timeDiff = Math.abs(crumb.timestamp - this._lastEvent.timestamp);\n return timeDiff <= THROTTLE_TIME_MS && this._lastEvent.message === crumb.message;\n }\n return false;\n }\n}\n","import { Collector } from '../api/Collector';\nimport { Recorder } from '../api/Recorder';\n\nexport default class ErrorCollector implements Collector {\n private _destination?: Recorder;\n\n constructor() {\n window.addEventListener(\n 'error',\n (event: ErrorEvent) => {\n this._destination?.captureErrorEvent(event);\n },\n true,\n );\n window.addEventListener(\n 'unhandledrejection',\n (event: PromiseRejectionEvent) => {\n if (event.reason) {\n this._destination?.captureError(event.reason);\n }\n },\n true,\n );\n }\n\n register(recorder: Recorder): void {\n this._destination = recorder;\n }\n unregister(): void {\n this._destination = undefined;\n }\n}\n","import { UrlFilter } from '../api/Options';\n\nexport default function filterUrl(filters: UrlFilter[], url?: string): string {\n if (!url) {\n return '';\n }\n return filters.reduce((filtered, filter) => filter(filtered), url);\n}\n","import { HttpBreadcrumb } from '../api/Breadcrumb';\nimport HttpCollectorOptions from '../collectors/http/HttpCollectorOptions';\nimport filterUrl from './filterUrl';\n\n/**\n * This function does in-place filtering of http breadcrumbs.\n *\n * @param crumb The breadcrumb to filter.\n */\nexport default function filterHttpBreadcrumb(\n crumb: HttpBreadcrumb,\n options: HttpCollectorOptions,\n): void {\n if (crumb.data?.url) {\n // Re-assigning for performance. The contract of the function is clear that the input\n // data is modified.\n // eslint-disable-next-line no-param-reassign\n crumb.data.url = filterUrl(options.urlFilters, crumb.data.url);\n }\n}\n","import { HttpBreadcrumb } from '../../api/Breadcrumb';\n\nconst LD_ORIGINAL_FETCH = '__LaunchDarkly_original_fetch';\n\nconst originalFetch = window.fetch;\n\n/**\n * Given fetch arguments produce a URL and method.\n *\n * Exposed for testing.\n *\n * @param input First parameter to fetch.\n * @param init Second, optional, parameter to fetch.\n * @returns Return the URL and method. If not method or url can be accessed, then 'GET' will be the\n * method and the url will be an empty string.\n */\nexport function processFetchArgs(\n input: RequestInfo | URL,\n init?: RequestInit | undefined,\n): { url: string; method: string } {\n let url = '';\n let method = 'GET';\n\n if (typeof input === 'string') {\n url = input;\n }\n // We may want to consider prop checks if this ends up being a problem for people.\n // `instanceof` was not added to Edge until 2015.\n if (typeof Request !== 'undefined' && input instanceof Request) {\n url = input.url;\n method = input.method;\n }\n if (typeof URL !== 'undefined' && input instanceof URL) {\n url = input.toString();\n }\n\n if (init) {\n method = init.method ?? method;\n }\n return { url, method };\n}\n\n/**\n * Decorate fetch and execute the callback whenever a fetch is completed providing a breadcrumb.\n *\n * @param callback Function which handles a breadcrumb.\n */\nexport default function decorateFetch(callback: (breadcrumb: HttpBreadcrumb) => void) {\n // TODO (SDK-884): Check if already wrapped?\n // TODO (SDK-884): Centralized mechanism to wrapping?\n\n // In this function we add type annotations for `this`. In this case we are telling the compiler\n // we don't care about the typing.\n\n // This is a function instead of an arrow function in order to preserve the original `this`.\n // Arrow functions capture the enclosing `this`.\n function wrapper(this: any, ...args: any[]): Promise<Response> {\n const timestamp = Date.now();\n // We are taking the original parameters and passing them through. We are not specifying their\n // type information and the number of parameters could be changed over time and the wrapper\n // would still function.\n return originalFetch.apply(this, args as any).then((response: Response) => {\n const crumb: HttpBreadcrumb = {\n class: 'http',\n timestamp,\n level: response.ok ? 'info' : 'error',\n type: 'fetch',\n data: {\n // We know these will be fetch args. We only can take 2 of them, one of which may be\n // undefined. We still use all the ars to apply to the original function.\n ...processFetchArgs(args[0], args[1]),\n statusCode: response.status,\n statusText: response.statusText,\n },\n };\n callback(crumb);\n return response;\n });\n }\n\n wrapper.prototype = originalFetch?.prototype;\n\n try {\n // Use defineProperty to prevent this value from being enumerable.\n Object.defineProperty(wrapper, LD_ORIGINAL_FETCH, {\n // Defaults to non-enumerable.\n value: originalFetch,\n writable: true,\n configurable: true,\n });\n } catch {\n // Intentional ignore.\n // TODO: If we add debug logging, then this should be logged.\n }\n\n window.fetch = wrapper;\n}\n","import { Collector } from '../../api/Collector';\nimport { Recorder } from '../../api/Recorder';\nimport filterHttpBreadcrumb from '../../filters/filterHttpBreadcrumb';\nimport decorateFetch from './fetchDecorator';\nimport HttpCollectorOptions from './HttpCollectorOptions';\n\n/**\n * Instrument fetch requests and generate a breadcrumb for each request.\n */\nexport default class FetchCollector implements Collector {\n private _destination?: Recorder;\n private _loggedIssue: boolean = false;\n\n constructor(options: HttpCollectorOptions) {\n decorateFetch((breadcrumb) => {\n let filtersExecuted = false;\n try {\n filterHttpBreadcrumb(breadcrumb, options);\n filtersExecuted = true;\n } catch (err) {\n if (!this._loggedIssue) {\n options.getLogger?.()?.warn('Error filtering http breadcrumb', err);\n this._loggedIssue = true;\n }\n }\n // Only add the breadcrumb if the filter didn't throw. We don't want to\n // report a breadcrumb that may have not have had the correct information redacted.\n if (filtersExecuted) {\n this._destination?.addBreadcrumb(breadcrumb);\n }\n });\n }\n\n register(recorder: Recorder, _sessionId: string): void {\n this._destination = recorder;\n }\n\n unregister(): void {\n this._destination = undefined;\n }\n}\n","import { HttpBreadcrumb } from '../../api/Breadcrumb';\n\nconst LD_ORIGINAL_XHR = '__LaunchDarkly_original_xhr';\nconst LD_ORIGINAL_XHR_OPEN = `${LD_ORIGINAL_XHR}_open`;\nconst LD_ORIGINAL_XHR_SEND = `${LD_ORIGINAL_XHR}_send`;\n\n// Key used to store data inside the xhr.\nconst LD_DATA_XHR = '__LaunchDarkly_data_xhr';\n\n// We want to monitor open to collect the URL and method.\nconst originalOpen = window.XMLHttpRequest.prototype.open;\n// We want to monitor send in order to generate an accurate timestamp.\nconst originalSend = window.XMLHttpRequest.prototype.send;\n\ninterface LDXhrData {\n method?: string;\n url?: string;\n timestamp?: number;\n error?: boolean;\n}\n\n/**\n * Decorate XMLHttpRequest and execute the callback whenever a request is completed.\n *\n * @param callback Function which handles a breadcrumb.\n */\nexport default function decorateXhr(callback: (breadcrumb: HttpBreadcrumb) => void) {\n // In these functions we add type annotations for `this`. The impact here should just\n // be that we get correct typing for typescript. They should not affect the output.\n\n // We are using functions instead of an arrow functions in order to preserve the original `this`.\n // Arrow functions capture the enclosing `this`.\n\n function wrappedOpen(this: XMLHttpRequest, ...args: any[]) {\n // Listen to error so we can tag this request as having an error. If there is no error event\n // then the request will assume to not have errored.\n // eslint-disable-next-line func-names\n this.addEventListener('error', function (_event: ProgressEvent<XMLHttpRequestEventTarget>) {\n // We know, if the data is present, that it has this shape, as we injected it.\n const data: LDXhrData = (this as any)[LD_DATA_XHR];\n data.error = true;\n });\n\n this.addEventListener(\n 'loadend',\n // eslint-disable-next-line func-names\n function (_event: ProgressEvent<XMLHttpRequestEventTarget>) {\n // We know, if the data is present, that it has this shape, as we injected it.\n const data: LDXhrData = (this as any)[LD_DATA_XHR];\n // Timestamp could be falsy for 0, but obviously that isn't a good timestamp, so we are ok.\n if (data && data.timestamp) {\n callback({\n class: 'http',\n timestamp: data.timestamp,\n level: data.error ? 'error' : 'info',\n type: 'xhr',\n data: {\n url: data.url,\n method: data.method,\n statusCode: this.status,\n statusText: this.statusText,\n },\n });\n }\n },\n true,\n );\n\n // We know these will be open arguments.\n originalOpen.apply(this, args as any);\n\n try {\n const xhrData: LDXhrData = {\n method: args?.[0],\n url: args?.[1],\n };\n // Use defineProperty to prevent this value from being enumerable.\n Object.defineProperty(this, LD_DATA_XHR, {\n // Defaults to non-enumerable.\n value: xhrData,\n writable: true,\n configurable: true,\n });\n } catch {\n // Intentional ignore.\n // TODO: If we add debug logging, then this should be logged.\n }\n }\n\n function wrappedSend(this: XMLHttpRequest, ...args: any[]) {\n // We know these will be open arguments.\n originalSend.apply(this, args as any);\n\n // We know, if the data is present, that it has this shape, as we injected it.\n const data: LDXhrData = (this as any)[LD_DATA_XHR];\n if (data) {\n data.timestamp = Date.now();\n }\n }\n\n window.XMLHttpRequest.prototype.open = wrappedOpen;\n window.XMLHttpRequest.prototype.send = wrappedSend;\n\n try {\n // Use defineProperties to prevent these values from being enumerable.\n // The properties default to non-enumerable.\n Object.defineProperties(window.XMLHttpRequest, {\n [LD_ORIGINAL_XHR_OPEN]: {\n value: originalOpen,\n writable: true,\n configurable: true,\n },\n [LD_ORIGINAL_XHR_SEND]: {\n value: originalSend,\n writable: true,\n configurable: true,\n },\n });\n } catch {\n // Intentional ignore.\n // TODO: If we add debug logging, then this should be logged.\n }\n}\n","import { Collector } from '../../api/Collector';\nimport { Recorder } from '../../api/Recorder';\nimport filterHttpBreadcrumb from '../../filters/filterHttpBreadcrumb';\nimport HttpCollectorOptions from './HttpCollectorOptions';\nimport decorateXhr from './xhrDecorator';\n\n/**\n * Instrument XMLHttpRequest and provide a breadcrumb for every XMLHttpRequest\n * which is completed.\n */\nexport default class XhrCollector implements Collector {\n private _destination?: Recorder;\n private _loggedIssue: boolean = false;\n\n constructor(options: HttpCollectorOptions) {\n decorateXhr((breadcrumb) => {\n let filtersExecuted = false;\n try {\n filterHttpBreadcrumb(breadcrumb, options);\n filtersExecuted = true;\n } catch (err) {\n if (!this._loggedIssue) {\n options.getLogger?.()?.warn('Error filtering http breadcrumb', err);\n this._loggedIssue = true;\n }\n }\n // Only add the breadcrumb if the filter didn't throw. We don't want to\n // report a breadcrumb that may have not have had the correct information redacted.\n if (filtersExecuted) {\n this._destination?.addBreadcrumb(breadcrumb);\n }\n });\n }\n\n register(recorder: Recorder, _sessionId: string): void {\n this._destination = recorder;\n }\n\n unregister(): void {\n this._destination = undefined;\n }\n}\n","const pollingRegex = /sdk\\/evalx\\/[^/]+\\/contexts\\/(?<context>[^/?]*)\\??.*?/;\nconst streamingREgex = /\\/eval\\/[^/]+\\/(?<context>[^/?]*)\\??.*?/;\n\n/**\n * Filter which redacts user information (auth) from a URL.\n *\n * If a username/password is present, then they are replaced with 'redacted'.\n * Authority reference: https://developer.mozilla.org/en-US/docs/Web/URI/Authority\n *\n * @param url URL to filter.\n * @returns A filtered URL.\n */\nfunction authorityUrlFilter(url: string): string {\n // This will work in browser environments, but in the future we may want to consider an approach\n // which doesn't rely on the browser's URL parsing. This is because other environments we may\n // want to target, such as ReactNative, may not have as robust URL parsing.\n // We first check if the URL can be parsed, because it may not include the base URL.\n try {\n // If the URL includes a protocol, if so, then it can probably be parsed.\n // Credentials require a full URL.\n if (url.includes('://')) {\n const urlObj = new URL(url);\n let hadAuth = false;\n if (urlObj.username) {\n urlObj.username = 'redacted';\n hadAuth = true;\n }\n if (urlObj.password) {\n urlObj.password = 'redacted';\n hadAuth = true;\n }\n if (hadAuth) {\n return urlObj.toString();\n }\n }\n } catch {\n // Could not parse the URL.\n }\n // If there was no auth information, then we don't need to modify the URL.\n return url;\n}\n\n/**\n * Filter which removes context information for browser JavaScript endpoints.\n *\n * @param url URL to filter.\n * @returns A filtered URL.\n */\nfunction ldUrlFilter(url: string): string {\n // TODO: Maybe we consider a way to identify LD requests so they can be filtered without\n // regular expressions.\n\n if (url.includes('/sdk/evalx')) {\n const regexMatch = url.match(pollingRegex);\n const context = regexMatch?.groups?.context;\n if (context) {\n return url.replace(context, '*'.repeat(context.length));\n }\n }\n if (url.includes('/eval/')) {\n const regexMatch = url.match(streamingREgex);\n const context = regexMatch?.groups?.context;\n if (context) {\n return url.replace(context, '*'.repeat(context.length));\n }\n }\n return url;\n}\n\n/**\n * Filter which redacts user information and removes context information for browser JavaScript endpoints.\n *\n * @param url URL to filter.\n * @returns A filtered URL.\n */\nexport default function defaultUrlFilter(url: string): string {\n return ldUrlFilter(authorityUrlFilter(url));\n}\n","import type { LDContext, LDEvaluationDetail } from '@launchdarkly/js-client-sdk';\n\nimport { BrowserTelemetryInspector } from './api/client/BrowserTelemetryInspector.js';\nimport BrowserTelemetryImpl from './BrowserTelemetryImpl.js';\nimport { ParsedOptions } from './options.js';\n\n/**\n * Create inspectors to register with an LDClient instance.\n *\n * @param options Optiont which determine which inspectors are created.\n * @param inspectors Inspectors will be added to this array.\n * @param telemetry The telemetry instance which inspectors will forward data to.\n */\nexport default function makeInspectors(\n options: ParsedOptions,\n inspectors: BrowserTelemetryInspector[],\n telemetry: BrowserTelemetryImpl,\n) {\n if (options.breadcrumbs.evaluations) {\n inspectors.push({\n type: 'flag-used',\n name: 'launchdarkly-browser-telemetry-flag-used',\n synchronous: true,\n method(flagKey: string, flagDetail: LDEvaluationDetail, context?: LDContext): void {\n telemetry.handleFlagUsed(flagKey, flagDetail, context);\n },\n });\n }\n\n if (options.breadcrumbs.flagChange) {\n inspectors.push({\n type: 'flag-detail-changed',\n name: 'launchdarkly-browser-telemetry-flag-used',\n synchronous: true,\n method(flagKey: string, detail: LDEvaluationDetail): void {\n telemetry.handleFlagDetailChanged(flagKey, detail);\n },\n });\n }\n}\n","import { MinLogger } from './api';\n\nexport const fallbackLogger: MinLogger = {\n // Intentionally using console.warn as a fallback logger.\n // eslint-disable-next-line no-console\n warn: console.warn,\n};\n\nconst loggingPrefix = 'LaunchDarkly - Browser Telemetry:';\n\nexport function prefixLog(message: string) {\n return `${loggingPrefix} ${message}`;\n}\n\nexport function safeMinLogger(logger: MinLogger | undefined): MinLogger {\n return {\n warn: (...args: any[]) => {\n if (!logger) {\n fallbackLogger.warn(...args);\n return;\n }\n\n try {\n logger.warn(...args);\n } catch {\n fallbackLogger.warn(...args);\n fallbackLogger.warn(\n prefixLog('The provided logger threw an exception, using fallback logger.'),\n );\n }\n },\n };\n}\n","// This implementation is the same as in the browser package. Eventually we\n// will want a common package for this type of code. (SDK-905)\n\n// The implementation in this file generates UUIDs in v4 format and is suitable\n// for use as a UUID in LaunchDarkly events. It is not a rigorous implementation.\n\n// It uses crypto.randomUUID when available.\n// If crypto.randomUUID is not available, then it uses random values and forms\n// the UUID itself.\n// When possible it uses crypto.getRandomValues, but it can use Math.random\n// if crypto.getRandomValues is not available.\n\n// UUIDv4 Struct definition.\n// https://www.rfc-archive.org/getrfc.php?rfc=4122\n// Appendix A. Appendix A - Sample Implementation\nconst timeLow = {\n start: 0,\n end: 3,\n};\nconst timeMid = {\n start: 4,\n end: 5,\n};\nconst timeHiAndVersion = {\n start: 6,\n end: 7,\n};\nconst clockSeqHiAndReserved = {\n start: 8,\n end: 8,\n};\nconst clockSeqLow = {\n start: 9,\n end: 9,\n};\nconst nodes = {\n start: 10,\n end: 15,\n};\n\nfunction getRandom128bit(): number[] {\n if (crypto && crypto.getRandomValues) {\n const typedArray = new Uint8Array(16);\n crypto.getRandomValues(typedArray);\n return [...typedArray.values()];\n }\n const values = [];\n for (let index = 0; index < 16; index += 1) {\n // Math.random is 0-1 with inclusive min and exclusive max.\n values.push(Math.floor(Math.random() * 256));\n }\n return values;\n}\n\nfunction hex(bytes: number[], range: { start: number; end: number }): string {\n let strVal = '';\n for (let index = range.start; index <= range.end; index += 1) {\n strVal += bytes[index].toString(16).padStart(2, '0');\n }\n return strVal;\n}\n\n/**\n * Given a list of 16 random bytes generate a UUID in v4 format.\n *\n * Note: The input bytes are modified to conform to the requirements of UUID v4.\n *\n * @param bytes A list of 16 bytes.\n * @returns A UUID v4 string.\n */\nexport function formatDataAsUuidV4(bytes: number[]): string {\n // https://www.rfc-archive.org/getrfc.php?rfc=4122\n // 4.4. Algorithms for Creating a UUID from Truly Random or\n // Pseudo-Random Numbers\n\n // Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and\n // one, respectively.\n // eslint-disable-next-line no-bitwise, no-param-reassign\n bytes[clockSeqHiAndReserved.start] = (bytes[clockSeqHiAndReserved.start] | 0x80) & 0xbf;\n // Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to\n // the 4-bit version number from Section 4.1.3.\n // eslint-disable-next-line no-bitwise, no-param-reassign\n bytes[timeHiAndVersion.start] = (bytes[timeHiAndVersion.start] & 0x0f) | 0x40;\n\n return (\n `${hex(bytes, timeLow)}-${hex(bytes, timeMid)}-${hex(bytes, timeHiAndVersion)}-` +\n `${hex(bytes, clockSeqHiAndReserved)}${hex(bytes, clockSeqLow)}-${hex(bytes, nodes)}`\n );\n}\n\nexport function fallbackUuidV4(): string {\n const bytes = getRandom128bit();\n return formatDataAsUuidV4(bytes);\n}\n\nexport default function randomUuidV4(): string {\n if (typeof crypto !== undefined && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n\n return fallbackUuidV4();\n}\n","/**\n * https://github.com/csnover/TraceKit\n * @license MIT\n * @namespace TraceKit\n */\n\n/**\n * This file has been vendored to make it compatible with ESM and to any potential window\n * level TraceKit instance.\n *\n * Functionality unused by this SDK has been removed to minimize size.\n *\n * It has additionally been converted to typescript.\n *\n * The functionality of computeStackTrace has been extended to allow for easier use of the context\n * information in stack frames.\n */\n\n/**\n * Currently the conversion to typescript is minimal, so the following eslint\n * rules are disabled.\n */\n\n/* eslint-disable func-names */\n/* eslint-disable no-shadow-restricted-names */\n/* eslint-disable prefer-destructuring */\n/* eslint-disable no-param-reassign */\n/* eslint-disable no-cond-assign */\n/* eslint-disable consistent-return */\n/* eslint-disable no-empty */\n/* eslint-disable no-plusplus */\n/* eslint-disable prefer-rest-params */\n/* eslint-disable no-useless-escape */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable no-continue */\n/* eslint-disable no-underscore-dangle */\n\n/**\n * Source context information.\n *\n * This was not present in the original source, but helps to easily identify which line in the\n * context is the original line.\n *\n * Without this knowledge of the source file is requires for a consumer to know the position\n * of the original source line within the context.\n */\nexport interface SourceContext {\n /**\n * The starting location in the source code. This is 1-based.\n */\n startFromSource?: number;\n contextLines: string[] | null;\n}\n\nexport interface TraceKitStatic {\n computeStackTrace: {\n (ex: Error, depth?: number): StackTrace;\n augmentStackTraceWithInitialElement: (\n stackInfo: StackTrace,\n url: string,\n lineNo: number | string,\n message: string,\n ) => boolean;\n computeStackTraceFromStackProp: (ex: Error) => StackTrace | null;\n guessFunctionName: (url: string, lineNo: number | string) => string;\n gatherContext: (url: string, line: number | string) => SourceContext | null;\n ofCaller: (depth?: number) => StackTrace;\n getSource: (url: string) => string[];\n };\n remoteFetching: boolean;\n collectWindowErrors: boolean;\n linesOfContext: number;\n debug: boolean;\n}\n\nconst TraceKit: any = {};\n\nexport interface StackFrame {\n url: string;\n func: string;\n args?: string[];\n /**\n * The line number of source code.\n * This is 1-based.\n */\n line?: number | null;\n column?: number | null;\n context?: string[] | null;\n /**\n * The source line number that is the first line of the context.\n * This is 1-based.\n */\n srcStart?: number;\n}\n\nexport type Mode = 'stack' | 'stacktrace' | 'multiline' | 'callers' | 'onerror' | 'failed';\n\nexport interface StackTrace {\n name: string;\n message: string;\n stack: StackFrame[];\n mode: Mode;\n incomplete?: boolean;\n partial?: boolean;\n}\n\n(function (window, undefined) {\n if (!window) {\n return;\n }\n\n // global reference to slice\n const _slice = [].slice;\n const UNKNOWN_FUNCTION = '?';\n\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types\n const ERROR_TYPES_RE =\n /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/;\n\n /**\n * A better form of hasOwnProperty<br/>\n * Example: `_has(MainHostObject, property) === true/false`\n *\n * @param {Object} object to check property\n * @param {string} key to check\n * @return {Boolean} true if the object has the key and it is not inherited\n */\n function _has(object: any, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(object, key);\n }\n\n /**\n * Returns true if the parameter is undefined<br/>\n * Example: `_isUndefined(val) === true/false`\n *\n * @param {*} what Value to check\n * @return {Boolean} true if undefined and false otherwise\n */\n function _isUndefined(what: any): boolean {\n return typeof what === 'undefined';\n }\n\n /**\n * Wrap any function in a TraceKit reporter<br/>\n * Example: `func = TraceKit.wrap(func);`\n *\n * @param {Function} func Function to be wrapped\n * @return {Function} The wrapped func\n * @memberof TraceKit\n */\n TraceKit.wrap = function traceKitWrapper(func: Function): Function {\n function wrapped(this: any) {\n try {\n return func.apply(this, arguments);\n } catch (e) {\n TraceKit.report(e);\n throw e;\n }\n }\n return wrapped;\n };\n\n /**\n * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript\n *\n * Syntax:\n * ```js\n * s = TraceKit.computeStackTrace.ofCaller([depth])\n * s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below)\n * ```\n *\n * Supports:\n * - Firefox: full stack trace with line numbers and unreliable column\n * number on top frame\n * - Opera 10: full stack trace with line and column numbers\n * - Opera 9-: full stack trace with line numbers\n * - Chrome: full stack trace with line and column numbers\n * - Safari: line and column number for the topmost stacktrace element\n * only\n * - IE: no line numbers whatsoever\n *\n * Tries to guess names of anonymous functions by looking for assignments\n * in the source code. In IE and Safari, we have to guess source file names\n * by searching for function bodies inside all page scripts. This will not\n * work for scripts that are loaded cross-domain.\n * Here be dragons: some function names may be guessed incorrectly, and\n * duplicate functions may be mismatched.\n *\n * TraceKit.computeStackTrace should only be used for tracing purposes.\n * Logging of unhandled exceptions should be done with TraceKit.report,\n * which builds on top of TraceKit.computeStackTrace and provides better\n * IE support by utilizing the window.onerror event to retrieve information\n * about the top of the stack.\n *\n * Note: In IE and Safari, no stack trace is recorded on the Error object,\n * so computeStackTrace instead walks its *own* chain of callers.\n * This means that:\n * * in Safari, some methods may be missing from the stack trace;\n * * in IE, the topmost function in the stack trace will always be the\n * caller of computeStackTrace.\n *\n * This is okay for tracing (because you are likely to be calling\n * computeStackTrace from the function you want to be the topmost element\n * of the stack trace anyway), but not okay for logging unhandled\n * exceptions (because your catch block will likely be far away from the\n * inner function that actually caused the exception).\n *\n * Tracing example:\n * ```js\n * function trace(message) {\n * var stackInfo = TraceKit.computeStackTrace.ofCaller();\n * var data = message + \"\\n\";\n * for(var i in stackInfo.stack) {\n * var item = stackInfo.stack[i];\n * data += (item.func || '[anonymous]') + \"() in \" + item.url + \":\" + (item.line || '0') + \"\\n\";\n * }\n * if (window.console)\n * console.info(data);\n * else\n * alert(data);\n * }\n * ```\n * @memberof TraceKit\n * @namespace\n */\n TraceKit.computeStackTrace = (function computeStackTraceWrapper() {\n const debug = false;\n const sourceCache: Record<string, string[]> = {};\n\n /**\n * Attempts to retrieve source code via XMLHttpRequest, which is used\n * to look up anonymous function names.\n * @param {string} url URL of source code.\n * @return {string} Source contents.\n * @memberof TraceKit.computeStackTrace\n */\n function loadSource(url: string): string {\n if (!TraceKit.remoteFetching) {\n // Only attempt request if remoteFetching is on.\n return '';\n }\n try {\n const getXHR = function () {\n try {\n return new window.XMLHttpRequest();\n } catch (e) {\n // explicitly bubble up the exception if not found\n // @ts-ignore\n return new window.ActiveXObject('Microsoft.XMLHTTP');\n }\n };\n\n const request = getXHR();\n request.open('GET', url, false);\n request.send('');\n return request.responseText;\n } catch (e) {\n return '';\n }\n }\n\n /**\n * Retrieves source code from the source code cache.\n * @param {string} url URL of source code.\n * @return {Array.<string>} Source contents.\n * @memberof TraceKit.computeStackTrace\n */\n function getSource(url: string): string[] {\n if (typeof url !== 'string') {\n return [];\n }\n\n if (!_has(sourceCache, url)) {\n // URL needs to be able to fetched within the acceptable domain. Otherwise,\n // cross-domain errors will be triggered.\n /*\n Regex matches:\n 0 - Full Url\n 1 - Protocol\n 2 - Domain\n 3 - Port (Useful for internal applications)\n 4 - Path\n */\n let source = '';\n let domain = '';\n try {\n domain = window.document.domain;\n } catch (e) {}\n const match = /(.*)\\:\\/\\/([^:\\/]+)([:\\d]*)\\/{0,1}([\\s\\S]*)/.exec(url);\n if (match && match[2] === domain) {\n source = loadSource(url);\n }\n sourceCache[url] = source ? source.split('\\n') : [];\n }\n\n return sourceCache[url];\n }\n\n /**\n * Tries to use an externally loaded copy of source code to determine\n * the name of a function by looking at the name of the variable it was\n * assigned to, if any.\n * @param {string} url URL of source code.\n * @param {(string|number)} lineNo Line number in source code.\n * @return {string} The function name, if discoverable.\n * @memberof TraceKit.computeStackTrace\n */\n function guessFunctionName(url: string, lineNo: string | number) {\n if (typeof lineNo !== 'number') {\n lineNo = Number(lineNo);\n }\n const reFunctionArgNames = /function ([^(]*)\\(([^)]*)\\)/;\n const reGuessFunction = /['\"]?([0-9A-Za-z$_]+)['\"]?\\s*[:=]\\s*(function|eval|new Function)/;\n let line = '';\n const maxLines = 10;\n const source = getSource(url);\n let m;\n\n if (!source.length) {\n return UNKNOWN_FUNCTION;\n }\n\n // Walk backwards from the first line in the function until we find the line which\n // matches the pattern above, which is the function definition\n for (let i = 0; i < maxLines; ++i) {\n line = source[lineNo - i] + line;\n\n if (!_isUndefined(line)) {\n if ((m = reGuessFunction.exec(line))) {\n return m[1];\n }\n if ((m = reFunctionArgNames.exec(line))) {\n return m[1];\n }\n }\n }\n\n return UNKNOWN_FUNCTION;\n }\n\n /**\n * Retrieves the surrounding lines from where an exception occurred.\n * @param {string} url URL of source code.\n * @param {(string|number)} line Line number in source code to center around for context.\n * @return {SourceContext} Lines of source code and line the source context starts on.\n * @memberof TraceKit.computeStackTrace\n */\n function gatherContext(url: string, line: string | number): SourceContext | null {\n if (typeof line !== 'number') {\n line = Number(line);\n }\n const source = getSource(url);\n\n if (!source.length) {\n return null;\n }\n\n const context = [];\n // linesBefore & linesAfter are inclusive with the offending line.\n // if linesOfContext is even, there will be one extra line\n // *before* the offending line.\n const linesBefore = Math.floor(TraceKit.linesOfContext / 2);\n // Add one extra line if linesOfContext is odd\n const linesAfter = linesBefore + (TraceKit.linesOfContext % 2);\n const start = Math.max(0, line - linesBefore - 1);\n const end = Math.min(source.length, line + linesAfter - 1);\n\n line -= 1; // convert to 0-based index\n\n for (let i = start; i < end; ++i) {\n if (!_isUndefined(source[i])) {\n context.push(source[i]);\n }\n }\n\n return context.length > 0\n ? {\n contextLines: context,\n // Source lines are in base-1.\n startFromSource: start + 1,\n }\n : null;\n }\n /**\n * Escapes special characters, except for whitespace, in a string to be\n * used inside a regular expression as a string literal.\n * @param {string} text The string.\n * @return {string} The escaped string literal.\n * @memberof TraceKit.computeStackTrace\n */\n function escapeRegExp(text: string): string {\n return text.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#]/g, '\\\\$&');\n }\n\n /**\n * Escapes special characters in a string to be used inside a regular\n * expression as a string literal. Also ensures that HTML entities will\n * be matched the same as their literal friends.\n * @param {string} body The string.\n * @return {string} The escaped string.\n * @memberof TraceKit.computeStackTrace\n */\n function escapeCodeAsRegExpForMatchingInsideHTML(body: string): string {\n return escapeRegExp(body)\n .replace('<', '(?:<|&lt;)')\n .replace('>', '(?:>|&gt;)')\n .replace('&', '(?:&|&amp;)')\n .replace('\"', '(?:\"|&quot;)')\n .replace(/\\s+/g, '\\\\s+');\n }\n\n /**\n * Determines where a code fragment occurs in the source code.\n * @param {RegExp} re The function definition.\n * @param {Array.<string>} urls A list of URLs to search.\n * @return {?Object.<string, (string|number)>} An object containing\n * the url, line, and column number of the defined function.\n * @memberof TraceKit.computeStackTrace\n */\n function findSourceInUrls(\n re: RegExp,\n urls: string[],\n ): {\n url: string;\n line: number;\n column: number;\n } | null {\n let source: any;\n let m: any;\n for (let i = 0, j = urls.length; i < j; ++i) {\n if ((source = getSource(urls[i])).length) {\n source = source.join('\\n');\n if ((m = re.exec(source))) {\n return {\n url: urls[i],\n line: source.substring(0, m.index).split('\\n').length,\n column: m.index - source.lastIndexOf('\\n', m.index) - 1,\n };\n }\n }\n }\n\n return null;\n }\n\n /**\n * Determines at which column a code fragment occurs on a line of the\n * source code.\n * @param {string} fragment The code fragment.\n * @param {string} url The URL to search.\n * @param {(string|number)} line The line number to examine.\n * @return {?number} The column number.\n * @memberof TraceKit.computeStackTrace\n */\n function findSourceInLine(fragment: string, url: string, line: string | number): number | null {\n if (typeof line !== 'number') {\n line = Number(line);\n }\n const source = getSource(url);\n const re = new RegExp(`\\\\b${escapeRegExp(fragment)}\\\\b`);\n let m: any;\n\n line -= 1;\n\n if (source && source.length > line && (m = re.exec(source[line]))) {\n return m.index;\n }\n\n return null;\n }\n\n /**\n * Determines where a function was defined within the source code.\n * @param {(Function|string)} func A function reference or serialized\n * function definition.\n * @return {?Object.<string, (string|number)>} An object containing\n * the url, line, and column number of the defined function.\n * @memberof TraceKit.computeStackTrace\n */\n function findSourceByFunctionBody(func: Function | string) {\n if (_isUndefined(window && window.document)) {\n return;\n }\n\n const urls = [window.location.href];\n const scripts = window.document.getElementsByTagName('script');\n let body;\n const code = `${func}`;\n const codeRE = /^function(?:\\s+([\\w$]+))?\\s*\\(([\\w\\s,]*)\\)\\s*\\{\\s*(\\S[\\s\\S]*\\S)\\s*\\}\\s*$/;\n const eventRE = /^function on([\\w$]+)\\s*\\(event\\)\\s*\\{\\s*(\\S[\\s\\S]*\\S)\\s*\\}\\s*$/;\n let re;\n let parts;\n let result;\n\n for (let i = 0; i < scripts.length; ++i) {\n const script = scripts[i];\n if (script.src) {\n urls.push(script.src);\n }\n }\n\n if (!(parts = codeRE.exec(code))) {\n re = new RegExp(escapeRegExp(code).replace(/\\s+/g, '\\\\s+'));\n }\n\n // not sure if this is really necessary, but I don’t have a test\n // corpus large enough to confirm that and it was in the original.\n else {\n const name = parts[1] ? `\\\\s+${parts[1]}` : '';\n const args = parts[2].split(',').join('\\\\s*,\\\\s*');\n\n body = escapeRegExp(parts[3]).replace(/;$/, ';?'); // semicolon is inserted if the function ends with a comment.replace(/\\s+/g, '\\\\s+');\n re = new RegExp(`function${name}\\\\s*\\\\(\\\\s*${args}\\\\s*\\\\)\\\\s*{\\\\s*${body}\\\\s*}`);\n }\n\n // look for a normal function definition\n if ((result = findSourceInUrls(re, urls))) {\n return result;\n }\n\n // look for an old-school event handler function\n if ((parts = eventRE.exec(code))) {\n const event = parts[1];\n body = escapeCodeAsRegExpForMatchingInsideHTML(parts[2]);\n\n // look for a function defined in HTML as an onXXX handler\n re = new RegExp(`on${event}=[\\\\'\"]\\\\s*${body}\\\\s*[\\\\'\"]`, 'i');\n\n // The below line is as it appears in the original code.\n // @ts-expect-error TODO (SDK-1037): Determine if this is a bug or handling for some unexpected case.\n if ((result = findSourceInUrls(re, urls[0]))) {\n return result;\n }\n\n // look for ???\n re = new RegExp(body);\n\n if ((result = findSourceInUrls(re, urls))) {\n return result;\n }\n }\n\n return null;\n }\n\n // Contents of Exception in various browsers.\n //\n // SAFARI:\n // ex.message = Can't find variable: qq\n // ex.line = 59\n // ex.sourceId = 580238192\n // ex.sourceURL = http://...\n // ex.expressionBeginOffset = 96\n // ex.expressionCaretOffset = 98\n // ex.expressionEndOffset = 98\n // ex.name = ReferenceError\n //\n // FIREFOX:\n // ex.message = qq is not defined\n // ex.fileName = http://...\n // ex.lineNumber = 59\n // ex.columnNumber = 69\n // ex.stack = ...stack trace... (see the example below)\n // ex.name = ReferenceError\n //\n // CHROME:\n // ex.message = qq is not defined\n // ex.name = ReferenceError\n // ex.type = not_defined\n // ex.arguments = ['aa']\n // ex.stack = ...stack trace...\n //\n // INTERNET EXPLORER:\n // ex.message = ...\n // ex.name = ReferenceError\n //\n // OPERA:\n // ex.message = ...message... (see the example below)\n // ex.name = ReferenceError\n // ex.opera#sourceloc = 11 (pretty much useless, duplicates the info in ex.message)\n // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace'\n\n /**\n * Computes stack trace information from the stack property.\n * Chrome and Gecko use this property.\n * @param {Error} ex\n * @return {?TraceKit.StackTrace} Stack trace information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceFromStackProp(ex: any): StackTrace | null {\n if (!ex.stack) {\n return null;\n }\n\n const chrome =\n /^\\s*at (.*?) ?\\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|\\/).*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\n const gecko =\n /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\\[native).*?|[^@]*bundle)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\n const winjs =\n /^\\s*at (?:((?:\\[object object\\])?.+) )?\\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\\d+)(?::(\\d+))?\\)?\\s*$/i;\n\n // Used to additionally parse URL/line/column from eval frames\n let isEval;\n const geckoEval = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\n const chromeEval = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\n\n const lines = ex.stack.split('\\n');\n const stack: StackFrame[] = [];\n let submatch: any;\n let parts: any;\n let element: StackFrame;\n const reference: any = /^(.*) is undefined$/.exec(ex.message);\n\n for (let i = 0, j = lines.length; i < j; ++i) {\n if ((parts = chrome.exec(lines[i]))) {\n const isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line\n isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line\n if (isEval && (submatch = chromeEval.exec(parts[2]))) {\n // throw out eval line/column and use top-most line/column number\n parts[2] = submatch[1]; // url\n parts[3] = submatch[2]; // line\n parts[4] = submatch[3]; // column\n }\n element = {\n url: !isNative ? parts[2] : null,\n func: parts[1] || UNKNOWN_FUNCTION,\n args: isNative ? [parts[2]] : [],\n line: parts[3] ? +parts[3] : null,\n column: parts[4] ? +parts[4] : null,\n };\n } else if ((parts = winjs.exec(lines[i]))) {\n element = {\n url: parts[2],\n func: parts[1] || UNKNOWN_FUNCTION,\n args: [],\n line: +parts[3],\n column: parts[4] ? +parts[4] : null,\n };\n } else if ((parts = gecko.exec(lines[i]))) {\n isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n if (isEval && (submatch = geckoEval.exec(parts[3]))) {\n // throw out eval line/column and use top-most line number\n parts[3] = submatch[1];\n parts[4] = submatch[2];\n parts[5] = null; // no column when eval\n } else if (i === 0 && !parts[5] && !_isUndefined(ex.columnNumber)) {\n // FireFox uses this awesome columnNumber property for its top frame\n // Also note, Firefox's column number is 0-based and everything else expects 1-based,\n // so adding 1\n // NOTE: this hack doesn't work if top-most frame is eval\n stack[0].column = ex.columnNumber + 1;\n }\n element = {\n url: parts[3],\n func: parts[1] || UNKNOWN_FUNCTION,\n args: parts[2] ? parts[2].split(',') : [],\n line: parts[4] ? +parts[4] : null,\n column: parts[5] ? +parts[5] : null,\n };\n } else {\n continue;\n }\n\n if (!element.func && element.line) {\n element.func = guessFunctionName(element.url, element.line);\n }\n\n const srcContext = gatherContext(element.url, element.line!);\n element.context = element.line ? (srcContext?.contextLines ?? null) : null;\n element.srcStart = srcContext?.startFromSource;\n stack.push(element);\n }\n\n if (!stack.length) {\n return null;\n }\n\n if (stack[0] && stack[0].line && !stack[0].column && reference) {\n stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line);\n }\n\n return {\n mode: 'stack',\n name: ex.name,\n message: ex.message,\n stack,\n };\n }\n\n /**\n * Computes stack trace information from the stacktrace property.\n * Opera 10+ uses this property.\n * @param {Error} ex\n * @return {?TraceKit.StackTrace} Stack trace information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceFromStacktraceProp(ex: any): StackTrace | null {\n // Access and store the stacktrace property before doing ANYTHING\n // else to it because Opera is not very good at providing it\n // reliably in other circumstances.\n const { stacktrace } = ex;\n if (!stacktrace) {\n return null;\n }\n\n const opera10Regex = / line (\\d+).*script (?:in )?(\\S+)(?:: in function (\\S+))?$/i;\n const opera11Regex =\n / line (\\d+), column (\\d+)\\s*(?:in (?:<anonymous function: ([^>]+)>|([^\\)]+))\\((.*)\\))? in (.*):\\s*$/i;\n const lines = stacktrace.split('\\n');\n const stack = [];\n let parts;\n\n for (let line = 0; line < lines.length; line += 2) {\n let element: StackFrame | null = null;\n if ((parts = opera10Regex.exec(lines[line]))) {\n element = {\n url: parts[2],\n line: +parts[1],\n column: null,\n func: parts[3],\n args: [],\n };\n } else if ((parts = opera11Regex.exec(lines[line]))) {\n element = {\n url: parts[6],\n line: +parts[1],\n column: +parts[2],\n func: parts[3] || parts[4],\n args: parts[5] ? parts[5].split(',') : [],\n };\n }\n\n if (element) {\n if (!element.func && element.line) {\n element.func = guessFunctionName(element.url, element.line);\n }\n if (element.line) {\n try {\n const srcContext = gatherContext(element.url, element.line);\n element.srcStart = srcContext?.startFromSource;\n element.context = element.line ? (srcContext?.contextLines ?? null) : null;\n } catch (exc) {}\n }\n\n if (!element.context) {\n element.context = [lines[line + 1]];\n }\n\n stack.push(element);\n }\n }\n\n if (!stack.length) {\n return null;\n }\n\n return {\n mode: 'stacktrace',\n name: ex.name,\n message: ex.message,\n stack,\n };\n }\n\n /**\n * NOT TESTED.\n * Computes stack trace information from an error message that includes\n * the stack trace.\n * Opera 9 and earlier use this method if the option to show stack\n * traces is turned on in opera:config.\n * @param {Error} ex\n * @return {?TraceKit.StackTrace} Stack information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceFromOperaMultiLineMessage(ex: Error): StackTrace | null {\n // TODO: Clean this function up\n // Opera includes a stack trace into the exception message. An example is:\n //\n // Statement on line 3: Undefined variable: undefinedFunc\n // Backtrace:\n // Line 3 of linked script file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.js: In function zzz\n // undefinedFunc(a);\n // Line 7 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function yyy\n // zzz(x, y, z);\n // Line 3 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function xxx\n // yyy(a, a, a);\n // Line 1 of function script\n // try { xxx('hi'); return false; } catch(ex) { TraceKit.report(ex); }\n // ...\n\n const lines = ex.message.split('\\n');\n if (lines.length < 4) {\n return null;\n }\n\n const lineRE1 =\n /^\\s*Line (\\d+) of linked script ((?:file|https?|blob)\\S+)(?:: in function (\\S+))?\\s*$/i;\n const lineRE2 =\n /^\\s*Line (\\d+) of inline#(\\d+) script in ((?:file|https?|blob)\\S+)(?:: in function (\\S+))?\\s*$/i;\n const lineRE3 = /^\\s*Line (\\d+) of function script\\s*$/i;\n const stack = [];\n const scripts = window && window.document && window.document.getElementsByTagName('script');\n const inlineScriptBlocks = [];\n let parts: any;\n\n for (const s in scripts) {\n if (_has(scripts, s) && !scripts[s].src) {\n inlineScriptBlocks.push(scripts[s]);\n }\n }\n\n for (let line = 2; line < lines.length; line += 2) {\n let item: any = null;\n if ((parts = lineRE1.exec(lines[line]))) {\n item = {\n url: parts[2],\n func: parts[3],\n args: [],\n line: +parts[1],\n column: null,\n };\n } else if ((parts = lineRE2.exec(lines[line]))) {\n item = {\n url: parts[3],\n func: parts[4],\n args: [],\n line: +parts[1],\n column: null, // TODO: Check to see if inline#1 (+parts[2]) points to the script number or column number.\n };\n const relativeLine = +parts[1]; // relative to the start of the <SCRIPT> block\n const script = inlineScriptBlocks[parts[2] - 1];\n if (script) {\n let source: any = getSource(item.url);\n if (source) {\n source = source.join('\\n');\n const pos = source.indexOf(script.innerText);\n if (pos >= 0) {\n item.line = relativeLine + source.substring(0, pos).split('\\n').length;\n }\n }\n }\n } else if ((parts = lineRE3.exec(lines[line]))) {\n const url = window.location.href.replace(/#.*$/, '');\n const re = new RegExp(escapeCodeAsRegExpForMatchingInsideHTML(lines[line + 1]));\n const src = findSourceInUrls(re, [url]);\n item = {\n url,\n func: '',\n args: [],\n line: src ? src.line : parts[1],\n column: null,\n };\n }\n\n if (item) {\n if (!item.func) {\n item.func = guessFunctionName(item.url, item.line);\n }\n const srcContext = gatherContext(item.url, item.line);\n item.srcStart = srcContext?.startFromSource;\n const context = srcContext?.contextLines;\n const midline = context ? context[Math.floor(context.length / 2)] : null;\n if (\n context &&\n midline &&\n midline.replace(/^\\s*/, '') === lines[line + 1].replace(/^\\s*/, '')\n ) {\n item.context = context;\n } else {\n // if (context) alert(\"Context mismatch. Correct midline:\\n\" + lines[i+1] + \"\\n\\nMidline:\\n\" + midline + \"\\n\\nContext:\\n\" + context.join(\"\\n\") + \"\\n\\nURL:\\n\" + item.url);\n item.context = [lines[line + 1]];\n }\n stack.push(item);\n }\n }\n if (!stack.length) {\n return null; // could not parse multiline exception message as Opera stack trace\n }\n\n return {\n mode: 'multiline',\n name: ex.name,\n message: lines[0],\n stack,\n };\n }\n\n /**\n * Adds information about the first frame to incomplete stack traces.\n * Safari and IE require this to get complete data on the first frame.\n * @param {TraceKit.StackTrace} stackInfo Stack trace information from\n * one of the compute* methods.\n * @param {string} url The URL of the script that caused an error.\n * @param {(number|string)} lineNo The line number of the script that\n * caused an error.\n * @param {string=} message The error generated by the browser, which\n * hopefully contains the name of the object that caused the error.\n * @return {boolean} Whether or not the stack information was\n * augmented.\n * @memberof TraceKit.computeStackTrace\n */\n function augmentStackTraceWithInitialElement(\n stackInfo: StackTrace,\n url: string,\n lineNo: number | string,\n message: string,\n ): boolean {\n const initial: any = {\n url,\n line: lineNo,\n };\n\n if (initial.url && initial.line) {\n stackInfo.incomplete = false;\n\n if (!initial.func) {\n initial.func = guessFunctionName(initial.url, initial.line);\n }\n\n if (!initial.context) {\n const srcContext = gatherContext(initial.url, initial.line);\n initial.context = srcContext?.contextLines ?? null;\n initial.srcStart = srcContext?.startFromSource;\n }\n\n const reference = / '([^']+)' /.exec(message);\n if (reference) {\n initial.column = findSourceInLine(reference[1], initial.url, initial.line);\n }\n\n if (stackInfo.stack.length > 0) {\n if (stackInfo.stack[0].url === initial.url) {\n if (stackInfo.stack[0].line === initial.line) {\n return false; // already in stack trace\n }\n if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) {\n stackInfo.stack[0].line = initial.line;\n stackInfo.stack[0].context = initial.context;\n return false;\n }\n }\n }\n\n stackInfo.stack.unshift(initial);\n stackInfo.partial = true;\n return true;\n }\n stackInfo.incomplete = true;\n\n return false;\n }\n\n /**\n * Computes stack trace information by walking the arguments.caller\n * chain at the time the exception occurred. This will cause earlier\n * frames to be missed but is the only way to get any stack trace in\n * Safari and IE. The top frame is restored by\n * {@link augmentStackTraceWithInitialElement}.\n * @param {Error} ex\n * @return {TraceKit.StackTrace=} Stack trace information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceByWalkingCallerChain(ex: any, depth: number) {\n const functionName = /function\\s+([_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*)?\\s*\\(/i;\n const stack = [];\n const funcs = {};\n let recursion = false;\n let parts: any;\n let item: any;\n let source;\n\n for (\n let curr = computeStackTraceByWalkingCallerChain.caller;\n curr && !recursion;\n curr = curr.caller\n ) {\n if (curr === computeStackTrace || curr === TraceKit.report) {\n continue;\n }\n\n item = {\n url: null,\n func: UNKNOWN_FUNCTION,\n args: [],\n line: null,\n column: null,\n };\n\n if (curr.name) {\n item.func = curr.name;\n } else if ((parts = functionName.exec(curr.toString()))) {\n item.func = parts[1];\n }\n\n if (typeof item.func === 'undefined') {\n try {\n item.func = parts.input.substring(0, parts.input.indexOf('{'));\n } catch (e) {}\n }\n\n if ((source = findSourceByFunctionBody(curr))) {\n item.url = source.url;\n item.line = source.line;\n\n if (item.func === UNKNOWN_FUNCTION) {\n item.func = guessFunctionName(item.url, item.line);\n }\n\n const reference = / '([^']+)' /.exec(ex.message || ex.description);\n if (reference) {\n item.column = findSourceInLine(reference[1], source.url, source.line);\n }\n }\n\n // @ts-ignore\n if (funcs[`${curr}`]) {\n recursion = true;\n } else {\n // @ts-ignore\n funcs[`${curr}`] = true;\n }\n\n stack.push(item);\n }\n\n if (depth) {\n stack.splice(0, depth);\n }\n\n const result: StackTrace = {\n mode: 'callers',\n name: ex.name,\n message: ex.message,\n stack,\n };\n augmentStackTraceWithInitialElement(\n result,\n ex.sourceURL || ex.fileName,\n ex.line || ex.lineNumber,\n ex.message || ex.description,\n );\n return result;\n }\n\n /**\n * Computes a stack trace for an exception.\n * @param {Error} ex\n * @param {(string|number)=} depth\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTrace(ex: any, depth: number): StackTrace {\n let stack: StackTrace | null = null;\n depth = depth == null ? 0 : +depth;\n\n try {\n // This must be tried first because Opera 10 *destroys*\n // its stacktrace property if you try to access the stack\n // property first!!\n stack = computeStackTraceFromStacktraceProp(ex);\n if (stack) {\n return stack;\n }\n } catch (e) {\n if (debug) {\n throw e;\n }\n }\n\n try {\n stack = computeStackTraceFromStackProp(ex);\n if (stack) {\n return stack;\n }\n } catch (e) {\n if (debug) {\n throw e;\n }\n }\n\n try {\n stack = computeStackTraceFromOperaMultiLineMessage(ex);\n if (stack) {\n return stack;\n }\n } catch (e) {\n if (debug) {\n throw e;\n }\n }\n\n try {\n stack = computeStackTraceByWalkingCallerChain(ex, depth + 1);\n if (stack) {\n return stack;\n }\n } catch (e) {\n if (debug) {\n throw e;\n }\n }\n\n return {\n name: ex.name,\n message: ex.message,\n mode: 'failed',\n stack: [],\n };\n }\n\n /**\n * Logs a stacktrace starting from the previous call and working down.\n * @param {(number|string)=} depth How many frames deep to trace.\n * @return {TraceKit.StackTrace} Stack trace information.\n * @memberof TraceKit.computeStackTrace\n */\n function computeStackTraceOfCaller(depth: number): StackTrace {\n depth = (depth == null ? 0 : +depth) + 1; // \"+ 1\" because \"ofCaller\" should drop one frame\n try {\n throw new Error();\n } catch (ex) {\n return computeStackTrace(ex, depth + 1);\n }\n }\n\n computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement;\n computeStackTrace.computeStackTraceFromStackProp = computeStackTraceFromStackProp;\n computeStackTrace.guessFunctionName = guessFunctionName;\n computeStackTrace.gatherContext = gatherContext;\n computeStackTrace.ofCaller = computeStackTraceOfCaller;\n computeStackTrace.getSource = getSource;\n\n return computeStackTrace;\n })();\n\n // Default options:\n if (!TraceKit.remoteFetching) {\n TraceKit.remoteFetching = true;\n }\n if (!TraceKit.collectWindowErrors) {\n TraceKit.collectWindowErrors = true;\n }\n if (!TraceKit.linesOfContext || TraceKit.linesOfContext < 1) {\n // 5 lines before, the offending line, 5 lines after\n TraceKit.linesOfContext = 11;\n }\n})(typeof window !== 'undefined' ? window : global);\n\nexport function getTraceKit(): TraceKitStatic {\n return TraceKit as TraceKitStatic;\n}\n","import { StackFrame } from '../api/stack/StackFrame';\nimport { StackTrace } from '../api/stack/StackTrace';\nimport { ParsedStackOptions } from '../options';\nimport { getTraceKit } from '../vendor/TraceKit';\n\n/**\n * In the browser we will not always be able to determine the source file that code originates\n * from. When you access a route it may just return HTML with embedded source, or just source,\n * in which case there may not be a file name.\n *\n * There will also be cases where there is no source file, such as when running with various\n * dev servers.\n *\n * In these situations we use this constant in place of the file name.\n */\nconst INDEX_SPECIFIER = '(index)';\n\n/**\n * For files hosted on the origin attempt to reduce to just a filename.\n * If the origin matches the source file, then the special identifier `(index)` will\n * be used.\n *\n * @param input The input URL.\n * @returns The output file name.\n */\nexport function processUrlToFileName(input: string, origin: string): string {\n let cleaned = input;\n if (input.startsWith(origin)) {\n cleaned = input.slice(origin.length);\n // If the input is a single `/` then it would get removed and we would\n // be left with an empty string. That empty string would get replaced with\n // the INDEX_SPECIFIER. In cases where a `/` remains, either singular\n // or at the end of a path, then we will append the index specifier.\n // For instance the route `/test/` would ultimately be `test/(index)`.\n if (cleaned.startsWith('/')) {\n cleaned = cleaned.slice(1);\n }\n\n if (cleaned === '') {\n return INDEX_SPECIFIER;\n }\n\n if (cleaned.endsWith('/')) {\n cleaned += INDEX_SPECIFIER;\n }\n }\n return cleaned;\n}\n\n/**\n * Clamp a value to be between an inclusive max an minimum.\n *\n * @param min The inclusive minimum value.\n * @param max The inclusive maximum value.\n * @param value The value to clamp.\n * @returns The clamped value in range [min, max].\n */\nfunction clamp(min: number, max: number, value: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nexport interface TrimOptions {\n /**\n * The maximum length of the trimmed line.\n */\n maxLength: number;\n\n /**\n * If the line needs to be trimmed, then this is the number of character to retain before the\n * originating character of the frame.\n */\n beforeColumnCharacters: number;\n}\n\n/**\n * Trim a source string to a reasonable size.\n *\n * @param options Configuration which affects trimming.\n * @param line The source code line to trim.\n * @param column The column which the stack frame originates from.\n * @returns A trimmed source string.\n */\nexport function trimSourceLine(options: TrimOptions, line: string, column: number): string {\n if (line.length <= options.maxLength) {\n return line;\n }\n const captureStart = Math.max(0, column - options.beforeColumnCharacters);\n const captureEnd = Math.min(line.length, captureStart + options.maxLength);\n return line.slice(captureStart, captureEnd);\n}\n\n/**\n * Given a context get trimmed source lines within the specified range.\n *\n * The context is a list of source code lines, this function returns a subset of\n * lines which have been trimmed.\n *\n * If an error is on a specific line of source code we want to be able to get\n * lines before and after that line. This is done relative to the originating\n * line of source.\n *\n * If you wanted to get 3 lines before the origin line, then this function would\n * need to be called with `start: originLine - 3, end: originLine`.\n *\n * If the `start` would underflow the context, then the start is set to 0.\n * If the `end` would overflow the context, then the end is set to the context\n * length.\n *\n * Exported for testing.\n *\n * @param start The inclusive start index.\n * @param end The exclusive end index.\n * @param trimmer Method which will trim individual lines.\n */\nexport function getLines(\n start: number,\n end: number,\n context: string[],\n trimmer: (val: string) => string,\n): string[] {\n const adjustedStart = start < 0 ? 0 : start;\n const adjustedEnd = end > context.length ? context.length : end;\n if (adjustedStart < adjustedEnd) {\n return context.slice(adjustedStart, adjustedEnd).map(trimmer);\n }\n return [];\n}\n\n/**\n * Given a stack frame produce source context about that stack frame.\n *\n * The source context includes the source line of the stack frame, some number\n * of lines before the line of the stack frame, and some number of lines\n * after the stack frame. The amount of context can be controlled by the\n * provided options.\n *\n * Exported for testing.\n */\nexport function getSrcLines(\n inFrame: {\n // Tracekit returns null potentially. We accept undefined as well to be as lenient here\n // as we can.\n context?: string[] | null;\n column?: number | null;\n srcStart?: number | null;\n line?: number | null;\n },\n options: ParsedStackOptions,\n): {\n srcBefore?: string[];\n srcLine?: string;\n srcAfter?: string[];\n} {\n const { context } = inFrame;\n // It should be present, but we don't want to trust that it is.\n if (!context) {\n return {};\n }\n const { maxLineLength } = options.source;\n const beforeColumnCharacters = Math.floor(maxLineLength / 2);\n\n // The before and after lines will not be precise while we use TraceKit.\n // By forking it we should be able to achieve a more optimal result.\n // We only need to do this if we are not getting sufficient quality using this\n // method.\n\n // Trimmer for non-origin lines. Starts at column 0.\n // Non-origin lines are lines which are not the line for a specific stack\n // frame, but instead the lines before or after that frame.\n // ```\n // console.log(\"before origin\"); // non-origin line\n // throw new Error(\"this is the origin\"); // origin line\n // console.log(\"after origin); // non-origin line\n // ```\n const trimmer = (input: string) =>\n trimSourceLine(\n {\n maxLength: options.source.maxLineLength,\n beforeColumnCharacters,\n },\n input,\n 0,\n );\n\n const origin = clamp(0, context.length - 1, (inFrame?.line ?? 0) - (inFrame.srcStart ?? 0));\n\n return {\n // The lines immediately preceeding the origin line.\n srcBefore: getLines(origin - options.source.beforeLines, origin, context, trimmer),\n srcLine: trimSourceLine(\n {\n maxLength: maxLineLength,\n beforeColumnCharacters,\n },\n context[origin],\n inFrame.column || 0,\n ),\n // The lines immediately following the origin line.\n srcAfter: getLines(origin + 1, origin + 1 + options.source.afterLines, context, trimmer),\n };\n}\n\n/**\n * Parse the browser stack trace into a StackTrace which contains frames with specific fields parsed\n * from the free-form stack. Browser stack traces are not standardized, so implementations handling\n * the output should be resilient to missing fields.\n *\n * @param error The error to generate a StackTrace for.\n * @returns The stack trace for the given error.\n */\nexport default function parse(error: Error, options: ParsedStackOptions): StackTrace {\n if (!options.enabled) {\n return {\n frames: [],\n };\n }\n\n const parsed = getTraceKit().computeStackTrace(error);\n const frames: StackFrame[] = parsed.stack.reverse().map((inFrame) => ({\n fileName: processUrlToFileName(inFrame.url, window.location.origin),\n function: inFrame.func,\n // Strip the nulls so we only ever return undefined.\n line: inFrame.line ?? undefined,\n col: inFrame.column ?? undefined,\n ...getSrcLines(inFrame, options),\n }));\n return {\n frames,\n };\n}\n","/**\n * A limited selection of type information is provided by the browser client SDK.\n * This is only a type dependency and these types should be compatible between\n * SDKs.\n */\nimport type { LDContext, LDEvaluationDetail } from '@launchdarkly/js-client-sdk';\n\nimport { LDClientInitialization, LDClientLogging, LDClientTracking, MinLogger } from './api';\nimport { Breadcrumb, FeatureManagementBreadcrumb } from './api/Breadcrumb';\nimport { BrowserTelemetry } from './api/BrowserTelemetry';\nimport { BrowserTelemetryInspector } from './api/client/BrowserTelemetryInspector';\nimport { Collector } from './api/Collector';\nimport { ErrorData } from './api/ErrorData';\nimport { EventData } from './api/EventData';\nimport ClickCollector from './collectors/dom/ClickCollector';\nimport KeypressCollector from './collectors/dom/KeypressCollector';\nimport ErrorCollector from './collectors/error';\nimport FetchCollector from './collectors/http/fetch';\nimport XhrCollector from './collectors/http/xhr';\nimport defaultUrlFilter from './filters/defaultUrlFilter';\nimport makeInspectors from './inspectors';\nimport { fallbackLogger, prefixLog } from './logging';\nimport { ParsedOptions, ParsedStackOptions } from './options';\nimport randomUuidV4 from './randomUuidV4';\nimport parse from './stack/StackParser';\nimport { getTraceKit } from './vendor/TraceKit';\n\n// TODO: Use a ring buffer for the breadcrumbs/pending events instead of shifting. (SDK-914)\n\nconst CUSTOM_KEY_PREFIX = '$ld:telemetry';\nconst ERROR_KEY = `${CUSTOM_KEY_PREFIX}:error`;\nconst SESSION_INIT_KEY = `${CUSTOM_KEY_PREFIX}:session:init`;\nconst GENERIC_EXCEPTION = 'generic';\nconst NULL_EXCEPTION_MESSAGE = 'exception was null or undefined';\nconst MISSING_MESSAGE = 'exception had no message';\n\n// Timeout for client initialization. The telemetry SDK doesn't require that the client be initialized, but it does\n// require that the context processing that happens during initialization complete. This is some subset of the total\n// initialization time, but we don't care if initialization actually completes within the, just that the context\n// is available for event sending.\nconst INITIALIZATION_TIMEOUT = 5;\n\n/**\n * Given a flag value ensure it is safe for analytics.\n *\n * If the parameter is not safe, then return undefined.\n *\n * TODO: Add limited JSON support. (SDK-916)\n * @param u The value to check.\n * @returns Either the value or undefined.\n */\nfunction safeValue(u: unknown): string | boolean | number | undefined {\n switch (typeof u) {\n case 'string':\n case 'boolean':\n case 'number':\n return u;\n default:\n return undefined;\n }\n}\n\nfunction applyFilter<T>(item: T | undefined, filter: (item: T) => T | undefined): T | undefined {\n return item === undefined ? undefined : filter(item);\n}\n\nfunction configureTraceKit(options: ParsedStackOptions) {\n if (!options.enabled) {\n return;\n }\n\n const TraceKit = getTraceKit();\n // Include before + after + source line.\n // TraceKit only takes a total context size, so we have to over capture and then reduce the lines.\n // So, for instance if before is 3 and after is 4 we need to capture 4 and 4 and then drop a line\n // from the before context.\n // The typing for this is a bool, but it accepts a number.\n const beforeAfterMax = Math.max(options.source.afterLines, options.source.beforeLines);\n // The assignment here has bene split to prevent esbuild from complaining about an assignment to\n // an import. TraceKit exports a single object and the interface requires modifying an exported\n // var.\n const anyObj = TraceKit as any;\n anyObj.linesOfContext = beforeAfterMax * 2 + 1;\n}\n\n/**\n * Check if the client supports LDClientLogging.\n *\n * @param client The client to check.\n * @returns True if the client is an instance of LDClientLogging.\n */\nfunction isLDClientLogging(client: unknown): client is LDClientLogging {\n return (client as any).logger !== undefined;\n}\n\nfunction isLDClientInitialization(client: unknown): client is LDClientInitialization {\n return (client as any).waitForInitialization !== undefined;\n}\n\nexport default class BrowserTelemetryImpl implements BrowserTelemetry {\n private _maxPendingEvents: number;\n private _maxBreadcrumbs: number;\n\n private _pendingEvents: { type: string; data: EventData }[] = [];\n private _client?: LDClientTracking;\n\n private _breadcrumbs: Breadcrumb[] = [];\n\n private _inspectorInstances: BrowserTelemetryInspector[] = [];\n private _collectors: Collector[] = [];\n private _sessionId: string = randomUuidV4();\n\n private _logger: MinLogger;\n\n private _registrationComplete: boolean = false;\n\n // Used to ensure we only log the event dropped message once.\n private _eventsDropped: boolean = false;\n // Used to ensure we only log the breadcrumb filter error once.\n private _breadcrumbFilterError: boolean = false;\n // Used to ensure we only log the error filter error once.\n private _errorFilterError: boolean = false;\n\n constructor(private _options: ParsedOptions) {\n configureTraceKit(_options.stack);\n\n // Error collector is always required.\n this._collectors.push(new ErrorCollector());\n this._collectors.push(..._options.collectors);\n\n this._maxPendingEvents = _options.maxPendingEvents;\n this._maxBreadcrumbs = _options.breadcrumbs.maxBreadcrumbs;\n\n // Set the initial logger, it may be replaced when the client is registered.\n // For typescript purposes, we need the logger to be directly set in the constructor.\n this._logger = this._options.logger ?? fallbackLogger;\n\n const urlFilters = [defaultUrlFilter];\n if (_options.breadcrumbs.http.customUrlFilter) {\n urlFilters.push(_options.breadcrumbs.http.customUrlFilter);\n }\n\n if (_options.breadcrumbs.http.instrumentFetch) {\n this._collectors.push(\n new FetchCollector({\n urlFilters,\n getLogger: () => this._logger,\n }),\n );\n }\n\n if (_options.breadcrumbs.http.instrumentXhr) {\n this._collectors.push(\n new XhrCollector({\n urlFilters,\n getLogger: () => this._logger,\n }),\n );\n }\n\n if (_options.breadcrumbs.click) {\n this._collectors.push(new ClickCollector());\n }\n\n if (_options.breadcrumbs.keyboardInput) {\n this._collectors.push(new KeypressCollector());\n }\n\n this._collectors.forEach((collector) =>\n collector.register(this as BrowserTelemetry, this._sessionId),\n );\n\n const impl = this;\n const inspectors: BrowserTelemetryInspector[] = [];\n makeInspectors(_options, inspectors, impl);\n this._inspectorInstances.push(...inspectors);\n }\n\n register(client: LDClientTracking): void {\n if (this._client !== undefined) {\n return;\n }\n\n this._client = client;\n\n // When the client is registered, we need to set the logger again, because we may be able to use the client's\n // logger.\n this._setLogger();\n\n const completeRegistration = () => {\n this._client?.track(SESSION_INIT_KEY, { sessionId: this._sessionId });\n\n this._pendingEvents.forEach((event) => {\n this._client?.track(event.type, event.data);\n });\n this._pendingEvents = [];\n this._registrationComplete = true;\n };\n\n if (isLDClientInitialization(client)) {\n // We don't actually need the client initialization to complete, but we do need the context processing that\n // happens during initialization to complete. This time will be some time greater than that, but we don't\n // care if initialization actually completes within the timeout.\n\n // An immediately invoked async function is used to ensure that the registration method can be called synchronously.\n // Making the `register` method async would increase the complexity for application developers.\n (async () => {\n try {\n await client.waitForInitialization(INITIALIZATION_TIMEOUT);\n } catch {\n // We don't care if the initialization fails.\n }\n completeRegistration();\n })();\n } else {\n // TODO(EMSR-36): Figure out how to handle the 4.x implementation.\n completeRegistration();\n }\n }\n\n private _setLogger() {\n // If the user has provided a logger, then we want to prioritize that over the client's logger.\n // If the client supports LDClientLogging, then we to prioritize that over the fallback logger.\n if (this._options.logger) {\n this._logger = this._options.logger;\n } else if (isLDClientLogging(this._client)) {\n this._logger = this._client.logger;\n } else {\n this._logger = fallbackLogger;\n }\n }\n\n inspectors(): BrowserTelemetryInspector[] {\n return this._inspectorInstances;\n }\n\n /**\n * Capture an event.\n *\n * If the LaunchDarkly client SDK is not yet registered, then the event\n * will be buffered until the client is registered.\n * @param type The type of event to capture.\n * @param event The event data.\n */\n private _capture(type: string, event: EventData) {\n const filteredEvent = this._applyFilters(event, this._options.errorFilters, (e: unknown) => {\n if (!this._errorFilterError) {\n this._errorFilterError = true;\n this._logger.warn(prefixLog(`Error applying error filters: ${e}`));\n }\n });\n if (filteredEvent === undefined) {\n return;\n }\n\n if (this._registrationComplete) {\n this._client?.track(type, filteredEvent);\n } else {\n this._pendingEvents.push({ type, data: filteredEvent });\n if (this._pendingEvents.length > this._maxPendingEvents) {\n if (!this._eventsDropped) {\n this._eventsDropped = true;\n this._logger.warn(\n prefixLog(\n `Maximum pending events reached. Old events will be dropped until the SDK client is registered.`,\n ),\n );\n }\n this._pendingEvents.shift();\n }\n }\n }\n\n captureError(exception: Error): void {\n const validException = exception !== undefined && exception !== null;\n\n const data: ErrorData = validException\n ? {\n type: exception.name || exception.constructor?.name || GENERIC_EXCEPTION,\n // Only coalesce null/undefined, not empty.\n message: exception.message ?? MISSING_MESSAGE,\n stack: parse(exception, this._options.stack),\n breadcrumbs: [...this._breadcrumbs],\n sessionId: this._sessionId,\n }\n : {\n type: GENERIC_EXCEPTION,\n message: NULL_EXCEPTION_MESSAGE,\n stack: { frames: [] },\n breadcrumbs: [...this._breadcrumbs],\n sessionId: this._sessionId,\n };\n this._capture(ERROR_KEY, data);\n }\n\n captureErrorEvent(errorEvent: ErrorEvent): void {\n this.captureError(errorEvent.error);\n }\n\n private _applyFilters<T>(\n item: T,\n filters: ((item: T) => T | undefined)[],\n handleError: (e: unknown) => void,\n ): T | undefined {\n try {\n return filters.reduce(\n (itemToFilter: T | undefined, filter: (item: T) => T | undefined) =>\n applyFilter(itemToFilter, filter),\n item,\n );\n } catch (e) {\n handleError(e);\n return undefined;\n }\n }\n\n addBreadcrumb(breadcrumb: Breadcrumb): void {\n const filtered = this._applyFilters(\n breadcrumb,\n this._options.breadcrumbs.filters,\n (e: unknown) => {\n if (!this._breadcrumbFilterError) {\n this._breadcrumbFilterError = true;\n this._logger.warn(prefixLog(`Error applying breadcrumb filters: ${e}`));\n }\n },\n );\n if (filtered !== undefined) {\n this._breadcrumbs.push(filtered);\n if (this._breadcrumbs.length > this._maxBreadcrumbs) {\n this._breadcrumbs.shift();\n }\n }\n }\n\n close(): void {\n this._collectors.forEach((collector) => collector.unregister());\n }\n\n /**\n * Used to automatically collect flag usage for breadcrumbs.\n *\n * When session replay is in use the data is also forwarded to the session\n * replay collector.\n *\n * @internal\n */\n handleFlagUsed(flagKey: string, detail: LDEvaluationDetail, _context?: LDContext): void {\n const breadcrumb: FeatureManagementBreadcrumb = {\n type: 'flag-evaluated',\n data: {\n key: flagKey,\n value: safeValue(detail.value),\n },\n timestamp: new Date().getTime(),\n class: 'feature-management',\n level: 'info',\n };\n this.addBreadcrumb(breadcrumb);\n }\n\n /**\n * Used to automatically collect flag detail changes.\n *\n * When session replay is in use the data is also forwarded to the session\n * replay collector.\n *\n * @internal\n */\n handleFlagDetailChanged(flagKey: string, detail: LDEvaluationDetail): void {\n const breadcrumb: FeatureManagementBreadcrumb = {\n type: 'flag-detail-changed',\n data: {\n key: flagKey,\n value: safeValue(detail.value),\n },\n timestamp: new Date().getTime(),\n class: 'feature-management',\n level: 'info',\n };\n\n this.addBreadcrumb(breadcrumb);\n }\n}\n","import { Collector } from './api/Collector';\nimport { MinLogger } from './api/MinLogger';\nimport {\n BreadcrumbFilter,\n BreadcrumbsOptions,\n ErrorDataFilter,\n HttpBreadcrumbOptions,\n Options,\n StackOptions,\n UrlFilter,\n} from './api/Options';\nimport { fallbackLogger, prefixLog, safeMinLogger } from './logging';\n\nconst disabledBreadcrumbs: ParsedBreadcrumbsOptions = {\n maxBreadcrumbs: 0,\n evaluations: false,\n flagChange: false,\n click: false,\n keyboardInput: false,\n http: {\n instrumentFetch: false,\n instrumentXhr: false,\n customUrlFilter: undefined,\n },\n filters: [],\n};\n\nconst disabledStack: ParsedStackOptions = {\n enabled: false,\n source: {\n beforeLines: 0,\n afterLines: 0,\n maxLineLength: 0,\n },\n};\n\nexport function defaultOptions(): ParsedOptions {\n return {\n breadcrumbs: {\n maxBreadcrumbs: 50,\n evaluations: true,\n flagChange: true,\n click: true,\n keyboardInput: true,\n http: {\n instrumentFetch: true,\n instrumentXhr: true,\n },\n filters: [],\n },\n stack: {\n enabled: true,\n source: {\n beforeLines: 3,\n afterLines: 3,\n maxLineLength: 280,\n },\n },\n maxPendingEvents: 100,\n collectors: [],\n errorFilters: [],\n };\n}\n\nfunction wrongOptionType(name: string, expectedType: string, actualType: string): string {\n return prefixLog(\n `Config option \"${name}\" should be of type ${expectedType}, got ${actualType}, using default value`,\n );\n}\n\nfunction checkBasic<T>(type: string, name: string, logger?: MinLogger): (item: T) => boolean {\n return (item: T) => {\n const actualType = typeof item;\n if (actualType === type) {\n return true;\n }\n logger?.warn(wrongOptionType(name, type, actualType));\n return false;\n };\n}\n\nfunction itemOrDefault<T>(item: T | undefined, defaultValue: T, checker?: (item: T) => boolean): T {\n if (item !== undefined && item !== null) {\n if (!checker) {\n return item;\n }\n if (checker(item)) {\n return item;\n }\n }\n return defaultValue;\n}\n\nfunction parseHttp(\n options: HttpBreadcrumbOptions | false | undefined,\n defaults: ParsedHttpOptions,\n logger?: MinLogger,\n): ParsedHttpOptions {\n if (options !== undefined && options !== false && typeof options !== 'object') {\n logger?.warn(\n wrongOptionType('breadcrumbs.http', 'HttpBreadCrumbOptions | false', typeof options),\n );\n return defaults;\n }\n\n if (options === false) {\n return {\n instrumentFetch: false,\n instrumentXhr: false,\n };\n }\n\n // Make sure that the custom filter is at least a function.\n if (options?.customUrlFilter) {\n if (typeof options.customUrlFilter !== 'function') {\n logger?.warn(\n prefixLog(\n `The \"breadcrumbs.http.customUrlFilter\" must be a function. Received ${typeof options.customUrlFilter}`,\n ),\n );\n }\n }\n const customUrlFilter =\n options?.customUrlFilter && typeof options?.customUrlFilter === 'function'\n ? options.customUrlFilter\n : undefined;\n\n return {\n instrumentFetch: itemOrDefault(\n options?.instrumentFetch,\n defaults.instrumentFetch,\n checkBasic('boolean', 'breadcrumbs.http.instrumentFetch', logger),\n ),\n instrumentXhr: itemOrDefault(\n options?.instrumentXhr,\n defaults.instrumentXhr,\n checkBasic('boolean', 'breadcrumbs.http.instrumentXhr', logger),\n ),\n customUrlFilter,\n };\n}\n\nfunction parseLogger(options: Options): MinLogger | undefined {\n if (options.logger) {\n const { logger } = options;\n if (typeof logger === 'object' && logger !== null && 'warn' in logger) {\n return safeMinLogger(logger);\n }\n // Using console.warn here because the logger is not suitable to log with.\n fallbackLogger.warn(wrongOptionType('logger', 'MinLogger or LDLogger', typeof logger));\n }\n return undefined;\n}\n\nfunction parseStack(\n options: StackOptions | false | undefined,\n defaults: ParsedStackOptions,\n logger?: MinLogger,\n): ParsedStackOptions {\n if (options === false) {\n return disabledStack;\n }\n return {\n // Internal option not parsed from the options object.\n enabled: true,\n source: {\n beforeLines: itemOrDefault(\n options?.source?.beforeLines,\n defaults.source.beforeLines,\n checkBasic('number', 'stack.beforeLines', logger),\n ),\n afterLines: itemOrDefault(\n options?.source?.afterLines,\n defaults.source.afterLines,\n checkBasic('number', 'stack.afterLines', logger),\n ),\n maxLineLength: itemOrDefault(\n options?.source?.maxLineLength,\n defaults.source.maxLineLength,\n checkBasic('number', 'stack.maxLineLength', logger),\n ),\n },\n };\n}\n\nfunction parseBreadcrumbs(\n options: BreadcrumbsOptions | false | undefined,\n defaults: ParsedBreadcrumbsOptions,\n logger: MinLogger | undefined,\n): ParsedBreadcrumbsOptions {\n if (options === false) {\n return disabledBreadcrumbs;\n }\n return {\n maxBreadcrumbs: itemOrDefault(\n options?.maxBreadcrumbs,\n defaults.maxBreadcrumbs,\n checkBasic('number', 'breadcrumbs.maxBreadcrumbs', logger),\n ),\n evaluations: itemOrDefault(\n options?.evaluations,\n defaults.evaluations,\n checkBasic('boolean', 'breadcrumbs.evaluations', logger),\n ),\n flagChange: itemOrDefault(\n options?.flagChange,\n defaults.flagChange,\n checkBasic('boolean', 'breadcrumbs.flagChange', logger),\n ),\n click: itemOrDefault(\n options?.click,\n defaults.click,\n checkBasic('boolean', 'breadcrumbs.click', logger),\n ),\n keyboardInput: itemOrDefault(\n options?.keyboardInput,\n defaults.keyboardInput,\n checkBasic('boolean', 'breadcrumbs.keyboardInput', logger),\n ),\n http: parseHttp(options?.http, defaults.http, logger),\n filters: itemOrDefault(options?.filters, defaults.filters, (item) => {\n if (Array.isArray(item)) {\n return true;\n }\n logger?.warn(wrongOptionType('breadcrumbs.filters', 'BreadcrumbFilter[]', typeof item));\n return false;\n }),\n };\n}\n\nexport default function parse(options: Options, logger?: MinLogger): ParsedOptions {\n const defaults = defaultOptions();\n if (options.breadcrumbs) {\n checkBasic('object', 'breadcrumbs', logger)(options.breadcrumbs);\n }\n if (options.stack) {\n checkBasic('object', 'stack', logger)(options.stack);\n }\n return {\n breadcrumbs: parseBreadcrumbs(options.breadcrumbs, defaults.breadcrumbs, logger),\n stack: parseStack(options.stack, defaults.stack, logger),\n maxPendingEvents: itemOrDefault(\n options.maxPendingEvents,\n defaults.maxPendingEvents,\n checkBasic('number', 'maxPendingEvents', logger),\n ),\n collectors: [\n ...itemOrDefault(options.collectors, defaults.collectors, (item) => {\n if (Array.isArray(item)) {\n return true;\n }\n logger?.warn(wrongOptionType('collectors', 'Collector[]', typeof item));\n return false;\n }),\n ],\n logger: parseLogger(options),\n errorFilters: itemOrDefault(options.errorFilters, defaults.errorFilters, (item) => {\n if (Array.isArray(item)) {\n return true;\n }\n logger?.warn(wrongOptionType('errorFilters', 'ErrorDataFilter[]', typeof item));\n return false;\n }),\n };\n}\n\n/**\n * Internal type for parsed http options.\n * @internal\n */\nexport interface ParsedHttpOptions {\n /**\n * True to instrument fetch and enable fetch breadcrumbs.\n */\n instrumentFetch: boolean;\n\n /**\n * True to instrument XMLHttpRequests and enable XMLHttpRequests breadcrumbs.\n */\n instrumentXhr: boolean;\n\n /**\n * Optional custom URL filter.\n */\n customUrlFilter?: UrlFilter;\n}\n\n/**\n * Internal type for parsed stack options.\n * @internal\n */\nexport interface ParsedStackOptions {\n enabled: boolean;\n source: {\n /**\n * The number of lines captured before the originating line.\n */\n beforeLines: number;\n\n /**\n * The number of lines captured after the originating line.\n */\n afterLines: number;\n\n /**\n * The maximum length of source line to include. Lines longer than this will be\n * trimmed.\n */\n maxLineLength: number;\n };\n}\n\n/**\n * Internal type for parsed breadcrumbs options.\n * @internal\n */\nexport interface ParsedBreadcrumbsOptions {\n /**\n * Set the maximum number of breadcrumbs. Defaults to 50.\n */\n maxBreadcrumbs: number;\n\n /**\n * True to enable automatic evaluation breadcrumbs. Defaults to true.\n */\n evaluations: boolean;\n\n /**\n * True to enable flag change breadcrumbs. Defaults to true.\n */\n flagChange: boolean;\n\n /**\n * True to enable click breadcrumbs. Defaults to true.\n */\n click: boolean;\n\n /**\n * True to enable input breadcrumbs for keypresses. Defaults to true.\n */\n keyboardInput?: boolean;\n\n /**\n * Settings for http instrumentation and breadcrumbs.\n */\n http: ParsedHttpOptions;\n\n /**\n * Custom breadcrumb filters.\n */\n filters: BreadcrumbFilter[];\n}\n\n/**\n * Internal type for parsed options.\n * @internal\n */\nexport interface ParsedOptions {\n /**\n * The maximum number of pending events. Events may be captured before the LaunchDarkly\n * SDK is initialized and these are stored until they can be sent. This only affects the\n * events captured during initialization.\n */\n maxPendingEvents: number;\n\n /**\n * Properties related to automatic breadcrumb collection, or `false` to disable automatic breadcrumbs.\n */\n breadcrumbs: ParsedBreadcrumbsOptions;\n\n /**\n * Settings which affect call stack capture, or `false` to exclude stack frames from error events .\n */\n stack: ParsedStackOptions;\n\n /**\n * Additional, or custom, collectors.\n */\n collectors: Collector[];\n\n /**\n * Logger to use for warnings.\n */\n logger?: MinLogger;\n\n /**\n * Custom error data filters.\n */\n errorFilters: ErrorDataFilter[];\n}\n","import { Options } from '../api';\nimport { BrowserTelemetry } from '../api/BrowserTelemetry';\nimport BrowserTelemetryImpl from '../BrowserTelemetryImpl';\nimport { fallbackLogger, prefixLog, safeMinLogger } from '../logging';\nimport parse from '../options';\n\nlet telemetryInstance: BrowserTelemetry | undefined;\nlet warnedClientNotInitialized: boolean = false;\n\n/**\n * Initialize the LaunchDarkly telemetry client\n *\n * This method should be called one time as early as possible in the application lifecycle.\n *\n * @example\n * ```\n * import { initTelemetry } from '@launchdarkly/browser-telemetry';\n *\n * initTelemetry();\n * ```\n *\n * After initialization the telemetry client must be registered with the LaunchDarkly SDK client.\n *\n * @example\n * ```\n * import { initTelemetry, register } from '@launchdarkly/browser-telemetry';\n *\n * initTelemetry();\n *\n * // Create your LaunchDarkly client following the LaunchDarkly SDK documentation.\n *\n * register(ldClient);\n * ```\n *\n * If using the 3.x version of the LaunchDarkly SDK, then you must also add inspectors when initializing your LaunchDarkly client.\n * This allows for integration with feature flag data.\n *\n * @example\n * ```\n * import { initTelemetry, register, inspectors } from '@launchdarkly/browser-telemetry';\n * import { init } from 'launchdarkly-js-client-sdk';\n *\n * initTelemetry();\n *\n * const ldClient = init('YOUR_CLIENT_SIDE_ID', {\n * inspectors: inspectors()\n * });\n *\n * register(ldClient);\n * ```\n *\n * @param options The options to use for the telemetry instance. Refer to {@link Options} for more information.\n */\nexport function initTelemetry(options?: Options) {\n const logger = safeMinLogger(options?.logger);\n\n if (telemetryInstance) {\n logger.warn(prefixLog('Telemetry has already been initialized. Ignoring new options.'));\n return;\n }\n\n const parsedOptions = parse(options || {}, logger);\n telemetryInstance = new BrowserTelemetryImpl(parsedOptions);\n}\n\n/**\n * Get the telemetry instance.\n *\n * In typical operation this method doesn't need to be called. Instead the functions exported by this package directly\n * use the telemetry instance.\n *\n * This function can be used when the telemetry instance needs to be injected into code instead of accessed globally.\n *\n * @returns The telemetry instance, or undefined if it has not been initialized.\n */\nexport function getTelemetryInstance(): BrowserTelemetry | undefined {\n if (!telemetryInstance) {\n if (warnedClientNotInitialized) {\n return undefined;\n }\n\n fallbackLogger.warn(prefixLog('Telemetry has not been initialized'));\n warnedClientNotInitialized = true;\n return undefined;\n }\n\n return telemetryInstance;\n}\n\n/**\n * Reset the telemetry instance to its initial state.\n *\n * This method is intended to be used in tests.\n *\n * @internal\n */\nexport function resetTelemetryInstance() {\n telemetryInstance = undefined;\n warnedClientNotInitialized = false;\n}\n","import { LDClientTracking } from '../api';\nimport { Breadcrumb } from '../api/Breadcrumb';\nimport { BrowserTelemetryInspector } from '../api/client/BrowserTelemetryInspector';\nimport { getTelemetryInstance } from './singletonInstance';\n\n/**\n * Returns an array of active SDK inspectors to use with SDK versions that do\n * not support hooks.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, this method will return an empty array.\n *\n * @returns An array of {@link BrowserTelemetryInspector} objects.\n */\nexport function inspectors(): BrowserTelemetryInspector[] {\n return getTelemetryInstance()?.inspectors() || [];\n}\n\n/**\n * Captures an Error object for telemetry purposes.\n *\n * Use this method to manually capture errors during application operation.\n * Unhandled errors are automatically captured, but this method can be used\n * to capture errors which were handled, but are still useful for telemetry.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, then the exception will be discarded.\n *\n * @param exception The Error object to capture\n */\nexport function captureError(exception: Error): void {\n getTelemetryInstance()?.captureError(exception);\n}\n\n/**\n * Captures a browser ErrorEvent for telemetry purposes.\n *\n * This method can be used to capture a manually created error event. Use this\n * function to represent application specific errors which cannot be captured\n * automatically or are not `Error` types.\n *\n * For most errors {@link captureError} should be used.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, then the error event will be discarded.\n *\n * @param errorEvent The ErrorEvent to capture\n */\nexport function captureErrorEvent(errorEvent: ErrorEvent): void {\n getTelemetryInstance()?.captureErrorEvent(errorEvent);\n}\n\n/**\n * Add a breadcrumb which will be included with telemetry events.\n *\n * Many breadcrumbs can be automatically captured, but this method can be\n * used for capturing manual breadcrumbs. For application specific breadcrumbs\n * the {@link CustomBreadcrumb} type can be used.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, then the breadcrumb will be discarded.\n *\n * @param breadcrumb The breadcrumb to add.\n */\nexport function addBreadcrumb(breadcrumb: Breadcrumb): void {\n getTelemetryInstance()?.addBreadcrumb(breadcrumb);\n}\n\n/**\n * Registers a LaunchDarkly client instance for telemetry tracking.\n *\n * This method connects the telemetry system to the specific LaunchDarkly\n * client instance. The client instance will be used to report telemetry\n * to LaunchDarkly and also for collecting flag and context data.\n *\n * Telemetry must be initialized, using {@link initTelemetry} before calling this method.\n * If telemetry is not initialized, then the client will not be registered, and no events will be sent to LaunchDarkly.\n *\n * @param client The {@link LDClientTracking} instance to register for\n * telemetry.\n */\nexport function register(client: LDClientTracking): void {\n getTelemetryInstance()?.register(client);\n}\n\n/**\n * Closes the telemetry system and stops data collection.\n *\n * In general usage this method is not required, but it can be used in cases\n * where collection needs to be stopped independent of application\n * lifecycle.\n *\n * If telemetry is not initialized, using {@link initTelemetry}, then this method will do nothing.\n */\nexport function close(): void {\n getTelemetryInstance()?.close();\n}\n"],"mappings":"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","names":["src_exports","__export","addBreadcrumb","captureError","captureErrorEvent","close","getTelemetryInstance","initTelemetry","initTelemetryInstance","inspectors","register","resetTelemetryInstance","__toCommonJS","getTarget","event","e","isNode","element","anyElement","getClassName","value","elementToString","components","className","toSelector","options","ptr","asString","ClickCollector","event","_a","target","getTarget","breadcrumb","toSelector","recorder","_sessionId","THROTTLE_TIME_MS","INPUT_TAG_NAMES","KeypressCollector","event","_a","target","getTarget","htmlElement","breadcrumb","toSelector","recorder","_sessionId","crumb","ErrorCollector","event","_a","recorder","filterUrl","filters","url","filtered","filter","filterHttpBreadcrumb","crumb","options","_a","filterUrl","LD_ORIGINAL_FETCH","originalFetch","processFetchArgs","input","init","_a","url","method","decorateFetch","callback","wrapper","args","timestamp","response","crumb","e","FetchCollector","options","decorateFetch","breadcrumb","_a","_b","_c","filtersExecuted","filterHttpBreadcrumb","err","recorder","_sessionId","LD_ORIGINAL_XHR","LD_ORIGINAL_XHR_OPEN","LD_ORIGINAL_XHR_SEND","LD_DATA_XHR","originalOpen","originalSend","decorateXhr","callback","wrappedOpen","args","_event","data","xhrData","e","wrappedSend","XhrCollector","options","decorateXhr","breadcrumb","_a","_b","_c","filtersExecuted","filterHttpBreadcrumb","err","recorder","_sessionId","pollingRegex","streamingREgex","authorityUrlFilter","url","urlObj","hadAuth","e","ldUrlFilter","_a","_b","regexMatch","context","defaultUrlFilter","makeInspectors","options","inspectors","telemetry","flagKey","flagDetail","context","detail","fallbackLogger","loggingPrefix","prefixLog","message","safeMinLogger","logger","args","e","timeLow","timeMid","timeHiAndVersion","clockSeqHiAndReserved","clockSeqLow","nodes","getRandom128bit","typedArray","values","index","hex","bytes","range","strVal","formatDataAsUuidV4","fallbackUuidV4","randomUuidV4","TraceKit","window","undefined","_slice","UNKNOWN_FUNCTION","ERROR_TYPES_RE","_has","object","key","_isUndefined","what","func","wrapped","e","sourceCache","loadSource","url","request","getSource","source","domain","match","guessFunctionName","lineNo","reFunctionArgNames","reGuessFunction","line","maxLines","m","i","gatherContext","context","linesBefore","linesAfter","start","end","escapeRegExp","text","escapeCodeAsRegExpForMatchingInsideHTML","body","findSourceInUrls","re","urls","j","findSourceInLine","fragment","findSourceByFunctionBody","scripts","code","codeRE","eventRE","parts","result","script","name","args","event","computeStackTraceFromStackProp","ex","_a","chrome","gecko","winjs","isEval","geckoEval","chromeEval","lines","stack","submatch","element","reference","isNative","srcContext","computeStackTraceFromStacktraceProp","stacktrace","opera10Regex","opera11Regex","exc","computeStackTraceFromOperaMultiLineMessage","lineRE1","lineRE2","lineRE3","inlineScriptBlocks","s","item","relativeLine","pos","src","midline","augmentStackTraceWithInitialElement","stackInfo","message","initial","computeStackTraceByWalkingCallerChain","depth","functionName","funcs","recursion","curr","computeStackTrace","computeStackTraceOfCaller","getTraceKit","INDEX_SPECIFIER","processUrlToFileName","input","origin","cleaned","clamp","min","max","value","trimSourceLine","options","line","column","captureStart","captureEnd","getLines","start","end","context","trimmer","adjustedStart","adjustedEnd","getSrcLines","inFrame","_a","_b","maxLineLength","beforeColumnCharacters","parse","error","getTraceKit","CUSTOM_KEY_PREFIX","ERROR_KEY","SESSION_INIT_KEY","GENERIC_EXCEPTION","NULL_EXCEPTION_MESSAGE","MISSING_MESSAGE","INITIALIZATION_TIMEOUT","safeValue","u","applyFilter","item","filter","configureTraceKit","options","TraceKit","getTraceKit","beforeAfterMax","anyObj","isLDClientLogging","client","isLDClientInitialization","BrowserTelemetryImpl","_options","randomUuidV4","_a","ErrorCollector","fallbackLogger","urlFilters","defaultUrlFilter","FetchCollector","XhrCollector","ClickCollector","KeypressCollector","collector","impl","inspectors","makeInspectors","completeRegistration","event","e","type","filteredEvent","prefixLog","exception","_b","data","parse","errorEvent","filters","handleError","itemToFilter","breadcrumb","filtered","flagKey","detail","_context","disabledBreadcrumbs","disabledStack","defaultOptions","wrongOptionType","name","expectedType","actualType","prefixLog","checkBasic","type","logger","item","itemOrDefault","defaultValue","checker","parseHttp","options","defaults","customUrlFilter","parseLogger","safeMinLogger","fallbackLogger","parseStack","_a","_b","_c","parseBreadcrumbs","parse","telemetryInstance","warnedClientNotInitialized","initTelemetry","options","logger","safeMinLogger","prefixLog","parsedOptions","parse","BrowserTelemetryImpl","getTelemetryInstance","fallbackLogger","resetTelemetryInstance","inspectors","_a","getTelemetryInstance","captureError","exception","captureErrorEvent","errorEvent","addBreadcrumb","breadcrumb","register","client","close","initTelemetryInstance","options","parsedOptions","parse","safeMinLogger","BrowserTelemetryImpl"]}