{"version":3,"file":"sf-1.50.h7l6hjyi.js","names":[],"sources":["../../../../src/js/client/api/iab/geomCache.ts","../../../../src/js/client/api/iab/numberCache.ts","../../../../src/js/client/app/components/adDetails.ts","../../../../src/js/client/app/components/disable/disableCookieAccess.ts","../../../../src/js/client/app/components/disable/disableGeolocationApi.ts","../../../../src/js/client/app/components/disable/disableUserAgent.ts","../../../../../../../node_modules/@amzn/grandprix-runtime/src/instrumentation/csa/core.ts","../../../../../../../node_modules/@amzn/grandprix-runtime/src/instrumentation/csa/metrics.ts","../../../../src/js/components/state/page/pageState.ts","../../../../src/js/components/weblabs.ts","../../../../src/js/components/metrics/csaMetrics.ts","../../../../src/js/client/app/components/disable/logUserAgentAccess.ts","../../../../src/js/client/app/components/disable/workAroundIOBugtt0156195085.ts","../../../../src/js/client/app/components/disable/disableAll.ts","../../../../../../../node_modules/@amzn/grandprix-runtime/src/messaging.ts","../../../../src/js/components/perf.ts","../../../../src/js/client/app/components/notifyParent.ts","../../../../src/js/client/app/components/percolateClickTracker.ts","../../../../src/js/client/app/components/referrers.ts","../../../../src/js/client/app/components/setupReportingObserver.ts","../../../../src/js/client/api/iab/sfApi.ts","../../../../src/js/client/app/components/dcm.ts","../../../../src/js/client/app/components/documentWrite.ts","../../../../../../../node_modules/@amzn/creative-rendering-monitor/src/btr.ts","../../../../../../../node_modules/@amzn/creative-rendering-monitor/src/creativeBTREvaluatorSync.ts","../../../../src/js/client/app/components/handleErrors.ts","../../../../src/js/components/bridge/core/wire.ts","../../../../../../../node_modules/@amzn/grandprix-runtime/src/instrumentation/csa/logging.ts","../../../../src/js/components/metrics/emitErrorLog.ts","../../../../src/js/components/bridge/core/sender.ts","../../../../src/js/components/bridge/csa/csaBridgeSender.ts","../../../../src/js/components/bridge/csm/csmBridgeSender.ts","../../../../src/js/client/app/components/windowGlobals.ts","../../../../../../../node_modules/@amzn/safeframe-model/dist-es/models/enums.js","../../../../src/js/components/util.ts","../../../../src/js/client/app/components/get-creative.ts","../../../../src/js/client/app/components/imageTemplateDetection.ts","../../../../src/js/components/pixels/pixelIdentifiers.ts","../../../../src/js/components/state/placement/placementState.ts","../../../../src/js/components/state/placement/pixelState.ts","../../../../src/js/components/pixels/pixel.ts","../../../../src/js/components/pixels/urlGenerators/impressionPixelUrlGenerator.ts","../../../../src/js/components/pixels/pixelMapper.ts","../../../../src/js/components/viewRateExperimentUtil.ts","../../../../src/js/client/app/components/render.ts","../../../../src/js/client/app/components/validateCreativeRendering.ts","../../../../src/js/client/app/components/writeCreativeToDOM.ts","../../../../src/js/components/beginToRender.ts","../../../../src/js/components/clickTracking/replace.ts","../../../../src/js/client/app/safeframeClient.ts","../../../../src/js/components/utils/hasOwn.ts","../../../../src/js/components/bridge/core/receiver.ts","../../../../src/js/components/bridge/safeFrameExt/safeFrameExtBridgeReceiver.ts","../../../../src/js/client/app/initSafeframeClient.ts","../../../../src/js/components/bridge/customMessage/customMessageSender.ts","../../../../src/js/components/bridge/sfclient/sfClientBridgeSender.ts","../../../../src/js/components/bridge/video/videoBridgeSender.ts","../../../../src/js/client/app/safeframeClientFactory.ts","../../../../src/js/client/app/entrypoints/sf.ts"],"sourcesContent":["import type { GeometricInformation } from '@amzn/safe-frame-client';\n\nimport type { Cache } from '@/components/cache.js';\n\nexport const defaultGeom: GeometricInformation = {\n    win: {\n        t: 0,\n        b: 0,\n        l: 0,\n        r: 0,\n        w: 0,\n        h: 0,\n    },\n    self: {\n        t: 0,\n        l: 0,\n        r: 0,\n        b: 0,\n        xiv: 0,\n        yiv: 0,\n        iv: 0,\n        z: 0,\n        w: 0,\n        h: 0,\n    },\n    exp: {\n        t: 0,\n        l: 0,\n        r: 0,\n        b: 0,\n        xs: 0,\n        yx: 0,\n    },\n};\n\nconst createGeomCache = (initial: GeometricInformation = defaultGeom): Cache<GeometricInformation> => {\n    const cachedGeom: GeometricInformation = initial;\n\n    return {\n        set(newGeom: GeometricInformation): void {\n            cachedGeom.self = {\n                ...cachedGeom.self,\n                ...newGeom.self,\n            };\n        },\n        get(): GeometricInformation {\n            return cachedGeom;\n        },\n    };\n};\n\nexport const geomCache = createGeomCache();\n","import type { Cache } from '@/components/cache.js';\n\nconst createNumberCache = (defaultNumber: number = -1): Cache<number> => {\n    let cachedNumber = defaultNumber;\n\n    return {\n        set(value: number): void {\n            cachedNumber = value;\n        },\n        get(): number {\n            return cachedNumber;\n        },\n    };\n};\n\nexport const inViewPercentageCache = createNumberCache();\n","import type { AdDetails } from '@amzn/safeframe-model';\n\n/**\n * Retrieves and parses {@link AdDetails} from the iframe's `window.name`.\n * @throws {Error} If `window.name` is empty or contains invalid JSON.\n */\nexport const getAdDetails = (): AdDetails => {\n    if (!window.name) {\n        throw new Error('Ad Details not found in name!');\n    }\n\n    try {\n        return JSON.parse(window.name);\n    } catch {\n        throw new Error(`Failed to parse Ad Details from name: ${window.name}`);\n    }\n};\n","/**\n * Disables creative access to set and get cookies.\n * @see https://issues.amazon.com/issues/APEX-4377\n */\nexport const disableCookieAccess = () => {\n    Object.defineProperty(Document.prototype, 'cookie', {\n        get: () => '',\n        set: () => {\n            // Empty\n        },\n    });\n};\n","/**\n * Disables geolocation API access for creatives.\n * @see https://issues.amazon.com/issues/CPP-24902\n */\nconst permissionDeniedError: GeolocationPositionError = {\n    code: 1, // PERMISSION_DENIED\n    message: 'Geolocation access disabled',\n    PERMISSION_DENIED: 1,\n    POSITION_UNAVAILABLE: 2,\n    TIMEOUT: 3,\n};\n\nexport const disableGeolocationApi = () => {\n    if (window?.navigator?.geolocation) {\n        window.navigator.geolocation.watchPosition = (\n            _successCallback: PositionCallback,\n            _errorCallback?: PositionErrorCallback | null,\n            _options?: PositionOptions,\n        ): number => {\n            _errorCallback?.(permissionDeniedError);\n            return 0;\n        };\n\n        window.navigator.geolocation.getCurrentPosition = (\n            _successCallback: PositionCallback,\n            _errorCallback?: PositionErrorCallback | null,\n            _options?: PositionOptions,\n        ) => {\n            _errorCallback?.(permissionDeniedError);\n        };\n    }\n};\n","/**\n * Disables user agent access for creatives.\n * @see https://shepherd.a2z.com/issues/e4e8cd86-419a-4e1a-96ff-b20a6615b8b5\n */\nexport const disableUserAgent = () => {\n    Object.defineProperty(Navigator.prototype, 'userAgent', {\n        get: () => '',\n        set: () => {\n            // Empty\n        },\n    });\n};\n","export const METRICS_SOURCE_GROUP = 'com.amazon.apm.stores.csa.metrics.prod';\nexport const LOGS_SOURCE_GROUP = 'com.amazon.apm.stores.csa.logs.prod';\nexport const NEXUS_SCHEMA_ID = 'com.amazon.apm.stores.ClientMetric.2';\nexport const NEXUS_PRODUCER_ID = 'apm-stores';\n\ntype LogCsaEventInput = {\n    sushiSourceGroup?: string;\n    producerId?: string;\n    data: Record<string, unknown>;\n};\n\n/**\n * Low-level transport: sends a single event to the CSA Events plugin.\n * Routes to either a Sushi source group or a Nexus producer depending on which\n * option is provided. Callers should use {@link emitCsaMetric} or {@link emitCsaLog} instead.\n *\n * @param sushiSourceGroup - Sushi source group to route the event to.\n * @param producerId - Nexus producer ID for the Nexus/Spektr emit path.\n * @param data - Arbitrary event payload.\n */\nexport const logCsaEvent = ({ sushiSourceGroup, producerId, data }: LogCsaEventInput): void =>\n    window.csa?.('Events', {\n        ...(producerId && { producerId }),\n        ...(sushiSourceGroup && { sushiSourceGroup }),\n    })?.('log', data, { ent: 'all' });\n","import { logCsaEvent, METRICS_SOURCE_GROUP, NEXUS_PRODUCER_ID, NEXUS_SCHEMA_ID } from './core.js';\n\nexport type CsaMetricInput = {\n    metricName: string;\n    metricValue: number;\n    timestamp?: Date;\n    dimensions: Record<string, string>;\n    weblabs?: Record<string, string>;\n};\n\n/**\n * Emits a CSA metric event to the metrics source group, which also routes to\n * the default CSA source group (Nexus → Spektr) for downstream analytics.\n *\n * Dual-emits: once to Sushi (full-precision metricValue, epoch ms timestamp) and once to\n * Nexus (rounded metricValue as int per the ClientMetric schema, ISO 8601 timestamp).\n *\n * @param metricName - Name of the metric to emit.\n * @param metricValue - Numeric value of the metric.\n * @param timestamp - When the metric was recorded. Defaults to now.\n * @param dimensions - Key-value pairs for metric dimensions.\n * @param weblabs - Active weblab treatments. Only included when provided.\n */\nexport const emitCsaMetric = ({\n    metricName,\n    metricValue,\n    timestamp = new Date(),\n    dimensions,\n    weblabs,\n}: CsaMetricInput): void => {\n    const base = { metricName, metricValue, dimensions };\n    logCsaEvent({\n        sushiSourceGroup: METRICS_SOURCE_GROUP,\n        data: { ...base, timestamp: timestamp.getTime(), ...(weblabs && { weblabs }) },\n    });\n    logCsaEvent({\n        producerId: NEXUS_PRODUCER_ID,\n        data: {\n            ...base,\n            metricValue: Math.round(metricValue),\n            timestamp: timestamp.toISOString(),\n            schemaId: NEXUS_SCHEMA_ID,\n        },\n    });\n};\n","type PageState = Record<string, Set<string>>;\n\ndeclare global {\n    interface Window {\n        AD_PLACEMENT: PageState;\n    }\n}\n\nconst getPageState = (): PageState => (window.AD_PLACEMENT ??= {});\n\nexport const getNamespace = (namespace: string): Set<string> => (getPageState()[namespace] ??= new Set());\n\nexport const createPageSet = (namespace: string) => {\n    const set = () => getNamespace(namespace);\n    return {\n        has: (key: string): boolean => set().has(key),\n        mark: (key: string): void => {\n            set().add(key);\n        },\n    };\n};\n\nexport const collapsedPlacements = createPageSet('collapsedPlacements');\nexport const emittedMetrics = createPageSet('loggedMetricNames');\nexport const feedbackState = createPageSet('feedback');\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    isAssigned(): boolean;\n    isInTreatment(): boolean;\n    getTreatment(): AllWeblabTreatment;\n}\n\nexport const createWeblab = (weblabsWindow: WeblabsWindow, prefix: string): Weblab => {\n    const weblabTreatment = (): AllWeblabTreatment | undefined =>\n        weblabsWindow?.renderingWeblabs?.[prefix]?.toLowerCase() as AllWeblabTreatment;\n\n    return {\n        is(treatment: WeblabTreatment): boolean {\n            return weblabTreatment() === treatment;\n        },\n        isAssigned(): boolean {\n            return weblabTreatment() !== undefined;\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 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 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 * Compares per-placement Light Ad assets with page-level loading at window load and at the first Light Ad placement.\n * @link https://app.weblab.amazon.dev/setup/APM_STORES_PAGE_LEVEL_LIGHT_AD_JS_1418728\n */\nexport const PAGE_LEVEL_LIGHT_AD_JS_WEBLAB_NAME = 'APM_STORES_PAGE_LEVEL_LIGHT_AD_JS_1418728';\nexport const PAGE_LEVEL_LIGHT_AD_JS_WEBLAB = () => createWeblab(window, PAGE_LEVEL_LIGHT_AD_JS_WEBLAB_NAME);\n\n/**\n * Collapses a Light Ad slot when Light Ad init fails, for example when the placement div is missing.\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_LIGHT_AD_INIT_FAILURE_COLLAPSE_1483332\n */\nexport const LIGHT_AD_INIT_FAILURE_COLLAPSE_WEBLAB_NAME =\n    'APM_STORES_JPS_JRS_SAFEFRAME_LIGHT_AD_INIT_FAILURE_COLLAPSE_1483332';\nexport const LIGHT_AD_INIT_FAILURE_COLLAPSE_WEBLAB = () =>\n    createWeblab(window, LIGHT_AD_INIT_FAILURE_COLLAPSE_WEBLAB_NAME);\n\n/**\n * Reuses the last known placement or iframe node when the page detaches it, for example the Events deals grid.\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_DETACHED_PLACEMENT_REUSE_1483333\n */\nexport const DETACHED_PLACEMENT_REUSE_WEBLAB_NAME = 'APM_STORES_JPS_JRS_SAFEFRAME_DETACHED_PLACEMENT_REUSE_1483333';\nexport const DETACHED_PLACEMENT_REUSE_WEBLAB = () => createWeblab(window, DETACHED_PLACEMENT_REUSE_WEBLAB_NAME);\n\n/**\n * T1 detects begin-to-render inside same-origin inner iframes (1 s window) and times every BTR window in real time.\n * C marks any creative with an inner iframe as BTR unknown and counts the 75 ms window in poll ticks.\n * @link https://weblab.amazon.com/wl/APM_STORES_JPS_JRS_SAFEFRAME_INNER_IFRAME_BTR_1487818\n */\nexport const INNER_IFRAME_BTR_WEBLAB_NAME = 'APM_STORES_JPS_JRS_SAFEFRAME_INNER_IFRAME_BTR_1487818';\nexport const INNER_IFRAME_BTR_WEBLAB = () => createWeblab(window, INNER_IFRAME_BTR_WEBLAB_NAME);\n","import { emitCsaMetric } from '@amzn/grandprix-runtime/src/instrumentation/csa/metrics.js';\nimport type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport { emittedMetrics } from '@/components/state/page/pageState.js';\nimport { PAGE_LEVEL_LIGHT_AD_JS_WEBLAB, PAGE_LEVEL_LIGHT_AD_JS_WEBLAB_NAME } from '@/components/weblabs.js';\n\ntype LifecycleMetricName = 'event:start' | 'event:prewrite' | 'event:postwrite' | 'event:btr' | 'event:load';\ntype CoordinateMetricName = 'coordinate:x' | 'coordinate:y';\nexport type PixelMetricName =\n    | 'pixel:imp:cod'\n    | 'pixel:imp:cod:single-video-ads'\n    | 'pixel:imp:cod:video'\n    | 'pixel:imp:cod:display'\n    | 'pixel:imp:btr'\n    | 'pixel:imp:btr:unknown'\n    | 'pixel:imp:btr:missing'\n    | 'pixel:imp:3p'\n    | 'pixel:imp:atf'\n    | 'pixel:view:iab'\n    | 'pixel:view:iab:video'\n    | 'pixel:view:iab:display'\n    | 'pixel:imp:skan'\n    | 'pixel:view:skan';\nexport type PixelErrorMetricName = `${PixelMetricName}:error`;\nexport type LightAdTimingMetricName = 'lightad:init:timing' | `${PixelMetricName}:timing`;\ntype MobileApiMetricName =\n    | 'sf:mobileapi:getPlacementInfo'\n    | 'sf:mobileapi:getUserAgentInfo'\n    | 'sf:mobileapi:getDocumentCookie'\n    | 'sf:mobileapi:getUserConnectionInfo';\n\ntype MashHandlerMetricName =\n    | 'sf:mash:openInApp3pBrowser'\n    | 'sf:mash:openInApp3pBrowser:success'\n    | 'sf:mash:openInApp3pBrowser:fail'\n    | 'sf:mash:openInExternalBrowser'\n    | 'sf:mash:showEmbeddedBrowser'\n    | 'sf:mash:isAUIAvailable';\nexport type CollapseMetricCode = 'creative' | 'client-setup' | 'host-setup' | 'client-error' | 'light-ad-init';\ntype CollapseMetricName = `placement:collapse:${CollapseMetricCode}` | 'placement:collapse';\n/**\n * Metric names emitted automatically by `bindReceiver` for every bridge call.\n * Csm and Csa are excluded since they are metric/logging channels themselves.\n *\n * If you add a method to a bridge interface, you MUST add the corresponding\n * metric name here — the test in bridgeMetricNames.test.ts will fail otherwise.\n */\nexport const BRIDGE_METRIC_NAMES = [\n    'sf:bridge:Video:updatePlayingTimeForVideo',\n    'sf:bridge:Video:requestVideoAutoplay',\n    'sf:bridge:Video:releaseVideoAutoplay',\n    'sf:bridge:Video:haveVideoAutoplayPermission',\n    'sf:bridge:Events:onSafeFrameReady',\n    'sf:bridge:Events:onPreCreativeWrite',\n    'sf:bridge:Events:onPostCreativeWrite',\n    'sf:bridge:Events:onCreativeBeginToRender',\n    'sf:bridge:Events:onCreativeLoad',\n    'sf:bridge:Events:onError',\n    'sf:bridge:Events:onClick',\n    'sf:bridge:SFClient:changeSize',\n    'sf:bridge:SFClient:collapseSlot',\n    'sf:bridge:SFClient:signalAdLoadedAndInteractive',\n    'sf:bridge:SFClient:feedbackLabelRendered',\n    'sf:bridge:SFClient:feedbackOpenModal',\n    'sf:bridge:SFClient:isOnAmazon',\n    'sf:bridge:CustomMessage:dispatch',\n    'sf:bridge:SafeFrameExt:populateSafeFrameExt',\n    'sf:bridge:SafeFrameExt:populateGeom',\n    'sf:bridge:Mash:openInApp3pBrowser',\n    'sf:bridge:Mash:openInApp3pBrowserReply',\n    'sf:bridge:MSFClient:onPageEvent',\n    'sf:bridge:MSFClient:onPageEventReply',\n    'sf:bridge:MSFClient:renderClickThroughAppAds',\n] as const;\nexport type BridgeMetricName = (typeof BRIDGE_METRIC_NAMES)[number];\n\n/** Client-local API metrics (not bridge calls, emitted directly by the client). */\ntype CustomMessageApiMetricName = 'sf:bridge:CustomMessage:registerCustomMessageListener';\n\ntype BlankAdMetricName = 'blank:ad:validation' | 'blank:ad:validation:error';\nexport type ObstructionMetricName = 'viewpixel:iab:obstruction' | 'viewpixel:iab:obstruction:recovered';\ntype DiagnosticMetricName =\n    | 'html:element:missing:placement'\n    | 'html:element:missing:iframe'\n    | 'html:element:detached:placement'\n    | 'html:element:detached:iframe'\n    | 'asset:load:timing'\n    | 'intersection:observer:invalid:target'\n    | 'reporting-observer:heavy-ad-intervention'\n    | 'sf:useragent:access'\n    | 'sf:host:port:rebind';\ntype ShepherdMetricName = 'shepherd:postmessage:parent';\ntype FeedbackMetricName = 'gpat:sponsored:label:rendered';\nexport type VideoMilestoneMetricName =\n    | 'lightad:video:canplay:duration'\n    | 'lightad:video:canplaythrough:duration'\n    | 'lightad:video:playing:duration';\ntype VideoMetricName =\n    | VideoMilestoneMetricName\n    | 'lightad:video:attach:duration'\n    | 'lightad:video:buffer:count'\n    | 'lightad:video:buffer:duration'\n    | 'lightad:video:prerender';\nexport type MetricName =\n    | LifecycleMetricName\n    | CoordinateMetricName\n    | PixelMetricName\n    | PixelErrorMetricName\n    | MobileApiMetricName\n    | MashHandlerMetricName\n    | CollapseMetricName\n    | BridgeMetricName\n    | CustomMessageApiMetricName\n    | BlankAdMetricName\n    | ObstructionMetricName\n    | DiagnosticMetricName\n    | ShepherdMetricName\n    | FeedbackMetricName\n    | VideoMetricName;\n\ninterface EmitPlacementMetricParams {\n    metricName: MetricName;\n    metricValue?: number;\n    adDetails: AdDetails | LightAdDetails;\n    timestamp?: Date;\n}\n\ninterface EmitMetricParams extends EmitPlacementMetricParams {\n    /** Low-cardinality dimensions to add without replacing canonical placement context. */\n    additionalDimensions?: Record<string, string>;\n    /** When set, emit at most once per metric and deduplication key on the page. */\n    deduplicationKey?: string;\n}\n\nexport const emitMetric = ({\n    metricName,\n    metricValue = 1,\n    adDetails: { logCxt },\n    timestamp,\n    additionalDimensions,\n    deduplicationKey,\n}: EmitMetricParams): void => {\n    if (deduplicationKey !== undefined) {\n        const key = `${metricName}:${deduplicationKey}`;\n        if (emittedMetrics.has(key)) return;\n        emittedMetrics.mark(key);\n    }\n\n    emitCsaMetric({\n        metricName,\n        metricValue,\n        timestamp,\n        dimensions: { ...additionalDimensions, ...logCxt },\n    });\n};\n\nexport const emitMetricOnce = (params: EmitPlacementMetricParams): void => {\n    if (emittedMetrics.has(params.metricName)) return;\n    emittedMetrics.mark(params.metricName);\n    emitMetric(params);\n};\n\nconst WEBLAB_METRIC_NAME = 'session:weblabs';\n\nconst emitWeblabMetricOnce = (adDetails: AdDetails | LightAdDetails): void => {\n    if (emittedMetrics.has(WEBLAB_METRIC_NAME)) return;\n    emittedMetrics.mark(WEBLAB_METRIC_NAME);\n\n    emitCsaMetric({\n        metricName: WEBLAB_METRIC_NAME,\n        metricValue: 1,\n        dimensions: { requestId: adDetails.logCxt.requestId },\n        weblabs: window.renderingWeblabs ?? {},\n    });\n};\n\nexport const emitWeblabMetric = (adDetails: AdDetails | LightAdDetails): void => {\n    emitWeblabMetricOnce(adDetails);\n};\n\ninterface EmitLightAdTimingMetricParams {\n    metricName: LightAdTimingMetricName;\n    metricValue: number;\n    adDetails: AdDetails | LightAdDetails;\n}\n\n/**\n * Emits milliseconds since time origin for Light Ad events.\n *\n * The metric is emitted only for page-level asset Weblab traffic, with its treatment attached to\n * the same event for direct Athena segmentation without a session-event join.\n */\nexport const emitLightAdTimingMetric = ({\n    metricName,\n    metricValue,\n    adDetails: { logCxt },\n}: EmitLightAdTimingMetricParams): void => {\n    const pageLevelWeblab = PAGE_LEVEL_LIGHT_AD_JS_WEBLAB();\n    if (logCxt.app !== 'LA' || !pageLevelWeblab.isAssigned()) return;\n\n    emitCsaMetric({\n        metricName,\n        metricValue,\n        dimensions: { ...logCxt },\n        weblabs: {\n            [PAGE_LEVEL_LIGHT_AD_JS_WEBLAB_NAME]: pageLevelWeblab.getTreatment().toUpperCase(),\n        },\n    });\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { emitMetricOnce } from '@/components/metrics/csaMetrics.js';\n\n/**\n * Overrides navigator.userAgent getter to emit a metric when a creative accesses it.\n * The real user agent value is still returned.\n */\nexport const logUserAgentAccess = (adDetails: AdDetails) => {\n    const realUserAgent = window.navigator.userAgent;\n    Object.defineProperty(Navigator.prototype, 'userAgent', {\n        get: () => {\n            emitMetricOnce({ metricName: 'sf:useragent:access', metricValue: 1, adDetails });\n            return realUserAgent;\n        },\n        set: () => {\n            // Empty\n        },\n    });\n};\n","/**\n * Workaround for iOS bug: allows clicks to propagate in iframe.\n * @see https://tt.amazon.com/0156195085\n * TODO Verify this is still needed.\n */\nexport const workAroundIOBugtt0156195085 = () => {\n    document.addEventListener(\n        'touchstart',\n        {\n            handleEvent: () => {\n                //do nothing\n            },\n        },\n        false,\n    );\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { disableCookieAccess } from '@/client/app/components/disable/disableCookieAccess.js';\nimport { disableGeolocationApi } from '@/client/app/components/disable/disableGeolocationApi.js';\nimport { disableUserAgent } from '@/client/app/components/disable/disableUserAgent.js';\nimport { logUserAgentAccess } from '@/client/app/components/disable/logUserAgentAccess.js';\nimport { workAroundIOBugtt0156195085 } from '@/client/app/components/disable/workAroundIOBugtt0156195085.js';\nimport { DISABLE_USER_AGENT_WEBLAB } from '@/components/weblabs.js';\n\nexport const disableAll = (adDetails: AdDetails) => {\n    disableCookieAccess();\n    disableGeolocationApi();\n    workAroundIOBugtt0156195085();\n    if (DISABLE_USER_AGENT_WEBLAB().is('t1')) {\n        disableUserAgent();\n    } else {\n        logUserAgentAccess(adDetails);\n    }\n};\n","export const readyMessage = 'sf iframe ready';\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nexport const PERF_SF_HOST = 'perf:sf:host';\nexport const PERF_SF_CLIENT = 'perf:sf:client';\nexport const PERF_SF_SETUP = 'perf:sf:setup';\nexport const PERF_LA = 'perf:la';\n\n/** The only ad-identity field perf marks read. Any AdDetails-like shape (full, wire-slim, light-ad) satisfies it. */\ntype MarkAdDetails = Pick<AdDetails, 'placementName'>;\n\nexport const getMarkName = (scope: string, message: string, adDetails?: MarkAdDetails): string =>\n    `${scope}${adDetails ? `:${adDetails.placementName}` : ''} - ${message}`;\n\nexport const mark = (scope: string, message: string, adDetails?: MarkAdDetails): 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 { readyMessage } from '@amzn/grandprix-runtime/src/messaging.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { mark, PERF_SF_CLIENT } from '@/components/perf.js';\n\n/**\n * Sends a {@link MessagePort} to the SafeFrame host page to establish a communication bridge.\n * Uses `postMessage` instead of `onload` as the latter is unreliable for hidden iframes.\n * @see https://stackoverflow.com/questions/12410606/hidden-iframe-onload-event\n * @param mp - The {@link MessagePort} to transfer to the parent.\n * @param adDetails - The {@link AdDetails} used for performance marking.\n */\nexport const sendMessagePortToParent = (mp: MessagePort, adDetails: AdDetails): void => {\n    mark(PERF_SF_CLIENT, `Start Send Ready ${mp}`, adDetails);\n    window.parent.postMessage(readyMessage, '*', [mp]);\n};\n","import type { HostMessageToClient } from '@amzn/grandprix-runtime/src/host-message.js';\n\nimport { CLICK_TRACKING_PAINTER_TEST } from '@/components/weblabs.js';\n\nexport const DEFAULT_PERCOLATE_TIMEOUT = 500;\n\nexport const getClickTrackingParamFromHost = async (port: MessagePort): Promise<string> => {\n    if (CLICK_TRACKING_PAINTER_TEST().isInTreatment()) {\n        return '';\n    }\n    return waitForPercolateClickTrackingFromHost(port);\n};\n\n/**\n *\n * @deprecated Migrate the logic to the GPAT side so we don't need to ask the wrapper.ts\n */\nexport const waitForPercolateClickTrackingFromHost = async (\n    mp: MessagePort,\n    timeout = DEFAULT_PERCOLATE_TIMEOUT,\n): Promise<string> => {\n    // Can't use race here because we need to remove the event listener\n    return new Promise<string>((resolve) => {\n        let timeoutId = 0;\n        const listener = (e: MessageEvent) => {\n            const command = e.data as HostMessageToClient;\n            const expectedCommand = 'percolateClickTracking';\n            if (command.command !== expectedCommand)\n                throw new Error(`Unexpected command ${command}, Expected ${expectedCommand}`);\n            window.clearTimeout(timeoutId); // We don't want to fire the trigger now\n            resolve(command.data);\n        };\n        // TODO Remove this after we have made sure it works\n        timeoutId = window.setTimeout(() => {\n            mp.removeEventListener('message', listener); // Don't want to process the next message as it won't be what we expect!\n            resolve('');\n        }, timeout);\n        mp.addEventListener('message', listener, { once: true });\n        mp.start();\n    });\n};\n","// Must be kept in sync with https://tiny.amazon.com/2xu3ne6j/SafeframeCSP\nexport const allowedReferrers: string[] = [\n    'amazon.com',\n    'amazon.in',\n    'amazon.de',\n    'amazon.co.jp',\n    'amazon.co.uk',\n    'amazon.ca',\n    'amazon.com.au',\n    'amazon.com.be',\n    'amazon.com.br',\n    'amazon.com.mx',\n    'amazon.com.tr',\n    'amazon.eg',\n    'amazon.es',\n    'amazon.fr',\n    'amazon.it',\n    'amazon.nl',\n    'amazon.pl',\n    'amazon.sa',\n    'amazon.se',\n    'amazon.sg',\n    'amazon.ae',\n    'amazon.co.za',\n    'amazon.cn',\n    'amazon.dev',\n    'boxofficemojo.com',\n    'a2z.com',\n    'console.harmony.a2z.com',\n    'depot.advertising.amazon.dev',\n    'harmony.a2z.com',\n    'd116tmsy8qpy37.cloudfront.net',\n    'd1u3onhraow3iz.cloudfront.net',\n    'd1ubtmbgqm1jlf.cloudfront.net',\n    'd2dk40qqpfbxei.cloudfront.net',\n    'd2jbcalcdp0p85.cloudfront.net',\n    'd2y0vsnh7zmbrq.cloudfront.net',\n    'd345aeerog89iv.cloudfront.net',\n    'imdb.com',\n];\n\nif (process.env.NODE_ENV !== 'production') {\n    // This is stripped from production builds. It is required for local browser testing since SF runs a check for\n    // document.referrer\n    allowedReferrers.push('localhost');\n}\n\nconst isMatched = (referrerHostName: string, allowedList: string[]): boolean => {\n    return allowedList.some((domain) => {\n        return referrerHostName === domain || referrerHostName.endsWith('.' + domain);\n    });\n};\n\nconst isReferrerAllowed = (): boolean => {\n    const referrer = document.referrer;\n\n    if (!referrer) {\n        return false; // No referrer means it's not allowed\n    }\n\n    try {\n        const url = new URL(referrer);\n        return isMatched(url.hostname, allowedReferrers);\n    } catch {\n        return false;\n    }\n};\n\n/**\n * Validates that the current document referrer is in the list of allowed referrers.\n * Skips the check when `window.origin` is `'null'` (e.g. sandboxed iframes).\n * @throws {Error} If the referrer is present but not in the allowed list.\n * @todo Clean up referrer check once https://sim.amazon.com/issues/CPP-41009 is solved.\n */\nexport const validateReferrerAllowed = (): void => {\n    if (window.origin !== 'null' && !isReferrerAllowed()) {\n        throw new Error(`Referrer not allowed: ${document.referrer}`);\n    }\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { emitMetric } from '@/components/metrics/csaMetrics.js';\n\n/**\n * Sets up a {@link ReportingObserver} to detect and log heavy ad interventions.\n * Observes intervention reports and flushes pending reports on page hide.\n * No-op if {@link ReportingObserver} is unavailable.\n * @see https://developer.chrome.com/blog/heavy-ad-interventions\n */\nexport const setupReportingObserver = (adDetails: AdDetails) => {\n    if (typeof window.ReportingObserver === 'undefined') return;\n\n    const reportingObserver = new ReportingObserver((reports) => checkReports(reports, adDetails), { buffered: true });\n\n    reportingObserver.observe();\n\n    document.addEventListener('pagehide', () => checkReports(reportingObserver.takeRecords(), adDetails));\n};\n\nconst checkReports = (reports: Report[] = [], adDetails: AdDetails): void =>\n    reports\n        .filter((report) => report.type === 'intervention')\n        .forEach(() => {\n            emitMetric({\n                metricName: 'reporting-observer:heavy-ad-intervention',\n                adDetails,\n            });\n        });\n","/**\n * @desc IAB safeframe API for some limited functionality\n * {@link http://www.iab.net/media/file/SafeFrames_v1.1_final.pdf}\n */\nimport type { ExternalParty, GeometricInformation } from '@amzn/safe-frame-client';\n\nimport { geomCache } from '@/client/api/iab/geomCache.js';\nimport { inViewPercentageCache } from '@/client/api/iab/numberCache.js';\n\ndeclare global {\n    interface Window {\n        $sf?: SafeFrame;\n    }\n}\n\nexport interface SafeFrame {\n    ext: ExternalParty;\n}\n\nexport const create$sf = (): SafeFrame => {\n    return {\n        ext: {\n            /**\n             * @desc Gives the inViewPercentage of the SafeFrame container as a whole number in [0, 100]\n             * @returns {Number} returns the inView percentage of the SafeFrame container\n             */\n            inViewPercentage: (): number => inViewPercentageCache.get(),\n\n            /**\n             * @desc Gives the geometric dimension and location of SafeFrame container\n             */\n            geom: (): GeometricInformation => geomCache.get(),\n        },\n    };\n};\n","const DCM_EIDS = '4|40004007';\n\ntype Dcmads = { eids?: string };\n\ndeclare global {\n    interface Window {\n        dcmads: Dcmads | undefined;\n    }\n}\n\n/**\n * Creates the dcmads config that dcmads.js reads to decide whether to append\n * creative content using document.write or HTMLElement.appendChild.\n * @see https://t.corp.amazon.com/HEDWIGTT-300\n */\nexport const createDcmAdsEids = (): Dcmads => ({\n    ...window.dcmads,\n    eids: DCM_EIDS,\n});\n","/**\n * Custom `document.write` implementation for SafeFrame iframes.\n *\n * Called by:\n * 1. The SF render script to add the creative to the DOM\n * 2. The creative for further mutations to the DOM\n *\n * When called during script execution ({@link document.currentScript} is set), the HTML is inserted\n * immediately after the running script and any subsequent sibling scripts are replayed.\n * Otherwise the entire document is replaced with the provided content.\n *\n * @param text - One or more HTML strings to write. Falsy values are filtered out.\n */\nexport const documentWriteImpl = (...text: string[]): void => {\n    const htmlContent = text\n        .filter((x) => !!x)\n        .map(String)\n        .join('');\n\n    // The below conditional checks if an inline script is running AND that document has not\n    // finished painting. In this case, document.write should append to the document immediately\n    // below that script, as described here: https://www.oreilly.com/library/view/javascript-the-definitive/0596000480/re204.html\n    // In all other cases we will replace the contents of the document with the string passed to document.write.\n    if (document.currentScript !== null) {\n        let currentElement: Element | null = document.currentScript;\n        currentElement.insertAdjacentHTML('afterend', htmlContent);\n\n        // Scripts do not execute when added via html string. Need to replay each script after the\n        // insertion point (via next sibling). If we used replayAll on the body, it would infinitely\n        // loop by replaying the script which called renderHTML in the first place.\n        currentElement = currentElement.nextElementSibling;\n        while (currentElement !== null) {\n            if (currentElement.tagName === 'SCRIPT') {\n                replayScriptTag(currentElement as HTMLScriptElement);\n            } else {\n                replayAllDescendantScriptsSerially(currentElement as HTMLElement);\n            }\n            currentElement = currentElement.nextElementSibling;\n        }\n    } else {\n        writeHtmlToDocumentRoot(htmlContent);\n        replayAllDescendantScriptsSerially(document.documentElement);\n    }\n};\n\n/**\n * Replaces the entire document content with the given HTML string.\n *\n * Uses {@link document.documentElement.innerHTML} so that the `<html>` element itself is preserved.\n * Creates the `<html>` element first if it does not exist.\n *\n * @param htmlContent - Raw HTML to write into the document root.\n */\nconst writeHtmlToDocumentRoot = (htmlContent: string): void => {\n    // setting innerHtml drops the host element's attributes, ie <html lang=\"en\">\n    // setting the outerHtml solves this, but setting outerHtml on document.documentElement is forbidden by the spec\n    // supporting a target of document.documentElement is a must\n\n    // Funciton fails with strict equality\n    // oxlint-disable-next-line eqeqeq\n    if (document.documentElement == undefined) {\n        const html = document.createElement('html');\n        document.appendChild(html);\n    }\n    document.documentElement.innerHTML = htmlContent;\n\n    // options for getting attributes from the html string include DOMParser or regex, but performance is a concern\n    // https://developer.mozilla.org/en-US/docs/Web/API/Element/attributes#enumerating_elements_attributes\n};\n\n/**\n * Replays every descendant `<script>` of the given element in document order (depth-first, pre-order).\n *\n * Scripts inserted via `innerHTML` are inert by spec, so each one is cloned and re-inserted\n * to trigger execution.\n *\n * @param containerElement - The root element whose descendant scripts should be replayed.\n */\nconst replayAllDescendantScriptsSerially = (containerElement: HTMLElement): void => {\n    // https://html.spec.whatwg.org/multipage/scripting.html#list-of-scripts-that-will-execute-in-order-as-soon-as-possible\n    // We cannot use createFragment because it is required to import in the body so we lose the HEAD/BODY/etc. tags\n    // So we use InnerHTML which will not execute the scripts but then dynamically recreate the script tags\n    // so that they will be executed (as they are not with innerHTML imported tags)\n    const adScripts = containerElement.querySelectorAll('script');\n    for (const adScript of adScripts) {\n        replayScriptTag(adScript);\n    }\n};\n\n/**\n * Replaces a single `<script>` element with an executable clone.\n *\n * For external scripts (`src` attribute present), the clone keeps the original `src` with `async` forced to `false`.\n * For inline scripts, the script body is encoded into a `data:` URI so the browser treats it as a new resource.\n *\n * @param adScript - The inert script element to replay.\n */\nconst replayScriptTag = (adScript: HTMLScriptElement): void => {\n    const range = document.createRange();\n    range.selectNode(adScript);\n    const adScriptCopyDoc = range.createContextualFragment(adScript.outerHTML);\n    const adScriptCopy = adScriptCopyDoc.firstElementChild as HTMLScriptElement;\n    if (adScriptCopy.getAttribute('src')) {\n        // https://html.spec.whatwg.org/multipage/scripting.html#attr-script-async\n        // Need to explicity force async to false to skip https://html.spec.whatwg.org/multipage/scripting.html#script-processing-model\n        // https://hsivonen.fi/script-execution/\n        adScriptCopy.async = false;\n    } else {\n        const scriptText = adScript.innerHTML;\n        adScriptCopy.async = false;\n        adScriptCopy.setAttribute('src', `data:text/javascript;charset=UTF-8,${encodeURIComponent(scriptText)}`);\n    }\n    adScript.parentNode?.insertBefore(adScriptCopy, adScript.nextSibling);\n    adScript.parentNode?.removeChild(adScript);\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 { EventsBridge } from '@/components/bridge/events/eventsBridge.js';\n\nconst isExtensionError = (source?: string): boolean =>\n    (source?.startsWith('chrome-extension://') || source?.startsWith('moz-extension://')) ?? false;\n\nconst isResizeObserverLoopError = (message: Event | string): boolean =>\n    typeof message === 'string' && message.includes('ResizeObserver loop');\n\nconst isIgnorableError = (message: Event | string, source?: string): boolean =>\n    isResizeObserverLoopError(message) || isExtensionError(source);\n\n/**\n * Creates a handler for window.onerror to catch any unexpected errors\n * coming from the creative code. We will log the error and attempt to\n * show a different ad or collapse the slot.\n */\nexport const createHandleErrors =\n    (eventsBridge: EventsBridge): OnErrorEventHandler =>\n    (message: Event | string, source?: string, lineno?: number, colno?: number, error?: Error): boolean => {\n        if (isIgnorableError(message, source)) {\n            console.debug('[SafeFrame] Suppressed ignorable error:', message, source, error);\n            return true;\n        }\n\n        eventsBridge.onError({\n            code: 'client-error',\n            isBTR: evaluateCreativeBeginToRender(document.body).success,\n            error: error ?? new Error(typeof message === 'string' ? message : 'Unknown error'),\n            source,\n            lineno,\n            colno,\n        });\n\n        // Returning true suppresses the default browser behavior\n        return true;\n    };\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { WireContext } from '@/components/bridge/core/bridge.js';\n\n/** Builds the per-message context factory used by bridge senders. */\nexport const contextFactory =\n    (adDetails: AdDetails): (() => WireContext) =>\n    () => ({ adDetails, timestamp: new Date() });\n\n/** No-op callable target for the Proxy. Exported for test coverage (the Proxy's apply trap intercepts all calls). */\nexport const proxyTarget = (): void => {};\n\n/**\n * Recursively builds a {@link Proxy} that accumulates a dot-notation path.\n *\n * This enables nested bridge interfaces like `ue.count` — accessing\n * `proxy.ue` returns a deeper proxy, and calling `proxy.ue.count(...)`\n * sends method `'ue.count'` with the provided arguments.\n */\nexport const buildProxy = (send: (...args: any[]) => void, prefix: string): unknown =>\n    new Proxy(proxyTarget, {\n        apply(_target, _thisArg, args: unknown[]) {\n            send(prefix, ...args);\n        },\n        get(_target, prop: string | symbol) {\n            if (typeof prop === 'symbol' || prop === 'then') return undefined;\n            const path = prefix ? `${prefix}.${prop}` : prop;\n            return buildProxy(send, path);\n        },\n    });\n","import { logCsaEvent, LOGS_SOURCE_GROUP } from './core.js';\n\nexport type LogLevel = 'fatal' | 'error' | 'warn' | 'info';\n\nexport type CsaLogInput = {\n    level: LogLevel;\n    message: string;\n    errorType?: string;\n    stack?: string;\n    code?: string;\n    source?: string;\n    lineno?: number;\n    colno?: number;\n    timestamp?: Date;\n    dimensions: Record<string, string>;\n};\n\n/**\n * Emits a structured log event to the CSA logs source group (our logs pipeline →\n * CloudWatch Logs, searched via Logs Insights). Not routed to Nexus.\n *\n * The event also carries metric fields (`metricName: log:level:${level}`, `metricValue: 1`)\n * so this single emission can be sliced and counted as a metric downstream by the CSA metrics\n * Lambda (for error/fatal alarming) without the client emitting twice — Sushi fans the logs\n * source group out to both the logs and metrics sinks.\n *\n * @param level - Severity: fatal | error | warn | info. Also forms the metricName.\n * @param message - Log message.\n * @param errorType - Error class name, when derived from an Error.\n * @param stack - Error stack, when available.\n * @param code - Error code, when available.\n * @param source - Source file or module where the error originated.\n * @param lineno - Line number where the error occurred.\n * @param colno - Column number where the error occurred.\n * @param timestamp - When the log was recorded. Defaults to now.\n * @param dimensions - Key-value log dimensions; also the metric dimensions for slicing.\n */\nexport const emitCsaLog = ({\n    level,\n    message,\n    errorType,\n    stack,\n    code,\n    source,\n    lineno,\n    colno,\n    timestamp = new Date(),\n    dimensions,\n}: CsaLogInput): void =>\n    logCsaEvent({\n        sushiSourceGroup: LOGS_SOURCE_GROUP,\n        data: {\n            metricName: `log:level:${level}`,\n            metricValue: 1,\n            level,\n            errorType,\n            message,\n            stack,\n            code,\n            source,\n            lineno,\n            colno,\n            timestamp: timestamp.getTime(),\n            dimensions,\n        },\n    });\n","import { emitCsaLog } from '@amzn/grandprix-runtime/src/instrumentation/csa/logging.js';\nimport type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\n// At least one of `message` or `error` must be provided.\ntype LogWithMessage = { message: string; error?: unknown };\ntype LogWithError = { message?: string; error: unknown };\ntype EmitErrorLogParams = {\n    adDetails: AdDetails | LightAdDetails;\n    code?: string;\n    source?: string;\n    lineno?: number;\n    colno?: number;\n} & (LogWithMessage | LogWithError);\n\n/**\n * Emits a structured client error log to the CSA logs source group (→ our logs pipeline →\n * CloudWatch Logs, searched via Logs Insights) for search and triage. The level is always\n * `error`. When an Error is provided, errorType/message/stack are derived from it.\n *\n * Only the log is emitted here — the client sends each event exactly once. Counts for alarming\n * (error/fatal volume) are derived downstream from the logs, not emitted by the client.\n *\n * @param input.message - Log message. Optional only when an Error is provided.\n * @param input.error - The caught value; normalized to an Error, from which errorType/message/stack\n *                      are derived. Accepts a non-Error throw so callers can pass what they caught.\n * @param input.adDetails - Ad context; logCxt becomes the log dimensions.\n * @param input.code - Error phase: 'client-setup' (during creative init) or 'client-error' (runtime).\n * @param input.source - Script URL or filename where the error occurred (from window.onerror).\n * @param input.lineno - Line number where the error occurred (from window.onerror).\n * @param input.colno - Column number where the error occurred (from window.onerror).\n */\nexport const emitErrorLog = ({ message, error, adDetails, code, source, lineno, colno }: EmitErrorLogParams): void => {\n    const err = toError(error);\n    emitCsaLog({\n        level: 'error',\n        errorType: err?.name,\n        message: message ?? err?.message ?? '',\n        stack: err?.stack,\n        code,\n        source,\n        lineno,\n        colno,\n        dimensions: { ...adDetails.logCxt },\n    });\n};\n\n/**\n * Normalizes a caught value into an Error. `undefined` stays `undefined`, so a message-only log emits\n * no errorType or stack. A non-Error object is JSON-serialized into the message so its properties\n * (e.g. a MashError's `code`) are not lost to `String()`'s \"[object Object]\"; anything else, and any\n * object JSON cannot serialize (circular refs), falls back to `String()`.\n */\nconst toError = (error: unknown): Error | undefined => {\n    if (error === undefined) return undefined;\n    if (error instanceof Error) return error;\n    if (typeof error === 'object') {\n        try {\n            return new Error(JSON.stringify(error));\n        } catch {\n            // Circular refs; fall through to String().\n        }\n    }\n    return new Error(String(error));\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { BridgeRegistry } from '@/components/bridge/core/bridge.js';\nimport { buildProxy, contextFactory } from '@/components/bridge/core/wire.js';\nimport { emitErrorLog } from '@/components/metrics/emitErrorLog.js';\nimport type { ArgsForPath } from '@/components/utils/argsForPath.js';\nimport type { NestedKeyOf } from '@/components/utils/nestedKeyOf.js';\n\n/**\n * Internal sender type that enforces compile-time checking on method\n * names and arguments before they cross the iframe→host boundary.\n */\ntype SendFn<T> = <M extends NestedKeyOf<T>>(method: M, ...args: ArgsForPath<T, M>) => void;\n\n/**\n * Creates a sender bound to a bridge on the given {@link MessagePort}.\n *\n * Each call captures a fresh {@link Context} (ad identity + timestamp)\n * and posts it to the host page. Errors are\n * logged rather than thrown so a failed metric or event never crashes\n * the ad creative.\n */\nconst sendMessage = <Namespace extends keyof BridgeRegistry>(\n    port: MessagePort,\n    namespace: Namespace,\n    adDetails: AdDetails,\n): SendFn<BridgeRegistry[Namespace]> => {\n    const getContext = contextFactory(adDetails);\n    return ((method: string, ...args: unknown[]): void => {\n        try {\n            port.postMessage({ namespace, method, args, context: getContext() });\n        } catch (e) {\n            emitErrorLog({ message: `Bridge send error in ${namespace}.${method}`, error: e, adDetails });\n        }\n    }) as SendFn<BridgeRegistry[Namespace]>;\n};\n\n/**\n * Creates a client-side proxy for a registered bridge that the SafeFrame\n * iframe uses to communicate with the host page.\n *\n * The proxy automatically builds dot-notation method paths (e.g.\n * `csm.ue.count(...)` becomes method `'ue.count'`), so adding methods\n * to a bridge interface requires zero client-side boilerplate.\n *\n * @typeParam Namespace - A key of {@link BridgeRegistry} identifying the bridge.\n * @param port      - The {@link MessagePort} connected to the host page.\n * @param namespace - Bridge namespace key (e.g. `'Csm'`).\n * @param adDetails - Full ad slot context embedded in every outgoing message.\n * @returns An object matching the bridge interface whose methods post\n *          messages over the port.\n *\n * @example\n * ```ts\n * const csm = createSender(port, 'Csm', adDetails);\n * csm.ueLogError(error, info);   // type-checked\n * csm.ue.count('myMetric', 1);   // nested path handled automatically\n * ```\n */\nexport const createSender = <Namespace extends keyof BridgeRegistry>(\n    port: MessagePort,\n    namespace: Namespace,\n    adDetails: AdDetails,\n): BridgeRegistry[Namespace] => {\n    const send = sendMessage(port, namespace, adDetails);\n    return buildProxy(send as (...args: any[]) => void, '') as BridgeRegistry[Namespace];\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { createSender } from '@/components/bridge/core/sender.js';\nimport type { CsaBridge, CsaNamespace, CsaOptions } from '@/components/bridge/csa/csaBridge.js';\n\n/**\n * Creates a `csa` proxy that forwards calls to the host page via the Csa bridge.\n * This makes `emitCsaMetric` (which calls `window.csa`) work transparently\n * inside the SafeFrame client iframe.\n */\nexport const createCsaBridgeSender = (mp: MessagePort, adDetails: AdDetails): typeof window.csa => {\n    const proxy: CsaBridge = createSender(mp, 'Csa', adDetails);\n\n    return ((csaNamespace: CsaNamespace, options: CsaOptions) => {\n        return (method: string, data: Record<string, unknown>) => {\n            proxy.csa(csaNamespace, options, method, data);\n        };\n    }) as typeof window.csa;\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { createSender } from '@/components/bridge/core/sender.js';\nimport type { AdditionalInfo, CsmBridge } from '@/components/bridge/csm/csmBridge.js';\n\nexport const createCsmBridgeSender = (mp: MessagePort, adDetails: AdDetails): CsmBridge => {\n    const proxy = createSender(mp, 'Csm', adDetails);\n    return {\n        ueLogError: (error: Error, info: AdditionalInfo) => proxy.ueLogError(error, info),\n        ue: { count: (metric: string, count?: number) => proxy.ue.count(metric, count) },\n    };\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { create$sf } from '@/client/api/iab/sfApi.js';\nimport { createDcmAdsEids } from '@/client/app/components/dcm.js';\nimport { documentWriteImpl } from '@/client/app/components/documentWrite.js';\nimport { createHandleErrors } from '@/client/app/components/handleErrors.js';\nimport type { SafeFrameClientFactory } from '@/client/app/safeframeClientFactory.js';\nimport { createCsaBridgeSender } from '@/components/bridge/csa/csaBridgeSender.js';\nimport { createCsmBridgeSender } from '@/components/bridge/csm/csmBridgeSender.js';\nimport type { EventsBridge } from '@/components/bridge/events/eventsBridge.js';\n\ninterface WindowGlobalsParams {\n    adDetails: AdDetails;\n    messagePort: MessagePort;\n    eventsBridge: EventsBridge;\n    safeFrameClientFactory: SafeFrameClientFactory;\n}\n\nexport const installWindowGlobals = ({\n    adDetails,\n    messagePort,\n    eventsBridge,\n    safeFrameClientFactory,\n}: WindowGlobalsParams): void => {\n    const csmBridge = createCsmBridgeSender(messagePort, adDetails);\n\n    document.write = documentWriteImpl;\n    window.$sf = create$sf();\n    window.csa = createCsaBridgeSender(messagePort, adDetails);\n    window.dcmads = createDcmAdsEids();\n    window.onerror = createHandleErrors(eventsBridge);\n    window.renderingWeblabs = JSON.parse(adDetails.weblabTreatments ?? '{}');\n    window.ue = csmBridge.ue;\n    window.ueLogError = csmBridge.ueLogError;\n\n    safeFrameClientFactory(adDetails, messagePort);\n};\n","export const AbpStatus = {\n    MINUS_ONE: \"-1\",\n    PLUS_ONE: \"1\",\n    ZERO: \"0\",\n};\nexport const DeviceType = {\n    DESKTOP: \"DESKTOP\",\n    MSHOP: \"MSHOP\",\n    MWEB: \"MWEB\",\n};\nexport const App = {\n    LA: \"LA\",\n    SF: \"SF\",\n};\nexport const MediaType = {\n    D: \"D\",\n    V: \"V\",\n};\nexport const Sizing = {\n    FIXED: \"FIXED\",\n    RATIO: \"RATIO\",\n};\n","export const safeFunctionWrapper = (\n    handler: (...safeArgs: any[]) => void,\n    errorHandler?: (msg: string, ex?: any) => void,\n    errorMessage?: string,\n): any => {\n    return (...args: any[]) => {\n        try {\n            handler(...args);\n        } catch (ex) {\n            errorHandler?.(errorMessage ? errorMessage : 'Error in handler', ex);\n        }\n    };\n};\n\n// Below code is for utf_8 compliant versions of atob/btoa\n//M DN https://developer.mozilla.org/en-US/docs/Glossary/Base64#solution_2_%E2%80%93_rewriting_atob_and_btoa_using_typedarrays_and_utf-8\n\nexport const utf_8_atob = (base64: string): string => b64_to_utf8(base64);\nexport const utf_8_btoa = (js_text: string): string => utf8_to_b64(js_text);\n\n// We use unescape even though not recommended due to performance and code size\nconst utf8_to_b64 = (utf8: string): string => {\n    return btoa(unescape(encodeURIComponent(utf8)));\n};\n\nconst b64_to_utf8 = (base64: string): string => {\n    return decodeURIComponent(escape(atob(base64)));\n};\n\n// Remove when https://issues.amazon.com/issues/V1533734779 is resolved.\nexport const removeAAXPayloadFromUrl = (url: string): string => {\n    if (!url) {\n        return url;\n    }\n    // oxlint-disable-next-line no-template-curly-in-string\n    return url.split('&c=${AAX_PAYLOAD}').join('');\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { utf_8_atob } from '@/components/util.js';\n\nexport const getCreative = (adDetails: AdDetails): string => {\n    if (!adDetails.htmlContentEncoded || adDetails.htmlContentEncoded.trim().length === 0)\n        throw new Error('No html content found on a server side fetch');\n    const htmlContent = adDetails.htmlContentEncodedLength\n        ? adDetails.htmlContentEncoded\n        : utf_8_atob(adDetails.htmlContentEncoded);\n    logIfError(htmlContent, adDetails.htmlContentEncodedLength);\n    return htmlContent;\n};\n\nconst logIfError = (htmlContent: string, htmlContentEncodedLength: number | undefined): void => {\n    if (htmlContentEncodedLength && htmlContent.length !== htmlContentEncodedLength) {\n        console.debug(\n            `Mismatched expected htmlContentEncoded size. Expected ${htmlContentEncodedLength} but got ${htmlContent.length}`,\n        );\n    }\n};\n","// Threshold for considering an image to be spanning the viewport (95%)\nconst VIEWPORT_COVERAGE_THRESHOLD = 0.95;\n\n// Threshold for considering text to be significant (num chars)\nconst SIGNIFICANT_TEXT_THRESHOLD = 75;\n\n// 1P image template ads generally have this class name\nconst AD_BACKGROUND_IMAGE_CLASS = 'ad-background-image';\n\n/**\n * Checks if an image covers a significant portion of the viewport width\n */\nexport const isImageCoveringViewportWidth = (imgWidth: number): boolean =>\n    imgWidth / window.innerWidth >= VIEWPORT_COVERAGE_THRESHOLD;\n\n/**\n * Checks if the document has significant text content\n */\nexport const hasSignificantText = (): boolean => {\n    // get innerText and strip whitespace\n    const text = (document.documentElement.innerText ?? '').replace(/\\s/g, '');\n    return text.length > SIGNIFICANT_TEXT_THRESHOLD;\n};\n\n/**\n * Checks an array of images for one with the target className\n * @param images\n * @returns\n */\nexport const hasAnyImageWithAdBackgroundClass = (images: HTMLImageElement[]) =>\n    images.some((image) => image.classList.contains(AD_BACKGROUND_IMAGE_CLASS));\n\n/**\n * Checks if any image covers all or most of the viewport width\n */\nexport const hasLargeImage = (images: HTMLImageElement[]): boolean =>\n    images.some((image) => isImageCoveringViewportWidth(image.getBoundingClientRect().width));\n\n/**\n * Determines if the ad is an image template ad and sends appropriate message if needed\n */\nexport const isImageTemplateAd = (): boolean => {\n    // Find all images in the creative\n    const images = Array.from(document.querySelectorAll('img'));\n\n    // no images in the ad means it is not an image template\n    if (!images.length) return false;\n\n    // if any image has .ad-background-class, it is an image template\n    if (hasAnyImageWithAdBackgroundClass(images)) return true;\n\n    // if no large images (spans viewport width), it is not an image template\n    if (!hasLargeImage(images)) return false;\n\n    // if the ad has a full width image, but has a lot of text, likely not an image template\n    if (hasSignificantText()) return false;\n\n    // all conditions met, this is likely an image-only ad\n    return true;\n};\n","import type { PixelMetricName } from '@/components/metrics/csaMetrics.js';\n\nexport type PixelIdentifier = {\n    readonly testId: string;\n    readonly metricName: PixelMetricName;\n};\n\nexport const BTR_IDENTIFIER: PixelIdentifier = { testId: 'ape_btr_impression', metricName: 'pixel:imp:btr' } as const;\nexport const IMPRESSION_IDENTIFIER: PixelIdentifier = {\n    testId: 'ape_impression',\n    metricName: 'pixel:imp:cod',\n} as const;\nexport const MEASURABILITY_IDENTIFIER: PixelIdentifier = {\n    testId: 'ape_measurability',\n    metricName: 'pixel:imp:atf',\n} as const;\nexport const IAB_VIEWABILITY_IDENTIFIER: PixelIdentifier = {\n    testId: 'ape_viewability_iab',\n    metricName: 'pixel:view:iab',\n} as const;\n","/**\n * Generic WeakMap-based state per placement DOM element.\n * Entries are garbage-collected when the element is removed from the DOM.\n */\nconst placementState = new WeakMap<HTMLElement, Map<string, string>>();\n\nexport const getState = <K extends string = string, V extends string = string>(\n    placementDiv: HTMLElement,\n    key: K,\n): V | undefined => placementState.get(placementDiv)?.get(key) as V | undefined;\n\nexport const setState = <K extends string = string, V extends string = string>(\n    placementDiv: HTMLElement,\n    key: K,\n    value: V,\n): void => {\n    const state = placementState.get(placementDiv);\n    if (state) {\n        state.set(key, value);\n    } else {\n        placementState.set(placementDiv, new Map([[key, value]]));\n    }\n};\n","import type { PixelMetricName } from '@/components/metrics/csaMetrics.js';\nimport { getState, setState } from '@/components/state/placement/placementState.js';\n\n/** Short string values to minimize bundle size (string literals are not minified). */\nconst FIRED = '0';\nconst ERROR = '1';\n\ntype PixelState = typeof FIRED | typeof ERROR;\n\nconst setPixelState = (div: HTMLElement, key: PixelMetricName, value: PixelState) =>\n    setState<PixelMetricName, PixelState>(div, key, value);\n\nexport const hasPixelFired = (div: HTMLElement, key: PixelMetricName): boolean =>\n    getState<PixelMetricName, PixelState>(div, key) === FIRED;\n\nexport const markPixelFired = (div: HTMLElement, key: PixelMetricName): void => setPixelState(div, key, FIRED);\n\nexport const markPixelError = (div: HTMLElement, key: PixelMetricName): void => setPixelState(div, key, ERROR);\n","import type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport { emitLightAdTimingMetric, emitMetric, type PixelMetricName } from '@/components/metrics/csaMetrics.js';\nimport type { FirePixel } from '@/components/pixels/firePixel.js';\nimport { IMPRESSION_IDENTIFIER, type PixelIdentifier } from '@/components/pixels/pixelIdentifiers.js';\nimport type { PixelUrlGenerator } from '@/components/pixels/pixelUrlGenerator.js';\nimport { hasPixelFired, markPixelError, markPixelFired } from '@/components/state/placement/pixelState.js';\nimport type { Creative } from '@/light-ad/domain/model/creative.js';\n\nconst requestOptions: RequestInit = { keepalive: true, mode: 'no-cors' } as const;\nconst SINGLE_VIDEO_ADS_IMPRESSION_METRIC = 'pixel:imp:cod:single-video-ads';\nconst IMPRESSION_3P_METRIC = 'pixel:imp:3p';\n/** Pixels that also emit a media type counter, keyed by the pixel's own metric name. */\nconst MEDIA_TYPE_METRICS: Partial<Record<PixelMetricName, { video: PixelMetricName; display: PixelMetricName }>> = {\n    'pixel:imp:cod': { video: 'pixel:imp:cod:video', display: 'pixel:imp:cod:display' },\n    'pixel:view:iab': { video: 'pixel:view:iab:video', display: 'pixel:view:iab:display' },\n};\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\n/** The {@link Placement} for a SafeFrame ad whose pixels measure `div`. */\nexport const toPlacement = (adDetails: AdDetails, div: HTMLElement): Placement => ({\n    id: adDetails.placementId,\n    name: adDetails.placementName,\n    div,\n    deviceType: adDetails.deviceType,\n});\n\nexport class Pixel implements FirePixel {\n    constructor(\n        private readonly url: string,\n        private readonly generatePixelUrl: PixelUrlGenerator,\n        private readonly pixelIdentifier: PixelIdentifier,\n        private readonly adDetails: AdDetails | LightAdDetails,\n        private readonly urls3p: string[] = [],\n    ) {}\n\n    public async fire(placement: Placement): Promise<void> {\n        if (hasPixelFired(placement.div, this.pixelIdentifier.metricName)) return;\n        markPixelFired(placement.div, this.pixelIdentifier.metricName);\n        try {\n            const pixelUrl = this.generatePixelUrl(this.url, placement);\n            const firedAt = performance.now();\n            const request = fetch(pixelUrl, requestOptions);\n            emitLightAdTimingMetric({\n                metricName: `${this.pixelIdentifier.metricName}:timing`,\n                metricValue: firedAt,\n                adDetails: this.adDetails,\n            });\n            await request;\n        } catch (e) {\n            markPixelError(placement.div, this.pixelIdentifier.metricName);\n            emitMetric({ metricName: `${this.pixelIdentifier.metricName}:error`, adDetails: this.adDetails });\n            throw e;\n        }\n        placement.div.appendChild(this.pixel(placement));\n        emitMetric({ metricName: this.pixelIdentifier.metricName, adDetails: this.adDetails });\n        const mediaTypeMetrics = MEDIA_TYPE_METRICS[this.pixelIdentifier.metricName];\n        if (mediaTypeMetrics) {\n            emitMetric({\n                metricName: this.isVideo() ? mediaTypeMetrics.video : mediaTypeMetrics.display,\n                adDetails: this.adDetails,\n            });\n        }\n        if (this.isSingleVideoAdsImpression()) {\n            emitMetric({ metricName: SINGLE_VIDEO_ADS_IMPRESSION_METRIC, adDetails: this.adDetails });\n        }\n\n        // Do not await for 3P URLs as rendering the ad doesn't depend on successful firing\n        this.urls3p.forEach((url3p) =>\n            fetch(url3p, requestOptions).then(\n                () => emitMetric({ metricName: IMPRESSION_3P_METRIC, adDetails: this.adDetails }),\n                () => emitMetric({ metricName: `${IMPRESSION_3P_METRIC}:error`, adDetails: this.adDetails }),\n            ),\n        );\n    }\n\n    /** Light Ads carry a videoCreative when they are video; SafeFrame ads carry an explicit mediaType. */\n    private isVideo = (): boolean =>\n        this.adDetails.logCxt.app === 'LA'\n            ? Boolean((this.adDetails as LightAdDetails).videoCreative)\n            : (this.adDetails as AdDetails).mediaType === 'V';\n\n    /**\n     * Single Video Ads card flow: JRS renders native VAST through the card, which owns the player,\n     * so the Light Ad arrives as a cards-flow video with setupVideoPlayer false.\n     */\n    private isSingleVideoAdsImpression = (): boolean => {\n        if (this.adDetails.logCxt.app !== 'LA') return false;\n\n        const lightAdDetails = this.adDetails as LightAdDetails;\n        return (\n            this.pixelIdentifier.metricName === IMPRESSION_IDENTIFIER.metricName &&\n            lightAdDetails.isCardsFlow === true &&\n            lightAdDetails.videoCreative?.setupVideoPlayer === false\n        );\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","import type { PixelUrlGenerator } from '@/components/pixels/pixelUrlGenerator.js';\n\nexport const generateImpressionPixelUrl: PixelUrlGenerator = (url: string): string => url;\n","import { createObstructionDetectionService } from '@amzn/creative-obstruction-detection/src/obstructionDetectionServiceImpl.js';\nimport type { AdDetails, DeviceType, LightAdDetails, MediaType } from '@amzn/safeframe-model';\n\nimport { MRCObstructionViewPixel } from '@/components/pixels/mrcObstructionViewPixel.js';\nimport { Pixel } from '@/components/pixels/pixel.js';\nimport {\n    BTR_IDENTIFIER,\n    IAB_VIEWABILITY_IDENTIFIER,\n    IMPRESSION_IDENTIFIER,\n    MEASURABILITY_IDENTIFIER,\n} from '@/components/pixels/pixelIdentifiers.js';\nimport type { FirePixelValidator } from '@/components/pixels/services/firePixelValidator.ts';\nimport { createViewabilityService } from '@/components/pixels/services/viewabilityServiceImpl.js';\nimport { createVisibiltyChangeService } from '@/components/pixels/services/visibilityChangeService.js';\nimport { SkanImpressionPixel } from '@/components/pixels/skanImpressionPixel.js';\nimport { SkanViewPixel } from '@/components/pixels/skanViewPixel.js';\nimport { generateBtrPixelUrl } from '@/components/pixels/urlGenerators/btrPixelUrlGenerator.js';\nimport { generateImpressionPixelUrl } from '@/components/pixels/urlGenerators/impressionPixelUrlGenerator.js';\nimport { generateMeasurabilityPixelUrl } from '@/components/pixels/urlGenerators/measurabilityPixelUrlGenerator.js';\nimport { generateMrcObstructionViewPixelUrl } from '@/components/pixels/urlGenerators/mrcObstructionViewPixelUrlGenerator.js';\nimport type { ViewabilityStandard } from '@/components/pixels/viewabilityStandards.js';\nimport { VIEWABILITY_STANDARDS } from '@/components/pixels/viewabilityStandards.js';\nimport { createViewabilityTracker } from '@/components/pixels/viewabilityTrackerImpl.js';\nimport type { ViewPixel } from '@/components/pixels/viewPixel.js';\nimport { NEW_VIEWABILITY_TRACKER_WEBLAB } from '@/components/weblabs.js';\n\nexport const mapToBtrPixel = (adDetails: AdDetails | LightAdDetails): Pixel | undefined => {\n    return adDetails.btrPixelUrl\n        ? new Pixel(adDetails.btrPixelUrl, generateBtrPixelUrl, BTR_IDENTIFIER, adDetails)\n        : undefined;\n};\n\nexport const mapToImpressionPixel = (adDetails: AdDetails | LightAdDetails, imp3pUrls: string[] = []): Pixel =>\n    new Pixel(adDetails.aaxImpPixelUrl, generateImpressionPixelUrl, IMPRESSION_IDENTIFIER, adDetails, imp3pUrls);\n\nexport const mapToMeasurabilityPixel = (adDetails: AdDetails | LightAdDetails): Pixel =>\n    new Pixel(adDetails.aaxInstrPixelUrl, generateMeasurabilityPixelUrl, MEASURABILITY_IDENTIFIER, adDetails);\n\nexport const createIabViewPixel = async (\n    mediaType: MediaType,\n    htmlElement: HTMLElement,\n    adDetails: AdDetails | LightAdDetails,\n    firePixelValidator: () => Promise<FirePixelValidator>,\n): Promise<ViewPixel> => {\n    if (mediaType === 'V') {\n        return createMrcViewPixel(adDetails, VIEWABILITY_STANDARDS.IAB_VIDEO, await firePixelValidator());\n    } else if (isDesktop(adDetails.deviceType) && isLargeAd(htmlElement)) {\n        return createMrcViewPixel(adDetails, VIEWABILITY_STANDARDS.IAB_LARGE_DISPLAY);\n    } else {\n        return createMrcViewPixel(adDetails, VIEWABILITY_STANDARDS.IAB_DISPLAY);\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    adDetails: AdDetails | LightAdDetails,\n    standard: ViewabilityStandard,\n    validator?: FirePixelValidator,\n): ViewPixel => {\n    const pixel = new Pixel(\n        adDetails.aaxInstrPixelUrl,\n        generateMrcObstructionViewPixelUrl(standard),\n        IAB_VIEWABILITY_IDENTIFIER,\n        adDetails,\n    );\n\n    if (NEW_VIEWABILITY_TRACKER_WEBLAB().is('t1')) {\n        return createViewabilityTracker(\n            [pixel],\n            standard,\n            createViewabilityService(createObstructionDetectionService(), adDetails),\n            validator ? [validator] : [],\n            adDetails,\n        );\n    } else {\n        return new MRCObstructionViewPixel(\n            pixel,\n            standard,\n            createVisibiltyChangeService(),\n            createViewabilityService(createObstructionDetectionService(), adDetails),\n            validator,\n            adDetails,\n        );\n    }\n};\n\nexport const mapToSkanImpressionPixel = (adDetails: AdDetails | LightAdDetails): SkanImpressionPixel | undefined => {\n    return adDetails.skAdNetwork ? new SkanImpressionPixel(adDetails) : undefined;\n};\n\nexport const mapToSkanViewPixel = (adDetails: AdDetails | LightAdDetails): ViewPixel | undefined => {\n    if (adDetails.skAdNetwork) {\n        const skanPixel = new SkanViewPixel(adDetails);\n        return new MRCObstructionViewPixel(\n            skanPixel,\n            VIEWABILITY_STANDARDS.SKAN,\n            createVisibiltyChangeService(),\n            createViewabilityService(createObstructionDetectionService(), adDetails),\n            undefined,\n            adDetails,\n        );\n    }\n    return undefined;\n};\n","import type { AdDetails, LightAdDetails } from '@amzn/safeframe-model';\n\nimport 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    adDetails: AdDetails | LightAdDetails,\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        adDetails,\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            adDetails,\n        );\n        btrViewabilityTracker.track(placement);\n    }\n};\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { EventsBridge } from '@/components/bridge/events/eventsBridge.js';\nimport type { LatencyTracker } from '@/components/perf.js';\nimport { toPlacement } from '@/components/pixels/pixel.js';\nimport { mapToImpressionPixel } from '@/components/pixels/pixelMapper.js';\nimport { isViewRateExperimentEnabled } from '@/components/viewRateExperimentUtil.js';\n\nexport const preCreativeWrite = (o: AdDetails, eventsBridge: EventsBridge, tracker: LatencyTracker): void => {\n    // The view rate experiment fires the impression on viewability instead of at prewrite\n    const experimentDelaysImpression = isViewRateExperimentEnabled(Number(o.adCreativeMetaData.adProgramId));\n    const hostFiresImpression = !experimentDelaysImpression && shouldFireImpressionInHost(o);\n\n    eventsBridge.onPreCreativeWrite(tracker.elapsed(), hostFiresImpression);\n\n    if (!hostFiresImpression && !experimentDelaysImpression) {\n        mapToImpressionPixel(o).fire(toPlacement(o, document.documentElement));\n    }\n};\n\n/**\n * Determines whether the COD impression pixel should fire on the host rather than\n * in the client iframe. True for slots where in-iframe firing is wrong: skyscraper-2\n * slots (may be `display:none`) and placements with a firePixelsAfter delay config\n * (the host waits for the delay before firing).\n *\n * @remarks\n * Remove this when true bill on view is launched.\n * Cleanup SIM: {@link https://taskei.amazon.dev/tasks/CPP-46601}\n */\nconst shouldFireImpressionInHost = (o: AdDetails): boolean => isFireImpInHostOverride(o) || Boolean(o.firePixelsAfter);\n\n/**\n * Hard-coded for skyscraper-2 slots to avoid firing impressions when the slot is `display:none`.\n */\nconst isFireImpInHostOverride = ({ slotName }: AdDetails): boolean =>\n    slotName === 'auto-left-advertising-2' || slotName.endsWith('-ad-left-2');\n","import type { CreativeRenderingValidators } from '@amzn/creative-rendering-validation/src/api/blankAdDetection.js';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { emitMetric } from '@/components/metrics/csaMetrics.js';\n\ndeclare global {\n    interface Window {\n        crv: CreativeRenderingValidators;\n    }\n}\n\nexport const validateCreativeRendering = (adDetails: AdDetails): void => {\n    const callBlankAdValidation = async () => {\n        if (typeof window?.crv?.detectAndReportBlankAd === 'function') {\n            clearInterval(intervalId);\n            try {\n                const result = await window.crv.detectAndReportBlankAd(document.body);\n                // 1 = blank ad detected (failure), 0 = valid ad (success). Rate = sum / N.\n                emitMetric({ metricName: 'blank:ad:validation', metricValue: result ? 1 : 0, adDetails });\n            } catch (_err) {\n                emitMetric({ metricName: 'blank:ad:validation:error', adDetails });\n            }\n        }\n    };\n\n    const intervalId = setInterval(callBlankAdValidation, 1000);\n};\n","import { documentWriteImpl } from '@/client/app/components/documentWrite.js';\n\n/** DOM element ID for the sentinel script tag used to detect when script replay is complete. */\nexport const creativeReplayId = 'creativeReplayStatus';\n\n/** Custom event name dispatched when all creative scripts have been replayed. */\nexport const creativeReplayCompleteEventName = 'creativeReplayComplete';\n\n/**\n * Writes creative HTML to the iframe document, replays all inline scripts,\n * and re-fires DOMContentLoaded/load events for the creative.\n *\n * This is the main entry point for rendering a creative inside a SafeFrame iframe.\n * It handles the full write lifecycle: DOM insertion, script replay, and synthetic\n * event dispatch so creatives that depend on load events work correctly.\n *\n * @param htmlContent - The raw HTML of the ad creative to render.\n */\nexport const writeCreativeToDOM = async (htmlContent: string): Promise<void> => {\n    const eventFired = waitForScriptReplayComplete();\n    documentWriteImpl(htmlContent, buildReplayCompleteScriptTag());\n    await eventFired;\n    replayDOMLoadEvents();\n};\n\n/**\n * Builds a sentinel `<script>` tag appended after the creative HTML.\n * When the browser executes it, the dispatched event signals that all preceding\n * creative scripts have finished replaying — i.e. the creative is fully written to the DOM.\n */\nconst buildReplayCompleteScriptTag = (): string =>\n    `<script id=\"${creativeReplayId}\">document.dispatchEvent(new CustomEvent(\"${creativeReplayCompleteEventName}\"));</script>`;\n\n/** Returns a promise that resolves once the {@link buildReplayCompleteScriptTag | sentinel script} fires. */\nconst waitForScriptReplayComplete = (): Promise<void> =>\n    new Promise((resolve) => {\n        document.addEventListener(creativeReplayCompleteEventName, () => resolve(), { once: true });\n    });\n\n/**\n * Marks the sentinel script so UI tests and debugging can see from the DOM that the creative fired.\n */\nconst markScriptAsFired = (attr: 'creativeLoad' | 'creativedomcontentloaded') =>\n    document.getElementById(creativeReplayId)?.setAttribute(attr, 'true');\n\n/**\n * Re-fires DOMContentLoaded and load events for the creative.\n * By the time creative HTML is written, the iframe's native events have already fired,\n * so creatives listening for them would miss them without these synthetic dispatches.\n */\nconst replayDOMLoadEvents = () => {\n    markScriptAsFired('creativedomcontentloaded');\n    document.dispatchEvent(new Event('DOMContentLoaded'));\n    markScriptAsFired('creativeLoad');\n    window.dispatchEvent(new Event('load'));\n};\n","import { evaluateCreativeBeginToRender } from '@amzn/creative-rendering-monitor/src/creativeBTREvaluatorSync.js';\n\nimport { INNER_IFRAME_BTR_WEBLAB } from '@/components/weblabs.js';\n\nexport interface BtrState {\n    isBtr: boolean;\n    isBtrUnknown: boolean;\n}\n\nconst BTR_WINDOW_MS = 75;\n// First guess from one benchmark (first image at ~507 ms); tune it from the event:btr latency of these creatives.\nconst INNER_IFRAME_BTR_WINDOW_MS = 1000;\n\nconst hasBegunToRender = (getElements: () => HTMLElement[]): boolean =>\n    getElements().some((element) => evaluateCreativeBeginToRender(element).success);\n\n/**\n * Polls until any of the elements begins to render, so a creative split across documents resolves on the first.\n * The elements are read again on each poll, because an inner iframe can replace its document during the wait.\n */\nconst waitForAnyBeginToRender = async (\n    getElements: () => HTMLElement[],\n    timeoutMs: number,\n    isRealTime?: boolean,\n): Promise<boolean> => {\n    // A hidden tab can slow intervals to one per second, so the weblab's T1 counts real time. Otherwise count ticks.\n    const deadline = performance.now() + timeoutMs;\n    const intervalMs = 5;\n    let elapsedMs = 0;\n\n    // setInterval never fires at t=0, so an already-rendered creative otherwise pays a wasted first\n    // tick before onCreativeLoad/onCreativeBeginToRender can fire. evaluateCreativeBeginToRender is a\n    // pure synchronous DOM read, so evaluate it once up front and skip the poll entirely when it passes.\n    if (hasBegunToRender(getElements)) {\n        return true;\n    }\n\n    return new Promise<boolean>((resolve) => {\n        const intervalId = setInterval(() => {\n            elapsedMs += intervalMs;\n            if (hasBegunToRender(getElements)) {\n                clearInterval(intervalId);\n                resolve(true);\n            } else if (isRealTime ? performance.now() >= deadline : elapsedMs >= timeoutMs) {\n                clearInterval(intervalId);\n                resolve(false);\n            }\n        }, intervalMs);\n    });\n};\n\nexport const waitForBeginToRender = (element: HTMLElement = document.body): Promise<boolean> =>\n    waitForAnyBeginToRender(() => [element], BTR_WINDOW_MS);\n\n/**\n * Resolves begin-to-render state for a creative. Inner iframes can only be inspected when they are same-origin\n * (e.g. HTML5 zip creatives served from the same CDN), so BTR is evaluated on the outer element and every inner\n * document. An inner iframe loads its own document before its images, so it gets a longer window than the 75 ms\n * of other creatives. If any inner iframe is cross-origin (contentDocument is null), or BTR isn't detected in a\n * creative with inner iframes, the creative is marked unknown so the BTR rate can be offset downstream.\n */\nexport const evaluateBtr = async (\n    btrPixelUrl: string | undefined,\n    element: HTMLElement = document.body,\n): Promise<BtrState> => {\n    if (!btrPixelUrl) {\n        return { isBtr: false, isBtrUnknown: false };\n    }\n    const iframes = Array.from(element.querySelectorAll('iframe'));\n    const inTreatment = INNER_IFRAME_BTR_WEBLAB().is('t1');\n    // C keeps the old behavior: any inner iframe is BTR unknown.\n    if (iframes.length && (!inTreatment || iframes.some((iframe) => !iframe.contentDocument))) {\n        return { isBtr: false, isBtrUnknown: true };\n    }\n\n    // An iframe with a src first exposes an empty about:blank document, which is replaced once the src loads.\n    const isBtr = await waitForAnyBeginToRender(\n        () => [element, ...iframes.map((iframe) => iframe.contentDocument?.body)].filter(Boolean) as HTMLElement[],\n        iframes.length ? INNER_IFRAME_BTR_WINDOW_MS : BTR_WINDOW_MS,\n        inTreatment,\n    );\n    return { isBtr, isBtrUnknown: iframes.length > 0 && !isBtr };\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, '&').replace(/^&+/, '').replace(/&+$/, '');\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 { evaluateCreativeBeginToRender } from '@amzn/creative-rendering-monitor/src/creativeBTREvaluatorSync.js';\nimport { DeviceType } from '@amzn/safeframe-model';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { getCreative } from '@/client/app/components/get-creative.js';\nimport { isImageTemplateAd } from '@/client/app/components/imageTemplateDetection.js';\nimport { preCreativeWrite } from '@/client/app/components/render.js';\nimport { validateCreativeRendering } from '@/client/app/components/validateCreativeRendering.js';\nimport { writeCreativeToDOM } from '@/client/app/components/writeCreativeToDOM.js';\nimport { evaluateBtr } from '@/components/beginToRender.js';\nimport type { EventsBridge } from '@/components/bridge/events/eventsBridge.js';\nimport { replaceForHtml } from '@/components/clickTracking/replace.js';\nimport type { LatencyTracker } from '@/components/perf.js';\nimport { CLICK_TRACKING_PAINTER_TEST } from '@/components/weblabs.js';\n\nexport interface InitSafeFrameClientParams {\n    adDetails: AdDetails;\n    clickTrackingParam: string;\n    eventsBridge: EventsBridge;\n    tracker: LatencyTracker;\n}\n\nexport const initSafeFrameClient = async ({\n    adDetails,\n    clickTrackingParam,\n    eventsBridge,\n    tracker,\n}: InitSafeFrameClientParams) => {\n    try {\n        eventsBridge.onSafeFrameReady(tracker.startTime);\n\n        const htmlContent = getCreativeHtml(adDetails, clickTrackingParam);\n\n        preCreativeWrite(adDetails, eventsBridge, tracker);\n        await writeCreativeToDOM(htmlContent);\n        eventsBridge.onPostCreativeWrite(tracker.elapsed());\n\n        const { isBtr, isBtrUnknown } = await evaluateBtr(adDetails.btrPixelUrl);\n        if (isBtr) {\n            eventsBridge.onCreativeBeginToRender(tracker.elapsed());\n        }\n\n        eventsBridge.onCreativeLoad({\n            isImageOnlyTemplate: isMobile(adDetails) && isImageTemplateAd(),\n            isBtr,\n            isBtrUnknown,\n            latency: tracker.elapsed(),\n        });\n\n        if (CLICK_TRACKING_PAINTER_TEST().isInTreatment()) {\n            document.body.addEventListener('click', () => eventsBridge.onClick(), { once: true });\n        }\n\n        validateCreativeRendering(adDetails);\n    } catch (err) {\n        eventsBridge.onError({\n            code: 'client-setup',\n            isBTR: evaluateCreativeBeginToRender(document.body).success,\n            error: err instanceof Error ? err : new Error(String(err)),\n        });\n    }\n};\n\nconst getCreativeHtml = (adDetails: AdDetails, clickTrackingParam: string) =>\n    CLICK_TRACKING_PAINTER_TEST().isInTreatment()\n        ? getCreative(adDetails)\n        : replaceForHtml(clickTrackingParam, getCreative(adDetails));\n\nconst isMobile = ({ deviceType }: AdDetails): boolean =>\n    deviceType === DeviceType.MWEB || deviceType === DeviceType.MSHOP;\n","/**\n * Type guard that checks whether `obj` is a non-null object with an own\n * property named `key`. Prevents accidental traversal into prototype\n * properties when walking dynamic paths.\n *\n * Note: `obj != null` is intentionally a loose equality check — it is\n * the idiomatic shorthand for `obj !== null && obj !== undefined`.\n */\nexport const hasOwn = (obj: unknown, key: string): obj is Record<string, unknown> =>\n    obj != null && typeof obj === 'object' && Object.prototype.hasOwnProperty.call(obj, key);\n","import type { BridgeMessage, BridgeRegistry, Context } from '@/components/bridge/core/bridge.js';\nimport { emitMetricOnce } from '@/components/metrics/csaMetrics.js';\nimport type { MetricName } from '@/components/metrics/csaMetrics.js';\nimport { emitErrorLog } from '@/components/metrics/emitErrorLog.js';\nimport { hasOwn } from '@/components/utils/hasOwn.js';\nimport type { IsFunction } from '@/components/utils/isFunction.js';\n\n/** Namespaces that are metric/logging channels and should not emit bridge metrics. */\nconst METRIC_EXEMPT_NAMESPACES_LIST = ['Csa', 'Csm'] as const satisfies readonly (keyof BridgeRegistry)[];\nexport type MetricExemptNamespace = (typeof METRIC_EXEMPT_NAMESPACES_LIST)[number];\nconst METRIC_EXEMPT_NAMESPACES: ReadonlySet<keyof BridgeRegistry> = new Set(METRIC_EXEMPT_NAMESPACES_LIST);\n\n/**\n * Transforms a bridge interface into its host-side implementation by\n * prepending a {@link Context} parameter to every method. This gives\n * each handler access to the ad identity and timing metadata sent by\n * the client iframe.\n *\n * - Functions `(...args) => R` become `(ctx: Context, ...args) => R`.\n * - Plain object branches (e.g. `ue: { count }`) are recursed into.\n * - Non-function, non-object leaves become `never` (compile-time guard).\n *\n * @typeParam T - The bridge interface to transform (e.g. `CsmBridge`).\n *\n * @example\n * ```ts\n * // CsmBridge.ue.count(metric, n?) becomes:\n * // ReceiverImpl<CsmBridge>.ue.count(ctx, metric, n?)\n * ```\n */\nexport type ReceiverImpl<T> = {\n    [K in keyof T]: IsFunction<T[K]> extends true\n        ? T[K] extends (...args: infer A) => infer R\n            ? (ctx: Context, ...args: A) => R\n            : never\n        : T[K] extends object\n          ? ReceiverImpl<T[K]>\n          : never;\n};\n\n/** The shape of a resolved host handler after dot-path lookup. */\ntype Handler = (ctx: Context, ...args: unknown[]) => unknown;\n\n/**\n * Resolves a dot-notation path (e.g. `'ue.count'`) to the handler\n * function inside a {@link ReceiverImpl} tree. Returns `undefined` if any\n * segment is missing, so unknown methods are silently ignored.\n */\nconst resolveMethod = (root: unknown, path: string): unknown =>\n    path.split('.').reduce<unknown>((obj, key) => (hasOwn(obj, key) ? obj[key] : undefined), root);\n\n/**\n * Listens on a {@link MessagePort} shared with the SafeFrame client\n * iframe and routes incoming messages to the matching handler in\n * {@link impl}.\n *\n * Multiple bridges (CSM, Events, etc.) share the same port. The\n * namespace guard ensures each listener only processes messages\n * addressed to its bridge, while dot-notation resolution maps\n * paths like `'ue.count'` to nested handler functions.\n *\n * @typeParam Namespace - A key of {@link BridgeRegistry} identifying the bridge.\n * @param port      - The {@link MessagePort} connected to the client iframe.\n * @param namespace - Bridge namespace key (e.g. `'Csm'`).\n * @param impl - Host-side handler tree produced by {@link ReceiverImpl}.\n *\n * @example\n * ```ts\n * bindReceiver(port, 'Csm', createCsmBridgeReceiver());\n * ```\n */\nexport const bindReceiver = <Namespace extends keyof BridgeRegistry>(\n    port: MessagePort,\n    namespace: Namespace,\n    impl: ReceiverImpl<BridgeRegistry[Namespace]>,\n): void => {\n    port.addEventListener('message', async ({ data }: MessageEvent<BridgeMessage<BridgeRegistry[Namespace]>>) => {\n        if (data?.namespace !== namespace) return;\n        try {\n            const fn = resolveMethod(impl, data.method as string);\n            if (typeof fn === 'function') {\n                const ctx: Context = { ...data.context, messagePort: port };\n                if (!METRIC_EXEMPT_NAMESPACES.has(namespace)) {\n                    emitMetricOnce({\n                        metricName: `sf:bridge:${namespace}:${data.method}` as MetricName,\n                        metricValue: 1,\n                        adDetails: ctx.adDetails,\n                    });\n                }\n                await (fn as Handler)(ctx, ...data.args);\n            }\n        } catch (e) {\n            emitErrorLog({\n                message: `Bridge error in ${namespace}.${data.method}`,\n                error: e,\n                adDetails: data.context.adDetails,\n            });\n        }\n    });\n};\n","import type { GeometricInformation } from '@amzn/safe-frame-client/dist/types/src/IABSafeFrameClient.js';\n\nimport type { ReceiverImpl } from '@/components/bridge/core/receiver.js';\nimport type {\n    GeomMessage,\n    SafeFrameExtBridge,\n    SafeFrameExtMessage,\n} from '@/components/bridge/safeFrameExt/safeFrameExtBridge.js';\nimport type { Cache } from '@/components/cache.js';\n\nexport const createSafeFrameExtBridgeReceiver = (\n    geomCache: Cache<GeometricInformation>,\n    inViewPercentageCache: Cache<number>,\n): ReceiverImpl<SafeFrameExtBridge> => ({\n    populateSafeFrameExt: (_ctx, { geom, inViewPercentage }: SafeFrameExtMessage): void => {\n        inViewPercentageCache.set(inViewPercentage);\n        geomCache.set(geom);\n    },\n    populateGeom: (_ctx, { geom }: GeomMessage): void => {\n        geomCache.set(geom);\n    },\n});\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { geomCache } from '@/client/api/iab/geomCache.js';\nimport { inViewPercentageCache } from '@/client/api/iab/numberCache.js';\nimport { getAdDetails } from '@/client/app/components/adDetails.js';\nimport { disableAll } from '@/client/app/components/disable/disableAll.js';\nimport { sendMessagePortToParent } from '@/client/app/components/notifyParent.js';\nimport { getClickTrackingParamFromHost } from '@/client/app/components/percolateClickTracker.js';\nimport { validateReferrerAllowed } from '@/client/app/components/referrers.js';\nimport { setupReportingObserver } from '@/client/app/components/setupReportingObserver.js';\nimport { installWindowGlobals } from '@/client/app/components/windowGlobals.js';\nimport { initSafeFrameClient } from '@/client/app/safeframeClient.js';\nimport type { SafeFrameClientFactory } from '@/client/app/safeframeClientFactory.js';\nimport { bindReceiver } from '@/components/bridge/core/receiver.js';\nimport { createSender } from '@/components/bridge/core/sender.js';\nimport { createSafeFrameExtBridgeReceiver } from '@/components/bridge/safeFrameExt/safeFrameExtBridgeReceiver.js';\nimport { emitErrorLog } from '@/components/metrics/emitErrorLog.js';\nimport { mark, PERF_SF_CLIENT, createLatencyTracker } from '@/components/perf.js';\nimport type { LatencyTracker } from '@/components/perf.js';\n\n/**\n * Bootstraps the SafeFrame client by creating a {@link MessageChannel} and sending a {@link MessagePort} to the SafeFrame host page.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API\n */\nexport const bootstrapSafeFrameClient = (safeFrameClientFactory: SafeFrameClientFactory): void => {\n    const tracker = createLatencyTracker();\n    validateReferrerAllowed();\n    const adDetails = getAdDetails();\n    const { port1: clientPort, port2: hostPort } = new MessageChannel();\n    setupSafeFrameClient(safeFrameClientFactory, clientPort, adDetails, tracker);\n    sendMessagePortToParent(hostPort, adDetails);\n};\n\nconst setupSafeFrameClient = async (\n    safeFrameClientFactory: SafeFrameClientFactory,\n    messagePort: MessagePort,\n    adDetails: AdDetails,\n    tracker: LatencyTracker,\n): Promise<void> => {\n    try {\n        disableAll(adDetails);\n        setupReportingObserver(adDetails);\n        mark(PERF_SF_CLIENT, 'SF received ad details', adDetails);\n\n        const eventsBridge = createSender(messagePort, 'Events', adDetails);\n\n        installWindowGlobals({ adDetails, messagePort, eventsBridge, safeFrameClientFactory });\n        bindReceiver(messagePort, 'SafeFrameExt', createSafeFrameExtBridgeReceiver(geomCache, inViewPercentageCache));\n\n        const clickTrackingParam = await getClickTrackingParamFromHost(messagePort);\n        messagePort.start();\n\n        initSafeFrameClient({ adDetails, clickTrackingParam, eventsBridge, tracker });\n    } catch (ex) {\n        emitErrorLog({ message: 'Could not init SafeFrame Client', error: ex, adDetails });\n    }\n};\n","import type { CustomMessageData, CustomMessageKey, SFClientAPI } from '@amzn/safe-frame-client-amzn';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport type { ReceiverImpl } from '@/components/bridge/core/receiver.js';\nimport { bindReceiver } from '@/components/bridge/core/receiver.js';\nimport type { CustomMessageBridge } from '@/components/bridge/customMessage/customMessageBridge.js';\nimport { emitMetricOnce } from '@/components/metrics/csaMetrics.js';\nimport { emitErrorLog } from '@/components/metrics/emitErrorLog.js';\n\nexport type CustomMessageSender = Pick<SFClientAPI, 'registerCustomMessageListener'>;\n\ntype CustomMessageListeners = Partial<Record<CustomMessageKey, (data: any) => void>>;\n\n/**\n * Client-side: creates the custom message sender (register API) and binds the\n * receiver that dispatches incoming host messages to registered callbacks.\n *\n * Creatives call `registerCustomMessageListener` on the returned object.\n * The host calls `createSender(port, 'CustomMessage', adDetails).dispatch(key, data)`\n * which arrives here and invokes the matching callback.\n */\nexport const createCustomMessageSender = (port: MessagePort, adDetails: AdDetails): CustomMessageSender => {\n    const mL: CustomMessageListeners = {};\n\n    bindReceiver(port, 'CustomMessage', createCustomMessageBridgeReceiver(mL));\n\n    return {\n        registerCustomMessageListener: <K extends CustomMessageKey>(\n            msgKey: K,\n            callback: (data: CustomMessageData[K]) => void,\n        ) => {\n            emitMetricOnce({\n                metricName: 'sf:bridge:CustomMessage:registerCustomMessageListener',\n                metricValue: 1,\n                adDetails,\n            });\n            mL[msgKey] = callback;\n        },\n    };\n};\n\nconst createCustomMessageBridgeReceiver = (mL: CustomMessageListeners): ReceiverImpl<CustomMessageBridge> => ({\n    dispatch({ adDetails }, msgKey: CustomMessageKey, data: CustomMessageData[typeof msgKey]): void {\n        const handler = mL[msgKey];\n        if (!handler) return;\n        try {\n            handler(data);\n        } catch (ex) {\n            emitErrorLog({ message: 'CustomMessage listener error', error: ex, adDetails });\n        }\n    },\n});\n","import type { AdDetails } from '@amzn/safeframe-model';\n\nimport { createSender } from '@/components/bridge/core/sender.js';\nimport type { SFClientBridge } from '@/components/bridge/sfclient/sfClientBridge.js';\nimport { emitMetricOnce } from '@/components/metrics/csaMetrics.js';\n\nexport const createSFClientBridgeSender = (port: MessagePort, adDetails: AdDetails): SFClientBridge => {\n    const send = createSender(port, 'SFClient', adDetails);\n    return {\n        changeSize: (width, height) => send.changeSize(width, height),\n        collapseSlot: () => send.collapseSlot(),\n        signalAdLoadedAndInteractive: () => send.signalAdLoadedAndInteractive(),\n        feedbackLabelRendered: () => send.feedbackLabelRendered(),\n        feedbackOpenModal: () => send.feedbackOpenModal(),\n        isOnAmazon: () => {\n            emitMetricOnce({ metricName: 'sf:bridge:SFClient:isOnAmazon', metricValue: 1, adDetails });\n            return true;\n        },\n    };\n};\n","import type { SFClientVideoAPI } from '@amzn/safe-frame-client-amzn';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { createSender } from '@/components/bridge/core/sender.js';\n\nexport const createVideoBridgeSender = (port: MessagePort, adDetails: AdDetails): SFClientVideoAPI => {\n    const send = createSender(port, 'Video', adDetails);\n    return {\n        updatePlayingTimeForVideo: (s) => send.updatePlayingTimeForVideo(s),\n        requestVideoAutoplay: (o) => send.requestVideoAutoplay(o),\n        releaseVideoAutoplay: () => send.releaseVideoAutoplay(),\n        haveVideoAutoplayPermission: () => send.haveVideoAutoplayPermission(),\n    };\n};\n","import type { SFClientAPI, SFClientVideoAPI } from '@amzn/safe-frame-client-amzn';\nimport type { AdDetails } from '@amzn/safeframe-model';\n\nimport { createGetDocumentCookie } from '@/client/api/client/local/getDocumentCookie.js';\nimport { createGetPlacementInfo } from '@/client/api/client/local/getPlacementInfo.js';\nimport { createGetUserAgentInfo } from '@/client/api/client/local/getUserAgentInfo.js';\nimport { createGetUserConnectionInfo } from '@/client/api/client/local/getUserConnectionInfo.js';\nimport type { ClientApis } from '@/client/api/internal/types.js';\nimport { createSender } from '@/components/bridge/core/sender.js';\nimport { createCustomMessageSender } from '@/components/bridge/customMessage/customMessageSender.js';\nimport { createMashBridgeClientSender } from '@/components/bridge/mash/mashBridgeClient.js';\nimport { createMSFClientBridgeSender } from '@/components/bridge/msfclient/msfClientBridgeClient.js';\nimport { createSFClientBridgeSender } from '@/components/bridge/sfclient/sfClientBridgeSender.js';\nimport { createVideoBridgeSender } from '@/components/bridge/video/videoBridgeSender.js';\n\nexport type SafeFrameClientFactory = (adDetails: AdDetails, messagePort: MessagePort) => ClientApis;\n\nconst createCommonClientApis = (adDetails: AdDetails, messagePort: MessagePort): SFClientAPI & SFClientVideoAPI => ({\n    ...createVideoBridgeSender(messagePort, adDetails),\n    ...createSFClientBridgeSender(messagePort, adDetails),\n    ...createCustomMessageSender(messagePort, adDetails),\n});\n\nexport const createMobileClientApis: SafeFrameClientFactory = (adDetails, messagePort) =>\n    (window.MSFClient = {\n        ...createCommonClientApis(adDetails, messagePort),\n        ...createMSFClientBridgeSender(messagePort, createSender(messagePort, 'MSFClient', adDetails)),\n        mash: createMashBridgeClientSender(messagePort, adDetails),\n        getPlacementInfo: createGetPlacementInfo(adDetails),\n        getUserAgentInfo: createGetUserAgentInfo(adDetails),\n        getDocumentCookie: createGetDocumentCookie(adDetails),\n        getUserConnectionInfo: createGetUserConnectionInfo(adDetails),\n    });\n\nexport const createDesktopClientApis: SafeFrameClientFactory = (adDetails, messagePort) =>\n    (window.SFClient = createCommonClientApis(adDetails, messagePort));\n","import type {} from '@/client/api/internal/clientWindow.js';\nimport { bootstrapSafeFrameClient } from '@/client/app/initSafeframeClient.js';\nimport { createDesktopClientApis } from '@/client/app/safeframeClientFactory.js';\nimport { mark, PERF_SF_CLIENT } from '@/components/perf.js';\n\nmark(PERF_SF_CLIENT, 'Enter sf.ts');\n\nif (!window.SFClient) {\n    bootstrapSafeFrameClient(createDesktopClientApis);\n}\n"],"x_google_ignoreList":[6,7,14,23,24,27,33],"mappings":"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"}