{"version":3,"file":"DAsf-1.50.dp8w9hyd.js","names":[],"sources":["../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/logging.ts","../../../../src/js/components/util.ts","../../../../src/js/components/perf.ts","../../../../src/js/components/messageChannel/csm/csmChannelHost.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/browseNode.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csm/util.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csm/counter.ts","../../../../src/js/components/feedback.ts","../../../../../../../node_modules/@amzn/creative-obstruction-detection/src/domObstructions/getDOMObstructionPercentage.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csa/events.ts","../../../../../../../node_modules/@amzn/creative-obstruction-detection/src/nativeObstructions/nativeObstructionsUtils.ts","../../../../../../../node_modules/@amzn/creative-obstruction-detection/src/nativeObstructions/getObstructions.ts","../../../../../../../node_modules/@amzn/creative-obstruction-detection/src/nativeObstructions/obstructionsEventListeners.ts","../../../../../../../node_modules/@amzn/creative-obstruction-detection/src/nativeObstructions/getNativeObstructionPercentage.ts","../../../../../../../node_modules/@amzn/creative-obstruction-detection/src/obstructionDetectionServiceImpl.ts","../../../../src/js/components/metrics/awsMetricLoggerApiKey.ts","../../../../src/js/components/metrics/awsMetricBatcher.ts","../../../../src/js/components/metrics/logMetricOnce.ts","../../../../src/js/components/weblabs.ts","../../../../src/js/components/metrics/awsMetricLogger.ts","../../../../src/js/components/intersectionObserver.ts","../../../../src/js/components/pixels/mrcObstructionViewPixel.ts","../../../../src/js/components/pixels/pixel.ts","../../../../src/js/components/pixels/pixelIdentifiers.ts","../../../../src/js/components/pixels/services/pixelLogger.ts","../../../../src/js/components/pixels/viewPixelUtil.ts","../../../../src/js/host/slotSpecific/placementSafezone.ts","../../../../src/js/components/pixels/services/viewabilityServiceImpl.ts","../../../../src/js/components/pixels/services/visibilityChangeService.ts","../../../../src/js/components/skadnetwork/skanAppAdsAttribution.ts","../../../../src/js/components/pixels/skanImpressionPixel.ts","../../../../src/js/components/pixels/skanViewPixel.ts","../../../../src/js/client/api/client/measurementMethods.ts","../../../../src/js/components/aax/aax.ts","../../../../src/js/components/urlQueryParams/addJSONQueryParamToURL.ts","../../../../src/js/components/pixels/urlGenerators/btrPixelUrlGenerator.ts","../../../../src/js/components/pixels/urlGenerators/impressionPixelUrlGenerator.ts","../../../../src/js/components/viewability.ts","../../../../src/js/components/pixels/urlGenerators/measurabilityPixelUrlGenerator.ts","../../../../src/js/components/pixels/placementData.ts","../../../../src/js/components/pixels/urlGenerators/mrcObstructionViewPixelUrlGenerator.ts","../../../../src/js/components/pixels/viewabilityStandards.ts","../../../../src/js/components/pixels/viewabilityTrackerImpl.ts","../../../../src/js/components/pixels/pixelMapper.ts","../../../../src/js/components/events/customEvents.ts","../../../../src/js/components/pixels/services/videoFirePixelValidator.ts","../../../../src/js/host/components/css.ts","../../../../src/js/components/metrics/size-info-logger.ts","../../../../src/js/host/components/placement.ts","../../../../src/js/host/api-client/handlers/changeSizeHandler.ts","../../../../src/js/host/domain/placement.ts","../../../../src/js/host/domain/placementMapper.ts","../../../../src/js/host/api-client/handlers/collapseSlotHandler.ts","../../../../src/js/components/homepage/homepageVideoOrchestrator.ts","../../../../src/js/host/components/iframe.ts","../../../../src/js/host/api-client/handlers/videoHandlers.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csa/latency.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csm/latency.ts","../../../../src/js/host/components/latency.ts","../../../../../../../node_modules/throttle-debounce/esm/index.js","../../../../src/js/host/components/loading.ts","../../../../src/js/host/components/waitUntilReadyForTracking.ts","../../../../src/js/host/api-client/CommonSupportedCommands.ts","../../../../src/js/components/cache.ts","../../../../src/js/components/metrics/assetMetricLogger.ts","../../../../src/js/host/components/csaMetrics.ts","../../../../src/js/components/metrics/coordinate-logger.ts","../../../../src/js/host/api-client/handlers/retailClickTrackingHandler.ts","../../../../src/js/components/viewRateExperimentUtil.ts","../../../../src/js/host/api-client/handlers/sendEventCreativeBeginToRenderHandler.ts","../../../../src/js/host/components/skanViewabilityTracker.ts","../../../../src/js/host/api-client/handlers/sendEventCreativeLoadedHandler.ts","../../../../src/js/host/api-client/handlers/sendSafeFrameExt.ts","../../../../src/js/host/slotSpecific/navCartClassToggle.ts","../../../../src/js/host/api-client/hostEventsChannel.ts","../../../../src/js/components/executeWhenConditionMet.ts","../../../../src/js/host/api-client/hostMessageReceiver.ts","../../../../src/js/host/api-client/hostMessageSender.ts","../../../../src/js/components/utils/hasOwn.ts","../../../../src/js/components/messageChannel/bridge/hostBridge.ts","../../../../src/js/host/api-page/safeframe-api.ts","../../../../src/js/host/context/HostContext.ts","../../../../src/js/host/api-page/safeframe-api-factory.ts","../../../../src/js/host/initSafeframeHost.ts","../../../../src/js/host/DAsf.ts"],"sourcesContent":["import { LogLevel } from './csmGlobal.js';\n\n/*\n * All Error logging should go through these 2 functions.\n * Issues which degrade customer experience should call {@link logFatal}\n * Log level descriptions: https://w.amazon.com/bin/view/ClientSideMetrics/UserDocs/JavascriptErrors/#Error_levels\n * This will send messages/errors to RTLA, which can be analyzed to provide more information.\n */\n\n/**\n * Logs a message to the console, with console.debug(message)\n * @param message text send to console\n */\nexport const logDebug = (message: string): void => {\n    console.debug(message);\n};\n\n/**\n * Sends a warn message to RTLA.\n * @param message the text string of the warn\n * @param err the error object to log, if omitted, an error object will be created using message\n */\nexport const logWarn = (message: string, err?: Error | any): void => {\n    console.warn(message, JSON.stringify(err));\n    emitToRTLA('WARN', message, toError(message, err));\n};\n\n/**\n * Send an error message to RTLA. Use {@link logFatal} instead for issues which degrade customer experience.\n * @param message the text string of the error\n * @param err the error object to log, if omitted, an error object will be created using message\n */\nexport const logError = (message: string, err?: Error | any): void => {\n    console.error(message, JSON.stringify(err));\n    emitToRTLA('ERROR', message, toError(message, err));\n};\n\n/**\n * Send a fatal error message to RTLA. Use {@link logError} instead for non-critical errors.\n * @param message the text string of the error\n * @param err the error object to log, if omitted, an error object will be created using message\n */\nexport const logFatal = (message: string, err?: Error | any): void => {\n    console.error(message, JSON.stringify(err));\n    emitToRTLA('FATAL', message, toError(message, err));\n};\n\nconst emitToRTLA = (level: LogLevel, message: string, err: Error): void => {\n    window.ueLogError?.(err, {\n        logLevel: level,\n        attribution: 'APE-safeframe',\n        message: message + ' | '\n    });\n};\n\nconst toError = (message: string, err: any): Error =>\n    err instanceof Error ? err : err ? new Error(err) : new Error(message);\n","// Utility Functions used by both Client and Server\nimport type {} from '@amzn/amazon-ui-page-ts';\n\nexport const safeFunctionWrapper = (\n    handler: (...safeArgs: any[]) => void,\n    errorHandler?: (msg: string, ex?: any) => void,\n    errorMessage?: string,\n): any => {\n    return (...args: any[]) => {\n        try {\n            handler(...args);\n        } catch (ex) {\n            errorHandler?.(errorMessage ? errorMessage : 'Error in handler', ex);\n        }\n    };\n};\n\n// Below code is for utf_8 compliant versions of atob/btoa\n//M DN https://developer.mozilla.org/en-US/docs/Glossary/Base64#solution_2_%E2%80%93_rewriting_atob_and_btoa_using_typedarrays_and_utf-8\n\nexport const utf_8_atob = (base64: string): string => b64_to_utf8(base64);\nexport const utf_8_btoa = (js_text: string): string => utf8_to_b64(js_text);\n\nconst base64TestRegexp = /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/;\n/**\n * @deprecated Remove once GPAT changes that only send text have been rolled out\n */\nconst isBase64 = (stringToTest: string) => base64TestRegexp.test(stringToTest);\n/**\n * @deprecated Remove once GPAT changes that only send text have been rolled out\n */\nexport const convertToStringIfBase64 = (stringToTest: string) =>\n    isBase64(stringToTest) ? utf_8_atob(stringToTest) : stringToTest;\n\nexport const convertToBase64IfString = (stringToTest: string) =>\n    isBase64(stringToTest) ? stringToTest : utf8_to_b64(stringToTest);\n\n// We use unescape even though not recommended due to performance and code size\nconst utf8_to_b64 = (utf8: string): string => {\n    return btoa(unescape(encodeURIComponent(utf8)));\n};\n\nconst b64_to_utf8 = (base64: string): string => {\n    return decodeURIComponent(escape(atob(base64)));\n};\n\n// Remove when https://issues.amazon.com/issues/V1533734779 is resolved.\nexport const removeAAXPayloadFromUrl = (url: string): string => {\n    if (!url) {\n        return url;\n    }\n    // oxlint-disable-next-line no-template-curly-in-string\n    return url.split('&c=${AAX_PAYLOAD}').join('');\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nexport const getMarkName = (scope: string, message: string, adDetails?: AdDetails): string =>\n    `${scope}${adDetails ? `:${adDetails.placementName}` : ''} - ${message}`;\n\nexport const mark = (scope: string, message: string, adDetails?: AdDetails): string => {\n    const markString = getMarkName(scope, message, adDetails);\n\n    performance?.mark?.(markString);\n\n    return markString;\n};\n\nexport interface LatencyTracker {\n    readonly startTime: number;\n    elapsed: () => number;\n}\n\nexport const createLatencyTracker = (): LatencyTracker => {\n    const startTime = performance.now();\n    return { startTime, elapsed: () => performance.now() - startTime };\n};\n","import type { Context } from '@/components/messageChannel/bridge/bridge.js';\nimport type { HostImpl } from '@/components/messageChannel/bridge/hostBridge.js';\nimport type { AdditionalInfo, CsmChannel } from '@/components/messageChannel/csm/csmChannel.js';\n\nexport const createHostCsmChannel = (): HostImpl<CsmChannel> => ({\n    ueLogError: (_ctx: Context, error: Error, additionalInfo: AdditionalInfo) =>\n        window.ueLogError?.(error, additionalInfo),\n    ue: {\n        count: (_ctx: Context, metric: string, count?: number) => window.ue?.count?.(metric, count),\n    },\n});\n","/*\n    The regex pattern used in Javelin for getting browseNode in the URL\n    https://code.amazon.com/packages/JavelinPrimingServiceCDK/blobs/mainline/--/configuration/appconfig/pageContextConfig-prod.json#L97\n*/\nconst regex = /(\\/b|\\/s|\\/l).*(node=)(\\d{1,12})/;\nconst cache = new Map();\n\nexport const getBrowseNode = (): string | null => {\n    if (!cache.has(window.location.href)) {\n        const match = regex.exec(window.location.href);\n        const browseNode = match && match[3] ? match[3] : null;\n        cache.set(window.location.href, browseNode);\n    }\n    return cache.get(window.location.href);\n};\n\nexport const getSlotWithBrowseNode = (slot: string): string | null => {\n    const browseNode = getBrowseNode();\n    if (!slot || !browseNode) {\n        return null;\n    }\n    const slotItems = slot.split(':');\n    slotItems.splice(slotItems.length - 1, 0, browseNode);\n    return slotItems.join(':');\n};\n\nexport const getPlacementWithBrowseNode = (placementId: string): string | null => {\n    const browseNode = getBrowseNode();\n    if (!browseNode) {\n        return null;\n    }\n\n    return `${placementId}:${browseNode}`;\n};\n","export const csmName = (name: string) => name.replace(/_/g, ':');\n","// https://w.amazon.com/index.php/ClientSideMetrics/UserDocs/Instrumentation/ClientSideCounters\nimport { getPlacementWithBrowseNode, getSlotWithBrowseNode } from '../browseNode.js';\nimport { csmName } from './util.js';\nimport type { Placement } from '../placement.js';\n\n/**\n * @description CSM - Increment placement level counter for a CSM metric.\n * @param metric The actual metrics name, without Placement information\n * @param placement The Placement you want to log metrics for\n * @param count The number to increment the count by (default 1)\n * @example incrementPlacementCounter('adfeedback:request', {id: '597b923a-8c7e-4665-9541-de88160dd0ba', name: 'Gateway_right-2_desktop'})\n * @example incrementPlacementCounter('adfeedback:request', {id: '597b923a-8c7e-4665-9541-de88160dd0ba', name: 'Gateway_right-2_desktop'}, 2)\n */\nexport const incrementCsmPlacementCounter = (metric: string, placement: Placement, count = 1) => {\n    if (!isUeCountAvailable()) return;\n\n    const countMetric = (metric: string, metricType: string | null, count: number) => {\n        if (!metricType) return;\n        ueCount(`${adPlacementMetric(metric)}:${metricType}`, count);\n    };\n\n    countMetric(metric, placement.id, count);\n    countMetric(metric, getPlacementWithBrowseNode(placement.id), count);\n\n    countMetric(metric, csmName(placement.name), count);\n    countMetric(metric, getSlotWithBrowseNode(csmName(placement.name)), count);\n};\n\n/**\n * @description CSM - Increment market level counter for a CSM metric.\n * @param metric The actual metrics name\n * @param count The number to increment the count by (default 1)\n * @example incrementCounter('adfeedback:request')\n * @example incrementCounter('adfeedback:request', 2)\n */\nexport const incrementCsmCounter = (metric: string, count = 1) => {\n    if (!isUeCountAvailable()) return;\n\n    ueCount(adPlacementMetric(metric), count);\n};\n\nexport const isUeCountAvailable = () => typeof window?.ue?.count === 'function';\nexport const ueCount = (metric: string, count: number) => window?.ue?.count(metric, count);\n\nconst adPlacementPrefix = 'adplacements';\nconst adPlacementMetric = (metric: string): string =>\n    metric.startsWith(adPlacementPrefix) ? metric : `${adPlacementPrefix}:${metric}`;\n","import {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport type { Placement } from '@amzn/apejs-instrumentation/src/metrics/placement.js';\n\nexport const openModal = (parentHtmlId: string): void => {\n    for (const child of getFeedbackDiv(parentHtmlId)?.children || []) {\n        if (isFeedbackLink(child)) {\n            (child as HTMLElement).click();\n            return;\n        }\n    }\n};\n\nexport const labelRendered = (placement: Placement): void => {\n    incrementCsmCounter('adfeedback:sponsoredlabelrendered');\n    incrementCsmPlacementCounter('adfeedback:sponsoredlabelrendered:creative', placement);\n};\n\nconst getFeedbackDiv = (parentHtmlId: string): HTMLElement | null =>\n    document.getElementById(parentHtmlId + '_Feedback');\nconst isFeedbackLink = (childElement: Element): boolean =>\n    childElement.tagName === 'A' || childElement.tagName === 'DIV';\n","/**\n * Measures the amount of the creative which is overlapped by a DOM element.\n * Any part of the creative which is offscreen is considered unobstructed.\n * @param placementElement - The placement HTML element\n * @param placementSafezoneDOMRect - The safezone DOMRect for the placement. Use {@link getPlacementSafezoneDOMRect} to get this value.\n * @returns The percentage of the creative that is obstructed by a DOM element\n */\nexport const getDOMObstructionPercentage = (\n    placementElement: HTMLElement,\n    placementSafezoneDOMRect: DOMRect,\n): number => {\n    const pointsToCheck: [number, number][] = getPointsToCheck(placementSafezoneDOMRect);\n    let obstructedPointsCount = 0;\n\n    // Check each point\n    for (const [x, y] of pointsToCheck) {\n        if (!isCoordinateInViewport(x, y)) continue;\n\n        const elementAtPoint = document.elementFromPoint(x, y);\n        if (elementAtPoint && isElementAtPointObstructing(elementAtPoint, placementElement)) {\n            obstructedPointsCount++;\n        }\n    }\n    return obstructedPointsCount / pointsToCheck.length;\n};\n\nexport const getPointsToCheck = (elementRect: DOMRect): [number, number][] => {\n    const rows = 10;\n    const pointsToCheck: [number, number][] = [];\n    for (let i = 0; i < rows; i++) {\n        pointsToCheck.push([\n            elementRect.left + elementRect.width / 2,\n            elementRect.top + (elementRect.height * (i + 0.5)) / rows,\n        ]);\n    }\n    return pointsToCheck;\n};\n\nexport const isCoordinateInViewport = (x: number, y: number): boolean => {\n    const viewportWidth: number = window.innerWidth || document.documentElement.clientWidth;\n    const viewportHeight: number = window.innerHeight || document.documentElement.clientHeight;\n    return x >= 0 && x <= viewportWidth && y >= 0 && y <= viewportHeight;\n};\n\nexport const isElementAtPointObstructing = (elementAtPoint: Element, creativeElement: HTMLElement): boolean => {\n    if (\n        !(elementAtPoint instanceof HTMLElement) ||\n        elementAtPoint === creativeElement ||\n        creativeElement.contains(elementAtPoint)\n    ) {\n        return false;\n    }\n\n    const computedStyle = window.getComputedStyle(elementAtPoint);\n    if (\n        computedStyle.display === 'none' ||\n        computedStyle.visibility === 'hidden' ||\n        computedStyle.pointerEvents === 'none' ||\n        parseFloat(computedStyle.opacity) < 0.7\n    ) {\n        return false;\n    }\n\n    const backgroundColor = computedStyle.backgroundColor;\n    const regexPattern = /,0\\)$/;\n    const isTransparentBackground =\n        backgroundColor === 'transparent' || regexPattern.test(backgroundColor) || backgroundColor === '';\n    if (isTransparentBackground && !computedStyle.backgroundImage.includes('url')) {\n        return false;\n    }\n    return true;\n};\n","import { logError } from '../logging.js';\nimport type { Placement } from '../placement.js';\nimport type {} from './global.js';\n/**\n * Attaches metadata from an `entity` to subsequent events. For example:\n * ```\n *   csa.addCsaEntity({ ABPStatus: ABP_STATUS[data.abpStatus as keyof typeof ABP_STATUS] });\n *   events('log', {schemaId: 'ApeSafeframe.csaEvent.1'}, {ent: 'all'})\n * ```\n *\n * will produce the following CSA log:\n * ```\n * \"data\": {\n *      \"schemaId\": \"ApeSafeframe.csaEvent.1\",\n *      \"metricName\": \"abpstatus_notenabled:Gateway_right-2_desktop:4293fb4d-96ae-46e9-81f1-7503c09f76f3\",\n *      \"metricValue\": 1,\n *      ...\n *      \"entities\": {\n *          \"adCreativeMetaData\": {\n *              \"id\": \"3v21xq-3ejsvn-ut5yxw-3kbtb4\",\n *              \"ABPStatus\": \"NotEnabled\"\n *          },\n *          ...\n *      }\n * ```\n * @param entity {Object} - metadata that can be attached to multiple events\n */\n\nexport const setCsaEntity = (entity: object): void => {\n    if (!window.csa) return;\n\n    try {\n        window.csa('Events', {\n            producerId: 'adplacements'\n        })('setEntity', { adCreativeMetaData: entity });\n    } catch (ex) {\n        logError(\"Error with 'setEntity' CSA\", ex);\n    }\n};\n\n/**\n * Increment counter for a CSA metric. For example:\n * ```\n * logCsaEvent(\"adload:htmlreached\", \"Gateway_desktop-ad-center-1_desktop\", \"73950e1c-6f66-4784-b2d9-e5d5693a4353\");\n * ```\n *\n * will produce the following CSA log:\n * ```\n * \"data\": {\n *      \"schemaId\": \"ApeSafeframe.csaEvent.1\",\n *      \"metricName\": \"adload:htmlreached:Gateway_desktop-ad-center-1_desktop:73950e1c-6f66-4784-b2d9-e5d5693a4353\",\n *      \"metricValue\": 1,\n *      ...\n * }\n * ```\n *\n * CSA events reference: https://info.analytics.a2z.com/#/docs/data_collection/csa/events\n */\nexport const incrementCsaPlacementCounter = (metric: string, placement: Placement, count = 1) => {\n    if (!window.csa) return;\n\n    try {\n        window.csa('Events', {\n            producerId: 'adplacements'\n        })(\n            'log',\n            {\n                schemaId: 'ApeSafeframe.csaEvent.1',\n                metricName: metric + ':' + placement.name + ':' + placement.id,\n                metricValue: count\n            },\n            { ent: 'all' }\n        );\n    } catch (ex) {\n        logError(\"Error with 'logCsaEvent' CSA\", ex);\n    }\n};\n\nexport const incrementCsaCounter = (metric: string, count = 1) => {\n    if (!window.csa) return;\n\n    try {\n        window.csa('Events', {\n            producerId: 'adplacements'\n        })(\n            'log',\n            {\n                schemaId: 'ApeSafeframe.csaEvent.1',\n                metricName: metric,\n                metricValue: count\n            },\n            { ent: 'all' }\n        );\n    } catch (ex) {\n        logError(\"Error with 'incrementCounter' CSA\", ex);\n    }\n};\n\nconst PRODUCER_ID = 'apm-stores';\nconst METRICS_SOURCE_GROUP = 'com.amazon.apm.stores.csa.metrics.prod';\nconst LOGS_SOURCE_GROUP = 'com.amazon.apm.stores.csa.logs.prod';\n\nconst logCsaEvent = (sushiSourceGroup: string, data: Record<string, unknown>): void =>\n    window.csa?.('Events', { producerId: PRODUCER_ID, sushiSourceGroup })?.('log', data);\n\nexport const emitCsaLog = (data: Record<string, unknown>): void => logCsaEvent(LOGS_SOURCE_GROUP, data);\n\nexport type CsaMetricInput = {\n    metricName: string;\n    metricValue: number;\n    timestamp?: Date;\n    dimension: Record<string, string>;\n};\n\n/**\n * Emits a CSA metric event to the metrics source group.\n *\n * @param input - The metric data to emit.\n * @param input.metricName - Name of the metric to emit.\n * @param input.metricValue - Numeric value of the metric.\n * @param input.timestamp - When the metric was recorded. Defaults to now.\n * @param input.dimension - Key-value pairs for metric dimensions.\n */\nexport const emitCsaMetric = ({ metricName, metricValue, timestamp = new Date(), dimension }: CsaMetricInput): void =>\n    logCsaEvent(METRICS_SOURCE_GROUP, {\n        metricName,\n        metricValue,\n        timestamp: timestamp.getTime(),\n        dimension\n    });\n","export const calculateObstructionPercentage = (placementRect: DOMRect, overlapRect: DOMRect) => {\n    const xOverlap = Math.max(\n        0,\n        Math.min(placementRect.right, overlapRect.right) - Math.max(placementRect.left, overlapRect.left),\n    );\n\n    const yOverlap = Math.max(\n        0,\n        Math.min(placementRect.bottom, overlapRect.bottom) - Math.max(placementRect.top, overlapRect.top),\n    );\n\n    if (xOverlap === 0 || yOverlap === 0) {\n        return 0;\n    }\n\n    const intersectionArea = xOverlap * yOverlap;\n    const placementDivElementArea = placementRect.width * placementRect.height;\n    return intersectionArea / placementDivElementArea;\n};\n\nexport const convertNativeElementToDomRect = (options: {\n    height: number;\n    top: number;\n    left?: number;\n    width?: number;\n}) => {\n    const { height, top, left = 0, width = windowWidth() } = options;\n    return {\n        top,\n        bottom: top + height,\n        left,\n        right: left + width,\n        width,\n        height,\n    } as DOMRect;\n};\n\nexport const windowWidth = () => {\n    return window.innerWidth || document.documentElement.clientWidth;\n};\n","import { convertNativeElementToDomRect } from './nativeObstructionsUtils.js';\n\nexport const MASH_API_NAME = 'mash';\n\nexport interface BoundingBox {\n    top: number;\n    left: number;\n    height: number;\n    width: number;\n}\n\nexport interface ObstructionsResponse {\n    boundingBoxes: BoundingBox[];\n    isFullyObstructed: boolean;\n}\n\nexport interface getObstructionsResponse {\n    boundingBoxes: DOMRect[];\n    isFullyObstructed: boolean;\n    latencyMs: number;\n}\n\n/**\n * Gets obstructions from the native app using the new MASH API.\n * This API returns information about UI elements that might be obstructing the ad.\n * Docs: https://w.amazon.com/bin/view/MShop/mShopRadXCXTeam/projects/AppCX/Documentation/Obstructions\n * @returns An array with 0,1 or 2 bounding rectangles which indicate top or bottom overlap, and a boolean\n *     indicating if the entire screen is obstructed\n */\nexport const getObstructions = async (\n    timeoutMs: number,\n): Promise<{ boundingBoxes: DOMRect[]; isFullyObstructed: boolean; latencyMs: number }> => {\n    return new Promise((res, rej) => {\n        if (!P) {\n            rej(new Error('mash:getobstructions:missing'));\n            return;\n        }\n\n        const timeout = setTimeout(() => {\n            rej(new Error('mash:getobstructions:timeout'));\n        }, timeoutMs);\n\n        const startTime = performance.now();\n        P.when(MASH_API_NAME).execute((mash) => {\n            if (!mash?.appCX?.uiOrchestrator?.getObstructions) {\n                clearTimeout(timeout);\n                rej(new Error('mash:getobstructions:missing'));\n                return;\n            }\n\n            mash.appCX.uiOrchestrator.getObstructions({\n                successCallback: (result: ObstructionsResponse) => {\n                    clearTimeout(timeout);\n                    res({\n                        boundingBoxes: (result.boundingBoxes || []).map(convertNativeElementToDomRect),\n                        isFullyObstructed: result.isFullyObstructed,\n                        latencyMs: performance.now() - startTime,\n                    });\n                },\n                failCallback: () => {\n                    clearTimeout(timeout);\n                    rej(new Error('mash:getobstructions:failure'));\n                },\n            });\n        });\n    });\n};\n","import { incrementCsmCounter } from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\n\nimport { MASH_API_NAME } from './getObstructions.js';\nimport { ObstructionsResponse } from './getObstructions.js';\n\nexport interface ObstructionsChangedEventResponse {\n    type: 'obstructionsChanged';\n    detail: ObstructionsResponse;\n}\n\n/**\n * Docs: https://w.amazon.com/bin/view/MShop/mShopRadXCXTeam/projects/AppCX/Documentation/Obstructions\n * @param handler\n */\nexport const addNativeObstructionsChangedListener = (\n    handler: (response: ObstructionsChangedEventResponse) => void,\n): void => {\n    if (!P) {\n        incrementCsmCounter('mash:missing', 1);\n        return;\n    }\n    P.when(MASH_API_NAME).execute((mash) => {\n        mash?.addEventListener('obstructionsChanged', handler);\n    });\n};\n\n/**\n * Docs: https://w.amazon.com/bin/view/MShop/mShopRadXCXTeam/projects/AppCX/Documentation/Obstructions\n * @param handler\n */\nexport const removeNativeObstructionsChangedListener = (\n    handler: (response: ObstructionsChangedEventResponse) => void,\n): void => {\n    if (!P) {\n        incrementCsmCounter('mash:missing', 1);\n        return;\n    }\n    P.when(MASH_API_NAME).execute((mash) => {\n        mash?.removeEventListener('obstructionsChanged', handler);\n    });\n};\n","import { incrementCsaCounter } from '@amzn/apejs-instrumentation/src/metrics/csa/events.js';\nimport { incrementCsmCounter } from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\n\nimport { getObstructions, getObstructionsResponse } from './getObstructions.js';\nimport { calculateObstructionPercentage, convertNativeElementToDomRect } from './nativeObstructionsUtils.js';\nimport {\n    addNativeObstructionsChangedListener,\n    ObstructionsChangedEventResponse,\n    removeNativeObstructionsChangedListener,\n} from './obstructionsEventListeners.js';\n\nexport interface NativeObstructionState {\n    metricsLogged: Set<string>;\n    listenerHandler?: (response: ObstructionsChangedEventResponse) => void;\n    setObstructingRectangles: (rects: DOMRect[]) => void;\n    getObstructingRectangles: () => DOMRect[];\n}\n\n/**\n * Measures the amount of the creative which is overlapped by native obstructions.\n * @param placementSafezoneDOMRect - The safezone DOMRect for the placement\n * @returns The percentage of the creative that is obstructed by native elements\n */\nexport const getNativeObstructionPercentage = (\n    placementSafezoneDOMRect: DOMRect,\n    nativeObstructionState: NativeObstructionState,\n): number => {\n    const obstructingRectangles = nativeObstructionState.getObstructingRectangles();\n    if (obstructingRectangles.length === 0) {\n        return 0;\n    }\n    const totalNativeObstruction = obstructingRectangles.reduce((total, rect) => {\n        return total + calculateObstructionPercentage(placementSafezoneDOMRect, rect);\n    }, 0);\n    return totalNativeObstruction;\n};\n\nexport const fetchNativeObstructions = async (nativeObstructionState: NativeObstructionState): Promise<void> => {\n    const aBitLessThan1Second = 950;\n    try {\n        nativeObstructionState.setObstructingRectangles([]);\n        if (!nativeObstructionState.listenerHandler) {\n            nativeObstructionState.listenerHandler = (response: ObstructionsChangedEventResponse) =>\n                nativeObstructionsChangedHandler(response, nativeObstructionState);\n            addNativeObstructionsChangedListener(nativeObstructionState.listenerHandler);\n        }\n        const obstructionsOutput = await getObstructions(aBitLessThan1Second);\n        nativeObstructionState.setObstructingRectangles(\n            getObstructionsRects(obstructionsOutput, nativeObstructionState),\n        );\n    } catch (err: any) {\n        logMetrics(err.message, nativeObstructionState);\n    }\n};\n\nconst nativeObstructionsChangedHandler = (\n    obstructionsChangedEventResponse: ObstructionsChangedEventResponse,\n    nativeObstructionState: NativeObstructionState,\n) => {\n    nativeObstructionState.setObstructingRectangles(\n        (obstructionsChangedEventResponse?.detail?.boundingBoxes || []).map(convertNativeElementToDomRect),\n    );\n};\n\nconst getObstructionsRects = (\n    response: getObstructionsResponse,\n    nativeObstructionState: NativeObstructionState,\n): DOMRect[] => {\n    if (response.isFullyObstructed) {\n        logMetrics('viewPixel:iab:obstruction:native:fullviewport', nativeObstructionState, 1);\n        return [convertNativeElementToDomRect({ height: window.innerHeight, top: 0 })];\n    }\n    emitGetObstructionsResponseMetrics(response.boundingBoxes, nativeObstructionState);\n    return response.boundingBoxes.map(convertNativeElementToDomRect);\n};\n\nconst logMetrics = (metricName: string, nativeObstructionState: NativeObstructionState, count = 1): void => {\n    if (!nativeObstructionState.metricsLogged.has(metricName)) {\n        incrementCsmCounter(metricName, count);\n        incrementCsaCounter(metricName, count);\n        nativeObstructionState.metricsLogged.add(metricName);\n    }\n};\n\nconst emitGetObstructionsResponseMetrics = (\n    boundingBoxes: DOMRect[],\n    nativeObstructionState: NativeObstructionState,\n): void => {\n    for (const boundingBox of boundingBoxes) {\n        logMetrics('mash:getobstructions:response:height', nativeObstructionState, boundingBox.height);\n        logMetrics('mash:getobstructions:response:top', nativeObstructionState, boundingBox.top);\n    }\n};\n\nexport const cleanupNativeObstructionsChangedListener = (nativeObstructionState: NativeObstructionState): void => {\n    if (nativeObstructionState.listenerHandler) {\n        try {\n            removeNativeObstructionsChangedListener(nativeObstructionState.listenerHandler);\n        } catch {\n            // Ignore errors specifically for when P is not defined (e.g., in browser test environments)\n        }\n        nativeObstructionState.listenerHandler = undefined;\n    }\n};\n","import { getDOMObstructionPercentage } from './domObstructions/getDOMObstructionPercentage.js';\nimport type { NativeObstructionState } from './nativeObstructions/getNativeObstructionPercentage.js';\nimport {\n    cleanupNativeObstructionsChangedListener,\n    fetchNativeObstructions,\n    getNativeObstructionPercentage,\n} from './nativeObstructions/getNativeObstructionPercentage.js';\nimport type { ObstructionDetectionService, ObstructionPercentageParams } from './obstructionDetectionService.js';\n\nexport const createObstructionDetectionService = (): ObstructionDetectionService => {\n    let obstructingRectangles: DOMRect[] = [];\n    const metricsLogged = new Set<string>();\n\n    const nativeObstructionState: NativeObstructionState = {\n        metricsLogged,\n        listenerHandler: undefined,\n        setObstructingRectangles: (rects: DOMRect[]) => {\n            obstructingRectangles = rects;\n        },\n        getObstructingRectangles: () => obstructingRectangles,\n    };\n\n    fetchNativeObstructions(nativeObstructionState);\n\n    return {\n        getObstructionPercentage({\n            element,\n            elementDOMRectOverride = element.getBoundingClientRect(),\n        }: ObstructionPercentageParams): number {\n            const domObstructionPercentage = getDOMObstructionPercentage(element, elementDOMRectOverride);\n            const nativeObstructionPercentage = getNativeObstructionPercentage(\n                elementDOMRectOverride,\n                nativeObstructionState,\n            );\n            return Math.max(domObstructionPercentage, nativeObstructionPercentage);\n        },\n        cleanup(): void {\n            cleanupNativeObstructionsChangedListener(nativeObstructionState);\n        },\n    };\n};\n","export const API_KEY: string = 'aUAZqFtiIp6VxqpW3coqZ2JdZnV3RN9S8yKMRIdJ';\n","import { API_KEY } from '@/components/metrics/awsMetricLoggerApiKey.js';\n\nexport const METRICS_ENDPOINT = 'https://qdbx3pbnx6veby23pzgaowu3q40tmmrr.lambda-url.us-east-1.on.aws';\nexport const STORAGE_KEY = 'APE_CW_METRICS';\nexport const BATCH_SIZE = 10;\n\nexport type PostMetricDTO = {\n    metrics: Metric[];\n    xApiKey: string;\n};\n\nexport type Metric = {\n    metricName: string;\n    timestamp: number;\n    value: number;\n    dimensions: Record<string, string>;\n};\n\nlet unloadHookRegistered = false;\n\n// Used for testing\nexport const resetUnloadHook = (): void => {\n    unloadHookRegistered = false;\n};\n\nexport const logMetric = (metric: Metric): void => {\n    if (!unloadHookRegistered) {\n        window.addEventListener('beforeunload', () => flushAndClear());\n        unloadHookRegistered = true;\n    }\n\n    const cache = getCache();\n    cache.push(metric);\n\n    if (cache.length >= BATCH_SIZE) {\n        flushCache(cache);\n    } else {\n        updateCache(cache);\n    }\n};\n\nconst getCache = (): Metric[] => {\n    const data = localStorage.getItem(STORAGE_KEY);\n    if (!data) return [];\n    try {\n        return JSON.parse(data) as Metric[];\n    } catch {\n        return [];\n    }\n};\n\nconst flushCache = (metrics: Metric[]): void => {\n    navigator.sendBeacon(METRICS_ENDPOINT, JSON.stringify(toPostMetricDTO(metrics)));\n    localStorage.removeItem(STORAGE_KEY);\n};\n\nconst toPostMetricDTO = (metrics: Metric[]): PostMetricDTO => ({\n    metrics: metrics,\n    xApiKey: API_KEY,\n});\n\nconst updateCache = (metrics: Metric[]): void => {\n    localStorage.setItem(STORAGE_KEY, JSON.stringify(metrics));\n};\n\nconst flushAndClear = (): void => {\n    const cache = getCache();\n    if (cache.length > 0) {\n        flushCache(cache);\n    }\n};\n","import type { Metric } from '@/components/metrics/awsMetricBatcher.js';\nimport { logMetric } from '@/components/metrics/awsMetricBatcher.js';\n\n/**\n * logMetric(), but ensure that the same metricName is only logged once per page load.\n */\nexport const logMetricOnce = (metric: Metric): void => {\n    if (!window.APE_SF) {\n        return;\n    }\n\n    // Initlialize the store if it doesn't exist\n    const store = (window.APE_SF.loggedMetricNames ??= new Set<string>());\n\n    if (store.has(metric.metricName)) {\n        return;\n    }\n\n    store.add(metric.metricName);\n\n    logMetric(metric);\n};\n","declare global {\n    // oxlint-disable-next-line\n    interface Window extends WeblabsWindow {}\n}\n\nexport type WeblabTreatment = `t${number}`;\n\nexport type AllWeblabTreatment = WeblabTreatment | 'c';\n\nexport interface WeblabsWindow {\n    renderingWeblabs?: { [key: string]: string };\n}\n\nexport interface Weblab {\n    is(treatment: WeblabTreatment): boolean;\n    isInTreatment(): boolean;\n    getTreatment(): AllWeblabTreatment;\n}\n\nexport const createWeblab = (weblabsWindow: WeblabsWindow, prefix: string): Weblab => {\n    const weblabTreatment = (): AllWeblabTreatment =>\n        weblabsWindow?.renderingWeblabs?.[prefix]?.toLowerCase() as AllWeblabTreatment;\n\n    return {\n        is(treatment: WeblabTreatment): boolean {\n            return weblabTreatment() === treatment;\n        },\n        isInTreatment(): boolean {\n            return !!weblabTreatment() && weblabTreatment() !== 'c';\n        },\n        getTreatment(): AllWeblabTreatment {\n            return weblabTreatment() ?? 'c';\n        },\n    };\n};\n\n/*\n * Used for gating IN art event styling\n * @link https://weblab.amazon.com/wl/ADPT_SF_HOMEPAGE_ART_THEMING_1298909\n */\nexport const ADPT_SF_HOMEPAGE_ART_THEMING = () => createWeblab(window, 'ADPT_SF_HOMEPAGE_ART_THEMING_1298909');\n\n/*\n * Used for sampling metrics logging at a low rate\n * @link https://weblab.amazon.com/wl/ADPT_SF_LOW_RATE_METRIC_LOGGING_1256362\n */\nexport const ADPT_SF_LOW_RATE_METRIC_LOGGING = () => createWeblab(window, 'ADPT_SF_LOW_RATE_METRIC_LOGGING_1256362');\n\n/**\n * Used to enable new retail tracking with the JRS test painter.\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_CLICK_TRACKING_PAINTER_TEST_1259727\n */\nexport const CLICK_TRACKING_PAINTER_TEST = () =>\n    createWeblab(window, 'APM_STORES_JPS_JRS_SAFEFRAME_CLICK_TRACKING_PAINTER_TEST_1259727');\n\n/**\n * Used to enable viewability-based impression pixel firing for CA, JP, and UK marketplaces.\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_VIEW_RATE_EXPERIMENT_1289633\n */\nexport const VIEW_RATE_EXPERIMENT = () =>\n    createWeblab(window, 'APM_STORES_JPS_JRS_SAFEFRAME_VIEW_RATE_EXPERIMENT_1289633');\n\n/**\n * Used to control timeout for placement viewability of Stores View Rate experiment in ES and FR marketplaces.\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_VIEW_RATE_EXPERIMENT_TIMEOUT_1373183\n */\nexport const VIEW_RATE_EXPERIMENT_TIMEOUT = () =>\n    createWeblab(window, 'APM_STORES_JPS_JRS_SAFEFRAME_VIEW_RATE_EXPERIMENT_TIMEOUT_1373183');\n\n/**\n * Used to disable user agent access for creatives\n * @link https://shepherd.a2z.com/issues/e4e8cd86-419a-4e1a-96ff-b20a6615b8b5\n */\nexport const DISABLE_USER_AGENT_WEBLAB = () =>\n    createWeblab(window, 'APM_STORES_JPS_JRS_SAFEFRAME_DISABLE_USER_AGENT_1326744');\n\n/**\n * Used to enable new viewability tracker implementation\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_NEW_VIEWABILITY_TRACKER_1354300\n */\nexport const NEW_VIEWABILITY_TRACKER_WEBLAB = () =>\n    createWeblab(window, 'APM_STORES_JPS_JRS_SAFEFRAME_NEW_VIEWABILITY_TRACKER_1354300');\n\n/**\n * Used to enable LightFrames on all eligible placement\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_LIGHT_ADS_EVERYWHERE_1362485\n */\nexport const LIGHT_ADS_EVERYWHERE_WEBLAB = () =>\n    createWeblab(window, 'APM_STORES_JPS_JRS_SAFEFRAME_LIGHT_ADS_EVERYWHERE_1362485');\n\n/**\n * Used to enable iframe ready retry mechanism for host message receiver\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_IFRAME_READY_RETRY_1374491\n */\nexport const IFRAME_READY_RETRY_WEBLAB = () =>\n    createWeblab(window, 'APM_STORES_JPS_JRS_SAFEFRAME_IFRAME_READY_RETRY_1374491');\n\n/**\n * Used to disable window.top\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_DISABLE_POSTMESSAGE_1327371\n */\nexport const DISABLE_POSTMESSAGE_WEBLAB = () =>\n    createWeblab(window, 'APM_STORES_JPS_JRS_SAFEFRAME_DISABLE_POSTMESSAGE_1327371');\n\n/**\n * Used to enable CSA metrics for safeframe\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_CSA_METRICS_1390278\n */\nexport const CSA_METRICS_WEBLAB = () => createWeblab(window, 'APM_STORES_JPS_JRS_SAFEFRAME_CSA_METRICS_1390278');\n","import type { AdDetails } from '@amzn/safeframe-model';\nimport type { LightAdDetails } from '@amzn/safeframe-model';\n\nimport type { Metric } from '@/components/metrics/awsMetricBatcher.js';\nimport { logMetric } from '@/components/metrics/awsMetricBatcher.js';\nimport { logMetricOnce } from '@/components/metrics/logMetricOnce.js';\nimport { ADPT_SF_LOW_RATE_METRIC_LOGGING } from '@/components/weblabs.js';\n\ntype MetricInputBase = {\n    /**\n     * The name of the metric to log. Use colon (:) to separate metric components. E.g., \"asset:load:timing\"\n     */\n    metricName: string;\n    /**\n     * Number of occurrences to log. Defaults to 1.\n     */\n    count?: number;\n    /**\n     * Additional dimensions to add to the metric. These will be merged with the default dimensions.\n     */\n    additionalDimensions?: Record<string, string>;\n    /**\n     * Whether the metric should only be logged once per page load\n     */\n    once?: boolean;\n};\n\ntype MetricInputSF = MetricInputBase & {\n    adDetails: AdDetails;\n};\n\ntype MetricInputLA = MetricInputBase & {\n    lightAdDetails: LightAdDetails;\n};\n\n/**\n * @deprecated This is not live yet. Don't use.\n * SIM: https://sim.amazon.com/issues/CPP-39529\n */\nexport const logLowRateMetricSF = ({\n    metricName,\n    adDetails,\n    count = 1,\n    additionalDimensions = {},\n    once = false,\n}: MetricInputSF): void => {\n    if (ADPT_SF_LOW_RATE_METRIC_LOGGING().is('t1')) {\n        const logFn = once ? logMetricOnce : logMetric;\n        logFn(toMetric(metricName, count, toSFDimensions(adDetails, additionalDimensions)));\n    }\n};\n\n/**\n * @deprecated This is not live yet. Don't use.\n * SIM: https://sim.amazon.com/issues/CPP-39529\n */\nexport const logLowRateMetricLA = ({\n    metricName,\n    lightAdDetails,\n    count = 1,\n    additionalDimensions = {},\n}: MetricInputLA): void => {\n    if (ADPT_SF_LOW_RATE_METRIC_LOGGING().is('t1')) {\n        logMetric(toMetric(metricName, count, toLADimensions(lightAdDetails, additionalDimensions)));\n    }\n};\n\nconst toMetric = (metricName: string, count: number, dimensions: Record<string, string>): Metric => ({\n    metricName: metricName,\n    timestamp: new Date().getTime(),\n    value: count,\n    dimensions: dimensions,\n});\n\nconst toSFDimensions = (adDetails: AdDetails, additionalDimensions: Record<string, string>): Record<string, string> => {\n    return {\n        app: 'SF',\n        siteName: adDetails.siteName,\n        slotName: adDetails.slotName,\n        pageType: adDetails.pageType,\n        placementId: adDetails.placementId,\n        mediaType: adDetails.mediaType,\n        programId: adDetails.adCreativeMetaData?.adProgramId,\n        creativeTemplateName: adDetails.adCreativeMetaData?.adCreativeTemplateName,\n        deviceType: adDetails.deviceType,\n        ...additionalDimensions,\n    };\n};\n\nconst toLADimensions = (\n    adDetails: LightAdDetails,\n    additionalDimensions: Record<string, string> | undefined,\n): Record<string, string> => {\n    return {\n        app: 'LA',\n        siteName: adDetails.siteName,\n        slotName: adDetails.slotName,\n        pageType: adDetails.pageType,\n        placementId: adDetails.placementId,\n        mediaType: adDetails.videoCreative ? 'V' : 'D',\n        programId: adDetails.adCreativeMetaData?.adProgramId,\n        creativeTemplateName: adDetails.adCreativeMetaData?.adCreativeTemplateName,\n        deviceType: adDetails.deviceType,\n        ...additionalDimensions,\n    };\n};\n","import type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport { logLowRateMetricLA, logLowRateMetricSF } from '@/components/metrics/awsMetricLogger.js';\n\ntype SetupIntersectionObserverParams = {\n    target: Element;\n    onIntersection: (observer: IntersectionObserver, entry: IntersectionObserverEntry) => void;\n    onExit: (observer: IntersectionObserver, entry: IntersectionObserverEntry) => void;\n    options?: IntersectionObserverInit;\n    adDetails?: AdDetails;\n    lightAdDetails?: LightAdDetails;\n};\n\nexport const setupIntersectionObserver = ({\n    target,\n    onIntersection,\n    onExit,\n    options,\n    adDetails,\n    lightAdDetails,\n}: SetupIntersectionObserverParams): IntersectionObserver => {\n    const observer = new IntersectionObserver((entries, observer) => {\n        entries.forEach((entry) => {\n            if (entry.isIntersecting) {\n                onIntersection(observer, entry);\n            } else {\n                onExit(observer, entry);\n            }\n        });\n    }, options);\n\n    if (!(target instanceof Element)) {\n        if (adDetails) {\n            logLowRateMetricSF({\n                metricName: 'intersection:observer:invalid:target',\n                adDetails,\n                additionalDimensions: { targetType: typeof target },\n            });\n        } else if (lightAdDetails) {\n            logLowRateMetricLA({\n                metricName: 'intersection:observer:invalid:target',\n                lightAdDetails,\n                additionalDimensions: { targetType: typeof target },\n            });\n        }\n    }\n\n    observer.observe(target);\n    return observer;\n};\n\nexport const observeUntilIntersection = async (\n    target: Element,\n    options?: IntersectionObserverInit,\n): Promise<IntersectionObserverEntry> => {\n    return new Promise<IntersectionObserverEntry>((resolve) => {\n        return setupIntersectionObserver({\n            target,\n            onIntersection: (observer, entry) => {\n                resolve(entry);\n                observer.unobserve(entry.target);\n            },\n            onExit: () => {},\n            options,\n        });\n    });\n};\n","import {\n    incrementCsaCounter,\n    incrementCsaPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csa/events.js';\nimport {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport { logFatal } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport { setupIntersectionObserver } from '@/components/intersectionObserver.js';\nimport type { FirePixel } from '@/components/pixels/firePixel.js';\nimport type { Placement } from '@/components/pixels/pixel.js';\nimport type { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.js';\nimport type { ViewabilityService } from '@/components/pixels/services/viewabilityService.js';\nimport type { VisibilityChangeService } from '@/components/pixels/services/visibilityChangeService.js';\nimport type { ViewabilityStandard } from '@/components/pixels/viewabilityStandards.js';\nimport type { ViewPixel } from '@/components/pixels/viewPixel.js';\n\nexport class MRCObstructionViewPixel implements ViewPixel, FirePixel {\n    private viewTimerTimeoutId?: NodeJS.Timeout;\n    private obstructionCheckIntervalId?: NodeJS.Timeout;\n    private shouldFirePixelIntervalId?: NodeJS.Timeout;\n    private metricsLogged: Set<string> = new Set();\n    private wasObstructed: boolean = false;\n\n    constructor(\n        private readonly pixel: FirePixel,\n        readonly viewabilityStandard: ViewabilityStandard,\n        readonly visibilityChangeService: VisibilityChangeService,\n        private readonly viewabilityService: ViewabilityService,\n        private readonly videoPixelValidator: FirePixelValidator | undefined,\n        private readonly adDetails?: AdDetails,\n        private readonly lightAdDetails?: LightAdDetails,\n    ) {}\n\n    postPixelFireCleanup(observer: IntersectionObserver, placement: Placement) {\n        observer.unobserve(placement.div);\n        clearTimeout(this.viewTimerTimeoutId);\n        clearInterval(this.obstructionCheckIntervalId);\n        this.visibilityChangeService.removeVisibilityChangeDetection();\n        this.emitObstructionRecoveryMetrics(placement);\n        this.viewabilityService.cleanup();\n    }\n\n    postPlacementExitsViewportCleanup() {\n        clearTimeout(this.viewTimerTimeoutId);\n        clearInterval(this.obstructionCheckIntervalId);\n        clearInterval(this.shouldFirePixelIntervalId);\n        this.visibilityChangeService.removeVisibilityChangeDetection();\n    }\n\n    fireInObserver(observer: IntersectionObserver, placement: Placement): void {\n        this.fire(placement);\n        this.postPixelFireCleanup(observer, placement);\n    }\n\n    startInViewTimer(observer: IntersectionObserver, placement: Placement) {\n        // set view timer for threshold time\n        this.viewTimerTimeoutId = setTimeout(\n            () => this.fireInObserver(observer, placement),\n            this.viewabilityStandard.thresholdTimeVisibleMs,\n        );\n\n        this.performContinuousObstructionCheck(observer, placement);\n        this.visibilityChangeService.setupVisibilityChangeDetection(this.viewTimerTimeoutId, observer, placement);\n    }\n\n    // Start continously checking for obstruction every 100ms. Resets timeouts and intervals if viewability obstruction occurs\n    performContinuousObstructionCheck(observer: IntersectionObserver, placement: Placement) {\n        const intervalMs: number = 100;\n        this.obstructionCheckIntervalId = setInterval(() => {\n            try {\n                const isViewabilityObstructed = this.viewabilityService.isViewabilityObstructed(\n                    placement,\n                    this.viewabilityStandard.thresholdPercentage,\n                );\n                if (isViewabilityObstructed) {\n                    this.wasObstructed = true;\n                    clearTimeout(this.viewTimerTimeoutId);\n                    clearInterval(this.obstructionCheckIntervalId);\n                    this.startInViewTimer(observer, placement);\n                }\n            } catch (error: any) {\n                logFatal(error?.message, error);\n                clearInterval(this.obstructionCheckIntervalId);\n            }\n        }, intervalMs);\n    }\n\n    track(placement: Placement): void {\n        setupIntersectionObserver({\n            target: placement.div,\n            onIntersection: (observer) => this.startInViewTimer(observer, placement),\n            onExit: () => this.postPlacementExitsViewportCleanup(),\n            options: { threshold: this.viewabilityStandard.thresholdPercentage },\n            adDetails: this.adDetails,\n            lightAdDetails: this.lightAdDetails,\n        });\n    }\n\n    async fire(placement: Placement): Promise<void> {\n        if (this.videoPixelValidator && !this.videoPixelValidator.shouldFirePixel()) {\n            await this.waitUntilShouldFirePixel();\n        }\n\n        this.pixel.fire(placement);\n    }\n\n    private waitUntilShouldFirePixel(): Promise<void> {\n        return new Promise((resolve) => {\n            this.shouldFirePixelIntervalId = setInterval(() => {\n                if (this.videoPixelValidator && this.videoPixelValidator.shouldFirePixel()) {\n                    clearInterval(this.shouldFirePixelIntervalId);\n                    resolve();\n                }\n            }, 100);\n        });\n    }\n\n    emitObstructionRecoveryMetrics = (placement: Placement): void => {\n        if (this.wasObstructed) {\n            this.logMetrics('viewpixel:iab:obstruction:recovered', 1, placement);\n        }\n    };\n\n    logMetrics = (metricName: string, count = 1, placement?: Placement): void => {\n        if (!this.metricsLogged.has(metricName)) {\n            incrementCsmCounter(metricName, count);\n            incrementCsaCounter(metricName, count);\n            if (placement) {\n                incrementCsmPlacementCounter(metricName, placement, count);\n                incrementCsaPlacementCounter(metricName, placement, count);\n            }\n            this.metricsLogged.add(metricName);\n        }\n    };\n}\n","import type { FirePixel } from '@/components/pixels/firePixel.js';\nimport type { PixelIdentifier } from '@/components/pixels/pixelIdentifiers.js';\nimport type { PixelUrlGenerator } from '@/components/pixels/pixelUrlGenerator.js';\nimport type { PixelLogger } from '@/components/pixels/services/pixelLogger.js';\nimport type { Creative } from '@/light-ad/domain/model/creative.js';\n\nconst requestOptions: RequestInit = { keepalive: true, mode: 'no-cors' } as const;\n\n/**\n * TODO: Update/Clean up the Placement type\n * SIM: https://sim.amazon.com/issues/CPP-40575\n */\nexport type Placement = {\n    readonly id: string;\n    readonly name: string;\n    readonly div: HTMLElement;\n    readonly deviceType: string;\n    readonly creative?: Creative;\n};\n\nexport type LoggingContext = {\n    aaxProgramId: number;\n};\n\nexport class Pixel implements FirePixel {\n    protected isFired: boolean = false;\n\n    constructor(\n        private readonly url: string,\n        private readonly loggingContext: LoggingContext,\n        private readonly generatePixelUrl: PixelUrlGenerator,\n        private readonly pixelIdentifier: PixelIdentifier,\n        private readonly pixelLogger: PixelLogger,\n        private readonly urls3p: string[] = [],\n    ) {}\n\n    public async fire(placement: Placement): Promise<void> {\n        if (this.isFired) return;\n        await fetch(this.generatePixelUrl(this.url, placement), requestOptions);\n        placement.div.appendChild(this.pixel(placement));\n        this.isFired = true;\n        this.pixelLogger(this.pixelIdentifier, this.loggingContext, placement);\n\n        // Do not await for 3P URLs as rendering the ad doesn't depend on successful firing\n        this.urls3p.forEach((url3p) => fetch(url3p, requestOptions));\n    }\n\n    /**\n     * This pixel is used by the UI Tests\n     * No src is set, as the pixel is fired by a fetch\n     */\n    private pixel = (placement: Placement): HTMLImageElement => {\n        const pixel = document.createElement('img');\n        pixel.id = `${this.pixelIdentifier.testId}_${placement.name}`;\n        pixel.style.display = 'none';\n        pixel.setAttribute('pixel-url', this.generatePixelUrl(this.url, placement));\n        return pixel;\n    };\n}\n","export type PixelIdentifier = {\n    readonly testId: string;\n    readonly csmLogId: string;\n};\n\nexport const BTR_IDENTIFIER: PixelIdentifier = { testId: 'ape_btr_impression', csmLogId: 'imp:btr' } as const;\nexport const IMPRESSION_IDENTIFIER: PixelIdentifier = { testId: 'ape_impression', csmLogId: 'imp:cod' } as const;\nexport const MEASURABILITY_IDENTIFIER: PixelIdentifier = { testId: 'ape_measurability', csmLogId: 'imp:atf' } as const;\nexport const SKAN_IMPRESSION_IDENTIFIER: PixelIdentifier = { testId: 'ape_impression', csmLogId: 'imp:skan' } as const;\nexport const SKAN_VIEW_IDENTIFIER: PixelIdentifier = { testId: 'skan_view_pixel', csmLogId: 'view:skan' } as const;\nexport const IAB_VIEWABILITY_IDENTIFIER: PixelIdentifier = {\n    testId: 'ape_viewability_iab',\n    csmLogId: 'view:iab',\n} as const;\n","import {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\n\nimport type { LoggingContext, Placement } from '@/components/pixels/pixel.js';\nimport type { PixelIdentifier } from '@/components/pixels/pixelIdentifiers.js';\n\nexport interface PixelLogger {\n    (pixelIdentifier: PixelIdentifier, loggingContext: LoggingContext, placement: Placement): void;\n}\n\nexport const logPixelFired =\n    (\n        csmCounter: typeof incrementCsmCounter = incrementCsmCounter,\n        csmPlacementCounter: typeof incrementCsmPlacementCounter = incrementCsmPlacementCounter,\n    ): PixelLogger =>\n    (pixelIdentifier, loggingContext, placement) => {\n        csmCounter(`pixel:${pixelIdentifier.csmLogId}`);\n        csmPlacementCounter(`pixel:${pixelIdentifier.csmLogId}`, placement);\n        csmCounter(`pixel:${pixelIdentifier.csmLogId}:${loggingContext.aaxProgramId}`);\n        csmCounter(`pixel:${pixelIdentifier.csmLogId}:device:${placement.deviceType?.toLowerCase()}`);\n    };\n","/**\n * Calculates what percentage of the element is within the viewport\n * @param safezoneDOMRect - The safezone DOMRect. Use {@link getPlacementSafezoneDOMRect} to get this value.\n * @returns a number between 0 and 1\n */\nexport const getVisiblePercentageInViewport = (safezoneDOMRect: DOMRect): number => {\n    const windowHeight = window.innerHeight || document.documentElement.clientHeight;\n    const windowWidth = window.innerWidth || document.documentElement.clientWidth;\n\n    const visibleRect = {\n        top: Math.max(0, safezoneDOMRect.top),\n        left: Math.max(0, safezoneDOMRect.left),\n        bottom: Math.min(windowHeight, safezoneDOMRect.bottom),\n        right: Math.min(windowWidth, safezoneDOMRect.right),\n    };\n\n    if (\n        safezoneDOMRect.top >= windowHeight ||\n        safezoneDOMRect.left >= windowWidth ||\n        safezoneDOMRect.bottom <= 0 ||\n        safezoneDOMRect.right <= 0 ||\n        safezoneDOMRect.width <= 0 ||\n        safezoneDOMRect.height <= 0\n    ) {\n        return 0;\n    }\n\n    const visibleArea = (visibleRect.right - visibleRect.left) * (visibleRect.bottom - visibleRect.top);\n    const totalArea = safezoneDOMRect.width * safezoneDOMRect.height;\n    const visiblePercentage = visibleArea / totalArea;\n    return visiblePercentage;\n};\n","import type { Placement } from '@/components/pixels/pixel.js';\n\n/**\n * H1's Safezone height and width with pixel count on Slide 15 of 27: @see https://amazon.awsapps.com/workdocs-amazon/index.html#/document/46972fcf864af9e6705e7469a0eec0082c54309b3f9af0c70c29af043352593d\n * @see https://design.amazon.com/styleguide/724BA9F0B089/homepage-design-guidelines/desktop-guidelines/desktop-tall-hero/#J83rKGvredLMM7\n */\nexport const SAFEZONE = {\n    H1_DESKTOP_HEIGHT: 240,\n    H1_DESKTOP_WIDTH: 940,\n} as const;\n\ntype Dimensions = {\n    height: number;\n    width: number;\n};\n\n/**\n * Returns the placement's safezone DOMRect.\n * @param placement\n * @returns The placement's safezone DOMRect to use for viewability and obstruction check\n */\nexport const getPlacementSafezoneDOMRect = (placement: Placement): DOMRect => {\n    if (isH1SafezoneEdgeCase(placement)) {\n        const dimensions: Dimensions = {\n            height: SAFEZONE.H1_DESKTOP_HEIGHT,\n            width: SAFEZONE.H1_DESKTOP_WIDTH,\n        };\n        return getUpdatedDOMRect(placement.div, dimensions);\n    }\n    return placement.div.getBoundingClientRect();\n};\n\n/**\n * Check if the placement is H1 Desktop, which is currently known to need special safe zone handling\n * @param placement\n * @returns True if the placement is an edgecase to require a special safezone.\n */\nexport const isH1SafezoneEdgeCase = (placement: Placement): boolean => {\n    const placementName = placement.name.toLowerCase();\n    const H1_DESKTOP_PLACEMENT_NAME = 'gateway_desktop-h1_desktop';\n    return placementName === H1_DESKTOP_PLACEMENT_NAME;\n};\n\n/**\n * Calculates a new DOMRect with updated dimensions while maintaining the vertical position\n * and horizontal center of the original element.\n * @param element - The HTML element to base the calculation on\n * @param newDimensions - The desired Dimensions (width and height) for the new DOMRect\n * @returns A new DOMRect with the specified Dimensions\n */\nexport const getUpdatedDOMRect = (element: HTMLElement, newDimensions: Dimensions): DOMRect => {\n    const originalDOMRect = element.getBoundingClientRect();\n    const center = (originalDOMRect.left + originalDOMRect.right) / 2;\n    const newX = center - newDimensions.width / 2;\n    return new DOMRect(newX, originalDOMRect.y, newDimensions.width, newDimensions.height);\n};\n","import {\n    incrementCsaCounter,\n    incrementCsaPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csa/events.js';\nimport {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport type { ObstructionDetectionService } from '@amzn/creative-obstruction-detection/src/obstructionDetectionService.js';\n\nimport type { Placement } from '@/components/pixels/pixel.js';\nimport type { ViewabilityService } from '@/components/pixels/services/viewabilityService.js';\nimport { getVisiblePercentageInViewport } from '@/components/pixels/viewPixelUtil.js';\nimport { getPlacementSafezoneDOMRect } from '@/host/slotSpecific/placementSafezone.js';\n\nexport const createViewabilityService = (\n    obstructionDetectionService: ObstructionDetectionService,\n): ViewabilityService => {\n    const metricsLogged: Set<string> = new Set();\n\n    const logMetrics = (metricName: string, count = 1, placement?: Placement): void => {\n        if (!metricsLogged.has(metricName)) {\n            incrementCsmCounter(metricName, count);\n            incrementCsaCounter(metricName, count);\n            if (placement) {\n                incrementCsmPlacementCounter(metricName, placement, count);\n                incrementCsaPlacementCounter(metricName, placement, count);\n            }\n            metricsLogged.add(metricName);\n        }\n    };\n\n    const isViewabilityObstructed = (placement: Placement, threshold: number): boolean => {\n        const placementSafezoneDOMRect = getPlacementSafezoneDOMRect(placement);\n        const visiblePercentageInViewport = getVisiblePercentageInViewport(placementSafezoneDOMRect);\n        const obstructionPercentage = obstructionDetectionService.getObstructionPercentage({\n            element: placement.div,\n            elementDOMRectOverride: placementSafezoneDOMRect,\n        });\n\n        const isViewabilityObstructed = visiblePercentageInViewport - obstructionPercentage < threshold;\n        if (isViewabilityObstructed) {\n            logMetrics('viewpixel:iab:obstruction', 1, placement);\n        }\n        return isViewabilityObstructed;\n    };\n\n    return {\n        isViewabilityObstructed(placement: Placement, threshold: number): boolean {\n            return isViewabilityObstructed(placement, threshold);\n        },\n        cleanup(): void {\n            obstructionDetectionService.cleanup();\n        },\n    };\n};\n","import type { Placement } from '@/components/pixels/pixel.js';\n\nexport interface VisibilityChangeService {\n    activeVisChangeHandler?: EventListenerOrEventListenerObject;\n    removeVisibilityChangeDetection(): void;\n    setupVisibilityChangeDetection: (\n        timeoutId: NodeJS.Timeout,\n        observer: IntersectionObserver,\n        placement: Placement,\n    ) => void;\n}\n\nexport const createVisibiltyChangeService = (): VisibilityChangeService => {\n    const visibilityChangeEventHandler = (\n        timeoutId: NodeJS.Timeout,\n        observer: IntersectionObserver,\n        placement: Placement,\n    ) => {\n        if (document.hidden) {\n            clearTimeout(timeoutId);\n            observer.unobserve(placement.div);\n        } else {\n            observer.observe(placement.div);\n        }\n    };\n\n    return {\n        removeVisibilityChangeDetection(): void {\n            if (this.activeVisChangeHandler) {\n                document.removeEventListener('visibilitychange', this.activeVisChangeHandler);\n                this.activeVisChangeHandler = undefined;\n            }\n        },\n\n        setupVisibilityChangeDetection(\n            timeoutId: NodeJS.Timeout,\n            observer: IntersectionObserver,\n            placement: Placement,\n        ): void {\n            this.removeVisibilityChangeDetection();\n            this.activeVisChangeHandler = () => visibilityChangeEventHandler(timeoutId, observer, placement);\n            document.addEventListener('visibilitychange', this.activeVisChangeHandler);\n        },\n    };\n};\n","import type { SKAdNetwork } from '@amzn/safeframe-model';\n\n/**\n * Wrapper functions for MASH Extension API - SKAN App Ads Plugin\n * https://tiny.amazon.com/rrn9ljkr\n */\ntype SkanAttributePluginCommand = {\n    skAdNetwork: SKAdNetwork;\n};\n\ntype SkanAttributeClickCommand = {\n    skAdNetwork: SKAdNetwork;\n    fallbackUrl: string;\n};\n\nexport type SkanAttributePlugin = {\n    startAttributeViewThroughAppAds: (command: SkanAttributePluginCommand) => void;\n    endAttributeViewThroughAppAds: (command: SkanAttributePluginCommand) => void;\n    renderClickThroughAppAds: (command: SkanAttributeClickCommand) => void;\n};\n\nexport const skanAttributePluginName = 'AppAdsMshopIOSPlugin';\n\n/**\n * @func startAttributeViewThroughAppAds\n * @desc Wrapper function for MASH Extension API - SKAN App Ads Plugin, handles startImpression attribution for App Ads with SKAdNetwork.\n *       This function is called when the ad is rendered.\n * @param skAdNetwork object is using  call SKAN API.\n */\nexport const startAttributeViewThroughAppAds = (skAdNetwork: SKAdNetwork): void => {\n    window.P?.when(skanAttributePluginName).execute((skanAttributePlugin: SkanAttributePlugin) => {\n        skanAttributePlugin.startAttributeViewThroughAppAds({ skAdNetwork: skAdNetwork });\n    });\n};\n\n/**\n * @func endAttributeViewThroughAppAds\n * @desc Wrapper function for MASH Extension API - SKAN App Ads Plugin, handles endImpression attribution for App Ads with SKAdNetwork.\n *       This function is called when the ad is viewed continuously for 2 secs\n *       (https://developer.apple.com/documentation/storekit/skadnetwork/endimpression(_:completionhandler:)?language=objc).\n * @param skAdNetwork {object} SKAdNetwork object pass to MASH API for app ads\n */\nexport const endAttributeViewThroughAppAds = (skAdNetwork: SKAdNetwork): void => {\n    window.P?.when(skanAttributePluginName).execute((skanAttributePlugin: SkanAttributePlugin) => {\n        skanAttributePlugin.endAttributeViewThroughAppAds({ skAdNetwork: skAdNetwork });\n    });\n};\n\n/**\n * @func renderClickThroughAppAds\n * @desc Wrapper function for MASH Extension API - SKAN App Ads Plugin, handles click-through attribution for App Ads with SKAdNetwork\n * @param skAdNetwork {?object} SK Ad Network object pass to MASH API for app ads click-through store-kit render\n * @param url {string} The fallback url used to pass to MASH API\n */\nexport const renderClickThroughAppAds = (skAdNetwork: SKAdNetwork, url: string): void => {\n    window.P?.when(skanAttributePluginName).execute((skanAttributePlugin: SkanAttributePlugin) => {\n        skanAttributePlugin.renderClickThroughAppAds({ skAdNetwork: skAdNetwork, fallbackUrl: url });\n    });\n};\n","import type { SKAdNetwork } from '@amzn/safeframe-model';\n\nimport type { FirePixel } from '@/components/pixels/firePixel.js';\nimport type { LoggingContext, Placement } from '@/components/pixels/pixel.js';\nimport { SKAN_IMPRESSION_IDENTIFIER } from '@/components/pixels/pixelIdentifiers.js';\nimport type { PixelLogger } from '@/components/pixels/services/pixelLogger.js';\nimport { startAttributeViewThroughAppAds } from '@/components/skadnetwork/skanAppAdsAttribution.js';\n\nexport class SkanImpressionPixel implements FirePixel {\n    private isFired: boolean = false;\n\n    constructor(\n        private readonly loggingContext: LoggingContext,\n        private readonly skAdNetwork: SKAdNetwork,\n        private readonly pixelLogger: PixelLogger,\n    ) {}\n\n    async fire(placement: Placement): Promise<void> {\n        if (this.isFired) {\n            return;\n        }\n\n        startAttributeViewThroughAppAds(this.skAdNetwork);\n        this.isFired = true;\n        this.pixelLogger(SKAN_IMPRESSION_IDENTIFIER, this.loggingContext, placement);\n    }\n}\n","import type { SKAdNetwork } from '@amzn/safeframe-model';\n\nimport type { FirePixel } from '@/components/pixels/firePixel.js';\nimport type { LoggingContext, Placement } from '@/components/pixels/pixel.js';\nimport { SKAN_VIEW_IDENTIFIER } from '@/components/pixels/pixelIdentifiers.js';\nimport type { PixelLogger } from '@/components/pixels/services/pixelLogger.js';\nimport { endAttributeViewThroughAppAds } from '@/components/skadnetwork/skanAppAdsAttribution.js';\n\nexport class SkanViewPixel implements FirePixel {\n    protected isFired: boolean = false;\n\n    constructor(\n        private readonly loggingContext: LoggingContext,\n        private readonly pixelLogger: PixelLogger,\n        private readonly skAdNetwork: SKAdNetwork,\n    ) {}\n\n    async fire(placement: Placement): Promise<void> {\n        if (this.isFired) {\n            return;\n        }\n\n        endAttributeViewThroughAppAds(this.skAdNetwork);\n        this.isFired = true;\n        this.pixelLogger(SKAN_VIEW_IDENTIFIER, this.loggingContext, placement);\n    }\n}\n","/**\n * measurementMethod will be an enum used for reporting purposes with following possible values\n *  * btr_client\n *  * btr_server\n *  * cod_client\n *  * cod_server\n *  * coi_client\n *  * coi_server\n *  * unknown (default option)\n * cod = Count on download: Creative html/script/tag/assets are requested by the client device.\n * coi = Count on Insertion: Represents counting at time of won bid / ad serve prior to download request by client.\n * btr = Begin to render: Creative assets are loaded and begin to render\n *\n */\nexport const BEGIN_TO_RENDER_CLIENT = 'btr_client' as const;\nexport const COUNT_ON_DOWNLOAD_CLIENT = 'cod_client' as const;\n\nexport type MEASUREMENT_METHODS = typeof BEGIN_TO_RENDER_CLIENT | typeof COUNT_ON_DOWNLOAD_CLIENT;\n","export const ATF_URL_KEY = 'atf' as const;\nexport const VIEW_PIXEL_URL_KEY = 'v' as const;\nexport const PUBLISHER_JSON_KEY = 'pj' as const;\nexport const BTR_JSON_KEY = 'c' as const;\nexport const aaxTypeMacro = /\\${AAX_TYPE}/;\nexport const aaxPayloadMacro = /\\${AAX_PAYLOAD}/;\n","const EMPTY_OBJECT_STRINGIFIED = '{}' as const;\nconst EMPTY_STRING = '' as const;\n\n/**\n * This function adds a query parameter to the given URL where the value is a JSON.\n * The most common use-case is addition of `publisherJSON` to AAX URLs. eg: https://evergreen.corp.amazon.com/aax-hub/apis/bid-api/xsp/#impression\n * If the existing URL already contains this parameter key, the two JSONs are merged based on the top-level keys.\n * In case of a conflict, priority is given to the new JSON.\n *\n * eg:\n * 1. If url contains json {\"key1\": \"value1\"}, and queryParamValueObject contains {\"key1\":\"value2\"}, priority is given to queryParamValueObject.\n *    Final json is {\"key1\":\"value2\"}\n * 2. If url contains json {\"key1\": \"value1\"}, and queryParamValueObject contains {\"key2\":\"value2\"}, JSONs are merged.\n *    Final json is {\"key1\":\"value1\", \"key2\":\"value2\"}\n *\n * @param {string} url - URL where query param needs to be added.\n * @param {string} queryParamKey - key of query param that needs to be added.\n * @param {Object} queryParamValueObject - value of query param that needs to be added.\n * @returns {string} URL with query param added.\n * @throws Error if invalid inputs are provided.\n **/\nexport const addJSONQueryParamToURL = (\n    url: string,\n    queryParamKey: string,\n    queryParamValueObject: { [key: string]: any },\n): string => {\n    if (queryParamKey === EMPTY_STRING) {\n        throw new Error(\n            'Invalid queryParamKey input to addJSONQueryParamToURL: ' +\n                JSON.stringify({ queryParamKey: queryParamKey }),\n        );\n    }\n    const urlObject = new URL(url);\n    const pk = urlObject.searchParams.get(queryParamKey);\n    const existingJSONString = pk ? pk : EMPTY_OBJECT_STRINGIFIED;\n    const existingJSONObject = JSON.parse(existingJSONString);\n    const mergedJSONObject = Object.assign(existingJSONObject, queryParamValueObject);\n    urlObject.searchParams.set(queryParamKey, JSON.stringify(mergedJSONObject));\n    return urlObject.toString();\n};\n","import { BEGIN_TO_RENDER_CLIENT } from '@/client/api/client/measurementMethods.js';\nimport { BTR_JSON_KEY } from '@/components/aax/aax.js';\nimport type { PixelUrlGenerator } from '@/components/pixels/pixelUrlGenerator.js';\nimport { addJSONQueryParamToURL } from '@/components/urlQueryParams/addJSONQueryParamToURL.js';\nimport { removeAAXPayloadFromUrl } from '@/components/util.js';\n\nexport const generateBtrPixelUrl: PixelUrlGenerator = (url: string): string =>\n    // Remove removeAAXPayloadFromUrl when https://issues.amazon.com/issues/V1533734779 is resolved.\n    addJSONQueryParamToURL(removeAAXPayloadFromUrl(url), BTR_JSON_KEY, {\n        measurementMethod: BEGIN_TO_RENDER_CLIENT,\n    });\n","import { COUNT_ON_DOWNLOAD_CLIENT } from '@/client/api/client/measurementMethods.js';\nimport { PUBLISHER_JSON_KEY } from '@/components/aax/aax.js';\nimport type { PixelUrlGenerator } from '@/components/pixels/pixelUrlGenerator.js';\nimport { addJSONQueryParamToURL } from '@/components/urlQueryParams/addJSONQueryParamToURL.js';\n\nexport const generateImpressionPixelUrl: PixelUrlGenerator = (url: string): string => {\n    const isPaets = url.includes('.paets.');\n    return addJSONQueryParamToURL(\n        url,\n        PUBLISHER_JSON_KEY,\n        isPaets ? {} : { measurementMethod: COUNT_ON_DOWNLOAD_CLIENT },\n    );\n};\n","import type {\n    ExpectedDistanceAvailableForExpansion,\n    SelfRelativeAndInView,\n    WindowBoundaries,\n} from '@amzn/safe-frame-client';\n\ninterface Location {\n    readonly t: number;\n    readonly l: number;\n    readonly r: number;\n    readonly b: number;\n    readonly w: number;\n    readonly h: number;\n    readonly z: number;\n}\n\n/*\n    Method for returning the parent window's height\n*/\nexport const windowHeight = () => {\n    return window.innerHeight || document.documentElement.clientHeight;\n};\n\n/*\n    Method for returning the parent window's width\n*/\nexport const windowWidth = () => {\n    return window.innerWidth || document.documentElement.clientWidth;\n};\n\n/*\n    Method for determining the distance of the top of the ad from the viewport.\n    Positive if ad is below the viewport, Negative if ad is in / above the viewport.\n*/\nexport const findDistanceFromViewport = (elem: HTMLElement) => {\n    const boundingRect = elem.getBoundingClientRect();\n    return boundingRect.top - windowHeight();\n};\n\nexport const convertBoundingClientRectToLocation = (boundingRect: DOMRect, z: number): Location => {\n    return {\n        t: boundingRect.top,\n        l: boundingRect.left,\n        r: boundingRect.right,\n        b: boundingRect.bottom,\n        w: boundingRect.width,\n        h: boundingRect.height,\n        z: z,\n    };\n};\n\n/*\n    Computes the location attributes of the element.\n*/\nexport const getElementLocation = (elem: HTMLElement): Location => {\n    const boundingRect = elem.getBoundingClientRect();\n    return convertBoundingClientRectToLocation(boundingRect, Number(window.getComputedStyle(elem, null).zIndex));\n};\n\n/*\n    Identifies the z-index and location, width, and height (in pixels) of an DOM element relative\n    to the browser or application window (win). In addition, width, height, and area percentage of\n    SafeFrame content in view is provided, based on how much of the container is located within the\n    boundaries of the browser or application window (win).\n    • {Number} t\n        The y coordinate (in pixels) of the top boundary of the SafeFrame container\n    • {Number} l\n        The x coordinate (in pixels) of the left side boundary of the SafeFrame container\n    • {Number} r\n        The x coordinate (in pixels) of the right side boundary of the SafeFrame container (self.l +\n        width of container)\n    • {Number} b\n        The y coordinate (in pixels) of the bottom boundary of the SafeFrame container (self.t +\n        height of container)\n    • {Number} xiv\n        The percentage (%) of width for the SafeFrame container that is in view (formatted as\n        \"0.14\" or \"1\")\n    • {Number} yiv\n        The percentage (%) of height for the SafeFrame container that is in view (formatted as\n        \"0.14\" or \"1\")\n    • {Number} iv\n        The percentage (%) of area for the SafeFrame container that is in view (formatted as\n        \"0.14\" or \"1\")\n    • {Number} z\n        The Z-index of the SafeFrame container\n    • {Number} w\n        The width (in pixels) of the SafeFrame container\n    • {Number} h\n        The height (in pixels) of the SafeFrame container\n */\n\nexport const getGeomSelfObjectElem = (elem: HTMLElement): SelfRelativeAndInView => {\n    return convertLocationToSelfRelativeAndInView(getElementLocation(elem));\n};\n\nexport const getGeomSelfObjectBoundingClientRect = (boundingClientRect: DOMRect) => {\n    return convertLocationToSelfRelativeAndInView(convertBoundingClientRectToLocation(boundingClientRect, NaN));\n};\n\nconst convertLocationToSelfRelativeAndInView = (elementLocation: Location): SelfRelativeAndInView => {\n    const elementViewPercentages = getElementViewPercentages(elementLocation);\n    const geomSelfObject: SelfRelativeAndInView = {\n        t: elementLocation.t,\n        l: elementLocation.l,\n        r: elementLocation.r,\n        b: elementLocation.b,\n        w: elementLocation.w,\n        h: elementLocation.h,\n        z: elementLocation.z,\n        xiv: elementViewPercentages.xiv,\n        yiv: elementViewPercentages.yiv,\n        iv: elementViewPercentages.iv,\n    };\n    return geomSelfObject;\n};\n\n/*\n    Helper method for identifying the location, width and height of the browser or application window\n    boundaries relative to the device screen.\n */\nexport const getWindowLocation = (): WindowBoundaries => {\n    const t = window.screenY ? window.screenY : window.screenTop;\n    const l = window.screenX ? window.screenX : window.screenLeft;\n    const w = windowWidth();\n    const h = windowHeight();\n    const location: WindowBoundaries = {\n        t,\n        l,\n        w,\n        h,\n        b: t + h,\n        r: l + w,\n    };\n    return location;\n};\n\n/*\n    Computes whether an element is in view without user scrolling.\n        Returns true when >= 50% of the element is in view without user scrolling.\n        Returns false when < 50% of the element is in view without user scrolling.\n        Returns undefined if viewability is not measurable.\n    This ATF/measurability information is added per sim: https://sim.amazon.com/issues/CAP-8767\n    This atf definition is different from atf information stored in XSP config.\n*/\nexport const getAtfInfo = (elem: HTMLElement): boolean | 'unknown' => {\n    const piv = getElementViewPercentageWithoutScrolling(elem);\n    if (piv == null) {\n        return 'unknown';\n    } else if (piv >= 0.5) {\n        return true;\n    }\n    return false;\n};\n\n// https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect\nconst invalidOrMissingOrHiddenBoundingBox = (bodyLoc: DOMRect) => {\n    return bodyLoc.width === 0 && bodyLoc.height === 0;\n};\n\n/*\n    Computes the percentage of element that is in view without scrolling.\n    @returns null means can't compute due to invalid document bounding box\n    Export for testing only\n*/\nexport function getElementViewPercentageWithoutScrolling(elem: HTMLElement): number | null {\n    const bodyLoc = document.body.getBoundingClientRect();\n    if (invalidOrMissingOrHiddenBoundingBox(bodyLoc)) return null;\n    const elemLoc = getElementLocation(elem);\n    const wh = windowHeight();\n    const ww = windowWidth();\n\n    const viewableWidth = Math.max(0, Math.min(bodyLoc.left + ww, elemLoc.r) - elemLoc.l);\n    const viewableHeight = Math.max(0, Math.min(bodyLoc.top + wh, elemLoc.b) - elemLoc.t);\n    const viewableRatio = (viewableWidth * viewableHeight) / (elemLoc.h * Math.min(elemLoc.w, ww));\n    const viewPercentageWithoutScrolling = Number(Math.min(1, Math.max(0, viewableRatio)).toFixed(2));\n    return viewPercentageWithoutScrolling;\n}\n\ninterface ElementViewPercentages {\n    xiv: number;\n    yiv: number;\n    iv: number;\n}\n\n/*\n    Computes the percentage of element that is in view.\n*/\nconst getElementViewPercentages = (elementLocation: Location): ElementViewPercentages => {\n    const theWindowWidth = windowWidth();\n    const theWindowHeight = windowHeight();\n    const heightViewable = Math.max(0, getViewableSegment(elementLocation.t, elementLocation.b, theWindowHeight));\n    const widthViewable = Math.max(0, getViewableSegment(elementLocation.l, elementLocation.r, theWindowWidth));\n    const areaViewable = heightViewable * widthViewable;\n    const totalArea = elementLocation.h * Math.min(elementLocation.w, theWindowWidth);\n    if (!(totalArea === 0 && areaViewable === 0)) {\n        return {\n            xiv: Number(Math.min(1, widthViewable / elementLocation.w).toFixed(2)),\n            yiv: Number(Math.min(1, heightViewable / elementLocation.h).toFixed(2)),\n            iv: Number(Math.min(1, Math.max(0, areaViewable / totalArea)).toFixed(2)),\n        };\n    } else {\n        return {\n            xiv: 0,\n            yiv: 0,\n            iv: 0,\n        };\n    }\n};\n\n/*\n    Identifies the expected distance available for expansion within the host content along with\n    information about whether controls allow the end user to scroll the page. If “scrollable,” the\n    element content can expand to dimensions greater than those provided.\n    One of elem or boundingClientRect must be non-null\n */\nexport const getElementExp = (elem: HTMLElement): ExpectedDistanceAvailableForExpansion => {\n    const boundingRect = elem.getBoundingClientRect();\n    return convertBoundingRectToExpectedDistanceAvailableForExpansion(boundingRect);\n};\n\nconst convertBoundingRectToExpectedDistanceAvailableForExpansion = (\n    boundingClientRect: DOMRect,\n): ExpectedDistanceAvailableForExpansion => {\n    return {\n        t: boundingClientRect.top,\n        l: boundingClientRect.left,\n        r: windowWidth() - boundingClientRect.right,\n        b: windowHeight() - boundingClientRect.bottom,\n        xs: Math.max(document.body.scrollWidth, document.documentElement.scrollWidth) > windowWidth() ? 1 : 0,\n        yx: Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) > windowHeight() ? 1 : 0,\n    };\n};\n\nexport const getBoundingClientRectExp = (boundingClientRect: DOMRect): ExpectedDistanceAvailableForExpansion => {\n    return convertBoundingRectToExpectedDistanceAvailableForExpansion(boundingClientRect);\n};\n\n/*\n    Helper method for determining the portion of a segment that is in view. This is used by\n    to determine percentage in view along a given dimension.\n\n    @param nearReference {Number} - The point closest to the origin (either boundingRect.top or boundingRect.left)\n    @param farReference {Number} - The point farthest from the origin (either boundingRect.bottom or boundingRect.right)\n    @param containerLength {Number} - The maximum viewable segment (either window.innerHeight or window.innerWidth)\n\n    @return {Number} - A floating point number representing the number of pixels in view along the given dimension\n*/\nconst getViewableSegment = (nearReference: number, farReference: number, containerLength: number): number => {\n    let amountViewable = 0;\n\n    if (!(document.visibilityState === 'visible')) {\n        return amountViewable;\n    }\n\n    if (nearReference > 0) {\n        amountViewable = containerLength - nearReference;\n    } else if (farReference > 0) {\n        amountViewable = Math.min(farReference, containerLength);\n    } else {\n        // If the far reference is negative, safe to assume no portion of the ad is viewable\n        amountViewable = 0;\n    }\n    // The maximum we can view will either be the width/height of the div or the height/width of the viewport\n    return Math.min(amountViewable, farReference - nearReference);\n};\n\nexport const canBeInSameViewport = (elemA: HTMLElement, elemB: HTMLElement): boolean | null => {\n    const locationA = getElementLocation(elemA);\n    const locationB = getElementLocation(elemB);\n    const ww = windowWidth();\n    const wh = windowHeight();\n    return (\n        locationA &&\n        locationB &&\n        (Math.abs(locationA.t - locationB.b) < wh || Math.abs(locationA.b - locationB.t) < wh) &&\n        (Math.abs(locationA.l - locationB.r) < ww || Math.abs(locationA.r - locationB.l) < ww)\n    );\n};\n","import { aaxPayloadMacro, aaxTypeMacro, ATF_URL_KEY } from '@/components/aax/aax.js';\nimport type { Placement } from '@/components/pixels/pixel.js';\nimport type { PixelUrlGenerator } from '@/components/pixels/pixelUrlGenerator.js';\nimport { getAtfInfo } from '@/components/viewability.js';\n\nexport const generateMeasurabilityPixelUrl: PixelUrlGenerator = (url: string, params: Placement): string => {\n    const payloadObj = { atf: getAtfInfo(params.div) };\n    const encodedUrlPayload = encodeURIComponent(JSON.stringify(payloadObj));\n    return aaxTypeMacro.test(url)\n        ? url.replace(aaxTypeMacro, ATF_URL_KEY).replace(aaxPayloadMacro, encodedUrlPayload)\n        : `${url.replace(/\\/$/, '')}/${ATF_URL_KEY}/${encodedUrlPayload}`;\n};\n","import type { Placement } from '@/components/pixels/pixel.js';\n\nexport const btr = {\n    set: (placement: Placement, value: boolean): void => {\n        placement.div.dataset.isBtr = String(value);\n    },\n    get: (placement: Placement): boolean => {\n        return placement.div.dataset.isBtr === String(true);\n    },\n};\n","import type { ViewableInfo } from '@amzn/safe-frame-client-amzn';\n\nimport { aaxPayloadMacro, aaxTypeMacro, VIEW_PIXEL_URL_KEY } from '@/components/aax/aax.js';\nimport type { Placement } from '@/components/pixels/pixel.js';\nimport type { PixelUrlGenerator } from '@/components/pixels/pixelUrlGenerator.js';\nimport { btr } from '@/components/pixels/placementData.js';\nimport type { ViewabilityStandard } from '@/components/pixels/viewabilityStandards.js';\n\nexport interface PixelUrlParams {\n    placement: Placement;\n    definition: string;\n    thresholdPercentage: number;\n    thresholdTimeVisibleMs: number;\n    isBtr: boolean;\n    adStartTime: number;\n}\n\n// https://w.amazon.com/bin/view/AdPT/ACS/SupplyQuality/VUE/CSM/PixelPayloadFormat/\nexport const pixelUrlParameters = (pixelUrlParams: PixelUrlParams): ViewableInfo => {\n    const placementDivRect = pixelUrlParams.placement.div.getBoundingClientRect();\n    return {\n        v: {\n            def: pixelUrlParams.definition,\n            p: pixelUrlParams.thresholdPercentage,\n            t: pixelUrlParams.thresholdTimeVisibleMs,\n            ib: pixelUrlParams.isBtr,\n        },\n        wh: window.innerHeight || document.documentElement.clientHeight,\n        ww: window.innerWidth || document.documentElement.clientWidth,\n        sx: window.scrollX,\n        sy: window.scrollY,\n        ah: placementDivRect.height,\n        aw: placementDivRect.width,\n        top: placementDivRect.top,\n        left: placementDivRect.left,\n        ptv: (new Date().getTime() - (window.aPageStart ?? 0)) / 1000,\n        ttv: (new Date().getTime() - pixelUrlParams.adStartTime) / 1000,\n    };\n};\n\nexport const generateMrcObstructionViewPixelUrl = (viewabilityStandard: ViewabilityStandard): PixelUrlGenerator => {\n    const adStartTime = new Date().getTime();\n    return (url: string, placement: Placement): string => {\n        const pixelUrlParams: PixelUrlParams = {\n            placement: placement,\n            definition: viewabilityStandard.definition,\n            thresholdPercentage: viewabilityStandard.thresholdPercentage,\n            thresholdTimeVisibleMs: viewabilityStandard.thresholdTimeVisibleMs,\n            isBtr: btr.get(placement),\n            adStartTime,\n        };\n\n        const encodedUrlPayload = encodeURIComponent(JSON.stringify(pixelUrlParameters(pixelUrlParams)));\n\n        return aaxTypeMacro.test(url)\n            ? url.replace(aaxTypeMacro, VIEW_PIXEL_URL_KEY).replace(aaxPayloadMacro, encodedUrlPayload)\n            : `${url.replace(/\\/+$/, '')}/${VIEW_PIXEL_URL_KEY}/${encodedUrlPayload}`;\n    };\n};\n","export type ViewabilityStandard = {\n    definition: string;\n    thresholdPercentage: number;\n    thresholdTimeVisibleMs: number;\n};\n\nconst IAB_VIDEO: ViewabilityStandard = {\n    definition: 'iab',\n    thresholdPercentage: 0.5,\n    thresholdTimeVisibleMs: 2000,\n} as const;\n\nconst IAB_LARGE_DISPLAY: ViewabilityStandard = {\n    definition: 'iab',\n    thresholdPercentage: 0.3,\n    thresholdTimeVisibleMs: 1000,\n} as const;\n\nconst IAB_DISPLAY: ViewabilityStandard = {\n    definition: 'iab',\n    thresholdPercentage: 0.5,\n    thresholdTimeVisibleMs: 1000,\n} as const;\n\nconst SKAN: ViewabilityStandard = {\n    definition: 'skan',\n    thresholdPercentage: 0.5,\n    thresholdTimeVisibleMs: 2000,\n} as const;\n\nexport const VIEWABILITY_STANDARDS = {\n    IAB_VIDEO,\n    IAB_LARGE_DISPLAY,\n    IAB_DISPLAY,\n    SKAN,\n} as const satisfies Record<string, ViewabilityStandard>;\n","import {\n    incrementCsaCounter,\n    incrementCsaPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csa/events.js';\nimport {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport { logFatal } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport { setupIntersectionObserver } from '@/components/intersectionObserver.js';\nimport type { Pixel, Placement } from '@/components/pixels/pixel.js';\nimport type { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.js';\nimport type { ViewabilityService } from '@/components/pixels/services/viewabilityService.js';\nimport type { ViewabilityStandard } from '@/components/pixels/viewabilityStandards.js';\nimport type { ViewPixel } from '@/components/pixels/viewPixel.js';\n\ntype Cleanup = () => void;\ntype State = { wasObstructed: boolean };\n\n/**\n * Creates a MRC-compliant viewability tracker that fires pixels when viewability thresholds are met.\n * Monitors viewport intersection, obstruction, and document visibility to ensure accurate viewability measurement.\n */\nexport const createViewabilityTracker = (\n    pixels: Pixel[],\n    viewabilityStandard: ViewabilityStandard,\n    viewabilityService: ViewabilityService,\n    firePixelValidators: FirePixelValidator[],\n    adDetails?: AdDetails,\n    lightAdDetails?: LightAdDetails,\n): ViewPixel => {\n    /**\n     * Starts tracking viewability for the given placement.\n     * Sets up an intersection observer to monitor when the placement meets the visibility threshold.\n     * This ensures we only poll when the placement is relevant (meets threshold visibility).\n     */\n    const track = (placement: Placement): void => {\n        let cleanup: Cleanup | undefined;\n        // State must be an object to persist across multiple startViewTimer calls (viewport exit/re-entry)\n        const state: State = { wasObstructed: false };\n\n        setupIntersectionObserver({\n            target: placement.div,\n            onIntersection: (observer) => (cleanup = startViewTimer(placement, observer, state)),\n            onExit: () => cleanup?.(), // May be undefined on initial callback if placement starts below threshold\n            options: { threshold: viewabilityStandard.thresholdPercentage },\n            adDetails,\n            lightAdDetails,\n        });\n    };\n\n    /**\n     * Starts the viewability timer when placement enters viewport.\n     * Checks every 100ms if the placement is viewable and fires pixel when threshold is met.\n     *\n     * The timer operates in three states:\n     * 1. If obstructed or hidden: marks for reset on next check (defers reset to avoid counting obstructed time)\n     * 2. If needs reset: resets the visible start time to current time (starts fresh count when unobstructed)\n     * 3. If visible and threshold met: fires pixel and cleans up\n     *\n     * The two-step reset ensures we don't count time while obstructed, and only start counting\n     * from the first unobstructed check after obstruction ends.\n     *\n     * @returns cleanup function to clear the interval and remove listeners\n     */\n    const startViewTimer = (placement: Placement, observer: IntersectionObserver, state: State): Cleanup => {\n        let visibleStartTime = performance.now();\n        let needsReset = false;\n\n        const intervalId = setInterval(() => {\n            // State 1: Obstruction detected - mark for reset to avoid counting obstructed time\n            if (isObstructed(placement) || isHidden()) {\n                state.wasObstructed = true;\n                needsReset = true;\n            }\n            // State 2: Reset timer after obstruction cleared - start fresh count\n            else if (needsReset) {\n                visibleStartTime = performance.now();\n                needsReset = false;\n            }\n            // State 3: Threshold met and validators pass - fire pixel and cleanup\n            else if (\n                hasMetThreshold(visibleStartTime, viewabilityStandard.thresholdTimeVisibleMs) &&\n                shouldFirePixel(firePixelValidators)\n            ) {\n                pixels.forEach((pixel) => pixel.fire(placement));\n                cleanup(state.wasObstructed);\n                observer.unobserve(placement.div);\n            }\n        }, IAB_WAIT_INTERVAL_MS);\n\n        const cleanup = (wasObstructed = false): void => {\n            if (wasObstructed) {\n                logObstructionRecovery(placement);\n            }\n            clearInterval(intervalId);\n            viewabilityService.cleanup();\n        };\n\n        return cleanup;\n    };\n\n    /**\n     * Checks if the placement is obstructed by other elements.\n     * @returns true if obstructed, false otherwise or on error\n     */\n    const isObstructed = (placement: Placement): boolean => {\n        try {\n            return viewabilityService.isViewabilityObstructed(placement, viewabilityStandard.thresholdPercentage);\n        } catch (error: any) {\n            logFatal(error?.message, error);\n            return false; // Treat errors as unobstructed to continue tracking\n        }\n    };\n\n    return { track, viewabilityStandard };\n};\n\n/**\n * Maximum allowed interval for checking viewability status per IAB standard.\n * Checks must occur at least every 100ms to accurately measure continuous viewable time.\n */\nconst IAB_WAIT_INTERVAL_MS = 100 as const;\n\n/**\n * Checks if the document is hidden (tab is not visible).\n * @returns true if document is hidden\n */\nconst isHidden = (): boolean => document.hidden;\n\n/**\n * Checks if the placement has been continuously visible for the required threshold time.\n * @param visibleStartTime - The timestamp when visibility started\n * @param thresholdTimeVisibleMs - The required threshold time in milliseconds\n * @returns true if threshold time has been met\n */\nconst hasMetThreshold = (visibleStartTime: number, thresholdTimeVisibleMs: number): boolean =>\n    performance.now() - visibleStartTime >= thresholdTimeVisibleMs;\n\n/**\n * Checks if all pixel validators allow firing the pixel.\n * @param validators - Array of validators to check\n * @returns true if all validators pass\n */\nconst shouldFirePixel = (validators: FirePixelValidator[]): boolean => validators.every((v) => v.shouldFirePixel());\n\n/**\n * Logs metrics when pixel fires after recovering from obstruction.\n * @param placement - The placement that recovered from obstruction\n */\nconst logObstructionRecovery = (placement: Placement): void => {\n    const metricName = 'viewpixel:iab:obstruction:recovered';\n    incrementCsmCounter(metricName);\n    incrementCsaCounter(metricName);\n    incrementCsmPlacementCounter(metricName, placement);\n    incrementCsaPlacementCounter(metricName, placement);\n};\n","import { createObstructionDetectionService } from '@amzn/creative-obstruction-detection/src/obstructionDetectionServiceImpl.js';\nimport type { AdDetails, DeviceType, LightAdDetails, MediaType, SKAdNetwork } from '@amzn/safeframe-model';\n\nimport { MRCObstructionViewPixel } from '@/components/pixels/mrcObstructionViewPixel.js';\nimport type { LoggingContext } from '@/components/pixels/pixel.js';\nimport { Pixel } from '@/components/pixels/pixel.js';\nimport {\n    BTR_IDENTIFIER,\n    IAB_VIEWABILITY_IDENTIFIER,\n    IMPRESSION_IDENTIFIER,\n    MEASURABILITY_IDENTIFIER,\n} from '@/components/pixels/pixelIdentifiers.js';\nimport type { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.ts';\nimport { logPixelFired } from '@/components/pixels/services/pixelLogger.js';\nimport { createViewabilityService } from '@/components/pixels/services/viewabilityServiceImpl.js';\nimport { createVisibiltyChangeService } from '@/components/pixels/services/visibilityChangeService.js';\nimport { SkanImpressionPixel } from '@/components/pixels/skanImpressionPixel.js';\nimport { SkanViewPixel } from '@/components/pixels/skanViewPixel.js';\nimport { generateBtrPixelUrl } from '@/components/pixels/urlGenerators/btrPixelUrlGenerator.js';\nimport { generateImpressionPixelUrl } from '@/components/pixels/urlGenerators/impressionPixelUrlGenerator.js';\nimport { generateMeasurabilityPixelUrl } from '@/components/pixels/urlGenerators/measurabilityPixelUrlGenerator.js';\nimport { generateMrcObstructionViewPixelUrl } from '@/components/pixels/urlGenerators/mrcObstructionViewPixelUrlGenerator.js';\nimport type { ViewabilityStandard } from '@/components/pixels/viewabilityStandards.js';\nimport { VIEWABILITY_STANDARDS } from '@/components/pixels/viewabilityStandards.js';\nimport { createViewabilityTracker } from '@/components/pixels/viewabilityTrackerImpl.js';\nimport type { ViewPixel } from '@/components/pixels/viewPixel.js';\nimport { NEW_VIEWABILITY_TRACKER_WEBLAB } from '@/components/weblabs.js';\n\nexport type PixelInfo = {\n    aaxImpPixelUrl: string;\n    imp3pUrls?: string[];\n    aaxInstrPixelUrl: string;\n    abpAcceptable: string;\n    abpStatus: string;\n    btrPixelUrl?: string;\n    skAdNetwork?: SKAdNetwork;\n    loggingContext: LoggingContext;\n};\n\nexport const mapToBtrPixel = ({ btrPixelUrl, loggingContext }: PixelInfo): Pixel | undefined => {\n    return btrPixelUrl\n        ? new Pixel(btrPixelUrl, loggingContext, generateBtrPixelUrl, BTR_IDENTIFIER, logPixelFired())\n        : undefined;\n};\n\nexport const mapToImpressionPixel = ({ aaxImpPixelUrl, imp3pUrls, loggingContext }: PixelInfo): Pixel =>\n    new Pixel(\n        aaxImpPixelUrl,\n        loggingContext,\n        generateImpressionPixelUrl,\n        IMPRESSION_IDENTIFIER,\n        logPixelFired(),\n        imp3pUrls,\n    );\n\nexport const mapToMeasurabilityPixel = ({ aaxInstrPixelUrl, loggingContext }: PixelInfo): Pixel =>\n    new Pixel(\n        aaxInstrPixelUrl,\n        loggingContext,\n        generateMeasurabilityPixelUrl,\n        MEASURABILITY_IDENTIFIER,\n        logPixelFired(),\n    );\n\nexport const createIabViewPixel = (\n    mediaType: MediaType,\n    htmlElement: HTMLElement,\n    pixelInfo: PixelInfo,\n    deviceType: DeviceType,\n    firePixelValidator: () => FirePixelValidator,\n    adDetails?: AdDetails,\n    lightAdDetails?: LightAdDetails,\n): ViewPixel => {\n    if (mediaType === 'V') {\n        return createMrcViewPixel(\n            pixelInfo,\n            VIEWABILITY_STANDARDS.IAB_VIDEO,\n            firePixelValidator(),\n            adDetails,\n            lightAdDetails,\n        );\n    } else if (isDesktop(deviceType) && isLargeAd(htmlElement)) {\n        return createMrcViewPixel(\n            pixelInfo,\n            VIEWABILITY_STANDARDS.IAB_LARGE_DISPLAY,\n            undefined,\n            adDetails,\n            lightAdDetails,\n        );\n    } else {\n        return createMrcViewPixel(pixelInfo, VIEWABILITY_STANDARDS.IAB_DISPLAY, undefined, adDetails, lightAdDetails);\n    }\n};\n\nconst isDesktop = (deviceType: DeviceType): boolean => deviceType === 'DESKTOP';\n\n/**\n * Large IAB view pixel is used to measure the time the ad is visible on the screen.\n * An ad can be considered a large ad if it is of 242,500 pixels are larger\n * @link https://www.iab.com/wp-content/uploads/2015/06/MRC-Viewable-Ad-Impression-Measurement-Guideline.pdf\n */\nconst isLargeAd = (htmlElement: HTMLElement): boolean => getSizeOfElementInTotalPixels(htmlElement) >= 242500;\n\nconst getSizeOfElementInTotalPixels = (htmlElement: HTMLElement): number =>\n    htmlElement.getBoundingClientRect().height * htmlElement.getBoundingClientRect().width;\n\nconst createMrcViewPixel = (\n    pixelInfo: PixelInfo,\n    standard: ViewabilityStandard,\n    validator?: FirePixelValidator,\n    adDetails?: AdDetails,\n    lightAdDetails?: LightAdDetails,\n): ViewPixel => {\n    const pixel = new Pixel(\n        pixelInfo.aaxInstrPixelUrl,\n        pixelInfo.loggingContext,\n        generateMrcObstructionViewPixelUrl(standard),\n        IAB_VIEWABILITY_IDENTIFIER,\n        logPixelFired(),\n    );\n\n    if (NEW_VIEWABILITY_TRACKER_WEBLAB().is('t1')) {\n        return createViewabilityTracker(\n            [pixel],\n            standard,\n            createViewabilityService(createObstructionDetectionService()),\n            validator ? [validator] : [],\n            adDetails,\n            lightAdDetails,\n        );\n    } else {\n        return new MRCObstructionViewPixel(\n            pixel,\n            standard,\n            createVisibiltyChangeService(),\n            createViewabilityService(createObstructionDetectionService()),\n            validator,\n            adDetails,\n            lightAdDetails,\n        );\n    }\n};\n\nexport const mapToSkanImpressionPixel = (pixelInfo: PixelInfo): SkanImpressionPixel | undefined => {\n    if (pixelInfo.skAdNetwork) {\n        return new SkanImpressionPixel(pixelInfo.loggingContext, pixelInfo.skAdNetwork, logPixelFired());\n    }\n    return undefined;\n};\n\nexport const mapToSkanViewPixel = (pixelInfo: PixelInfo): ViewPixel | undefined => {\n    if (pixelInfo.skAdNetwork) {\n        const skanPixel = new SkanViewPixel(pixelInfo.loggingContext, logPixelFired(), pixelInfo.skAdNetwork);\n        return new MRCObstructionViewPixel(\n            skanPixel,\n            VIEWABILITY_STANDARDS.SKAN,\n            createVisibiltyChangeService(),\n            createViewabilityService(createObstructionDetectionService()),\n            undefined,\n        );\n    }\n    return undefined;\n};\n","export function addCustomEventListener<T>(target: EventTarget, type: string, handler: (event: CustomEvent<T>) => void) {\n    target.addEventListener(type, ((e: Event) => {\n        handler(e as CustomEvent<T>);\n    }) as EventListener);\n}\n","import { addCustomEventListener } from '@/components/events/customEvents.js';\nimport type { Placement } from '@/components/pixels/pixel.js';\nimport type { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.js';\n\nexport const SF_VIDEO_CONTINUOUS_PLAYTIME_SECONDS_EVENT = 'sfVideoContinuousPlaytimeSeconds';\n\nexport type SfVideoContinuousPlaytimeEventDetail = {\n    sfVideoContinuousPlaytimeSeconds: number;\n};\n\nexport const createSafeFrameVideoFirePixelValidator = (placement: Placement): FirePixelValidator => {\n    let sfVideoContinuousPlaytimeSeconds = 0;\n\n    addCustomEventListener<SfVideoContinuousPlaytimeEventDetail>(\n        placement.div,\n        SF_VIDEO_CONTINUOUS_PLAYTIME_SECONDS_EVENT,\n        (event) => {\n            sfVideoContinuousPlaytimeSeconds = event.detail.sfVideoContinuousPlaytimeSeconds;\n        },\n    );\n\n    return {\n        shouldFirePixel(): boolean {\n            return sfVideoContinuousPlaytimeSeconds >= 2;\n        },\n    };\n};\n\nexport const createLightAdVideoFirePixelValidator = (element: HTMLElement): FirePixelValidator => {\n    const video = element?.querySelector('video');\n    if (!video) throw new Error(`No <video> element found inside #${element.id}`);\n\n    let playbackStartTime = 0;\n    let continuousPlaytime = 0;\n\n    video.addEventListener('play', () => {\n        continuousPlaytime = 0;\n        playbackStartTime = performance.now();\n    });\n\n    video.addEventListener('pause', () => (continuousPlaytime = 0));\n\n    video.addEventListener('ended', () => (continuousPlaytime = 0));\n\n    video.addEventListener('timeupdate', () => {\n        if (!video.paused) {\n            continuousPlaytime = performance.now() - playbackStartTime;\n        }\n    });\n\n    return {\n        shouldFirePixel(): boolean {\n            return continuousPlaytime >= 2000;\n        },\n    };\n};\n","import type { DeviceType } from '@amzn/safeframe-model';\n\n/**\n * The baseline font sizes for each device type.\n * Code references:\n * Desktop: https://tiny.amazon.com/x47zohww/AmazonUIBaseCSS/ab418f40/_reset.scss#L53\n * Mobile: https://tiny.amazon.com/ngvoylv3/AmazonUIBaseCSS/acdd7b75/_base_touch.device_type=mobile.scss#L2\n *\n */\nexport const BASE_FONT_SIZES: Record<DeviceType, number> = {\n    DESKTOP: 16,\n    MSHOP: 10,\n    MWEB: 10,\n};\n\n/**\n * Ensure that length has unit per https://www.w3.org/TR/css3-values/#lengths\n *\n * @param {string} value Length with px, %, or unitless (treat as px)\n * @returns {string} Valid length with px or %\n */\nexport const ensureValidLength = (value: any): string => {\n    if (value && !isPercentage(value) && !isPixel(value)) {\n        return value + 'px';\n    }\n    return value;\n};\n\nexport const isPercentage = (value: string): boolean => {\n    return value?.length > 1 && value.charAt(value.length - 1) === '%';\n};\n\nexport const isPixel = (value: string): boolean => {\n    return value.length > 2 && value.substring(value.length - 2) === 'px';\n};\n\nexport const makeSizeExplicitPercentOrPx = (value: string): string =>\n    isPercentage(value) ? value : `${parseInt(value)}px`;\n\n/**\n * This utility function takes a string value, e.g. 60px or 100%, and computes the appropriate lh value. If the value is\n * a percentage, i.e. 75%, we simply return the string back. Otherwise, we parse the value and divide it by the provided\n * root font size.\n *\n * Keep in mind that `lh` units are calculated based on the current element's line height. For example, if the\n * line-height is 10px, then 5lh = 5 * 10px = 50px;\n *\n * For more details, see this Quip doc:\n * https://quip-amazon.com/lFotAjjaiDqy/Relative-Unit-Sizing-for-APM-Placements\n *\n * SIM ticket to track browser updates and yearly audits:\n * https://sim.amazon.com/issues/CPP-42326\n */\nexport const makeSizeExplicitPercentOrRelativeUnit = (value: string, deviceType: DeviceType = 'MWEB'): string => {\n    if (isPercentage(value)) return value;\n\n    const val = parseFloat(value);\n    const fontSize = BASE_FONT_SIZES[deviceType];\n\n    if (!val || !fontSize) return 'inherit';\n\n    return `${val / fontSize}lh`;\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { logLowRateMetricSF } from '@/components/metrics/awsMetricLogger.js';\nimport type { PlacementSize } from '@/host/api-client/handlers/changeSizeHandler.js';\nimport { isPercentage } from '@/host/components/css.js';\n\nexport const logChangeSize = (adDetails: AdDetails, size: PlacementSize) => {\n    const getDimension = (dimension: string) => (isPercentage(dimension) ? dimension : parseInt(dimension));\n\n    logLowRateMetricSF({\n        metricName: `creative:size:changeSize`,\n        adDetails: adDetails,\n        additionalDimensions: {\n            postSize: `${getDimension(size.width)}x${getDimension(size.height)}`,\n        },\n    });\n};\n\nexport const logResponsivePlacement = (adDetails: AdDetails): void => {\n    if (RESPONSIVE_PLACEMENTS.has(adDetails.slotName) && !isDefaultCreativePreview(adDetails)) {\n        logLowRateMetricSF({\n            metricName: 'responsivePlacement',\n            adDetails,\n            additionalDimensions: {\n                responsiveCreative: String(adDetails.responsiveCreative),\n                responsivePlacement: String(adDetails.responsivePlacement),\n                creativeId: adDetails.adCreativeMetaData.adCreativeId,\n            },\n        });\n    }\n};\n\nexport const RESPONSIVE_PLACEMENTS = new Set([\n    // Regular slots\n    'desktop-homepage-btf-card-1',\n    'desktop-homepage-btf-card-2',\n    'desktop-homepage-btf-card-3',\n    'desktop-homepage-btf-left',\n    'abgw-btf-card-1',\n    'ams-detail-right-pbook',\n    'goldbox-ads',\n    'fresh-hero-quick-promo',\n    'wfm-hero-quick-promo',\n    'fresh-odp-desktop-ad-2',\n    'dynamic-zoetrope-1',\n    'mobile-app-detail-lpo',\n    'mobile-detail-lpo',\n    'desktop-detail-lpo',\n\n    // VSSM\n    'ee-vssm-desktop-1',\n    'ee-vssm-desktop-5',\n    'ee-vssm-desktop-9',\n    'merchandised-search-3',\n    'merchandised-search-9',\n    'merchandised-vssm-desktop-1',\n    'merchandised-vssm-desktop-2',\n    'merchandised-vssm-desktop-3',\n    'merchandised-vssm-desktop-4',\n    'merchandised-vssm-desktop-5',\n    'merchandised-vssm-desktop-6',\n    'merchandised-vssm-mobile-1',\n    'merchandised-vssm-mobile-2',\n    'merchandised-vssm-mobile-3',\n    'merchandised-vssm-mobile-4',\n    'merchandised-vssm-mobile-5',\n    'merchandised-vssm-mobile-6',\n]);\n\nconst isDefaultCreativePreview = ({ htmlContentEncoded }: AdDetails): boolean =>\n    !!htmlContentEncoded?.includes(\n        'This is a default creative preview. It is usually displayed when the requested creative is inactive.',\n    );\n","import { incrementCsmCounter } from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport { logLowRateMetricSF } from '@/components/metrics/awsMetricLogger.js';\n\nexport const getWrapper = (adDetails: AdDetails | LightAdDetails): HTMLElement | null => {\n    const adUnitWrapperId = 'adUnitWrapperId' in adDetails ? adDetails.adUnitWrapperId : undefined;\n    return adUnitWrapperId ? document.getElementById(adUnitWrapperId) : null;\n};\n\nexport const getPlacement = (adDetails: AdDetails): HTMLDivElement => {\n    const { adUnitPlacementId } = adDetails;\n    const placement = document.getElementById(adUnitPlacementId);\n\n    if (!placement) {\n        const { readyState } = document;\n\n        incrementCsmCounter('getplacement:undefined');\n        logLowRateMetricSF({\n            metricName: 'html:element:missing:placement',\n            adDetails: adDetails,\n            additionalDimensions: {\n                readyState,\n                adUnitPlacementId,\n                placementCount: getPlacementCount(adUnitPlacementId),\n            },\n        });\n    }\n\n    return placement as HTMLDivElement;\n};\n\nconst getPlacementCount = (adUnitPlacementId: string) =>\n    String(document.querySelectorAll(`#${adUnitPlacementId}`).length);\n","import { logDebug, logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { logChangeSize } from '@/components/metrics/size-info-logger.js';\nimport { isPercentage, makeSizeExplicitPercentOrPx } from '@/host/components/css.js';\nimport { getPlacement } from '@/host/components/placement.js';\n\nexport type PlacementSize = {\n    width: string;\n    height: string;\n};\n\nexport const changeSizeHandler = (adDetails: AdDetails, size: PlacementSize) => {\n    logDebug('ChangeSize API has been deprecated');\n    if (!isChangeSizeSupported(adDetails)) return;\n\n    if (resizePlacement(adDetails, size)) {\n        logChangeSize(adDetails, size);\n    }\n};\n\nconst resizePlacement = (adDetails: AdDetails, size: PlacementSize): boolean => {\n    if (!isAllowedSize(size)) {\n        logError(`Size w:'${size.width}', h:'${size.height}' is not allow-listed for '${adDetails.placementName}'`);\n        return false;\n    }\n\n    const div = getPlacement(adDetails);\n\n    if (supportChangeSizeResize(adDetails, size)) {\n        div.style.maxHeight = makeSizeExplicitPercentOrPx(size.height);\n    }\n\n    if (isPercentage(size.height) || isPercentage(size.width)) {\n        div.style.width = makeSizeExplicitPercentOrPx(size.width);\n        div.style.height = makeSizeExplicitPercentOrPx(size.height);\n    } else {\n        div.removeAttribute('style');\n        div.style.aspectRatio = `${parseInt(size.width)} / ${parseInt(size.height)}`;\n    }\n\n    return true;\n};\n\nconst isAllowedSize = (size: PlacementSize): boolean => {\n    const height = makeSizeExplicitPercentOrPx(size.height);\n    const width = makeSizeExplicitPercentOrPx(size.width);\n\n    const allowedSizes = [\n        { width: '100%', height: '169px' },\n        { width: '300px', height: '250px' },\n    ];\n\n    return allowedSizes.some((allowedSize) => height === allowedSize.height && width === allowedSize.width);\n};\n\nconst isChangeSizeSupported = (adDetails: AdDetails): boolean =>\n    adDetails.slotName === 'hero-quick-promo' &&\n    (adDetails.adCreativeMetaData?.adCreativeTemplateName === 'Personalized Responsive eCommerce' ||\n        !adDetails.adCreativeMetaData?.adCreativeTemplateName) &&\n    adDetails.mediaType === 'D';\n\nconst supportChangeSizeResize = (adDetails: AdDetails, size: PlacementSize): boolean =>\n    adDetails.slotName === 'hero-quick-promo' && isPercentage(size.width);\n","import {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport type { Placement as PlacementInterface } from '@amzn/apejs-instrumentation/src/metrics/placement.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { logLowRateMetricSF } from '@/components/metrics/awsMetricLogger.js';\n\nexport type CollapseCode = 'CREATIVE' | 'CLIENT_SETUP' | 'HOST_SETUP' | 'CLIENT_ERROR';\n\nexport class Placement implements PlacementInterface {\n    constructor(\n        public readonly id: string,\n        public readonly name: string,\n        private readonly wrapperDivId: string | undefined,\n        private readonly divId: string,\n    ) {}\n\n    collapse(adDetails: AdDetails, code: CollapseCode): void {\n        this.wrapperDiv && (this.wrapperDiv.style.display = 'none');\n        this.div.style.display = 'none';\n        logLowRateMetricSF({\n            metricName: 'placement:collapse',\n            adDetails: adDetails,\n            additionalDimensions: {\n                code: code,\n                isBlank: `${isBlank(adDetails)}`,\n                creativeId: adDetails.adCreativeMetaData.adCreativeId,\n            },\n        });\n        incrementCsmCounter('safeframe:placement:collapse');\n        incrementCsmPlacementCounter('safeframe:placement:collapse', { id: this.id, name: this.name });\n    }\n\n    private get wrapperDiv(): HTMLDivElement | null {\n        return this.wrapperDivId ? (document.getElementById(this.wrapperDivId) as HTMLDivElement) : null;\n    }\n\n    public get div(): HTMLDivElement {\n        return document.getElementById(this.divId) as HTMLDivElement;\n    }\n}\n\nconst isBlank = (adDetails: AdDetails) => {\n    const match = adDetails.htmlContentEncoded.match(/<div id=\"ad\">\\s*(.*?)\\s*<\\/div>/s);\n    if (!match) return false;\n\n    const content = match[1].trim();\n    return content === '';\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { Placement } from '@/host/domain/placement.js';\n\nexport const mapToPlacement = (adDetails: AdDetails): Placement => {\n    return new Placement(\n        adDetails.placementId,\n        adDetails.placementName,\n        adDetails.adUnitWrapperId,\n        adDetails.adUnitPlacementId,\n    );\n};\n","import {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport { logDebug } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { CollapseCode } from '@/host/domain/placement.js';\nimport { mapToPlacement } from '@/host/domain/placementMapper.js';\n\nexport const collapseSlotHandler = (adDetails: AdDetails, code: CollapseCode): void => {\n    if (window.APE_SF?.collapsedPlacements.has(adDetails.adUnitPlacementId)) {\n        logDebug('Slot already collapsed');\n        return;\n    }\n\n    const placement = { id: adDetails.placementId, name: adDetails.placementName };\n    incrementCsmCounter('messenger:collapseSlot');\n    incrementCsmPlacementCounter('messenger:collapseSlot', placement);\n    incrementCsmCounter(`messenger:collapseSlot${code}`);\n    incrementCsmPlacementCounter(`messenger:collapseSlot${code}`, placement);\n    incrementCsmCounter(`collapse:${code.toLowerCase()}`);\n    incrementCsmPlacementCounter(`collapse:${code.toLowerCase()}`, placement);\n    mapToPlacement(adDetails).collapse(adDetails, code);\n\n    window.APE_SF?.collapsedPlacements.add(adDetails.adUnitPlacementId);\n};\n","/**\n * Wrapper functions for Homepage Video Orchestrator\n * https://quip-amazon.com/A20AAkbGNjbX/Video-Orchestrator\n * https://code.amazon.com/packages/AmazonHomepageCardAssets/blobs/mainline/--/src/gw-video-orchestrator.js\n */\nimport { logDebug } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\n\ntype GwVideoOrchestrator = {\n    subscribe: (element: HTMLElement, callback: SubscribeCallback, options?: GwVideoOrchestratorOptions) => void;\n    elect: (element?: HTMLElement) => void;\n};\n\ntype SubscribeCallback = (isLeader: boolean) => void;\n\nexport type GwVideoOrchestratorOptions = {\n    minVisiblePercentForLeader?: number; // number 0 to 1. The percentage of an element in the view which is bigger than this threshold is considered onScreen. Default is 0.5.\n    priority?: number; // number 0 to 100. Highest priority wins. HERO should subscribe with 100. Default is 50.\n};\n\nconst gwVideoOrchestratorPName = 'gw-video-orchestrator';\n\nexport const subscribe = (\n    element: HTMLElement,\n    callback: SubscribeCallback,\n    options?: GwVideoOrchestratorOptions,\n): void => {\n    window.P?.when(gwVideoOrchestratorPName).execute((gwVideoOrchestrator: GwVideoOrchestrator) => {\n        try {\n            gwVideoOrchestrator.subscribe(element, callback, options);\n        } catch (error) {\n            logDebug(`gw-video-orchestrator error: ${JSON.stringify(error)}`);\n        }\n    });\n};\n\nexport const elect = (element: HTMLElement): void => homepageElect(element);\n\nexport const unelect = (): void => homepageElect();\n\nconst homepageElect = (element?: HTMLElement): void => {\n    window.P?.when(gwVideoOrchestratorPName).execute((gwVideoOrchestrator: GwVideoOrchestrator) => {\n        gwVideoOrchestrator.elect(element);\n    });\n};\n","import { incrementCsmCounter } from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { logLowRateMetricSF } from '@/components/metrics/awsMetricLogger.js';\n\nexport const getIFrame = (adDetails: AdDetails): HTMLIFrameElement => {\n    const { adUnitIframeId } = adDetails;\n    const iframe = document.getElementById(adUnitIframeId);\n\n    if (!iframe) {\n        const { readyState } = document;\n\n        incrementCsmCounter('getiframe:undefined');\n        logLowRateMetricSF({\n            metricName: 'html:element:missing:iframe',\n            adDetails: adDetails,\n            additionalDimensions: {\n                readyState,\n                adUnitIframeId,\n                iframeCount: getIframeCount(adUnitIframeId),\n            },\n        });\n    }\n\n    return iframe as HTMLIFrameElement;\n};\n\nconst getIframeCount = (adUnitIframeId: string) => String(document.querySelectorAll(`#${adUnitIframeId}`).length);\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { GwVideoOrchestratorOptions } from '@/components/homepage/homepageVideoOrchestrator.js';\nimport { elect, subscribe, unelect } from '@/components/homepage/homepageVideoOrchestrator.js';\nimport { canBeInSameViewport } from '@/components/viewability.js';\nimport type { HostMessageSender } from '@/host/api-client/hostMessageSender.js';\nimport { getIFrame } from '@/host/components/iframe.js';\n\nlet autoplayLock: string | null = null;\n\nexport const requestVideoAutoplayHandler = (\n    adDetails: AdDetails,\n    data: GwVideoOrchestratorOptions,\n    messenger: HostMessageSender,\n) => {\n    const sendCanAutoPlayMessage = (canAutoplay: boolean) =>\n        messenger.sendCustomMessageToAd(adDetails.arid, 'videoAutoplayResponse', canAutoplay);\n\n    if (isHomepage(adDetails.pageType)) {\n        subscribe(getIFrame(adDetails), sendCanAutoPlayMessage, data);\n    } else {\n        if (autoplayLock === adDetails.arid) {\n            sendCanAutoPlayMessage(true);\n        } else if (autoplayLock === null && noPlayingVideoNearby(getIFrame(adDetails))) {\n            autoplayLock = adDetails.arid;\n            sendCanAutoPlayMessage(true);\n        } else {\n            sendCanAutoPlayMessage(false);\n        }\n    }\n};\n\nexport const releaseVideoAutoplayHandler = () => {\n    unelect();\n    autoplayLock = null;\n};\n\nexport const haveVideoAutoplayPermissionHandler = (adDetails: AdDetails) => {\n    elect(getIFrame(adDetails));\n    autoplayLock = adDetails.arid;\n};\n\nconst isHomepage = (pageType?: string): boolean => pageType?.toLowerCase() === 'gateway';\n\nconst noPlayingVideoNearby = (element: HTMLElement): boolean => {\n    return ![...document.getElementsByTagName('video')].some(\n        (video) => !video.paused && canBeInSameViewport(element, video),\n    );\n};\n","import type { CsaLatencyMarker } from './global.js';\n\n/**\n * Records a CSA Content Latency marker for a placement element.\n * Timestamps are epoch-based (`Date.now()`), not `performance.now()`.\n * No-ops if CSA is unavailable.\n *\n * @param element - The placement DOM element to record latency for.\n * @param marker - The well-known latency marker name to record.\n * @param timestamp - Optional absolute timestamp. Defaults to now if omitted.\n *\n * @see {@link https://w.amazon.com/bin/view/ClientSideMetrics/UserDocs/CSA/Plugins/ContentInstrumentation/ContentLatency/}\n */\nexport const sendCsaLatencyMetric = (element: HTMLElement, marker: CsaLatencyMarker, timestamp?: Date): void => {\n    window.csa?.('Content', { element })('mark', marker, timestamp?.getTime());\n};\n","import type { Placement } from '../placement.js';\nimport { csmName } from './util.js';\n\ntype UetLatencyEvent = 'bb' | 'be' | 'af' | 'cf';\ntype UexLatencyEvent = 'ld';\n\n/**\n * CSM widget latency marker events.\n *\n * Markers are recorded via `uet()` (timing) or `uex()` (timing + send).\n * All markers require a scope name and `{wb: 1}` flag.\n * Timestamps are epoch-based (`Date.now()`), not `performance.now()`.\n *\n * @remarks\n * **Firing order:**\n *\n * There is no enforced ordering between `bb`, `be`, `af`, and `cf` —\n * they simply record timestamps. However, the conventional order\n * that aligns with their semantic meaning is:\n *\n *\n\n * bb → af → cf → be → ld\n * │    │    │    │    └─ Must be last. Triggers postback.\n * │    │    │    └────── Widget HTML finished rendering\n * │    │    └─────────── Critical/useful content ready\n * │    └──────────────── Visible portion rendered\n * └───────────────────── Widget starts rendering\n *\n\n *\n * Only `bb` and `ld` are needed for minimal instrumentation.\n * Use `af`, `cf`, `be` when you need finer-grained breakdown.\n *\n * **Hard rules:**\n * 1. `'ld'` must always be the last marker fired — it sends all\n *    collected timestamps to the server.\n * 2. Every scope that logs `'bb'` must also log `'ld'`, or metrics\n *    for **all** widgets on the page will be blocked.\n *\n * - `'bb'` — Body Begin: Fire when your widget starts rendering.\n * - `'af'` — Above The Fold: Fire when the visible portion of your widget has rendered.\n * - `'cf'` — Critical Feature: Fire when the main/useful content of your widget has rendered.\n * - `'be'` — Body End: Fire when your widget's HTML finishes rendering.\n * - `'ld'` — Loaded (required): Fire when your widget is fully loaded.\n *   Triggers the postback to send all widget metrics to the server.\n *\n * @see {@link https://w.amazon.com/bin/view/ClientSideMetrics/UserDocs/Instrumentation/InstrumentingWidgets}\n */\nexport type LatencyEvent = UetLatencyEvent | UexLatencyEvent;\n\ndeclare global {\n    // https://code.amazon.com/packages/ClickstreamBrowserDataJavaScript/blobs/mainline/--/javascript/head-open.js\n    interface Window {\n        /** Records a timing marker for a given scope. Timestamp is epoch-based (`Date.now()`). */\n        uet?(\n            eventName: UetLatencyEvent,\n            scope?: string,\n            scopeOptions?: Record<string, unknown>,\n            timeOverride?: number\n        ): void;\n        /** Records a timing marker and sends the postback to the server. */\n        uex?(\n            eventName: UexLatencyEvent,\n            scope?: string,\n            scopeOptions?: Record<string, unknown>,\n            timeOverride?: number\n        ): void;\n    }\n}\n\n/** Parameters for emitting a CSM widget latency metric. */\nexport interface LatencyMetric {\n    /** The latency marker to record. */\n    latencyEvent: LatencyEvent;\n    /** Optional key to further qualify the metric scope (e.g. `'SafeFrame'` or `'LightAd'`). */\n    scope?: string;\n    /** The ad placement to emit metrics for. */\n    placement: Placement;\n    /** Absolute timestamp to record. Defaults to now. Must be epoch-compatible (`Date`). */\n    timestamp?: Date;\n}\n\n/**\n * Emits a single CSM widget latency marker for a given scope.\n * Routes to `uet()` for timing markers or `uex()` for `'ld'` (which triggers the server postback).\n * No-ops if the required window function is unavailable.\n */\nconst emitLatency = (event: LatencyEvent, scope: string, time: number): void => {\n    if (event === 'ld') window.uex?.(event, scope, { wb: 1 }, time);\n    else window.uet?.(event, scope, { wb: 1 }, time);\n};\n\n/**\n * Emits CSM latency metrics for an ad placement, keyed by both placement ID and name.\n * Each call produces two scoped metrics to allow lookup by either identifier.\n * Uses a consistent timestamp across both scopes to ensure aligned measurements.\n *\n * Metrics are published to PMET under `scope:adplacements:<scope?>:<placement>:<metricName>`.\n *\n * @example\n * ```ts\n * sendCsmLatencyMetric({ latencyEvent: 'bb', placement, scope: 'SF' });\n * // ... ad renders ...\n * sendCsmLatencyMetric({ latencyEvent: 'ld', placement, scope: 'LA' });\n *\n */\nexport const sendCsmLatencyMetric = ({ latencyEvent, scope, placement, timestamp }: LatencyMetric): void => {\n    const prefix = `adplacements:${scope ? `${csmName(scope)}:` : ''}`;\n    const time = timestamp?.getTime() ?? Date.now();\n\n    emitLatency(latencyEvent, prefix + placement.id, time);\n    emitLatency(latencyEvent, prefix + csmName(placement.name), time);\n};\n","import type { CsaLatencyMarker } from '@amzn/apejs-instrumentation/src/metrics/csa/global.js';\nimport { sendCsaLatencyMetric } from '@amzn/apejs-instrumentation/src/metrics/csa/latency.js';\nimport type { LatencyEvent } from '@amzn/apejs-instrumentation/src/metrics/csm/latency.js';\nimport { sendCsmLatencyMetric } from '@amzn/apejs-instrumentation/src/metrics/csm/latency.js';\nimport type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport type { AppId } from '@/host/components/csaMetrics.js';\nimport { getWrapper } from '@/host/components/placement.js';\n\nexport interface AdLatencyMetric {\n    adDetails: AdDetails | LightAdDetails;\n    latencyEvent: LatencyEvent;\n    scope: AppId;\n    timestamp?: Date;\n}\n\nconst csaEvents: Partial<Record<LatencyEvent, CsaLatencyMarker[]>> = {\n    bb: ['t0', 'bodyBegin'],\n    af: ['aboveTheFold'],\n    cf: ['criticalFeature', 'functional'],\n    ld: ['loaded', 'feat_vl100'],\n};\n\nexport const sendLatencyMetric = ({ adDetails, latencyEvent, scope, timestamp }: AdLatencyMetric): void => {\n    const element = getWrapper(adDetails) ?? (document.getElementById(adDetails.adUnitPlacementId) as HTMLElement);\n    const { placementId: id, placementName: name } = adDetails;\n\n    sendCsmLatencyMetric({ latencyEvent, placement: { id, name }, scope, timestamp });\n    csaEvents[latencyEvent]?.forEach((marker) => sendCsaLatencyMetric(element, marker, timestamp));\n};\n\n/**\n * When a creative supports TTI (Time To Interactive) measurement, it calls\n * `SFClient.signalAdLoadedAndInteractive()` itself, which is the sole source of `cf` and `ld` metrics.\n * SafeFrame must not fire these metrics to avoid double-counting.\n */\nexport const shouldSafeFrameFireLoadedMetrics = (\n    adDetails: Pick<AdDetails, 'creativeSupportsTTIMeasurement'>,\n): boolean => !adDetails.creativeSupportsTTIMeasurement;\n","/* eslint-disable no-undefined,no-param-reassign,no-shadow */\n\n/**\n * Throttle execution of a function. Especially useful for rate limiting\n * execution of handlers on events like resize and scroll.\n *\n * @param {number} delay -                  A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher)\n *                                            are most useful.\n * @param {Function} callback -               A function to be executed after delay milliseconds. The `this` context and all arguments are passed through,\n *                                            as-is, to `callback` when the throttled-function is executed.\n * @param {object} [options] -              An object to configure options.\n * @param {boolean} [options.noTrailing] -   Optional, defaults to false. If noTrailing is true, callback will only execute every `delay` milliseconds\n *                                            while the throttled-function is being called. If noTrailing is false or unspecified, callback will be executed\n *                                            one final time after the last throttled-function call. (After the throttled-function has not been called for\n *                                            `delay` milliseconds, the internal counter is reset).\n * @param {boolean} [options.noLeading] -   Optional, defaults to false. If noLeading is false, the first throttled-function call will execute callback\n *                                            immediately. If noLeading is true, the first the callback execution will be skipped. It should be noted that\n *                                            callback will never executed if both noLeading = true and noTrailing = true.\n * @param {boolean} [options.debounceMode] - If `debounceMode` is true (at begin), schedule `clear` to execute after `delay` ms. If `debounceMode` is\n *                                            false (at end), schedule `callback` to execute after `delay` ms.\n *\n * @returns {Function} A new, throttled, function.\n */\nfunction throttle (delay, callback, options) {\n  var _ref = options || {},\n      _ref$noTrailing = _ref.noTrailing,\n      noTrailing = _ref$noTrailing === void 0 ? false : _ref$noTrailing,\n      _ref$noLeading = _ref.noLeading,\n      noLeading = _ref$noLeading === void 0 ? false : _ref$noLeading,\n      _ref$debounceMode = _ref.debounceMode,\n      debounceMode = _ref$debounceMode === void 0 ? undefined : _ref$debounceMode;\n  /*\n   * After wrapper has stopped being called, this timeout ensures that\n   * `callback` is executed at the proper times in `throttle` and `end`\n   * debounce modes.\n   */\n\n\n  var timeoutID;\n  var cancelled = false; // Keep track of the last time `callback` was executed.\n\n  var lastExec = 0; // Function to clear existing timeout\n\n  function clearExistingTimeout() {\n    if (timeoutID) {\n      clearTimeout(timeoutID);\n    }\n  } // Function to cancel next exec\n\n\n  function cancel(options) {\n    var _ref2 = options || {},\n        _ref2$upcomingOnly = _ref2.upcomingOnly,\n        upcomingOnly = _ref2$upcomingOnly === void 0 ? false : _ref2$upcomingOnly;\n\n    clearExistingTimeout();\n    cancelled = !upcomingOnly;\n  }\n  /*\n   * The `wrapper` function encapsulates all of the throttling / debouncing\n   * functionality and when executed will limit the rate at which `callback`\n   * is executed.\n   */\n\n\n  function wrapper() {\n    for (var _len = arguments.length, arguments_ = new Array(_len), _key = 0; _key < _len; _key++) {\n      arguments_[_key] = arguments[_key];\n    }\n\n    var self = this;\n    var elapsed = Date.now() - lastExec;\n\n    if (cancelled) {\n      return;\n    } // Execute `callback` and update the `lastExec` timestamp.\n\n\n    function exec() {\n      lastExec = Date.now();\n      callback.apply(self, arguments_);\n    }\n    /*\n     * If `debounceMode` is true (at begin) this is used to clear the flag\n     * to allow future `callback` executions.\n     */\n\n\n    function clear() {\n      timeoutID = undefined;\n    }\n\n    if (!noLeading && debounceMode && !timeoutID) {\n      /*\n       * Since `wrapper` is being called for the first time and\n       * `debounceMode` is true (at begin), execute `callback`\n       * and noLeading != true.\n       */\n      exec();\n    }\n\n    clearExistingTimeout();\n\n    if (debounceMode === undefined && elapsed > delay) {\n      if (noLeading) {\n        /*\n         * In throttle mode with noLeading, if `delay` time has\n         * been exceeded, update `lastExec` and schedule `callback`\n         * to execute after `delay` ms.\n         */\n        lastExec = Date.now();\n\n        if (!noTrailing) {\n          timeoutID = setTimeout(debounceMode ? clear : exec, delay);\n        }\n      } else {\n        /*\n         * In throttle mode without noLeading, if `delay` time has been exceeded, execute\n         * `callback`.\n         */\n        exec();\n      }\n    } else if (noTrailing !== true) {\n      /*\n       * In trailing throttle mode, since `delay` time has not been\n       * exceeded, schedule `callback` to execute `delay` ms after most\n       * recent execution.\n       *\n       * If `debounceMode` is true (at begin), schedule `clear` to execute\n       * after `delay` ms.\n       *\n       * If `debounceMode` is false (at end), schedule `callback` to\n       * execute after `delay` ms.\n       */\n      timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);\n    }\n  }\n\n  wrapper.cancel = cancel; // Return the wrapper function.\n\n  return wrapper;\n}\n\n/* eslint-disable no-undefined */\n/**\n * Debounce execution of a function. Debouncing, unlike throttling,\n * guarantees that a function is only executed a single time, either at the\n * very beginning of a series of calls, or at the very end.\n *\n * @param {number} delay -               A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.\n * @param {Function} callback -          A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, as-is,\n *                                        to `callback` when the debounced-function is executed.\n * @param {object} [options] -           An object to configure options.\n * @param {boolean} [options.atBegin] -  Optional, defaults to false. If atBegin is false or unspecified, callback will only be executed `delay` milliseconds\n *                                        after the last debounced-function call. If atBegin is true, callback will be executed only at the first debounced-function call.\n *                                        (After the throttled-function has not been called for `delay` milliseconds, the internal counter is reset).\n *\n * @returns {Function} A new, debounced function.\n */\n\nfunction debounce (delay, callback, options) {\n  var _ref = options || {},\n      _ref$atBegin = _ref.atBegin,\n      atBegin = _ref$atBegin === void 0 ? false : _ref$atBegin;\n\n  return throttle(delay, callback, {\n    debounceMode: atBegin !== false\n  });\n}\n\nexport { debounce, throttle };\n//# sourceMappingURL=index.js.map\n","import { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport { throttle } from 'throttle-debounce';\n\nimport { safeFunctionWrapper } from '@/components/util.js';\nimport { findDistanceFromViewport } from '@/components/viewability.js';\n\n// Pure javascript version of the delayLoad function from GPAT\nexport const delayUntil = async (firePixelAfter: string | undefined, slotElem: HTMLElement) => {\n    if (!firePixelAfter?.trim().match(/^\\d{1,4}px$/g)) {\n        return;\n    }\n    /* Implement JIT loading, render the ads when the slot that is X pixels above the Encore is viewable.\n     * X will be an adjustable variable based on the regex above.\n     */\n    return await loadJustInTime(\n        parseInt(firePixelAfter, 10),\n        slotElem,\n        (elem: HTMLElement, offset: number): boolean => {\n            const distance = findDistanceFromViewport(elem);\n            return elem && distance <= offset;\n        },\n    );\n};\n\n/*\n    Helper method to implement JIT loading\n    It will execute callback after satisfyConditionToLoadAd(slotElem, offset) return true\n*/\nconst loadJustInTime = async (\n    offset: number,\n    slotElem: HTMLElement,\n    satisfyConditionToLoadAd: (slotElem: HTMLElement, offset: number) => boolean,\n) => {\n    return new Promise<void>((r) => {\n        const positionTracker = () => {\n            if (satisfyConditionToLoadAd(slotElem, offset)) {\n                r();\n                window.removeEventListener('scroll', throttledPositionTracker);\n                window.removeEventListener('resize', throttledPositionTracker);\n            }\n        };\n\n        const throttledPositionTracker = safeFunctionWrapper(\n            throttle(20, () => {\n                positionTracker();\n            }),\n            logError,\n        );\n        window.addEventListener('scroll', throttledPositionTracker);\n        window.addEventListener('resize', throttledPositionTracker);\n        // An initial fire is needed because certain cases the browser\n        // returns to the page to the same vertical position without calling\n        // scroll or resize\n        positionTracker();\n    });\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { observeUntilIntersection } from '@/components/intersectionObserver.js';\nimport { delayUntil } from '@/host/components/loading.js';\nimport { getPlacement } from '@/host/components/placement.js';\n\n/**\n * Waits for any configured pixel delay, then waits until the ad is in the DOM and visible.\n */\nexport const waitUntilReadyForTracking = async (adDetails: AdDetails) => {\n    const placement = getPlacement(adDetails);\n\n    if (adDetails.firePixelsAfter) {\n        await delayUntil(adDetails.firePixelsAfter, placement);\n    }\n\n    // We used to need to check for prerender but no longer\n    // https://groups.google.com/a/chromium.org/g/blink-reviews/c/hddZM1HibrY\n    // https://udn.realityripple.com/docs/Web/API/Document/visibilityState\n    // Once we have a either a hidden or visible document then we can begin to check for the intersection\n    await observeUntilIntersection(placement, {\n        root: hasFixedPositionAncestor(placement) ? VIEWPORT_ROOT : document.documentElement,\n    });\n};\n\n/** Null root tells IntersectionObserver to use the viewport as the root */\nconst VIEWPORT_ROOT = null;\n\n/**\n * Function for returning if an element has an ancestor with css set to position:fixed.\n * @param element to check ancestors for\n * @return returns a boolean on if the given element has a fixed position ancestor or not\n */\nconst hasFixedPositionAncestor = (element: HTMLElement): boolean => {\n    let currentParent: HTMLElement | null = element;\n    while (currentParent) {\n        // we need to use computed style because fixed position may be inherited/computed and not set inline\n        const parentStyle = window.getComputedStyle(currentParent, null);\n        if (parentStyle.getPropertyValue('position') === 'fixed') {\n            return true;\n        }\n        currentParent = currentParent.parentElement;\n    }\n\n    return false;\n};\n","import { incrementCsmCounter } from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport type {} from '@/client/app/safeframeClient.js';\nimport { type TimestampData } from '@/components/commands.js';\nimport { labelRendered, openModal } from '@/components/feedback.js';\nimport type { GwVideoOrchestratorOptions } from '@/components/homepage/homepageVideoOrchestrator.js';\nimport type { PixelInfo } from '@/components/pixels/pixelMapper.js';\nimport { mapToImpressionPixel } from '@/components/pixels/pixelMapper.js';\nimport type { SfVideoContinuousPlaytimeEventDetail } from '@/components/pixels/services/videoFirePixelValidator.js';\nimport { SF_VIDEO_CONTINUOUS_PLAYTIME_SECONDS_EVENT } from '@/components/pixels/services/videoFirePixelValidator.js';\nimport { changeSizeHandler } from '@/host/api-client/handlers/changeSizeHandler.js';\nimport { collapseSlotHandler } from '@/host/api-client/handlers/collapseSlotHandler.js';\nimport {\n    haveVideoAutoplayPermissionHandler,\n    releaseVideoAutoplayHandler,\n    requestVideoAutoplayHandler,\n} from '@/host/api-client/handlers/videoHandlers.js';\nimport type { HostMessageSender } from '@/host/api-client/hostMessageSender.js';\nimport { sendLatencyMetric } from '@/host/components/latency.js';\nimport { getPlacement } from '@/host/components/placement.js';\nimport { waitUntilReadyForTracking } from '@/host/components/waitUntilReadyForTracking.js';\nimport type { HostContext } from '@/host/context/HostContext.js';\n\n// These are the commands that are supported by all the ad-serving platforms.\n// Do not add anything that you do not want to be run directly by the SF client javascript simply by receiving a message!\n// These are validated staticaly for literals on the client side but at runtime it is fair game\nexport class CommonSupportedCommands {\n    constructor(\n        protected readonly hms: HostMessageSender,\n        public hc: HostContext,\n    ) {}\n\n    changeSize = changeSizeHandler;\n\n    /**\n     * Verified in use May 29 2025\n     * https://csm.amazon.com/#/rulelist/metric/474984\n     */\n    requestVideoAutoplay = (adDetails: AdDetails, data: GwVideoOrchestratorOptions) => {\n        incrementCsmCounter('common:supported:command:requestVideoAutoplay');\n        requestVideoAutoplayHandler(adDetails, data, this.hms);\n    };\n\n    /**\n     * Verified in use May 29 2025\n     * https://csm.amazon.com/#/rulelist/metric/474985\n     */\n    releaseVideoAutoplay = () => {\n        incrementCsmCounter('common:supported:command:releaseVideoAutoplay');\n        releaseVideoAutoplayHandler();\n    };\n\n    /**\n     * Verified in use May 29 2025\n     * https://csm.amazon.com/#/rulelist/metric/474986\n     */\n    haveVideoAutoplayPermission = (adDetails: AdDetails) => {\n        incrementCsmCounter('common:supported:command:haveVideoAutoplayPermission');\n        haveVideoAutoplayPermissionHandler(adDetails);\n    };\n\n    feedbackLabelRendered = (adDetails: AdDetails) =>\n        labelRendered({\n            id: adDetails.placementId,\n            name: adDetails.placementName,\n        });\n    feedbackOpenModal = (adDetails: AdDetails) => openModal(adDetails.adUnitWrapperId ?? adDetails.adUnitPlacementId);\n\n    collapseSlot = collapseSlotHandler;\n\n    /**\n     * Fires the COD impression pixel on the host side using the Light Ads logic\n     *\n     * @param {AdInfo} adInfo - Ad information object\n     */\n    sendEventAddedCreative = async (adDetails: AdDetails) => {\n        await waitUntilReadyForTracking(adDetails);\n        await mapToImpressionPixel(getPixelInfo(adDetails)).fire({\n            id: adDetails.placementId,\n            name: adDetails.placementName,\n            div: getPlacement(adDetails),\n            deviceType: adDetails.deviceType,\n        });\n    };\n\n    /**\n     * Called when the client signals the creative is fully loaded and interactive.\n     * Fires the 'cf' (critical feature) and 'ld' (loaded) latency metrics on the host side.\n     */\n    signalAdLoadedAndInteractive = (adDetails: AdDetails, { timestamp }: TimestampData) => {\n        sendLatencyMetric({ adDetails, latencyEvent: 'cf', scope: 'SF', timestamp });\n        sendLatencyMetric({ adDetails, latencyEvent: 'ld', scope: 'SF', timestamp });\n    };\n\n    /**\n     * Called when client send continuous playtime for video creatives.\n     */\n    sendSfVideoContinuousPlaytimeSeconds = (adDetails: AdDetails, data: SfVideoContinuousPlaytimeEventDetail) => {\n        const placement = getPlacement(adDetails);\n        const sfVideoContinuousPlaytimeSecondsEvent = new CustomEvent<SfVideoContinuousPlaytimeEventDetail>(\n            SF_VIDEO_CONTINUOUS_PLAYTIME_SECONDS_EVENT,\n            {\n                detail: data,\n            },\n        );\n        placement.dispatchEvent(sfVideoContinuousPlaytimeSecondsEvent);\n    };\n}\n\nexport const getPixelInfo = (adDetails: AdDetails): PixelInfo => ({\n    aaxImpPixelUrl: adDetails.aaxImpPixelUrl,\n    aaxInstrPixelUrl: adDetails.aaxInstrPixelUrl,\n    abpAcceptable: adDetails.abpAcceptable,\n    abpStatus: adDetails.abpStatus ?? '-1',\n    btrPixelUrl: adDetails.btrPixelUrl,\n    skAdNetwork: adDetails.skAdNetwork,\n    loggingContext: {\n        aaxProgramId: Number(adDetails.adCreativeMetaData.adProgramId),\n    },\n});\n","export interface Cache<T> {\n    set(value: T): void;\n    get(): T;\n}\n\nexport interface MapCache<K, V> {\n    set(key: K, value: V): void;\n    get(key: K): V | undefined;\n}\n\nexport const createMapCache = <K, V>(): MapCache<K, V> => {\n    const map = new Map<K, V>();\n\n    return {\n        set(key: K, value: V): void {\n            map.set(key, value);\n        },\n        get(key: K): V | undefined {\n            return map.get(key);\n        },\n    };\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { logLowRateMetricSF } from '@/components/metrics/awsMetricLogger.js';\n\nconst ENTRY_NAME_REGEX = /AdPlacementStyleAssets|apePlacements/;\n\nexport const logAssetMetrics = (adDetails: AdDetails): void => {\n    const entries = performance.getEntriesByType('resource');\n    const entry = entries.find((entry) => entry.name.match(ENTRY_NAME_REGEX)?.[0]) as PerformanceResourceTiming;\n\n    if (entry) {\n        const assetName = entry.name.match(ENTRY_NAME_REGEX)?.[0];\n\n        logLowRateMetricSF({\n            metricName: 'asset:load:timing',\n            adDetails,\n            additionalDimensions: {\n                ...(assetName && { assetName }),\n                assetUrl: entry.name,\n                dns: String(entry.domainLookupEnd - entry.domainLookupStart),\n                tcp: String(entry.connectEnd - entry.connectStart),\n                ttfb: String(entry.responseStart - entry.requestStart),\n                download: String(entry.responseEnd - entry.responseStart),\n                total: String(entry.responseEnd - entry.startTime),\n            },\n            once: true,\n        });\n    }\n};\n","import { emitCsaMetric } from '@amzn/apejs-instrumentation/src/metrics/csa/events.js';\nimport type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport { CSA_METRICS_WEBLAB } from '@/components/weblabs.js';\n\nexport type AppId = 'SF' | 'LA';\n\ntype RequestId = string;\n\ndeclare global {\n    interface Window {\n        ue_id?: RequestId;\n    }\n}\n\ntype LifecycleMetricName = 'event:start' | 'event:prewrite' | 'event:postwrite' | 'event:btr' | 'event:load';\ntype CoordinateMetricName = 'coordinate:x' | 'coordinate:y';\nexport type MetricName = LifecycleMetricName | CoordinateMetricName;\n\ninterface EmitPlacementMetricParams {\n    metricName: MetricName;\n    metricValue: number;\n    adDetails: AdDetails | LightAdDetails;\n    app: AppId;\n    timestamp?: Date;\n}\n\nexport const emitMetric = ({ metricName, metricValue, adDetails, app, timestamp }: EmitPlacementMetricParams): void => {\n    if (!CSA_METRICS_WEBLAB().is('t1')) return;\n\n    const { slotName, siteName, deviceType, pageType, placementId } = adDetails;\n\n    emitCsaMetric({\n        metricName,\n        metricValue,\n        timestamp,\n        dimension: {\n            app,\n            slotName,\n            siteName,\n            deviceType,\n            pageType,\n            placementId,\n            ...(window.ue_id ? { requestId: window.ue_id } : {}),\n        },\n    });\n};\n","import { incrementCsmPlacementCounter } from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport { emitMetric } from '@/host/components/csaMetrics.js';\nimport type { AppId } from '@/host/components/csaMetrics.js';\nimport type { Placement } from '@/host/domain/placement.js';\n\nexport const logCoordinates = (placement: Placement, adDetails: AdDetails | LightAdDetails, app: AppId) => {\n    try {\n        const { x, y } = placement.div.getBoundingClientRect();\n        incrementCsmPlacementCounter('coordinate:x', placement, x);\n        incrementCsmPlacementCounter('coordinate:y', placement, y);\n        emitMetric({ metricName: 'coordinate:x', metricValue: x, adDetails, app });\n        emitMetric({ metricName: 'coordinate:y', metricValue: y, adDetails, app });\n    } catch (_e) {\n        // We don't want to log this error because it's not a critical error\n        // We just use this to log the coordinates of the placement\n        // If it fails once in a while, it's not a big deal\n        return;\n    }\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { MapCache } from '@/components/cache.js';\nimport { getPlacement } from '@/host/components/placement.js';\n\nexport const CLICK_FAILURE_METRIC_CSM = 'adplacements:retailClickTracking:failure';\nexport const CLICK_MISSING_URL_METRIC_CSM = 'adplacements:retailClickTracking:missingUrl';\nexport const CLICK_SUCCESS_METRIC_CSM = 'adplacements:retailClickTracking:clickSuccess';\n\nexport const cacheClickTrackingUrl = (adDetails: AdDetails, urlCache: MapCache<string, string>): void => {\n    const url = getPlacement(adDetails)?.getAttribute('data-click-addr');\n    if (url) {\n        urlCache.set(adDetails.adUnitPlacementId, url);\n        console.log('Click tracking: Cached URL:', url, 'Placement:', adDetails.adUnitPlacementId);\n    }\n};\n\nexport const fireRetailClickTrackingFromCache = (adDetails: AdDetails, url: string | undefined): void => {\n    if (url) {\n        getPlacement(adDetails)?.removeAttribute('onclick');\n        fireRetailClickTracking(url);\n        console.log('Click tracking: Fired URL:', url, 'Placement:', adDetails.adUnitPlacementId);\n    } else {\n        window.ue.count(CLICK_MISSING_URL_METRIC_CSM, 1);\n        console.log('Click tracking: URL is missing', 'Placement:', adDetails.adUnitPlacementId);\n    }\n};\n\nexport const fireRetailClickTracking = async (retailClickTrackingUrl: string) => {\n    try {\n        const response = await fetch(retailClickTrackingUrl, { keepalive: true, redirect: 'manual' });\n        if (response.ok || response.type === 'opaqueredirect') {\n            window.ue.count(CLICK_SUCCESS_METRIC_CSM, 1);\n        } else {\n            window.ue.count(CLICK_FAILURE_METRIC_CSM, 1);\n        }\n    } catch (_ex) {\n        window.ue.count(CLICK_FAILURE_METRIC_CSM, 1);\n    }\n};\n","import type { Pixel } from '@/components/pixels/pixel.js';\nimport type { Placement } from '@/components/pixels/pixel.js';\nimport { btr } from '@/components/pixels/placementData.js';\nimport type { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.js';\nimport type { ViewabilityService } from '@/components/pixels/services/viewabilityService.js';\nimport { createViewabilityTracker } from '@/components/pixels/viewabilityTrackerImpl.js';\nimport { VIEW_RATE_EXPERIMENT, VIEW_RATE_EXPERIMENT_TIMEOUT } from '@/components/weblabs.js';\n\n/**\n * TODO: Clean up View Rate Experiment\n * https://sim.amazon.com/issues/ASPEN-9994\n */\nexport interface ViewRateExperimentPixels {\n    impressionPixel: Pixel;\n    btrPixel?: Pixel;\n    measurabilityPixel: Pixel;\n}\n\nconst weblabTreatmentToThreshold: Record<string, number> = {\n    c: 0,\n    t1: 0.1,\n    t2: 0.2,\n    t3: 0.3,\n    t4: 0.4,\n    t5: 0.5,\n};\n\nconst weblabTreatmentToTimeout: Record<string, number> = {\n    c: 0,\n    t1: 100,\n    t2: 200,\n    t3: 300,\n    t4: 400,\n    t5: 500,\n    t6: 600,\n    t7: 700,\n    t8: 800,\n    t9: 900,\n};\n\nexport const isViewRateExperimentEnabled = (aaxProgramId: number): boolean => {\n    return aaxProgramId !== 1004 && VIEW_RATE_EXPERIMENT().isInTreatment();\n};\n\nconst btrFirePixelValidator = (placement: Placement): FirePixelValidator => {\n    return {\n        shouldFirePixel(): boolean {\n            return btr.get(placement);\n        },\n    };\n};\n\nexport const trackViewRateExperiment = (\n    placement: Placement,\n    pixels: ViewRateExperimentPixels,\n    viewabilityService: ViewabilityService,\n): void => {\n    const viewabilityStandard = {\n        definition: '',\n        thresholdPercentage: weblabTreatmentToThreshold[VIEW_RATE_EXPERIMENT().getTreatment()],\n        thresholdTimeVisibleMs: weblabTreatmentToTimeout[VIEW_RATE_EXPERIMENT_TIMEOUT().getTreatment()],\n    };\n    // ViewabilityTracker for impression and measurability pixels\n    const impViewabilityTracker = createViewabilityTracker(\n        [pixels.impressionPixel, pixels.measurabilityPixel],\n        viewabilityStandard,\n        viewabilityService,\n        [],\n    );\n    impViewabilityTracker.track(placement);\n\n    // ViewabilityTracker for btrPixel\n    if (pixels.btrPixel) {\n        const btrViewabilityTracker = createViewabilityTracker(\n            [pixels.btrPixel],\n            viewabilityStandard,\n            viewabilityService,\n            [btrFirePixelValidator(placement)],\n        );\n        btrViewabilityTracker.track(placement);\n    }\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { mapToBtrPixel } from '@/components/pixels/pixelMapper.js';\nimport { isViewRateExperimentEnabled } from '@/components/viewRateExperimentUtil.js';\nimport { getPixelInfo } from '@/host/api-client/CommonSupportedCommands.js';\nimport { getPlacement } from '@/host/components/placement.js';\nimport { waitUntilReadyForTracking } from '@/host/components/waitUntilReadyForTracking.js';\n\nexport const sendEventCreativeBeginToRenderHandler = async (adDetails: AdDetails) => {\n    // Do nothing: use view rate IO to fire BTR pixel\n    if (isViewRateExperimentEnabled(Number(adDetails.adCreativeMetaData.adProgramId))) return;\n\n    await waitUntilReadyForTracking(adDetails);\n\n    mapToBtrPixel(getPixelInfo(adDetails))?.fire({\n        id: adDetails.placementId,\n        name: adDetails.placementName,\n        div: getPlacement(adDetails),\n        deviceType: adDetails.deviceType,\n    });\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { Placement } from '@/components/pixels/pixel.js';\nimport type { PixelInfo } from '@/components/pixels/pixelMapper.js';\nimport { mapToSkanImpressionPixel, mapToSkanViewPixel } from '@/components/pixels/pixelMapper.js';\nimport { getPixelInfo } from '@/host/api-client/CommonSupportedCommands.js';\nimport { getPlacement } from '@/host/components/placement.js';\n\nexport const enableSkanViewabilityTracker = async (adDetails: AdDetails) => {\n    const pixelInfo: PixelInfo = getPixelInfo(adDetails);\n    const placement: Placement = {\n        id: adDetails.placementId,\n        name: adDetails.placementName,\n        div: getPlacement(adDetails),\n        deviceType: adDetails.deviceType,\n    };\n\n    await mapToSkanImpressionPixel(pixelInfo)?.fire(placement);\n    mapToSkanViewPixel(pixelInfo)?.track(placement);\n};\n","import { createObstructionDetectionService } from '@amzn/creative-obstruction-detection/src/obstructionDetectionServiceImpl.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { ViewPixelOptionsData } from '@/components/commands.js';\nimport type { Placement } from '@/components/pixels/pixel.js';\nimport type { PixelInfo } from '@/components/pixels/pixelMapper.js';\nimport {\n    createIabViewPixel,\n    mapToBtrPixel,\n    mapToImpressionPixel,\n    mapToMeasurabilityPixel,\n} from '@/components/pixels/pixelMapper.js';\nimport { btr } from '@/components/pixels/placementData.js';\nimport { createSafeFrameVideoFirePixelValidator } from '@/components/pixels/services/videoFirePixelValidator.js';\nimport { createViewabilityService } from '@/components/pixels/services/viewabilityServiceImpl.js';\nimport type { ViewPixel } from '@/components/pixels/viewPixel.ts';\nimport { isViewRateExperimentEnabled, trackViewRateExperiment } from '@/components/viewRateExperimentUtil.js';\nimport { getPixelInfo } from '@/host/api-client/CommonSupportedCommands.js';\nimport { getPlacement } from '@/host/components/placement.js';\nimport { enableSkanViewabilityTracker } from '@/host/components/skanViewabilityTracker.js';\nimport { waitUntilReadyForTracking } from '@/host/components/waitUntilReadyForTracking.js';\n\nexport const sendEventCreativeLoadedHandler = async (adDetails: AdDetails, data: ViewPixelOptionsData) => {\n    const placementDiv = getPlacement(adDetails);\n    await waitUntilReadyForTracking(adDetails);\n    const pixelInfo: PixelInfo = getPixelInfo(adDetails);\n    const placement: Placement = {\n        id: adDetails.placementId,\n        name: adDetails.placementName,\n        div: placementDiv,\n        deviceType: adDetails.deviceType,\n    };\n\n    btr.set(placement, data.isBtr);\n\n    if (isViewRateExperimentEnabled(Number(adDetails.adCreativeMetaData.adProgramId))) {\n        const obstructionDetectionService = createObstructionDetectionService();\n        trackViewRateExperiment(\n            placement,\n            {\n                impressionPixel: mapToImpressionPixel(pixelInfo),\n                btrPixel: mapToBtrPixel(pixelInfo),\n                measurabilityPixel: mapToMeasurabilityPixel(pixelInfo),\n            },\n            createViewabilityService(obstructionDetectionService),\n        );\n    } else {\n        mapToMeasurabilityPixel(pixelInfo).fire(placement);\n    }\n\n    enableSkanViewabilityTracker(adDetails);\n\n    const iabViewPixel = getIabViewPixel(pixelInfo, adDetails, placement);\n\n    iabViewPixel.track(placement);\n};\n\nconst getIabViewPixel = (pixelInfo: PixelInfo, adDetails: AdDetails, placement: Placement): ViewPixel => {\n    const videoFirePixelValidator = () => createSafeFrameVideoFirePixelValidator(placement);\n    return createIabViewPixel(\n        adDetails.mediaType,\n        placement.div,\n        pixelInfo,\n        adDetails.deviceType,\n        videoFirePixelValidator,\n        adDetails,\n    );\n};\n","import type {\n    GeometricInformation,\n    SelfRelativeAndInView,\n    WholePercentage,\n} from '@amzn/safe-frame-client/dist/types/src/IABSafeFrameClient.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { HostMessageSender } from '@/host/api-client/hostMessageSender.js';\nimport { getIFrame } from '@/host/components/iframe.js';\n\nconst ALL_WHOLE_PERCENT_NUMBERS = Array.from({ length: 100 }, (_, i) => (i + 1) / 100);\n\nexport const sendSafeFrameExtOnIntersection = (adDetails: AdDetails, hms: HostMessageSender) => {\n    const iframe = getIFrame(adDetails);\n    if (!iframe) return;\n\n    new IntersectionObserver((entries) => entries.forEach((entry) => sendSafeFrameExt(adDetails, hms, entry)), {\n        threshold: ALL_WHOLE_PERCENT_NUMBERS,\n    }).observe(iframe);\n};\n\nconst sendSafeFrameExt = (\n    adDetails: AdDetails,\n    hms: HostMessageSender,\n    { target, intersectionRect, boundingClientRect, intersectionRatio }: IntersectionObserverEntry,\n): void => {\n    const iframe = target as HTMLIFrameElement;\n    const percentVisibleOnX = intersectionRect.width / boundingClientRect.width;\n    const percentVisibleOnY = intersectionRect.height / boundingClientRect.height;\n\n    hms.sendMessageToAd<SafeFrameExtMessage>(adDetails.arid, 'populateSafeFrameExt', {\n        geom: {\n            self: {\n                t: boundingClientRect.top,\n                l: boundingClientRect.left,\n                r: boundingClientRect.right,\n                b: boundingClientRect.bottom,\n                xiv: percentVisibleOnX,\n                yiv: percentVisibleOnY,\n                iv: intersectionRatio,\n                z: 1,\n                w: iframe.offsetWidth,\n                h: iframe.offsetHeight,\n            },\n        } as Partial<GeometricInformation> as GeometricInformation,\n        inViewPercentage: Math.round(intersectionRatio * 100),\n    });\n};\n\nexport const sendGeomOnInterval = (adDetails: AdDetails, hms: HostMessageSender): void => {\n    const iframe = getIFrame(adDetails);\n\n    if (!iframe) return;\n\n    setInterval(() => {\n        const rect = iframe.getBoundingClientRect();\n\n        hms.sendMessageToAd<GeomMessage>(adDetails.arid, 'populateGeom', {\n            geom: {\n                self: {\n                    t: rect.top,\n                    l: rect.left,\n                    r: rect.right,\n                    b: rect.bottom,\n                    z: 1,\n                    w: iframe.offsetWidth,\n                    h: iframe.offsetHeight,\n                } as Partial<SelfRelativeAndInView> as SelfRelativeAndInView,\n            } as Partial<GeometricInformation> as GeometricInformation,\n        });\n    }, 250);\n};\n\nexport interface SafeFrameExtMessage {\n    geom: GeometricInformation;\n    inViewPercentage: WholePercentage;\n}\n\nexport interface GeomMessage {\n    geom: GeometricInformation;\n}\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { getPlacement } from '@/host/components/placement.js';\n\nexport const EWC_EXIST_CLASS_NAME = 'nav-ewc-persistent-hover';\nexport const EWC_SELECTOR = 'div#nav-flyout-ewc';\nconst NAV_CART_TOGGLE_CLASS = 'nav-cart';\nexport const NAV_CART_FULL_WIDTH_VAR = '--nav-cart-full-width';\nexport const NAV_CART_HALF_WIDTH_VAR = '--nav-cart-half-width';\n\nexport const toggleNavCartClassOnMutation = (adDetails: AdDetails): void => {\n    const target = document.documentElement;\n    const placementDiv = getPlacement(adDetails);\n\n    toggleNavCartClass(target, placementDiv);\n\n    new MutationObserver((mutations) => {\n        for (const mutation of mutations) {\n            if (mutation.type === 'attributes' && mutation.attributeName === 'class') {\n                const targetElement = mutation.target as HTMLElement;\n                toggleNavCartClass(targetElement, placementDiv);\n            }\n        }\n    }).observe(target, {\n        attributes: true,\n        attributeFilter: ['class'],\n    });\n};\n\nconst toggleNavCartClass = (targetElement: Element, placementDiv: HTMLElement) => {\n    if (targetElement.classList.contains(EWC_EXIST_CLASS_NAME)) {\n        placementDiv.classList.add(NAV_CART_TOGGLE_CLASS);\n        const ewcWidth = getEwcWidth();\n        placementDiv.style.setProperty(NAV_CART_FULL_WIDTH_VAR, `${ewcWidth}px`);\n        placementDiv.style.setProperty(NAV_CART_HALF_WIDTH_VAR, `${ewcWidth / 2}px`);\n    } else {\n        placementDiv.classList.remove(NAV_CART_TOGGLE_CLASS);\n    }\n};\n\nconst getEwcWidth = (): number => {\n    const ewc = document.querySelector(EWC_SELECTOR);\n    return ewc instanceof HTMLElement ? ewc.offsetWidth : 0;\n};\n","import {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { createMapCache } from '@/components/cache.js';\nimport type { ComputedAdDetailsData } from '@/components/commands.js';\nimport type { Context } from '@/components/messageChannel/bridge/bridge.js';\nimport type { HostImpl } from '@/components/messageChannel/bridge/hostBridge.js';\nimport type {\n    EventsChannel,\n    OnCreativeLoadPayload,\n    OnErrorPayload,\n} from '@/components/messageChannel/eventsChannel.js';\nimport { logAssetMetrics } from '@/components/metrics/assetMetricLogger.js';\nimport { logCoordinates } from '@/components/metrics/coordinate-logger.js';\nimport { logResponsivePlacement } from '@/components/metrics/size-info-logger.js';\nimport { mark } from '@/components/perf.js';\nimport { collapseSlotHandler } from '@/host/api-client/handlers/collapseSlotHandler.js';\nimport {\n    cacheClickTrackingUrl,\n    fireRetailClickTrackingFromCache,\n} from '@/host/api-client/handlers/retailClickTrackingHandler.js';\nimport { sendEventCreativeBeginToRenderHandler } from '@/host/api-client/handlers/sendEventCreativeBeginToRenderHandler.js';\nimport { sendEventCreativeLoadedHandler } from '@/host/api-client/handlers/sendEventCreativeLoadedHandler.js';\nimport { sendGeomOnInterval, sendSafeFrameExtOnIntersection } from '@/host/api-client/handlers/sendSafeFrameExt.js';\nimport type { HostMessageSender } from '@/host/api-client/hostMessageSender.js';\nimport { emitMetric } from '@/host/components/csaMetrics.js';\nimport { sendLatencyMetric, shouldSafeFrameFireLoadedMetrics } from '@/host/components/latency.js';\nimport { getPlacement } from '@/host/components/placement.js';\nimport { mapToPlacement } from '@/host/domain/placementMapper.js';\nimport { toggleNavCartClassOnMutation } from '@/host/slotSpecific/navCartClassToggle.js';\n\nexport const createHostEventsChannel = (hms: HostMessageSender): HostImpl<EventsChannel> => {\n    const clickTrackingUrlCache = createMapCache<string, string>();\n\n    return {\n        onSafeFrameReady({ adDetails, timestamp }: Context, startTime: number): void {\n            emitMetric({\n                metricName: 'event:start',\n                app: 'SF',\n                adDetails,\n                timestamp,\n                metricValue: startTime,\n            });\n            sendLatencyMetric({ adDetails, latencyEvent: 'bb', scope: 'SF', timestamp });\n\n            mark('perf:sf:host', 'safeFrameReady', adDetails);\n            hms.sendMessageToAd<ComputedAdDetailsData>(adDetails.arid, 'setupComputedAdDetails', {\n                aPageStart: window.aPageStart, // This is used for https://console.harmony.a2z.com/aax-hub/apis/logging-api/aax-log#pixel-view-payload-log computation so we can delay this\n                adStartTime: new Date().getTime(), // https://console.harmony.a2z.com/aax-hub/apis/logging-api/aax-log#pixel-view-payload-log\n            });\n\n            //Exposed the resize event to SafeFrame window\n            window.addEventListener('resize', () => {\n                hms.sendCustomMessageToAd(adDetails.arid, 'resize', {\n                    height: window.innerHeight,\n                    width: window.innerWidth,\n                });\n            });\n\n            toggleNavCartClassOnMutation(adDetails);\n            sendSafeFrameExtOnIntersection(adDetails, hms);\n            sendGeomOnInterval(adDetails, hms);\n            logCoordinates(mapToPlacement(adDetails), adDetails, 'SF');\n            logAssetMetrics(adDetails);\n            cacheClickTrackingUrl(adDetails, clickTrackingUrlCache);\n        },\n\n        onPreCreativeWrite({ adDetails, timestamp }: Context, latency: number): void {\n            emitMetric({\n                metricName: 'event:prewrite',\n                app: 'SF',\n                adDetails,\n                timestamp,\n                metricValue: latency,\n            });\n        },\n\n        onPostCreativeWrite({ adDetails, timestamp }: Context, latency: number): void {\n            emitMetric({\n                metricName: 'event:postwrite',\n                app: 'SF',\n                adDetails,\n                timestamp,\n                metricValue: latency,\n            });\n            sendLatencyMetric({ adDetails, latencyEvent: 'af', scope: 'SF', timestamp });\n        },\n\n        onCreativeBeginToRender({ adDetails, timestamp }: Context, latency: number): void {\n            emitMetric({\n                metricName: 'event:btr',\n                app: 'SF',\n                adDetails,\n                timestamp,\n                metricValue: latency,\n            });\n            if (shouldSafeFrameFireLoadedMetrics(adDetails)) {\n                sendLatencyMetric({ adDetails, latencyEvent: 'cf', scope: 'SF', timestamp });\n            }\n            sendEventCreativeBeginToRenderHandler(adDetails);\n        },\n\n        onCreativeLoad(\n            { adDetails, timestamp }: Context,\n            { isImageOnlyTemplate, isBtr, latency }: OnCreativeLoadPayload,\n        ): void {\n            emitMetric({\n                metricName: 'event:load',\n                app: 'SF',\n                adDetails,\n                timestamp,\n                metricValue: latency,\n            });\n            if (shouldSafeFrameFireLoadedMetrics(adDetails)) {\n                if (!isBtr) {\n                    sendLatencyMetric({ adDetails, latencyEvent: 'cf', scope: 'SF', timestamp });\n                }\n                sendLatencyMetric({ adDetails, latencyEvent: 'ld', scope: 'SF', timestamp });\n            }\n\n            logResponsivePlacement(adDetails);\n\n            if (isImageOnlyTemplate) {\n                getPlacement(adDetails).classList.add('is-image-oo');\n            }\n\n            sendEventCreativeLoadedHandler(adDetails, { isBtr });\n        },\n\n        onError({ adDetails }: Context, { code, isBTR, error }: OnErrorPayload): void {\n            logEvent('eventsChannel:onError', adDetails);\n            logEvent(`eventsChannel:onError:${code}`, adDetails);\n            if (code === 'CLIENT_SETUP') {\n                logError('Failed to setup creative', error);\n            }\n            if (!isBTR && (code === 'CLIENT_ERROR' || code === 'CLIENT_SETUP')) {\n                collapseSlotHandler(adDetails, code);\n            }\n        },\n\n        onClick({ adDetails }: Context): void {\n            fireRetailClickTrackingFromCache(adDetails, clickTrackingUrlCache.get(adDetails.adUnitPlacementId));\n        },\n    };\n};\n\nconst logEvent = (metric: string, adDetails: AdDetails): void => {\n    const m = metric.toLowerCase();\n    incrementCsmCounter(m, performance.now());\n    incrementCsmPlacementCounter(\n        m,\n        {\n            id: adDetails.placementId,\n            name: adDetails.placementName,\n        },\n        performance.now(),\n    );\n};\n","/**\n * Parameters for executeWhenConditionMet function.\n */\ninterface ExecuteWhenConditionMetParams {\n    /** Function that returns true when the condition is met */\n    condition: () => boolean;\n    /** Async action to execute when condition is met */\n    action: () => Promise<void>;\n    /** Maximum time to wait in milliseconds (default: 1000ms) */\n    maxWaitMs?: number;\n    /** Multiplier for exponential backoff (default: 1.5) */\n    backoffMultiplier?: number;\n}\n\n/**\n * Repeatedly checks a condition and executes an action when the condition is met.\n * Uses requestAnimationFrame for fast initial checks (first 200ms), then switches\n * to exponential backoff with setTimeout.\n *\n * @param params - Configuration parameters\n * @returns Promise that resolves when action completes, rejects on timeout or error\n * @throws Error if condition is not met within maxWaitMs\n *\n * @example\n * ```typescript\n * await executeWhenConditionMet({\n *   condition: () => document.getElementById('ad-container') !== null,\n *   action: async () => { console.log('Ad container ready'); },\n *   maxWaitMs: 2000,\n *   backoffMultiplier: 2\n * });\n * ```\n */\nexport const executeWhenConditionMet = async ({\n    condition,\n    action,\n    maxWaitMs = 1000,\n    backoffMultiplier = 1.5,\n}: ExecuteWhenConditionMetParams) => {\n    if (condition()) {\n        await action();\n        return;\n    }\n\n    return new Promise<void>((resolve, reject) => {\n        const startTime = performance.now();\n        let currentDelay = 50;\n        const fastPhaseMs = 200;\n\n        const retry = async (): Promise<void> => {\n            if (condition()) {\n                try {\n                    await action();\n                    resolve();\n                } catch (error) {\n                    reject(error);\n                }\n                return;\n            }\n\n            const elapsed = performance.now() - startTime;\n\n            if (elapsed >= maxWaitMs) {\n                reject(new Error(`Condition not met after ${maxWaitMs}ms`));\n                return;\n            }\n\n            if (elapsed < fastPhaseMs) {\n                requestAnimationFrame(retry);\n            } else {\n                setTimeout(retry, currentDelay);\n                currentDelay = Math.min(currentDelay * backoffMultiplier, 200);\n            }\n        };\n\n        retry();\n    });\n};\n","import {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\nimport { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { ToHostCommandType } from '@/client/api/internal/clientMessageSender.js';\nimport { executeWhenConditionMet } from '@/components/executeWhenConditionMet.js';\nimport type { ClientMessageToHost } from '@/components/messenger.js';\nimport { IFRAME_READY_RETRY_WEBLAB } from '@/components/weblabs.js';\nimport type { CommonSupportedCommands } from '@/host/api-client/CommonSupportedCommands.js';\n\n/**\n * Handles messages sent from the SafeFrame client to the host.\n * Routes commands to supported command handlers. Channel messages\n * (CSM, Events) are handled by the bridge via {@link bindHostImpl}.\n */\nexport class HostMessageReceiver {\n    constructor(readonly supportedCommands: CommonSupportedCommands) {}\n\n    /**\n     * Receives a message from the SafeFrame client.\n     * When {@link IFRAME_READY_RETRY_WEBLAB} is `t1`, defers execution until the iframe element is present in the DOM.\n     */\n    receiveMessage = async ({ data }: MessageEvent<ClientMessageToHost>) => {\n        /**\n         * Other channels (e.g. CSM, Events) share the same message port,\n         * so not every message will carry a `command`. Default to an empty\n         * object and bail early when `command` is absent to ignore messages\n         * intended for those other channels.\n         */\n        const { command, adDetails, payload } = data ?? {};\n        if (!command) return;\n\n        try {\n            if (IFRAME_READY_RETRY_WEBLAB().is('t1')) {\n                await executeWhenConditionMet({\n                    condition: () => !!document.getElementById(adDetails.adUnitIframeId),\n                    action: async () => await this.execute(command, adDetails, payload),\n                });\n            } else {\n                await this.execute(command, adDetails, payload);\n            }\n        } catch (ex) {\n            logError(`Problem with command '${command}': ${JSON.stringify(payload)}`, ex);\n        }\n    };\n\n    private execute = (command: ToHostCommandType, adDetails: AdDetails, payload: any): Promise<void> | undefined => {\n        const supportedAction = this.supportedCommands[command as keyof typeof this.supportedCommands];\n        if (typeof supportedAction === 'function') {\n            logAPIInvocation(command, adDetails);\n            return Promise.resolve(supportedAction(adDetails, payload));\n        }\n\n        return Promise.resolve();\n    };\n}\n\nconst logAPIInvocation = (command: string, adDetails: AdDetails): void => {\n    const metric = `messenger:${command}`;\n    incrementCsmCounter(metric);\n    incrementCsmPlacementCounter(metric, {\n        id: adDetails.placementId,\n        name: adDetails.placementName,\n    });\n};\n","import type { HostMessageToClient } from '@/components/messaging/types.js';\nimport type { ToClientCommandType } from '@/components/messaging/types.js';\nimport type { AdMap } from '@/types/adCommon.js';\n\n/*\n * This class is responsible for sending messages to the Safeframe\n */\nexport class HostMessageSender {\n    constructor(public readonly adMap: AdMap) {}\n\n    sendMessageToAd = <T>(arid: string, command: ToClientCommandType, data?: T) => {\n        const port1 = this.adMap[arid].messagePort;\n        const msg: HostMessageToClient = {\n            command: command,\n            data: data,\n        };\n        port1.postMessage(msg);\n    };\n\n    sendCustomMessageToAd = (arid: string, msgKey: string, data: any) => {\n        const msgData = {\n            key: msgKey,\n            data: data,\n        };\n        this.sendMessageToAd(arid, 'customMessage', msgData);\n    };\n}\n","/**\n * Type guard that checks whether `obj` is a non-null object with an own\n * property named `key`. Prevents accidental traversal into prototype\n * properties when walking dynamic paths.\n *\n * Note: `obj != null` is intentionally a loose equality check — it is\n * the idiomatic shorthand for `obj !== null && obj !== undefined`.\n */\nexport const hasOwn = (obj: unknown, key: string): obj is Record<string, unknown> =>\n    obj != null && typeof obj === 'object' && Object.prototype.hasOwnProperty.call(obj, key);\n","import { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\n\nimport type { BridgeMessage, ChannelRegistry, Context } from '@/components/messageChannel/bridge/bridge.js';\nimport { hasOwn } from '@/components/utils/hasOwn.js';\nimport type { IsFunction } from '@/components/utils/isFunction.js';\n\n/**\n * Transforms a channel interface into its host-side implementation by\n * prepending a {@link Context} parameter to every method. This gives\n * each handler access to the ad identity and timing metadata sent by\n * the client iframe.\n *\n * - Functions `(...args) => R` become `(ctx: Context, ...args) => R`.\n * - Plain object branches (e.g. `ue: { count }`) are recursed into.\n * - Non-function, non-object leaves become `never` (compile-time guard).\n *\n * @typeParam T - The channel interface to transform (e.g. `CsmChannel`).\n *\n * @example\n * ```ts\n * // CsmChannel.ue.count(metric, n?) becomes:\n * // HostImpl<CsmChannel>.ue.count(ctx, metric, n?)\n * ```\n */\nexport type HostImpl<T> = {\n    [K in keyof T]: IsFunction<T[K]> extends true\n        ? T[K] extends (...args: infer A) => infer R\n            ? (ctx: Context, ...args: A) => R\n            : never\n        : T[K] extends object\n          ? HostImpl<T[K]>\n          : never;\n};\n\n/** The shape of a resolved host handler after dot-path lookup. */\ntype Handler = (ctx: Context, ...args: unknown[]) => unknown;\n\n/**\n * Resolves a dot-notation path (e.g. `'ue.count'`) to the handler\n * function inside a {@link HostImpl} tree. Returns `undefined` if any\n * segment is missing, so unknown methods are silently ignored.\n */\nconst resolveMethod = (root: unknown, path: string): unknown =>\n    path.split('.').reduce<unknown>((obj, key) => (hasOwn(obj, key) ? obj[key] : undefined), root);\n\n/**\n * Listens on a {@link MessagePort} shared with the SafeFrame client\n * iframe and routes incoming messages to the matching handler in\n * {@link impl}.\n *\n * Multiple channels (CSM, Events, etc.) share the same port. The\n * namespace guard ensures each listener only processes messages\n * addressed to its channel, while dot-notation resolution maps\n * paths like `'ue.count'` to nested handler functions.\n *\n * @typeParam Namespace - A key of {@link ChannelRegistry} identifying the channel.\n * @param port      - The {@link MessagePort} connected to the client iframe.\n * @param namespace - Channel namespace key (e.g. `'CsmChannel'`).\n * @param impl - Host-side handler tree produced by {@link HostImpl}.\n *\n * @example\n * ```ts\n * bindHostImpl(port, 'CsmChannel', createHostCsmChannel());\n * ```\n */\nexport const bindHostImpl = <Namespace extends keyof ChannelRegistry>(\n    port: MessagePort,\n    namespace: Namespace,\n    impl: HostImpl<ChannelRegistry[Namespace]>,\n): void => {\n    port.addEventListener('message', async ({ data }: MessageEvent<BridgeMessage<ChannelRegistry[Namespace]>>) => {\n        if (data?.namespace !== namespace) return;\n        try {\n            const fn = resolveMethod(impl, data.method as string);\n            if (typeof fn === 'function') {\n                const ctx: Context = { ...data.context, messagePort: port };\n                await (fn as Handler)(ctx, ...data.args);\n            }\n        } catch (e) {\n            logError(`Bridge error in ${namespace}.${data.method}`, e);\n        }\n    });\n};\n","import { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { bindHostImpl } from '@/components/messageChannel/bridge/hostBridge.js';\nimport type { HostImpl } from '@/components/messageChannel/bridge/hostBridge.js';\nimport type { CsmChannel } from '@/components/messageChannel/csm/csmChannel.js';\nimport type { EventsChannel } from '@/components/messageChannel/eventsChannel.js';\nimport { mark } from '@/components/perf.js';\nimport type { HostMessageReceiver } from '@/host/api-client/hostMessageReceiver.js';\nimport type { HostContext } from '@/host/context/HostContext.js';\nimport { mapToPlacement } from '@/host/domain/placementMapper.js';\n\nexport interface SafeframeApi {\n    // Loads all the ads on the page\n    secondPhaseLoadAd: (\n        arid: string,\n        adDetails: AdDetails,\n        messagePortFromClient: MessagePort,\n        startSafeFrameCSM?: Date,\n    ) => void;\n    setupMessageChannel: (messagePortFromClient: MessagePort, adDetails: AdDetails, startSafeFrameCSM?: Date) => void;\n    collapsedPlacements: Set<string>;\n    /**\n     * Set of metric names that have already been logged to avoid duplicate logging.\n     */\n    loggedMetricNames?: Set<string>;\n}\n\nexport class SafeframeApiImpl implements SafeframeApi {\n    constructor(\n        readonly hc: HostContext,\n        readonly hmr: HostMessageReceiver,\n        private readonly eventsImpl: HostImpl<EventsChannel>,\n        private readonly csmImpl: HostImpl<CsmChannel>,\n    ) {}\n\n    collapsedPlacements: Set<string> = new Set<string>();\n\n    /**\n     * Initializes an entry in the ad map using the ARID (Ad Request ID) as the key.\n     * @param {AdDetails} adDetails - Object containing ad configuration details including ARID and slot name\n     * @param {MessagePort} clientSetupMessagePort - Message port for communication with the client setup\n     * @throws {Error} May throw an error during ad map entry creation\n     */\n    readonly initializeAdMap = (adDetails: AdDetails, clientSetupMessagePort: MessagePort) => {\n        try {\n            this.hc.adMap[adDetails.arid] = {\n                messagePort: clientSetupMessagePort,\n            };\n        } catch (ex) {\n            logError(`Error creating safeFrame ${adDetails.slotName}`, ex);\n        }\n    };\n\n    /**\n     * This is called from inline GPAT script when the iframe for a slot has emitted an \"sf iframe ready\" message.\n     * It is responsible for setting up globals, firing metrics, and rendering the sponsored label.\n     */\n    readonly secondPhaseLoadAd = async (\n        arid: string,\n        adDetails: AdDetails,\n        messagePortFromClient: MessagePort,\n    ): Promise<void> => {\n        await this.setupMessageChannel(messagePortFromClient, adDetails);\n    };\n\n    readonly setupMessageChannel = async (\n        messagePortFromClient: MessagePort,\n        adDetails: AdDetails,\n        _startSafeFrameCSM?: Date,\n    ): Promise<void> => {\n        mark('perf:sf:host', 'Start setupMessagePort', adDetails);\n\n        this.initializeAdMap(adDetails, messagePortFromClient);\n\n        const placement = mapToPlacement(adDetails);\n\n        try {\n            bindHostImpl(messagePortFromClient, 'EventsChannel', this.eventsImpl);\n            bindHostImpl(messagePortFromClient, 'CsmChannel', this.csmImpl);\n            connectMessageChannel(this.hc, adDetails, this.hmr);\n        } catch (e) {\n            placement.collapse(adDetails, 'HOST_SETUP');\n            throw e;\n        }\n    };\n}\n\n/**\n * Assigns {@link HostMessageReceiver} as listener on the message port.\n * Message Channels work like a queue that holds messages until consumed,\n * so this function triggers ingestion of any waiting messages from the iframe.\n */\nexport const connectMessageChannel = (hc: HostContext, adDetails: AdDetails, hmr: HostMessageReceiver): void => {\n    hc.adMap[adDetails.arid].messagePort.onmessage = hmr.receiveMessage;\n};\n","import type { AdMap } from '@/types/adCommon.js';\n\nexport class HostContext {\n    constructor(public readonly adMap: AdMap = {}) {}\n}\n","import { createHostCsmChannel } from '@/components/messageChannel/csm/csmChannelHost.js';\nimport { CommonSupportedCommands } from '@/host/api-client/CommonSupportedCommands.js';\nimport { createHostEventsChannel } from '@/host/api-client/hostEventsChannel.js';\nimport { HostMessageReceiver } from '@/host/api-client/hostMessageReceiver.js';\nimport { HostMessageSender } from '@/host/api-client/hostMessageSender.js';\nimport { MobileSupportedCommands } from '@/host/api-client/MobileSupportedCommands.js';\nimport { SafeframeApiImpl } from '@/host/api-page/safeframe-api.js';\nimport { HostContext } from '@/host/context/HostContext.js';\n\nexport const createSafeframeDesktopApi = (): SafeframeApiImpl => {\n    const hc = new HostContext();\n    const hms = new HostMessageSender(hc.adMap);\n    const hmr = new HostMessageReceiver(new CommonSupportedCommands(hms, hc));\n    return new SafeframeApiImpl(hc, hmr, createHostEventsChannel(hms), createHostCsmChannel());\n};\n\nexport const createSafeframeMobileApi = (): SafeframeApiImpl => {\n    const hc = new HostContext();\n    const hms = new HostMessageSender(hc.adMap);\n    const hmr = new HostMessageReceiver(new MobileSupportedCommands(hms, hc));\n    return new SafeframeApiImpl(hc, hmr, createHostEventsChannel(hms), createHostCsmChannel());\n};\n","import { mark } from '@/components/perf.js';\nimport { createSafeframeDesktopApi, createSafeframeMobileApi } from '@/host/api-page/safeframe-api-factory.js';\nimport type { SafeframeApi } from '@/host/api-page/safeframe-api.js';\n\ndeclare global {\n    interface Window {\n        APE_SF: SafeframeApi | undefined;\n    }\n}\n\nexport const initSafeframeHostDesktop = (): void => {\n    mark('perf:sf:host', 'initSafeframeHostDesktop');\n    if (window.APE_SF) return;\n\n    mark('perf:sf:host', 'initSafeframeHostDesktop init');\n    window.APE_SF = createSafeframeDesktopApi();\n};\n\nexport const initSafeframeHostMobile = (): void => {\n    mark('perf:sf:host', 'initSafeframeHostMobile');\n    if (window.APE_SF) return;\n\n    mark('perf:sf:host', 'initSafeframeHostMobile init');\n    window.APE_SF = createSafeframeMobileApi();\n};\n","import { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\n\nimport { safeFunctionWrapper } from '@/components/util.js';\nimport { initSafeframeHostDesktop } from '@/host/initSafeframeHost.js';\n\nsafeFunctionWrapper(() => initSafeframeHostDesktop(), logError, 'Error initializing safeFrame')();\n"],"x_google_ignoreList":[0,4,5,6,8,9,10,11,12,13,14,56,57,59],"mappings":"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"}