{"version":3,"file":"ApeDLA-1.50.i9j6dbsr.js","names":[],"sources":["../../../../src/js/components/perf.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/logging.ts","../../../../../../../node_modules/throttle-debounce/esm/index.js","../../../../src/js/components/viewability.ts","../../../../src/js/components/executeWithDelay.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csa/events.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csm/util.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csm/tag.ts","../../../../src/js/components/metrics/metric-tagger.ts","../../../../src/js/components/metrics/latency-metric-type.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/browseNode.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csm/counter.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csa/latency.ts","../../../../../../../node_modules/@amzn/apejs-instrumentation/src/metrics/csm/latency.ts","../../../../src/js/components/metrics/metric-service-csa-csm-impl.ts","../../../../src/js/components/metrics/metric-service.ts","../../../../src/js/light-ad/domain/metric/metricPublisher.ts","../../../../src/js/light-ad/domain/metric/latencyMetrics.ts","../../../../src/js/light-ad/domain/metric/metricCounters.ts","../../../../src/js/light-ad/helpers/callbackRegistry.ts","../../../../src/js/light-ad/outbound/lightAdRepo.ts","../../../../src/js/light-ad/domain/service/lightAdService.ts","../../../../src/js/components/metrics/awsMetricLoggerApiKey.ts","../../../../src/js/components/metrics/awsMetricBatcher.ts","../../../../src/js/components/weblabs.ts","../../../../src/js/components/metrics/logMetricOnce.ts","../../../../src/js/components/metrics/awsMetricLogger.ts","../../../../src/js/light-ad/domain/model/placement.ts","../../../../../../../node_modules/@amzn/creative-obstruction-detection/src/domObstructions/getDOMObstructionPercentage.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/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/host/slotSpecific/placementSafezone.ts","../../../../src/js/components/pixels/viewPixelUtil.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/MEASUREMENT_METHODS.ts","../../../../src/js/components/aax/aax.ts","../../../../src/js/components/urlQueryParams/addJSONQueryParamToURL.ts","../../../../src/js/components/util.ts","../../../../src/js/components/pixels/urlGenerators/btrPixelUrlGenerator.ts","../../../../src/js/components/pixels/urlGenerators/impressionPixelUrlGenerator.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/pixels/services/videoFirePixelValidator.ts","../../../../../../../node_modules/@amzn/creative-rendering-monitor/src/btr.ts","../../../../../../../node_modules/@amzn/creative-rendering-monitor/src/creativeBTREvaluatorSync.ts","../../../../src/js/client/clientReporter.ts","../../../../src/js/components/viewRateExperimentUtil.ts","../../../../src/js/components/clickTracking/getSlotPlaceholder.ts","../../../../src/js/components/clickTracking/replace.ts","../../../../src/js/light-ad/domain/service/click-tracking-service.ts","../../../../src/js/light-ad/domain/model/displayCreative.ts","../../../../src/js/components/homepage/homepageHerotator.ts","../../../../src/js/light-ad/domain/service/h1HerotatorService.ts","../../../../src/js/light-ad/domain/service/videoControlsVisibilityService.ts","../../../../src/js/components/homepage/homepageVideoOrchestrator.ts","../../../../src/js/light-ad/domain/service/videoOrchestratorService.ts","../../../../src/js/light-ad/domain/service/wd1AutoRotatorService.ts","../../../../src/js/light-ad/helpers/navigate.ts","../../../../src/js/light-ad/domain/model/videoCreative.ts","../../../../src/js/light-ad/inbound/mapper/creativeMapper.ts","../../../../src/js/light-ad/inbound/mapper/placementMapper.ts","../../../../src/js/light-ad/inbound/mapper/lightAdMapper.ts","../../../../src/js/components/feedback.ts","../../../../src/js/light-ad/inbound/feedbackApi.ts","../../../../src/js/light-ad/inbound/videoApi.ts","../../../../src/js/light-ad/inbound/lightAdApi.ts","../../../../src/js/light-ad/initLightAd.ts","../../../../src/js/light-ad/ApeDLA.ts"],"sourcesContent":["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 { 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","/* 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 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 { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport { throttle } from 'throttle-debounce';\n\nimport type {} from './amznJQ/index.d.js';\nimport { findDistanceFromViewport } from './viewability.js';\n\n/*\n    Helper method to implement JIT execution\n    It will execute callback after `elem` is `offset` pixels below the viewport.\n*/\n/**\n *\n * @deprecated Replace this with delayUntil\n */\nconst executeJustInTime = (callback: () => void, offset: number, elem: HTMLElement) => {\n    let callbackExecuted = false;\n    const isReadyToExecute = () => {\n        const distance = findDistanceFromViewport(elem);\n        return distance && distance <= offset;\n    };\n\n    const positionTracker = () => {\n        if (isReadyToExecute()) {\n            callback();\n            callbackExecuted = true;\n        }\n    };\n\n    const throttledPositionTracker = throttle(20, () => {\n        positionTracker();\n\n        if (callbackExecuted) {\n            window.removeEventListener('scroll', throttledPositionTracker);\n            window.removeEventListener('resize', throttledPositionTracker);\n        }\n    });\n\n    positionTracker();\n    if (!callbackExecuted) {\n        window.addEventListener('scroll', throttledPositionTracker);\n        window.addEventListener('resize', throttledPositionTracker);\n    }\n};\n\nexport interface ExecuteAfterDelay {\n    callback: () => void;\n    errorCallback?: () => void;\n    delayConfig?: string;\n    placementDiv: HTMLDivElement;\n    siteName?: string;\n}\n\n/**\n * Execute a function after a particular event\n * Supported events: https://w.amazon.com/bin/view/Ad_Placements/SafeFrame/#Lazyload_logic\n */\nexport const executeWithDelay = ({\n    callback,\n    errorCallback,\n    delayConfig,\n    placementDiv,\n    siteName,\n}: ExecuteAfterDelay): void => {\n    const callbackToExecute = () => {\n        try {\n            callback();\n        } catch (ex) {\n            logError('delayLoad failed', ex);\n            errorCallback?.();\n        }\n    };\n\n    if (delayConfig?.trim().match(/^\\d{1,4}px$/g)) {\n        /**\n         * JIT loading - execute the callback function when the user has scrolled to X pixels above the placement div.\n         * X will be an adjustable variable based on the regex above.\n         */\n        executeJustInTime(callbackToExecute, parseInt(delayConfig, 10), placementDiv);\n    } else if (delayConfig === 'inView' && siteName === 'amazon.in') {\n        // TODO: remove inView, after view based billing support: https://sim.amazon.com/issues/CPP-42945\n        // Execute callback when ad div enters viewport\n        const observer = new IntersectionObserver(\n            (entries) => {\n                // Use intersectionRatio > 0 to determine visibility\n                for (const entry of entries) {\n                    if (entry.intersectionRatio > 0) {\n                        callbackToExecute();\n                        observer.unobserve(placementDiv);\n                        break;\n                    }\n                }\n            },\n            { threshold: [0, 0.01] },\n        );\n        observer.observe(placementDiv);\n    } else {\n        // including loadAfter:'clickTracking' for placements with enableClickTracking=true\n        callbackToExecute();\n    }\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 const emitCsaMetric = (data: Record<string, unknown>): void => logCsaEvent(METRICS_SOURCE_GROUP, data);\n","export const csmName = (name: string) => name.replace(/_/g, ':');\n","// https://w.amazon.com/index.php/ClientSideMetrics/UserDocs/Instrumentation/Tags\nimport { csmName } from './util.js';\nimport type { Placement } from '../placement.js';\n\n/**\n * @description CSM - Add custom label you can associate with your hit on Placement level.\n * @param tagPrefix start of key to add to window.ue.tag\n * @param placement The Placement you want to log metrics for\n * @param tagSuffix end of key to add to window.ue.tag (optional)\n * @example addPlacementTag('adrender', {id: '597b923a-8c7e-4665-9541-de88160dd0ba', name: 'Gateway_right-2_desktop'})\n * @example addPlacementTag('adrender', {id: '597b923a-8c7e-4665-9541-de88160dd0ba', name: 'Gateway_right-2_desktop'}, 'suffix')\n */\nexport const addCsmPlacementTag = (tagPrefix: string, placement: Placement, tagSuffix?: string): void => {\n    if (!isUeTagAvailable()) return;\n    ueTag(placementTag(tagPrefix, placement.id, tagSuffix));\n    ueTag(placementTag(tagPrefix, csmName(placement.name), tagSuffix));\n};\n\n/**\n * @description CSM - Add custom label you can associate with your hit on Market level.\n * @example addTag('adrender')\n * @param tagPrefix start of key to add to window.ue.tag\n * @param tagSuffix end of key to add to window.ue.tag (optional)\n */\nexport const addCsmTag = (tagPrefix: string, tagSuffix?: string): void => {\n    if (!isUeTagAvailable()) return;\n    ueTag(tagPrefix + getTagSuffix(tagSuffix));\n};\n\nexport const isUeTagAvailable = () => typeof window?.ue?.tag === 'function';\nexport const ueTag = (tag: string) => window?.ue?.tag(tag);\n\nconst placementTag = (tagPrefix: string, placement: string, tagSuffix: string | undefined) =>\n    `${tagPrefix}:${placement}${getTagSuffix(tagSuffix)}`;\nconst getTagSuffix = (tagSuffix: string | undefined) => (tagSuffix ? `:${tagSuffix}` : '');\n","import { setCsaEntity } from '@amzn/apejs-instrumentation/src/metrics/csa/events.js';\nimport { addCsmPlacementTag, addCsmTag } from '@amzn/apejs-instrumentation/src/metrics/csm/tag.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\nimport type { LightAdDetails } from '@amzn/safeframe-model';\n\nimport type { Placement } from '../../light-ad/domain/model/placement.js';\n\nexport const addLightAdTags = (placement: Placement, lightAdDetails: LightAdDetails) => {\n    addCsmPlacementTag('adrender', placement);\n    addCsmPlacementTag('adrender:lightad', placement);\n    if (lightAdDetails.adCreativeMetaData.adCreativeId) {\n        addCsmPlacementTag('adrender', placement, `creativeid:${lightAdDetails.adCreativeMetaData.adCreativeId}`);\n        setCsaEntity({ creativeId: lightAdDetails.adCreativeMetaData.adCreativeId.toString() });\n    }\n    if (lightAdDetails.adCreativeMetaData.adProgramId) {\n        addCsmPlacementTag('adrender', placement, `programid:${lightAdDetails.adCreativeMetaData.adProgramId}`);\n        setCsaEntity({ programId: lightAdDetails.adCreativeMetaData.adProgramId.toString() });\n    }\n    if (typeof lightAdDetails.isCardsFlow !== 'undefined') {\n        setCsaEntity({ isCardsFlow: lightAdDetails.isCardsFlow.toString() });\n    }\n    const creativeTemplateName = getCreativeTemplateNameForTagging(lightAdDetails);\n    addCsmPlacementTag('adrender', placement, `creativetemplatename:${creativeTemplateName}`);\n    setCsaEntity({\n        adrender: 'true',\n        creativeTemplateName: creativeTemplateName,\n        isLightAds: 'true',\n    });\n};\n\nexport const addSafeframeTags = (adDetails: AdDetails) => {\n    if (!adDetails?.adCreativeMetaData || !Object.keys(adDetails.adCreativeMetaData).length) {\n        addCsmTag('noadrender');\n        setCsaEntity({ adrender: 'false' });\n        return;\n    }\n\n    addCsmTag('adrender');\n    addCsmTag('adrender:safeframe');\n\n    tagTemplate(adDetails);\n    tagCreativeId(adDetails);\n    tagProgramId(adDetails);\n    tagIsCardsFlow(adDetails);\n};\n\nconst tagTemplate = (adDetails: AdDetails): void => {\n    const creativeTemplateName = getCreativeTemplateNameForTagging(adDetails);\n    addCsmTag('adrender', 'creativetemplatename:' + creativeTemplateName);\n    setCsaEntity({\n        adrender: 'true',\n        creativeTemplateName: creativeTemplateName,\n        isLightAds: 'false',\n    });\n};\n\n/*\n * Helper function to prepare creative template name for tagging\n * 1. Change to lower case\n * 2. Remove all non-alphanumeric characters\n * 3. Use 'unknown' if it does not exist\n */\nexport const getCreativeTemplateNameForTagging = (adDetails: AdDetails | LightAdDetails): string => {\n    if (adDetails.adCreativeMetaData.adCreativeTemplateName) {\n        return adDetails.adCreativeMetaData.adCreativeTemplateName.toLowerCase().replace(/[^0-9a-z]/g, '');\n    }\n\n    return 'unknown';\n};\n\nconst tagCreativeId = (adDetails: AdDetails): void => {\n    if (adDetails.adCreativeMetaData.adCreativeId) {\n        addCsmTag('adrender', 'creativeid:' + adDetails.adCreativeMetaData.adCreativeId);\n        setCsaEntity({\n            creativeId: adDetails.adCreativeMetaData.adCreativeId,\n        });\n    }\n};\n\nconst tagProgramId = (adDetails: AdDetails): void => {\n    if (adDetails.adCreativeMetaData.adProgramId) {\n        addCsmTag('adrender', 'programid:' + adDetails.adCreativeMetaData.adProgramId);\n        setCsaEntity({\n            adProgramId: adDetails.adCreativeMetaData.adProgramId,\n        });\n    }\n};\n\nconst tagIsCardsFlow = (adDetails: AdDetails): void => {\n    if (adDetails.isCardsFlow !== undefined) {\n        setCsaEntity({\n            isCardsFlow: adDetails.isCardsFlow.toString(),\n        });\n    }\n};\n","type CsaKey = 't0' | 'bodyBegin' | 'bodyEnd' | 'aboveTheFold' | 'criticalFeature' | 'functional' | 'loaded';\n\ntype CsmKey = 'af' | 'bb' | 'be' | 'cf' | 'ld';\n\nconst HOST_SCOPE = 'sfImpression' as const;\nconst LIGHTAD_SCOPE = 'LightAdImpression' as const;\nconst VIEWABLE_LATENCY = 'viewablelatency' as const;\n\ntype CsmMessage = typeof HOST_SCOPE | typeof LIGHTAD_SCOPE | typeof VIEWABLE_LATENCY;\n\nexport interface LatencyMetricType {\n    readonly csaKey: CsaKey;\n    readonly csmKey: CsmKey;\n    readonly csmMessage?: CsmMessage;\n}\n\nconst create = (csaKey: CsaKey, csmKey: CsmKey, csmMessage?: CsmMessage): LatencyMetricType => {\n    return { csaKey, csmKey, csmMessage };\n};\n\nexport const BODY_BEGIN = create('bodyBegin', 'bb');\nexport const BODY_BEGIN_HOST_SCOPE = create('bodyBegin', 'bb', HOST_SCOPE);\nexport const BODY_BEGIN_LIGHTAD_SCOPE = create('bodyBegin', 'bb', LIGHTAD_SCOPE);\n\nexport const BODY_END = create('bodyEnd', 'be');\n\nexport const CRITICAL_FEATURE = create('criticalFeature', 'cf');\nexport const CRITICAL_FEATURE_HOST_SCOPE = create('criticalFeature', 'cf', HOST_SCOPE);\nexport const CRITICAL_FEATURE_LIGHTAD_SCOPE = create('criticalFeature', 'cf', LIGHTAD_SCOPE);\n\nexport const LOADED = create('loaded', 'ld');\nexport const LOADED_HOST_SCOPE = create('loaded', 'ld', HOST_SCOPE);\nexport const LOADED_LIGHTAD_SCOPE = create('loaded', 'ld', LIGHTAD_SCOPE);\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","// 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 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 */\ntype 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 { sendCsaLatencyMetric } from '@amzn/apejs-instrumentation/src/metrics/csa/latency.js';\nimport { sendCsmLatencyMetric } from '@amzn/apejs-instrumentation/src/metrics/csm/latency.js';\n\nimport type { LatencyMetric } from './latency-metric.js';\nimport type { MetricService } from './metric-service.js';\n\nexport class MetricServiceCsaCsmImpl implements MetricService {\n    sendLatencyMetric({\n        latencyMetricType,\n        placementId,\n        placementName,\n        placementDivId,\n        timestamp,\n    }: LatencyMetric): void {\n        sendCsmLatencyMetric({\n            latencyEvent: latencyMetricType.csmKey,\n            scope: latencyMetricType.csmMessage,\n            placement: { id: placementId, name: placementName },\n            timestamp: timestamp,\n        });\n\n        sendCsaLatencyMetric(\n            document.getElementById(placementDivId) as HTMLDivElement,\n            latencyMetricType.csaKey as any,\n            timestamp,\n        );\n    }\n}\n","import type { LatencyMetric } from './latency-metric.js';\nimport { MetricServiceCsaCsmImpl } from './metric-service-csa-csm-impl.js';\n\nexport interface MetricService {\n    sendLatencyMetric(latencyMetric: LatencyMetric): void;\n}\n\nexport const metricService = (): MetricService => {\n    return new MetricServiceCsaCsmImpl();\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';\n\nimport type { LatencyMetricType } from '../../../components/metrics/latency-metric-type.js';\nimport { metricService } from '../../../components/metrics/metric-service.js';\nimport type { Placement } from '../model/placement.js';\n\nexport class MetricCounterPublisher {\n    constructor(\n        private readonly csaMetricName: string,\n        private readonly csmMetricName: string,\n        private readonly placement: Placement,\n        private readonly shouldFireSlotAgnosticMetric: boolean = false,\n    ) {}\n\n    publishCount(): void {\n        incrementCsmPlacementCounter(this.csmMetricName, this.placement);\n        incrementCsaPlacementCounter(this.csaMetricName, this.placement);\n\n        if (this.shouldFireSlotAgnosticMetric) {\n            incrementCsmCounter(this.csmMetricName);\n            incrementCsaCounter(this.csaMetricName);\n        }\n    }\n}\n\nexport class MetricLatencyPublisher {\n    constructor(\n        private readonly latencyMetricType: LatencyMetricType,\n        private readonly placement: Placement,\n    ) {}\n\n    publishLatency(timestamp?: number): void {\n        metricService().sendLatencyMetric({\n            latencyMetricType: this.latencyMetricType,\n            placementId: this.placement.id,\n            placementName: this.placement.name,\n            placementDivId: this.placement.divId,\n            timestamp: new Date(timestamp ?? performance.now()),\n        });\n    }\n}\n","import { BODY_BEGIN_LIGHTAD_SCOPE, LOADED } from '../../../components/metrics/latency-metric-type.js';\nimport type { Placement } from '../model/placement.js';\nimport { MetricLatencyPublisher } from './metricPublisher.js';\n\nexport const bodyBeginLightAd = (placement: Placement) =>\n    new MetricLatencyPublisher(BODY_BEGIN_LIGHTAD_SCOPE, placement);\n\nexport const loadedLightAd = (placement: Placement) => new MetricLatencyPublisher(LOADED, placement);\n","import type { Placement } from '../model/placement.js';\nimport { MetricCounterPublisher } from './metricPublisher.js';\n\nexport class AdLoadMetric {\n    static start = (placement: Placement): MetricCounterPublisher =>\n        new MetricCounterPublisher('adload_start', 'adload:start', placement, true);\n    static renderError = (placement: Placement): MetricCounterPublisher =>\n        new MetricCounterPublisher('adload_rendererror', 'adload:rendererror', placement);\n    static callback = (placement: Placement): MetricCounterPublisher =>\n        new MetricCounterPublisher('adload_delayloadcallback', 'adload:delayloadcallback', placement);\n}\n","/**\n * Registry for managing callbacks that wait for keys to become ready.\n * Uses observer pattern to notify callbacks when keys are ready.\n */\nexport interface CallbackRegistry {\n    /**\n     * Register a callback to be executed when a key becomes ready.\n     *\n     * @param key - Unique identifier for the value\n     * @param callback - Function to execute when key is ready\n     */\n    onReady(key: string, callback: () => void): void;\n\n    /**\n     * Notify that a key is ready and execute all pending callbacks for that key.\n     *\n     * @param key - Unique identifier for the value\n     */\n    notifyReady(key: string): void;\n}\n\n/**\n * Creates a new callback registry instance.\n * Each instance maintains its own callback storage.\n */\n\nexport const createCallbackRegistry = (): CallbackRegistry => {\n    const callbacks = new Map<string, (() => void)[]>();\n\n    return {\n        onReady: (key: string, callback: () => void): void => {\n            const existingCallbacks = callbacks.get(key) || [];\n            existingCallbacks.push(callback);\n            callbacks.set(key, existingCallbacks);\n        },\n\n        notifyReady: (key: string): void => {\n            const keyCallbacks = callbacks.get(key);\n            if (keyCallbacks) {\n                keyCallbacks.forEach((cb) => cb());\n                callbacks.delete(key);\n            }\n        },\n    };\n};\n","import type { LightAdDetails } from '@amzn/safeframe-model';\n\nimport type { Placement } from '../domain/model/placement.js';\nimport { createCallbackRegistry } from '../helpers/callbackRegistry.js';\n\ndeclare global {\n    // oxlint-disable-next-line\n    interface Window extends LightAdWindow {}\n}\n\nexport type LightAdEntity = {\n    lightAdDetails: LightAdDetails;\n    placement: Placement;\n    processedTimestamp?: number;\n};\n\nexport interface LightAdWindow {\n    lightAds: { [key: string]: LightAdEntity };\n}\n\nexport interface LightAdRepo {\n    get(placementDiv: HTMLElement): Promise<LightAdEntity>;\n    save(lightAdEntity: LightAdEntity): void;\n}\n\nconst ensureLightAds = (window: LightAdWindow): void => {\n    if (!window.lightAds) {\n        window.lightAds = {};\n    }\n};\n\nconst callbackRegistry = createCallbackRegistry();\nconst getEntityReadyKey = (placementDivId: string): string => `la-entity-ready-${placementDivId}`;\n\nexport const lightAdRepo = (lightAdWindow: LightAdWindow = window): LightAdRepo => {\n    ensureLightAds(lightAdWindow);\n\n    return {\n        get: (placementDiv: HTMLElement): Promise<LightAdEntity> => {\n            const entity = lightAdWindow.lightAds[placementDiv.id];\n            if (entity) return Promise.resolve(entity);\n\n            return new Promise((resolve) => {\n                callbackRegistry.onReady(getEntityReadyKey(placementDiv.id), () => {\n                    resolve(lightAdWindow.lightAds[placementDiv.id]);\n                });\n            });\n        },\n\n        save: (lightAdEntity: LightAdEntity): void => {\n            const placementId = lightAdEntity.placement.div.id;\n            lightAdWindow.lightAds[placementId] = lightAdEntity;\n            callbackRegistry.notifyReady(getEntityReadyKey(placementId));\n        },\n    };\n};\n","import { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\n\nimport { executeWithDelay } from '@/components/executeWithDelay.js';\nimport { addLightAdTags } from '@/components/metrics/metric-tagger.js';\nimport { mark } from '@/components/perf.js';\nimport { bodyBeginLightAd } from '@/light-ad/domain/metric/latencyMetrics.js';\nimport { AdLoadMetric } from '@/light-ad/domain/metric/metricCounters.js';\nimport type { LightAd } from '@/light-ad/domain/model/LightAd.js';\nimport { lightAdRepo } from '@/light-ad/outbound/lightAdRepo.js';\n\nexport const processLightAd = (lightAd: LightAd): void => {\n    markLightAdProcessed(lightAd);\n    mark('perf:la', 'markLightAdProcessed');\n    processLightAdHelper(lightAd);\n};\n\nconst processLightAdHelper = async ({ placement, lightAdDetails }: LightAd): Promise<void> => {\n    mark('perf:la', 'processLightAdHelper');\n    try {\n        addLightAdTags(placement, lightAdDetails);\n        mark('perf:la', 'addLightAdTags');\n\n        AdLoadMetric.start(placement).publishCount();\n        bodyBeginLightAd(placement).publishLatency();\n        mark('perf:la', 'bodyBeginLightAd');\n\n        AdLoadMetric.callback(placement).publishCount();\n        const renderPromise = placement.render();\n\n        executeWithDelay({\n            callback: async () => {\n                placement.firePreRenderImpression();\n                await renderPromise;\n                mark('perf:la', 'renderComplete');\n                placement.track();\n            },\n            delayConfig: lightAdDetails.firePixelsAfter,\n            placementDiv: placement.div,\n            siteName: lightAdDetails.siteName,\n        });\n    } catch (error) {\n        AdLoadMetric.renderError(placement).publishCount();\n        await placement.collapse();\n        logError(`Unable to process Light Ad`, error);\n    }\n};\n\nconst markLightAdProcessed = ({ placement, lightAdDetails }: LightAd): void => {\n    lightAdRepo().save({\n        processedTimestamp: performance.now(),\n        placement: placement,\n        lightAdDetails: lightAdDetails,\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","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 { 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","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 { ADPT_SF_LOW_RATE_METRIC_LOGGING } from '@/components/weblabs.js';\n\nimport { logMetricOnce } from './logMetricOnce.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 {\n    incrementCsmCounter,\n    incrementCsmPlacementCounter,\n} from '@amzn/apejs-instrumentation/src/metrics/csm/counter.js';\n\nimport { logLowRateMetricLA } from '@/components/metrics/awsMetricLogger.js';\nimport { lightAdRepo } from '@/light-ad/outbound/lightAdRepo.js';\n\nimport { loadedLightAd } from '../metric/latencyMetrics.js';\nimport type { Creative } from './creative.js';\n\nexport class Placement {\n    constructor(\n        public readonly id: string,\n        public readonly name: string,\n        public readonly divId: string,\n        public readonly creative: Creative,\n        public readonly deviceType: string,\n    ) {}\n\n    render = async (): Promise<void> => {\n        await this.creative.render(this);\n        loadedLightAd(this).publishLatency(performance.now());\n    };\n\n    firePreRenderImpression = (): void => {\n        this.creative.firePreRenderImpression(this);\n    };\n\n    track = (): void => {\n        this.creative.track(this);\n    };\n\n    collapse = async (): Promise<void> => {\n        incrementCsmCounter('lightad:placement:collapse');\n        incrementCsmPlacementCounter('lightad:placement:collapse', { id: this.id, name: this.name });\n        this.parentDiv.style.display = 'none';\n        const entity = await lightAdRepo().get(this.div);\n        logLowRateMetricLA({\n            metricName: 'placement:collapse',\n            lightAdDetails: entity.lightAdDetails,\n            additionalDimensions: {\n                code: 'LA',\n                creativeId: entity.lightAdDetails.adCreativeMetaData.adCreativeId,\n            },\n        });\n    };\n\n    public get div(): HTMLDivElement {\n        return document.getElementById(this.divId) as HTMLDivElement;\n    }\n\n    public get parentDiv(): HTMLDivElement {\n        return this.div.parentElement as HTMLDivElement;\n    }\n}\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","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","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 { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.js';\nimport type { ViewPixel } from '@/components/pixels/viewPixel.js';\n\nimport type { Placement } from './pixel.js';\nimport type { ViewabilityService } from './services/viewabilityService.js';\nimport type { VisibilityChangeService } from './services/visibilityChangeService.js';\nimport type { ViewabilityStandard } from './viewabilityStandards.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 { Creative } from '@/light-ad/domain/model/creative.js';\n\nimport type { FirePixel } from './firePixel.js';\nimport type { PixelIdentifier } from './pixelIdentifiers.js';\nimport type { PixelUrlGenerator } from './pixelUrlGenerator.js';\nimport type { PixelLogger } from './services/pixelLogger.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 '../pixel.js';\nimport type { PixelIdentifier } from '../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","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","/**\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 {\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 { getPlacementSafezoneDOMRect } from '@/host/slotSpecific/placementSafezone.js';\n\nimport type { Placement } from '../pixel.js';\nimport { getVisiblePercentageInViewport } from '../viewPixelUtil.js';\nimport type { ViewabilityService } from './viewabilityService.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 '../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 { startAttributeViewThroughAppAds } from '../skadnetwork/skanAppAdsAttribution.js';\nimport type { FirePixel } from './firePixel.js';\nimport type { LoggingContext, Placement } from './pixel.js';\nimport { SKAN_IMPRESSION_IDENTIFIER } from './pixelIdentifiers.js';\nimport type { PixelLogger } from './services/pixelLogger.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 { endAttributeViewThroughAppAds } from '../skadnetwork/skanAppAdsAttribution.js';\nimport type { FirePixel } from './firePixel.js';\nimport type { LoggingContext, Placement } from './pixel.js';\nimport { SKAN_VIEW_IDENTIFIER } from './pixelIdentifiers.js';\nimport type { PixelLogger } from './services/pixelLogger.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","// 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/**\n * Check if the given mediaType is video\n * @param {String} mediaType - mediaType value from AAX\n * @returns {Boolean} isVideo - True if mediaType is V\n */\nexport const isVideo = (mediaType: string): boolean => mediaType === 'V';\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\nexport const isEmptyObject = (obj?: object) => {\n    return obj && Object.keys(obj).length === 0 && obj.constructor === Object;\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 { BEGIN_TO_RENDER_CLIENT } from '@/client/MEASUREMENT_METHODS.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/MEASUREMENT_METHODS.js';\n\nimport { PUBLISHER_JSON_KEY } from '../../aax/aax.js';\nimport { addJSONQueryParamToURL } from '../../urlQueryParams/addJSONQueryParamToURL.js';\nimport type { PixelUrlGenerator } from '../pixelUrlGenerator.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 { aaxPayloadMacro, aaxTypeMacro, ATF_URL_KEY } from '../../aax/aax.js';\nimport { getAtfInfo } from '../../viewability.js';\nimport type { Placement } from '../pixel.js';\nimport type { PixelUrlGenerator } from '../pixelUrlGenerator.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 './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 '../../aax/aax.js';\nimport type { Placement } from '../pixel.js';\nimport type { PixelUrlGenerator } from '../pixelUrlGenerator.js';\nimport { btr } from '../placementData.js';\nimport type { ViewabilityStandard } from '../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 { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.js';\nimport type { ViewPixel } from '@/components/pixels/viewPixel.js';\n\nimport type { Pixel, Placement } from './pixel.js';\nimport type { ViewabilityService } from './services/viewabilityService.js';\nimport type { ViewabilityStandard } from './viewabilityStandards.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 type { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.ts';\nimport type { ViewPixel } from '@/components/pixels/viewPixel.js';\n\nimport { NEW_VIEWABILITY_TRACKER_WEBLAB } from '../weblabs.js';\nimport { MRCObstructionViewPixel } from './mrcObstructionViewPixel.js';\nimport type { LoggingContext } from './pixel.js';\nimport { Pixel } from './pixel.js';\nimport {\n    BTR_IDENTIFIER,\n    IAB_VIEWABILITY_IDENTIFIER,\n    IMPRESSION_IDENTIFIER,\n    MEASURABILITY_IDENTIFIER,\n} from './pixelIdentifiers.js';\nimport { logPixelFired } from './services/pixelLogger.js';\nimport { createViewabilityService } from './services/viewabilityServiceImpl.js';\nimport { createVisibiltyChangeService } from './services/visibilityChangeService.js';\nimport { SkanImpressionPixel } from './skanImpressionPixel.js';\nimport { SkanViewPixel } from './skanViewPixel.js';\nimport { generateBtrPixelUrl } from './urlGenerators/btrPixelUrlGenerator.js';\nimport { generateImpressionPixelUrl } from './urlGenerators/impressionPixelUrlGenerator.js';\nimport { generateMeasurabilityPixelUrl } from './urlGenerators/measurabilityPixelUrlGenerator.js';\nimport { generateMrcObstructionViewPixelUrl } from './urlGenerators/mrcObstructionViewPixelUrlGenerator.js';\nimport type { ViewabilityStandard } from './viewabilityStandards.js';\nimport { VIEWABILITY_STANDARDS } from './viewabilityStandards.js';\nimport { createViewabilityTracker } from './viewabilityTrackerImpl.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","import { addCustomEventListener } from '@/components/events/customEvents.js';\nimport type { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.js';\n\nimport type { Placement } from '../pixel.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","export const btr = {\n    set: (element: HTMLElement, value: boolean): void => {\n        element.dataset.isBtr = String(value);\n    },\n    get: (element: HTMLElement): boolean => {\n        return element.dataset.isBtr === String(true);\n    },\n};\n","/**\n * Possible status codes indicating the evaluation result of a creative's rendering.\n */\nimport { btr } from './btr.js';\n\nexport type Code = 'BEGIN_TO_RENDER' | 'ERROR' | 'NO_CREATIVE';\n\n/**\n * Represents the response structure for evaluating whether a creative has begun to render.\n */\nexport interface CreativeBeginToRenderResponse {\n    /** Indicates whether the creative has begun to render successfully. */\n    success: boolean;\n\n    /** The status code indicating the result of the evaluation. */\n    code: Code;\n}\n\n/**\n * Evaluates whether a creative inside the provided container has begun to render.\n * This is determined by checking the BTR dataset flag or if any visible images within the container have loaded.\n *\n * @param creativeContainer - The HTML element containing the creative.\n * @returns A response indicating whether rendering has begun.\n */\nexport const evaluateCreativeBeginToRender = (creativeContainer: HTMLElement): CreativeBeginToRenderResponse => {\n    if (btr.get(creativeContainer)) {\n        return { success: true, code: 'BEGIN_TO_RENDER' };\n    }\n\n    const images = Array.from(creativeContainer.querySelectorAll('img')).filter(\n        (x) => getComputedStyle(x).display !== 'none',\n    );\n    return evaluateAnyImageLoaded(images);\n};\n\n/**\n * Evaluates whether any image in the provided list has successfully loaded.\n *\n * The function checks if at least one image is fully loaded (i.e., it is marked as complete\n * and has non-zero dimensions). If no images are present, it returns `NO_CREATIVE`.\n * If at least one image loads successfully, it returns `BEGIN_TO_RENDER`.\n * If all images fail to load, it returns `ERROR`.\n *\n * @param images - An array of HTML image elements to evaluate.\n * @returns A response indicating whether rendering has begun, no creative was found, or an error occurred.\n */\nconst evaluateAnyImageLoaded = (images: HTMLImageElement[]): CreativeBeginToRenderResponse => {\n    if (images.length === 0) {\n        return { success: false, code: 'NO_CREATIVE' };\n    }\n\n    return images.some((img) => img.complete && img.naturalWidth > 0 && img.naturalHeight > 0)\n        ? { success: true, code: 'BEGIN_TO_RENDER' }\n        : { success: false, code: 'ERROR' };\n};\n","import { evaluateCreativeBeginToRender } from '@amzn/creative-rendering-monitor/src/creativeBTREvaluatorSync.js';\n\nimport type { MEASUREMENT_METHODS } from './MEASUREMENT_METHODS.js';\nimport { BEGIN_TO_RENDER_CLIENT, COUNT_ON_DOWNLOAD_CLIENT } from './MEASUREMENT_METHODS.js';\n\nexport const tryWaitForBTR = async (element: HTMLElement = document.body): Promise<MEASUREMENT_METHODS> => {\n    const btrEvaluationWaitTime = 75;\n    let elapsedTime = 0;\n    const intervalMs = 5;\n\n    return new Promise<MEASUREMENT_METHODS>((resolve) => {\n        const intervalId = setInterval(() => {\n            elapsedTime += intervalMs;\n\n            const response = evaluateCreativeBeginToRender(element);\n            if (response.success) {\n                clearInterval(intervalId);\n                resolve(BEGIN_TO_RENDER_CLIENT);\n            } else if (elapsedTime >= btrEvaluationWaitTime) {\n                clearInterval(intervalId);\n                resolve(COUNT_ON_DOWNLOAD_CLIENT);\n            }\n        }, intervalMs);\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","const DATA_ATTRIBUTE_NAME = 'data-val';\n/**\n * This function is used to get percolate clickTracking parameter from placeholder div's attribute 'data-val'.\n * @param identifier - slot identifier following this format `pageType_slotName_subPageType`.\n * @returns clickTrackingParam in placeholder div.  If it does not exist it will return empty string.\n *\n * If clickPrependKey is set and creative is clickTrackingSupported, Javelin will return placeholder div\n * to percolate with `data-val='&pd_rd_pdhdr=t'`.\n * If enabled through symphony creative parameters, percolate will put clickTracking parameter in this attribute by\n * replacing '&pd_rd_pdhlr=t'.\n **/\nexport const getClickTrackingParamWithSlotId = (identifier: string): string | '' => {\n    if (identifier === '') {\n        return '';\n    }\n    const targetId = `ape_${identifier}_placement_ClickTracking`;\n    const element = document.getElementById(targetId);\n    return element?.getAttribute?.(DATA_ATTRIBUTE_NAME) ?? '';\n};\n\n/**\n * This function is used to get percolate clickTracking parameter from placeholder div's attribute 'data-val'.\n * @param pageType - used to create slot identifier\n * @param subPageType - used to create slot identifier\n * @param slotName  - used to create slot identifier\n * @returns clickTrackingParam in placeholder div.'\n *\n * If clickPrependKey is set and creative is clickTrackingSupported, Javelin will return placeholder div\n * to percolate with `data-val='&pd_rd_pdhdr=t'`.\n * If enabled through symphony creative parameters, percolate will put clickTracking parameter in this attribute by\n * replacing '&pd_rd_pdhlr=t'.\n **/\nexport const getSlotPlaceholder = (pageType: string, subPageType: string, slotName: string): string => {\n    const identifier = [pageType, slotName, subPageType].join('_');\n    return getClickTrackingParamWithSlotId(identifier);\n};\n","const PLACEHOLDER_DEFAULT = '&pd_rd_plhdr=t';\n\n/**\n *  HTML entity examples:\n *      Symbols\n *          shortest: &lt;\n *          longest: &Omicron;\n *\n *      Numbers\n *          (0-31 are control characters)\n *          shortest: &#32;\n *          longest: &#8721;\n *\n *  Regular Expressions\n *      Entity Numbers: (&#(0-){2};)|(&#(a-z){3};)|(&#(a-z){4};)\n *      Entity Symbols: (&(a-z){2};)|(&(a-z){3};)|(&(a-z){4};)|(&(a-z){5};)|(&(a-z){6};)|(&(a-z){7};)\n */\nconst REGEX_MATCH = new RegExp(\n    /((&#\\d{2,4};)|(&[a-z]{2};)|(&[a-z]{3,7};)|(%[a-fA-F0-9]{2})|(\\W))pd_rd_plhdr(=|%3D)t((&#\\d{2,4};)|(&[a-z]{2,7};)|(%[a-fA-F0-9]{2})|(\\W))/,\n);\n\n/**\n * Indices must be updated if RegEx groups are modified.\n * Each left and right group has 10 subgroups.\n * String.prototype.match() call will return the results of 22 groups.\n * Main result of the left matching group will be at index 1, while\n * the primary result of the right group is stored at index 12.\n */\nconst LEFT_GROUP_INDEX = 1;\nconst MIDDLE_GROUP_INDEX = 7;\nconst RIGHT_GROUP_INDEX = 8;\nconst LEFT_GROUP_VALUE = '$' + LEFT_GROUP_INDEX;\nconst RIGHT_GROUP_VALUE = '$' + RIGHT_GROUP_INDEX;\n\n/**\n * Replaces placeholders in HTML content with a specified click tracker value.\n *\n * This function substitutes the placeholder `PLACEHOLDER_DEFAULT` (`&pd_rd_plhdr=t`) in the provided\n * HTML content with the given click tracker value. It handles cases where the placeholder is surrounded\n * by HTML entities or URL encoding, ensuring that the replacement respects the format of the surrounding content.\n *\n * @param {string} clickTracker - The replacement value for the placeholder.\n *   - If the value matches the default placeholder or is empty/whitespace, no replacement is performed.\n *   - HTML entities in the value are escaped (e.g., `&` becomes `&amp;`) when appropriate.\n * @param {string} htmlContent - The HTML content where the placeholder should be replaced.\n * @returns {string} The updated HTML content with placeholders replaced.\n */\nexport const replaceForHtml = (clickTracker: string, htmlContent: string): string => {\n    let content = htmlContent,\n        replacement = clickTracker;\n\n    if (clickTracker === PLACEHOLDER_DEFAULT || clickTracker.trim() === '') {\n        return content;\n    }\n\n    replacement = replacement.replace(/&amp;/g, '&');\n    if (replacement.startsWith('&')) {\n        replacement = replacement.replace(/^&+/, '');\n    }\n    if (replacement.endsWith('&')) {\n        replacement = replacement.replace(/&+$/, '');\n    }\n\n    try {\n        let match;\n        let executions = 0;\n        do {\n            executions++;\n            match = content.match(REGEX_MATCH);\n\n            if (!match) {\n                break;\n            }\n\n            const left = match[LEFT_GROUP_INDEX]; // Match of main left group - not subgroups\n            const right = match[RIGHT_GROUP_INDEX]; // Match of main right group - not subgroups\n            const middle = match[MIDDLE_GROUP_INDEX]; // Match middle group (equals sign)\n\n            const hasHtmlEntity =\n                (left.startsWith('&') && left.endsWith(';')) || (right.startsWith('&') && right.endsWith(';'));\n            const hasUrlEncoding = left.startsWith('%') && right.startsWith('%') && middle === '%3D';\n\n            if (hasHtmlEntity) {\n                content = content.replace(\n                    REGEX_MATCH,\n                    LEFT_GROUP_VALUE + replacement.replace(/&/g, '&amp;') + RIGHT_GROUP_VALUE,\n                );\n            } else if (hasUrlEncoding) {\n                content = content.replace(\n                    REGEX_MATCH,\n                    LEFT_GROUP_VALUE + encodeURIComponent(replacement) + RIGHT_GROUP_VALUE,\n                );\n            } else {\n                content = content.replace(REGEX_MATCH, LEFT_GROUP_VALUE + replacement + RIGHT_GROUP_VALUE);\n            }\n        } while (match && executions < 10);\n    } catch (_ex) {\n        return htmlContent;\n    }\n\n    return content;\n};\n\n/**\n * Replaces placeholders in a URL with a specified click tracker value.\n *\n * This function searches for occurrences of the placeholder `pd_rd_plhdr=t` in the given URL\n * and replaces them with the specified click tracker value. It also trims leading or trailing\n * ampersands (`&` or `&amp;`) from the replacement value to avoid introducing malformed URLs.\n *\n * @param {string} clickTracker - The replacement value for the placeholder.\n *   - If the value matches the default placeholder or is empty/whitespace, no replacement is performed.\n * @param {string} url - The URL where the placeholder should be replaced.\n * @returns {string} The updated URL with placeholders replaced.\n */\nexport const replaceForUrl = (clickTracker: string, url: string): string => {\n    if (clickTracker === PLACEHOLDER_DEFAULT || clickTracker.trim() === '') {\n        return url;\n    }\n\n    const URL_PLACEHOLDER_REGEX = /pd_rd_plhdr=t/g;\n    const trimAmpersands = (clickTracker: string): string => {\n        return clickTracker.trim().replace(/^(&amp;|&)+|(&amp;|&)+$/g, '');\n    };\n\n    return url.replace(URL_PLACEHOLDER_REGEX, trimAmpersands(clickTracker));\n};\n","import { getClickTrackingParamWithSlotId } from '../../../components/clickTracking/getSlotPlaceholder.js';\nimport { replaceForUrl } from '../../../components/clickTracking/replace.js';\nimport type { Placement } from '../../../components/pixels/pixel.js';\n\nexport const replaceClickTrackingParamForDisplayCreative = async (placement: Placement): Promise<void> => {\n    const clickTrackingParam = getClickTrackingParamWithSlotId(placement.name);\n    if (!clickTrackingParam) return;\n\n    for (const a of placement.div.querySelectorAll('a')) {\n        a.href = replaceForUrl(clickTrackingParam, a.href);\n    }\n};\n","import { createObstructionDetectionService } from '@amzn/creative-obstruction-detection/src/obstructionDetectionServiceImpl.js';\n\nimport { tryWaitForBTR } from '@/client/clientReporter.js';\nimport { BEGIN_TO_RENDER_CLIENT, type MEASUREMENT_METHODS } from '@/client/MEASUREMENT_METHODS.js';\nimport type { Placement } from '@/components/pixels/pixel.js';\nimport { btr } from '@/components/pixels/placementData.js';\nimport { createViewabilityService } from '@/components/pixels/services/viewabilityServiceImpl.js';\nimport { isViewRateExperimentEnabled, trackViewRateExperiment } from '@/components/viewRateExperimentUtil.js';\nimport { LIGHT_ADS_EVERYWHERE_WEBLAB } from '@/components/weblabs.js';\nimport { replaceClickTrackingParamForDisplayCreative } from '@/light-ad/domain/service/click-tracking-service.js';\n\nimport type { Creative } from './creative.js';\nimport type { Pixels } from './pixels.js';\n\nexport const createDisplayCreative = (placementDivId: string, pixels: Pixels, adProgramId: number): Creative => {\n    let _isBtr = false;\n\n    return {\n        adElement: document.getElementById(placementDivId)!.querySelector('img'),\n\n        async render(placement: Placement): Promise<void> {\n            _isBtr =\n                (await (LIGHT_ADS_EVERYWHERE_WEBLAB().is('t1')\n                    ? tryWaitForBTRLightAds(placement.div, placement.name)\n                    : tryWaitForBTR(placement.div))) === BEGIN_TO_RENDER_CLIENT;\n\n            replaceClickTrackingParamForDisplayCreative(placement);\n        },\n\n        firePreRenderImpression(placement: Placement): void {\n            fireCODImpression(placement, pixels, adProgramId);\n        },\n\n        track(placement: Placement): void {\n            fireImpressions(placement, pixels, _isBtr, adProgramId);\n            trackViewability(placement, pixels);\n        },\n    };\n};\n\nconst fireCODImpression = (placement: Placement, pixels: Pixels, adProgramId: number): void => {\n    if (isViewRateExperimentEnabled(adProgramId)) {\n        // Do Nothing: delay firing of the COD impression pixel\n    } else {\n        pixels.impressionPixel.fire(placement);\n    }\n};\n\nexport const fireImpressions = (placement: Placement, pixels: Pixels, isBtr: boolean, adProgramId: number): void => {\n    btr.set(placement, isBtr);\n    const obstructionDetectionService = createObstructionDetectionService();\n    if (isViewRateExperimentEnabled(adProgramId)) {\n        trackViewRateExperiment(\n            placement,\n            {\n                impressionPixel: pixels.impressionPixel,\n                btrPixel: pixels.btrPixel,\n                measurabilityPixel: pixels.measurabilityPixel,\n            },\n            createViewabilityService(obstructionDetectionService),\n        );\n        return;\n    }\n\n    if (btr.get(placement)) {\n        pixels.btrPixel?.fire(placement);\n    }\n    pixels.measurabilityPixel.fire(placement);\n    pixels.skanImpressionPixel?.fire(placement).then(() => pixels.skanTrackingPixel?.track(placement));\n};\n\nconst trackViewability = (placement: Placement, pixels: Pixels): void => {\n    pixels.iabViewPixel.track(placement);\n};\n\n/**\n * Wrapper for tryWaitForBTR to handle Intermediate Light Ads scenarios.\n */\nconst tryWaitForBTRLightAds = async (element: HTMLElement, placementName: string): Promise<MEASUREMENT_METHODS> =>\n    tryWaitForBTR(getTargetElementForBTR(element, placementName));\n\n/**\n * Attempts to retrieve the correct target element for BTR evaluation. If the given element has a shadow root, use that.\n * If the element given has an iframe, access its inner body and return that. Otherwise, return the original element.\n */\nconst getTargetElementForBTR = (element: HTMLElement, placementName: string): HTMLElement => {\n    // Check for Shadow DOM\n    if (element.shadowRoot) {\n        // TODO(@calwlai): update evaluateCreativeBeginToRender() to accept ParentNode instead of HTMLElement, since\n        // ShadowRoot satisifies .querySelectorAll(), but is not an HTMLElement.\n        return element.shadowRoot as unknown as HTMLElement;\n    }\n\n    // Check for un-sandboxed iframe\n    const iframe = document.getElementById(`ape_la_${placementName}_iframe`) as HTMLIFrameElement | null;\n    if (iframe?.contentDocument?.body) {\n        return iframe.contentDocument.body;\n    }\n\n    return element;\n};\n","/**\n * Wrapper functions for Homepage Video Orchestrator\n * https://quip-amazon.com/2p4vAbdbNDVg/AmazonHomepage-Herotator-resources\n * https://code.amazon.com/packages/AmazonGatewayHerotatorJS/blobs/mainline/--/src/herotator-controller.js\n */\n\nexport type GwHerotator = {\n    pause: () => void;\n    resume: () => void;\n    addObserver: (type: string, listener: () => void) => void;\n    removeObserver: (type: string, listener: () => void) => void;\n};\n\nconst gwDesktopHerotatorPName = 'gw-desktop-herotator';\n\nexport const pauseHerotator = (): void => {\n    window.P?.when(gwDesktopHerotatorPName).execute((gwHerotator: GwHerotator): void => {\n        gwHerotator.pause();\n    });\n};\n\nexport const resumeHerotator = (): void => {\n    window.P?.when(gwDesktopHerotatorPName).execute((gwHerotator: GwHerotator): void => {\n        gwHerotator.resume();\n    });\n};\n\nexport const addObserverHerotator = (type: string, listener: () => void): void => {\n    window.P?.when(gwDesktopHerotatorPName).execute((gwHerotator: GwHerotator): void => {\n        gwHerotator.addObserver(type, listener);\n    });\n};\n\nexport const removeObserverHerotator = (type: string, listener: () => void): void => {\n    window.P?.when(gwDesktopHerotatorPName).execute((gwHerotator: GwHerotator): void => {\n        gwHerotator.removeObserver(type, listener);\n    });\n};\n","import { addObserverHerotator, pauseHerotator, resumeHerotator } from '@/components/homepage/homepageHerotator.js';\n\nexport const setupH1Herotator = (video: HTMLVideoElement): void => {\n    addObserverHerotator('page_changed', () => (video.currentTime = 0));\n\n    // When video starts playing, pause Herotator\n    if (!video.paused) {\n        pauseHerotator();\n    }\n    video.addEventListener('play', () => pauseHerotator());\n    video.addEventListener('timeupdate', () => {\n        if (!video.paused) pauseHerotator();\n    });\n\n    // User pauses video, rotator resumes\n    video.addEventListener('pause', () => resumeHerotator());\n\n    // Video finishes, rotator resumes\n    video.addEventListener('ended', () => resumeHerotator());\n};\n","export const setupVideoControlsVisibility = (placementDivId: string, video: HTMLVideoElement): void => {\n    setupPlayPauseControls(\n        video,\n        getControl(placementDivId, 'play') ?? getControl(placementDivId, 'replay'),\n        getControl(placementDivId, 'pause'),\n    );\n    setupMuteControls(video, getControl(placementDivId, 'muted'), getControl(placementDivId, 'audio'));\n    setupCcControls(getControl(placementDivId, 'cc_on'), getControl(placementDivId, 'cc_off'));\n};\n\nconst setupPlayPauseControls = (\n    video: HTMLVideoElement,\n    playReplayControl: HTMLElement | null,\n    pauseControl: HTMLElement | null,\n): void => {\n    video.paused\n        ? toggleVisibility(playReplayControl, pauseControl)\n        : toggleVisibility(pauseControl, playReplayControl);\n    video.addEventListener('play', () => toggleVisibility(pauseControl, playReplayControl));\n    video.addEventListener('pause', () => toggleVisibility(playReplayControl, pauseControl));\n    video.addEventListener('ended', () => toggleVisibility(playReplayControl, pauseControl));\n};\n\nconst setupMuteControls = (\n    video: HTMLVideoElement,\n    mutedControl: HTMLElement | null,\n    audioControl: HTMLElement | null,\n): void => {\n    video.muted ? toggleVisibility(mutedControl, audioControl) : toggleVisibility(audioControl, mutedControl);\n    video.addEventListener('mute', () => toggleVisibility(mutedControl, audioControl));\n    video.addEventListener('unmute', () => toggleVisibility(audioControl, mutedControl));\n};\n\nconst setupCcControls = (ccEnableControl: HTMLElement | null, ccDisableControl: HTMLElement | null): void => {\n    toggleVisibility(ccEnableControl, ccDisableControl);\n    ccEnableControl?.addEventListener('click', () => toggleVisibility(ccDisableControl, ccEnableControl));\n    ccDisableControl?.addEventListener('click', () => toggleVisibility(ccEnableControl, ccDisableControl));\n};\n\nconst hide = (el: HTMLElement | null) => el?.style.setProperty('display', 'none');\nconst show = (el: HTMLElement | null) => el?.style.removeProperty('display');\nconst toggleVisibility = (toShow: HTMLElement | null, toHide: HTMLElement | null): void => {\n    show(toShow);\n    hide(toHide);\n};\n\nconst CONTROL_PREFIX = '_h1_control_';\nconst getControl = (id: string, suffix: string) => document.getElementById(`${id}${CONTROL_PREFIX}${suffix}`);\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 { elect, subscribe, unelect } from '@/components/homepage/homepageVideoOrchestrator.js';\n\nexport const videosUserPaused = new Set<string>();\n\nconst subscribeToVideoOrchestrator = (video: HTMLVideoElement): void => {\n    subscribe(\n        video,\n        (isLeader) => {\n            if (isLeader && video.paused && !videosUserPaused.has(video.id)) {\n                video.play();\n            } else if (!isLeader && !video.paused) {\n                video.pause();\n            }\n        },\n        {\n            priority: 100,\n        },\n    );\n};\n\nconst handlePauseOrEnd = (video: HTMLVideoElement) => {\n    videosUserPaused.add(video.id);\n    unelect();\n};\n\nexport const setupVideoOrchestrator = (video: HTMLVideoElement): void => {\n    subscribeToVideoOrchestrator(video);\n    video.addEventListener('user-play', () => {\n        videosUserPaused.delete(video.id);\n        elect(video);\n    });\n    video.addEventListener('user-pause', () => handlePauseOrEnd(video));\n    video.addEventListener('ended', () => handlePauseOrEnd(video));\n};\n","export const setupWD1AutoRotation = async (placement: HTMLElement, video: HTMLVideoElement): Promise<void> => {\n    await autorotationOrchestratorReady();\n\n    if (!video.paused) {\n        placement.dispatchEvent(createEvent(placement, 'painterAttentionStart'));\n    }\n\n    video.addEventListener('play', () => placement.dispatchEvent(createEvent(placement, 'painterAttentionStart')));\n    video.addEventListener('pause', () => placement.dispatchEvent(createEvent(placement, 'painterAttentionEnd')));\n    video.addEventListener('ended', () => placement.dispatchEvent(createEvent(placement, 'painterAttentionEnd')));\n};\n\nconst createEvent = (placement: HTMLElement, eventType: string): Event =>\n    new CustomEvent(eventType, {\n        bubbles: true,\n        detail: {\n            painterInstanceId: placement.id,\n        },\n    });\n\nconst autorotationOrchestratorReady = async (): Promise<void> => {\n    return new Promise<void>((resolve) => {\n        window.P?.when('gw-wd-autorotation-orchestrator').execute(() => {\n            resolve();\n        });\n    });\n};\n","/**\n * This is a simplified version of\n * https://code.amazon.com/packages/D16GCreativeComponents/blobs/5c7fa05b8acbbaaea446a4489279db7c154a5294/--/src/modules/click-events/navigate.js\n *\n * The current target for OLV is endemic ad linking to Amazon page, so we only have limited support for external landing page: open in new window,\n * once we support non-endemic ad, we would need to handle external browser and prime now scenarios in mShop.\n */\n\nconst AMAZON_DOMAIN_REGEX = /^((https?:)?\\/\\/)(.*\\.)?amazon\\./;\nconst IN_SAME_WINDOW = '_top';\nconst IN_NEW_WINDOW = '_blank';\nconst CLICK_TO_NAVIGATION_DELAY_IN_MS = 150;\n\nexport const navigate = (url: string) => {\n    if (AMAZON_DOMAIN_REGEX.test(url)) {\n        setTimeout(() => {\n            window.open(url, IN_SAME_WINDOW);\n        }, CLICK_TO_NAVIGATION_DELAY_IN_MS);\n    } else {\n        window.open(url, IN_NEW_WINDOW);\n    }\n};\n","import { logDebug } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\n\nimport { btr } from '@/components/pixels/placementData.js';\nimport { setupH1Herotator } from '@/light-ad/domain/service/h1HerotatorService.js';\nimport { setupVideoControlsVisibility } from '@/light-ad/domain/service/videoControlsVisibilityService.js';\nimport { setupVideoOrchestrator } from '@/light-ad/domain/service/videoOrchestratorService.js';\nimport { setupWD1AutoRotation } from '@/light-ad/domain/service/wd1AutoRotatorService.js';\n\nimport { navigate } from '../../helpers/navigate.js';\nimport type { Creative } from './creative.js';\nimport type { Pixels } from './pixels.js';\nimport type { Placement } from './placement.js';\n\nexport const CCTrackMode = {\n    DISABLED: 'disabled',\n    ENABLED: 'showing',\n    ENABLED_BUT_HIDDEN: 'hidden',\n} as const;\n\nconst pixelsFired = new Set<string>();\n\nexport const createVideoCreative = (\n    placementDivId: string,\n    pixels: Pixels,\n    trackingEvents: TrackingEvents,\n): Creative => {\n    const waitForAdToLoad = (video: HTMLVideoElement): Promise<void> => {\n        return new Promise((resolve, reject) => {\n            video.addEventListener('canplaythrough', () => resolve());\n            video.addEventListener('error', (e) => reject(e));\n            if (video.readyState >= 3) resolve();\n        });\n    };\n\n    return {\n        adElement: document.getElementById(placementDivId)!.querySelector('video'),\n\n        async render(placement: Placement): Promise<void> {\n            if (!this.adElement) return;\n            rewindVideoOnEnded(this.adElement as HTMLVideoElement);\n            setupH1Herotator(this.adElement as HTMLVideoElement);\n            setupWD1AutoRotation(placement.div, this.adElement as HTMLVideoElement);\n            setupVideoOrchestrator(this.adElement as HTMLVideoElement);\n            setupVideoControlsVisibility(placementDivId, this.adElement as HTMLVideoElement);\n            setupVideoClosedCaptions(placementDivId, this.adElement as HTMLVideoElement);\n            await waitForAdToLoad(this.adElement as HTMLVideoElement);\n        },\n\n        firePreRenderImpression(_: Placement): void {},\n\n        track(placement: Placement): void {\n            const video = this.adElement as HTMLVideoElement;\n            fireImpressions(video, placement, pixels, trackingEvents);\n            trackViewability(pixels, placement);\n            trackVastEvents(video, placement, trackingEvents);\n        },\n    };\n};\n\nconst rewindVideoOnEnded = (video: HTMLVideoElement): void => {\n    video.addEventListener('ended', () => (video.currentTime = 0));\n};\n\n// We only support VTTCue for now (.vtt files)\nconst enableCcOverlay = (cue: VTTCue, overlay: HTMLElement) => {\n    overlay.textContent = cue.text;\n    overlay.style.removeProperty('display');\n};\n\nconst disableCcOverlay = (overlay: HTMLElement) => {\n    overlay.textContent = '';\n    overlay.style.setProperty('display', 'none');\n};\n\nconst updateCcOverlay = (track: TextTrack, overlay: HTMLElement) => {\n    const cue = track.activeCues && (track.activeCues[0] as VTTCue);\n    if (cue?.text) {\n        // if there is an active cue, update its text and show it\n        enableCcOverlay(cue, overlay);\n    } else {\n        // if there is no active cue, set text to blank and hide the overlay\n        disableCcOverlay(overlay);\n    }\n};\n\nconst isCcDisabled = (track: TextTrack) => track.mode === CCTrackMode.DISABLED;\nconst isCcEnabled = (track: TextTrack) => track.mode === CCTrackMode.ENABLED_BUT_HIDDEN;\n\nconst setupVideoClosedCaptions = (placementDivId: string, video: HTMLVideoElement) => {\n    const ccOverlay = document.getElementById(`${placementDivId}_h1_overlay_cc`);\n\n    // Add custom subtitle handling if the cc overlay exists\n    if (ccOverlay && video.textTracks && video.textTracks.length > 0) {\n        const track = video.textTracks[0];\n\n        // cc is disabled by default\n        track.mode = CCTrackMode.DISABLED;\n\n        // custom event fired when track.mode is changed manually by the user\n        track.addEventListener('modechange', () => {\n            const cueChangeHandler = () => updateCcOverlay(track, ccOverlay);\n\n            if (isCcDisabled(track)) {\n                disableCcOverlay(ccOverlay);\n                track.removeEventListener('cuechange', cueChangeHandler);\n            } else if (isCcEnabled(track)) {\n                updateCcOverlay(track, ccOverlay);\n                track.addEventListener('cuechange', cueChangeHandler);\n            }\n        });\n    }\n};\n\nconst fireImpressions = (\n    video: HTMLVideoElement,\n    placement: Placement,\n    pixels: Pixels,\n    trackingEvents: TrackingEvents,\n): void => {\n    if (video.paused) {\n        video.addEventListener(\n            'playing',\n            () => {\n                btr.set(placement, true);\n                pixels.impressionPixel.fire(placement);\n                pixels.btrPixel?.fire(placement);\n                pixels.measurabilityPixel.fire(placement);\n                firePixels(trackingEvents.impressions);\n            },\n            { once: true },\n        );\n    } else {\n        btr.set(placement, true);\n        pixels.impressionPixel.fire(placement);\n        pixels.btrPixel?.fire(placement);\n        pixels.measurabilityPixel.fire(placement);\n        firePixels(trackingEvents.impressions);\n    }\n};\n\nconst trackViewability = (pixels: Pixels, placement: Placement): void => {\n    pixels.iabViewPixel.track(placement);\n};\n\nconst trackVastEvents = (video: HTMLVideoElement, placement: Placement, trackingEvents: TrackingEvents): void => {\n    trackErrorEvent(video, placement, trackingEvents);\n    trackStartEvent(video, trackingEvents);\n    trackProgressEvents(video, trackingEvents);\n    trackCompleteEvent(video, trackingEvents);\n    trackMuteEvent(video, trackingEvents);\n    trackUnmuteEvent(video, trackingEvents);\n    trackPauseEvent(video, trackingEvents);\n    trackRewindEvent(video, trackingEvents);\n    trackResumeEvent(video, trackingEvents);\n    trackVideoClickEvent(video, trackingEvents);\n};\n\nconst trackErrorEvent = async (\n    video: HTMLVideoElement,\n    placement: Placement,\n    trackingEvents: TrackingEvents,\n): Promise<void> => {\n    if (video.error) {\n        await placement.collapse();\n        trackingEvents.error && firePixel(trackingEvents.error);\n    } else {\n        video.addEventListener('error', async () => {\n            await placement.collapse();\n            trackingEvents.error && firePixel(trackingEvents.error);\n        });\n    }\n};\n\nconst trackStartEvent = (video: HTMLVideoElement, trackingEvents: TrackingEvents): void => {\n    if (video.paused) {\n        video.addEventListener('play', () => firePixels(trackingEvents.start));\n    } else {\n        firePixels(trackingEvents.start);\n    }\n};\n\nconst trackProgressEvents = (video: HTMLVideoElement, trackingEvents: TrackingEvents): void => {\n    video.addEventListener('timeupdate', () => {\n        const progress = video.currentTime / video.duration;\n        if (progress >= 0.25) firePixels(trackingEvents.firstQuartile);\n        if (progress >= 0.5) firePixels(trackingEvents.midpoint);\n        if (progress >= 0.75) firePixels(trackingEvents.thirdQuartile);\n    });\n};\n\nconst trackCompleteEvent = (video: HTMLVideoElement, trackingEvents: TrackingEvents): void => {\n    video.addEventListener('ended', () => firePixels(trackingEvents.complete));\n};\n\nconst trackMuteEvent = (video: HTMLVideoElement, trackingEvents: TrackingEvents): void => {\n    video.addEventListener('mute', () => firePixels(trackingEvents.mute));\n};\n\nconst trackUnmuteEvent = (video: HTMLVideoElement, trackingEvents: TrackingEvents): void => {\n    video.addEventListener('unmute', () => firePixels(trackingEvents.unmute));\n};\n\nconst trackPauseEvent = (video: HTMLVideoElement, trackingEvents: TrackingEvents): void => {\n    video.addEventListener('pause', () => firePixels(trackingEvents.pause));\n};\n\nconst trackRewindEvent = (video: HTMLVideoElement, trackingEvents: TrackingEvents): void => {\n    let previousCurrentTime = -1;\n    video.addEventListener('timeupdate', () => {\n        if (video.currentTime < previousCurrentTime) {\n            firePixels(trackingEvents.rewind);\n        }\n        previousCurrentTime = video.currentTime;\n    });\n};\n\nconst trackResumeEvent = (video: HTMLVideoElement, trackingEvents: TrackingEvents): void => {\n    let isPaused = false;\n    video.addEventListener('pause', () => (isPaused = true));\n    video.addEventListener('play', () => isPaused && firePixels(trackingEvents.resume));\n};\n\nconst trackVideoClickEvent = (video: HTMLVideoElement, trackingEvents: TrackingEvents): void => {\n    video.addEventListener('click', (e) => {\n        e.preventDefault();\n        firePixels(trackingEvents.clickTracking);\n        trackingEvents.clickThrough && navigate(trackingEvents.clickThrough);\n    });\n};\n\nconst firePixels = async (pixelUrls: string[]): Promise<void> => {\n    for (const pixelUrl of pixelUrls) {\n        await firePixel(pixelUrl);\n    }\n};\n\nconst firePixel = async (pixelUrl: string): Promise<void> => {\n    if (pixelsFired.has(pixelUrl)) {\n        return;\n    }\n\n    pixelsFired.add(pixelUrl);\n\n    await fetch(pixelUrl, {\n        keepalive: true,\n        mode: 'no-cors',\n        priority: 'low',\n    } as RequestInit);\n    logDebug('Fired pixel: ' + pixelUrl);\n};\n\nexport type TrackingEvents = {\n    impressions: string[];\n    error?: string;\n    start: string[];\n    firstQuartile: string[];\n    midpoint: string[];\n    thirdQuartile: string[];\n    complete: string[];\n    mute: string[];\n    unmute: string[];\n    pause: string[];\n    rewind: string[];\n    resume: string[];\n    clickThrough?: string;\n    clickTracking: string[];\n};\n","import type { LightAdDetails } from '@amzn/safeframe-model';\n\nimport type { PixelInfo } from '@/components/pixels/pixelMapper.js';\nimport {\n    createIabViewPixel,\n    mapToBtrPixel,\n    mapToImpressionPixel,\n    mapToMeasurabilityPixel,\n    mapToSkanImpressionPixel,\n    mapToSkanViewPixel,\n} from '@/components/pixels/pixelMapper.js';\nimport { createLightAdVideoFirePixelValidator } from '@/components/pixels/services/videoFirePixelValidator.js';\n\nimport type { Creative } from '../../domain/model/creative.js';\nimport { createDisplayCreative } from '../../domain/model/displayCreative.js';\nimport { createVideoCreative } from '../../domain/model/videoCreative.js';\n\nexport const mapToCreative = (lightAdDetails: LightAdDetails): Creative =>\n    lightAdDetails.videoCreative ? mapToVideoCreative(lightAdDetails) : mapToDisplayCreative(lightAdDetails);\n\nconst mapToDisplayCreative = (lightAdDetails: LightAdDetails): Creative =>\n    createDisplayCreative(\n        lightAdDetails.adUnitPlacementId,\n        mapToPixels(lightAdDetails),\n        Number(lightAdDetails.adCreativeMetaData.adProgramId),\n    );\n\nconst mapToVideoCreative = (lightAdDetails: LightAdDetails): Creative => {\n    const videoCreativeDto = lightAdDetails.videoCreative!;\n    return createVideoCreative(lightAdDetails.adUnitPlacementId, mapToPixels(lightAdDetails), {\n        impressions: videoCreativeDto.impressions,\n        error: videoCreativeDto.error,\n        start: videoCreativeDto.trackingEvents.start ?? [],\n        firstQuartile: videoCreativeDto.trackingEvents.firstQuartile ?? [],\n        midpoint: videoCreativeDto.trackingEvents.midpoint ?? [],\n        thirdQuartile: videoCreativeDto.trackingEvents.thirdQuartile ?? [],\n        complete: videoCreativeDto.trackingEvents.complete ?? [],\n        mute: videoCreativeDto.trackingEvents.mute ?? [],\n        unmute: videoCreativeDto.trackingEvents.unmute ?? [],\n        pause: videoCreativeDto.trackingEvents.pause ?? [],\n        rewind: videoCreativeDto.trackingEvents.rewind ?? [],\n        resume: videoCreativeDto.trackingEvents.resume ?? [],\n        clickThrough: videoCreativeDto.videoClicks.clickThrough,\n        clickTracking: videoCreativeDto.videoClicks.clickTracking,\n    });\n};\n\nconst mapToPixels = (lightAdDetails: LightAdDetails) => {\n    const htmlElement = document.getElementById(lightAdDetails.adUnitPlacementId) as HTMLDivElement;\n    const pixelInfo = createPixelInfo(lightAdDetails);\n    const mediaType = lightAdDetails.videoCreative ? 'V' : 'D';\n    const videoFirePixelValidator = () => createLightAdVideoFirePixelValidator(htmlElement);\n    return {\n        impressionPixel: mapToImpressionPixel(pixelInfo),\n        measurabilityPixel: mapToMeasurabilityPixel(pixelInfo),\n        iabViewPixel: createIabViewPixel(\n            mediaType,\n            htmlElement,\n            pixelInfo,\n            lightAdDetails.deviceType,\n            videoFirePixelValidator,\n            undefined,\n            lightAdDetails,\n        ),\n        skanImpressionPixel: mapToSkanImpressionPixel(pixelInfo),\n        skanTrackingPixel: mapToSkanViewPixel(pixelInfo),\n        btrPixel: mapToBtrPixel(pixelInfo),\n    };\n};\n\nconst createPixelInfo = (lightAdDetails: LightAdDetails): PixelInfo => ({\n    aaxImpPixelUrl: lightAdDetails.aaxImpPixelUrl,\n    imp3pUrls: lightAdDetails.imp3pUrls,\n    aaxInstrPixelUrl: lightAdDetails.aaxInstrPixelUrl,\n    abpAcceptable: lightAdDetails.abpAcceptable,\n    abpStatus: lightAdDetails.abpStatus ?? '-1',\n    btrPixelUrl: lightAdDetails.btrPixelUrl,\n    skAdNetwork: lightAdDetails.skAdNetwork,\n    loggingContext: {\n        aaxProgramId: Number(lightAdDetails.adCreativeMetaData.adProgramId),\n    },\n});\n","import type { LightAdDetails } from '@amzn/safeframe-model';\n\nimport { Placement } from '../../domain/model/placement.js';\nimport { mapToCreative } from './creativeMapper.js';\n\nexport const mapToPlacement = (lightAdDetails: LightAdDetails): Placement => {\n    return new Placement(\n        lightAdDetails.placementId,\n        lightAdDetails.placementName,\n        lightAdDetails.adUnitPlacementId,\n        mapToCreative(lightAdDetails),\n        lightAdDetails.deviceType,\n    );\n};\n","import type { LightAdDetails } from '@amzn/safeframe-model';\n\nimport type { LightAd } from '../../domain/model/LightAd.js';\nimport { mapToPlacement } from './placementMapper.js';\n\nexport const fromLightAdDetails = (lightAdDetails: LightAdDetails): LightAd => {\n    const placement = mapToPlacement(lightAdDetails);\n    return {\n        placement,\n        lightAdDetails: lightAdDetails,\n    };\n};\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","import { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport type { LightAdDetails } from '@amzn/safeframe-model';\n\nimport { labelRendered, openModal } from '@/components/feedback.js';\n\nimport { lightAdRepo } from '../outbound/lightAdRepo.js';\n\nexport interface FeedbackApi {\n    /**\n     * Notifies that the feedback label has been rendered.\n     * You must call this method after inserting your own SL into the DOM.\n     * @param elementId - ID of the placement div or any child element within it\n     */\n    labelRendered(elementId: string): Promise<void>;\n\n    /**\n     * Opens the ad feedback modal.\n     * @param elementId - ID of the placement div or any child element within it\n     */\n    openModal(elementId: string): void;\n}\n\nexport class FeedbackApiImpl implements FeedbackApi {\n    async labelRendered(elementId: string): Promise<void> {\n        try {\n            const lightAdDetails = await getAdDetailsFromElementId(elementId);\n\n            labelRendered({\n                id: lightAdDetails.placementId,\n                name: lightAdDetails.placementName,\n            });\n        } catch (err) {\n            logError(`Light ad - labelRendered failed for '${sanitizeForLog(elementId)}'`, err);\n        }\n    }\n\n    openModal(elementId: string): void {\n        try {\n            const placementParentDiv = getPlacementDiv(elementId).parentElement!;\n            openModal(placementParentDiv.id);\n        } catch (err) {\n            logError(`Light ad - openModal failed for '${sanitizeForLog(elementId)}'`, err);\n        }\n    }\n}\n\nconst getAdDetailsFromElementId = async (elementId: string): Promise<LightAdDetails> => {\n    const placementDiv = getPlacementDiv(elementId);\n    const entity = await lightAdRepo().get(placementDiv);\n    return entity.lightAdDetails;\n};\n\nconst getPlacementDiv = (elementId: string): HTMLElement => {\n    const element = document.getElementById(elementId);\n\n    if (!element) {\n        throw new Error(`Element '${elementId}' doesn't exist`);\n    }\n\n    if (element.classList.contains('ape-placement')) {\n        return element;\n    }\n\n    const placementDiv = element.closest('.ape-placement');\n\n    if (!placementDiv) {\n        throw new Error(`No placement div found for element '${elementId}'`);\n    }\n\n    return placementDiv as HTMLElement;\n};\n\n/**\n * Sanitizes input for logging by removing newline and carriage return characters.\n * Prevents CWE-117 log injection attacks where malicious input could inject fake log entries.\n */\nconst sanitizeForLog = (input: string): string => input.replace(/[\\r\\n]/g, '');\n","import { CCTrackMode } from '../domain/model/videoCreative.js';\nimport { lightAdRepo } from '../outbound/lightAdRepo.js';\n\nexport interface VideoApi {\n    replay: (placementDivId: string) => Promise<void>;\n    play: (placementDivId: string) => Promise<void>;\n    pause: (placementDivId: string) => Promise<void>;\n    mute: (placementDivId: string) => Promise<void>;\n    unmute: (placementDivId: string) => Promise<void>;\n    enableCc: (placementDivId: string) => Promise<void>;\n    disableCc: (placementDivId: string) => Promise<void>;\n    visibilityChange: (controlsToDisplay: string[], controlsToHide: string[]) => void;\n}\n\nexport class VideoApiImpl implements VideoApi {\n    async replay(placementDivId: string): Promise<void> {\n        const video = await getVideo(placementDivId);\n        video.currentTime = 0;\n        await this.play(placementDivId);\n    }\n\n    async play(placementDivId: string): Promise<void> {\n        const video = await getVideo(placementDivId);\n        video.play();\n        video.dispatchEvent(new CustomEvent('user-play'));\n    }\n\n    async pause(placementDivId: string): Promise<void> {\n        const video = await getVideo(placementDivId);\n        video.pause();\n        video.dispatchEvent(new CustomEvent('user-pause'));\n    }\n\n    async mute(placementDivId: string): Promise<void> {\n        const video = await getVideo(placementDivId);\n        video.muted = true;\n        video.dispatchEvent(new CustomEvent('mute'));\n    }\n\n    async unmute(placementDivId: string): Promise<void> {\n        const video = await getVideo(placementDivId);\n        video.muted = false;\n        video.dispatchEvent(new CustomEvent('unmute'));\n    }\n\n    /**\n     * Enables closed-captions for our video by setting the text track to 'hidden', which means the track will still\n     * fire events like 'cuechange' and will not display the captions natively. If there's currently an active cue,\n     * immediately populate our closed captions overlay and show it.\n     */\n    async enableCc(placementDivId: string): Promise<void> {\n        const video = await getVideo(placementDivId);\n        const ccOverlay = document.getElementById(`${placementDivId}_h1_overlay_cc`);\n        const track = video?.textTracks?.[0];\n\n        if (!video || !ccOverlay || !track) {\n            return;\n        }\n\n        // hidden means the text tracks will still fire events and we can populate our overlay\n        track.mode = CCTrackMode.ENABLED_BUT_HIDDEN;\n        track.dispatchEvent(new CustomEvent('modechange'));\n    }\n\n    /**\n     * Disables closed captions for our video by setting the text track to 'disabled'. It will stop firing events on the\n     * track. We de-populate our closed captions overlay and hide it.\n     */\n    async disableCc(placementDivId: string): Promise<void> {\n        const video = await getVideo(placementDivId);\n        const ccOverlay = document.getElementById(`${placementDivId}_h1_overlay_cc`);\n        const track = video?.textTracks?.[0];\n\n        if (!video || !ccOverlay || !track) {\n            return;\n        }\n\n        track.mode = CCTrackMode.DISABLED;\n        track.dispatchEvent(new CustomEvent('modechange'));\n    }\n\n    visibilityChange(controlsToDisplay: string[], controlsToHide: string[]): void {\n        controlsToDisplay.forEach((control) => {\n            document.getElementById(control)?.style.removeProperty('display');\n        });\n        controlsToHide.forEach((control) => {\n            document.getElementById(control)?.style.setProperty('display', 'none');\n        });\n    }\n}\n\nconst getVideo = async (placementDivId: string): Promise<HTMLVideoElement> => {\n    const placementDiv = document.getElementById(placementDivId)!;\n    const entity = await lightAdRepo().get(placementDiv);\n    return entity.placement.creative.adElement as HTMLVideoElement;\n};\n","import { logError } from '@amzn/apejs-instrumentation/src/metrics/logging.js';\nimport type { LightAdDetails } from '@amzn/safeframe-model';\n\nimport { mark } from '@/components/perf.js';\nimport { processLightAd } from '@/light-ad/domain/service/lightAdService.js';\nimport { fromLightAdDetails } from '@/light-ad/inbound/mapper/lightAdMapper.js';\n\nimport type { FeedbackApi } from './feedbackApi.js';\nimport { FeedbackApiImpl } from './feedbackApi.js';\nimport type { VideoApi } from './videoApi.js';\nimport { VideoApiImpl } from './videoApi.js';\n\nexport interface LightAdApi {\n    init(lightAdDetails: LightAdDetails): void;\n\n    feedback: FeedbackApi;\n\n    video: VideoApi;\n}\n\nexport class LightAdApiImpl implements LightAdApi {\n    /**\n     * Initializes and processes a light ad with the provided details.\n     * Called from GrandPrixAdTemplates light-ad.ftl template.\n     * @see https://code.amazon.com/packages/GrandPrixAdTemplates/blobs/mainline/--/templates/amazon/light-ad.ftl\n     * @param lightAdDetails - The light ad configuration and content details\n     */\n    init = (lightAdDetails: LightAdDetails) => {\n        mark('perf:la', 'init');\n        try {\n            processLightAd(fromLightAdDetails(lightAdDetails));\n        } catch (err) {\n            logError('Error LightAdApi.init', err);\n        }\n    };\n\n    feedback = new FeedbackApiImpl();\n\n    video = new VideoApiImpl();\n}\n","import { mark } from '@/components/perf.js';\n\nimport type { LightAdApi } from './inbound/lightAdApi.js';\nimport { LightAdApiImpl } from './inbound/lightAdApi.js';\n\ndeclare global {\n    interface Window {\n        APE_LA: LightAdApi;\n    }\n}\n\nexport const LIGHT_AD_API_READY_EVENT = 'LIGHT_AD_API_READY_EVENT';\n\nexport const initLightAd = (): void => {\n    if (window.APE_LA) {\n        return;\n    }\n\n    mark('perf:la', 'create LightAdApiImpl');\n    window.APE_LA = new LightAdApiImpl();\n    window.dispatchEvent(new CustomEvent(LIGHT_AD_API_READY_EVENT));\n};\n","/**\n * Entry point for Desktop version of light ad client-side script\n */\nimport { initLightAd } from './initLightAd.js';\n\ninitLightAd();\n"],"x_google_ignoreList":[1,2,5,6,7,10,11,12,13,28,29,30,31,32,33,59,60],"mappings":"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"}