stormcloud-video-player 0.8.23 → 0.8.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1561,1175 +1561,1226 @@ function publishMQTT(topic, payload) {
1561
1561
  return false;
1562
1562
  }
1563
1563
  }
1564
- // src/utils/tracking.ts
1565
- var cachedBrowserId = null;
1566
- function getClientInfo() {
1567
- var _screen, _screen1, _screen2, _screen3, _screen_orientation, _screen4, _screen5, _window, _window1, _window_screen_orientation, _window_screen, _navigator_languages;
1564
+ // src/utils/vastEnvironmentSignals.ts
1565
+ var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
1566
+ var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
1567
+ var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
1568
+ var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
1569
+ var AIRY_APP_NAME = "AiryTV Movies & TV";
1570
+ var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
1571
+ var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
1572
+ var PLAYER_ID_STORAGE_KEY = "stormcloud.player.id";
1573
+ var LG_TEST_APP_ID = "com.hulu.plus";
1574
+ var LG_TEST_APP_NAME = "Hulu";
1575
+ var LG_TEST_CONTENT_URL = "https://www.hulu.com/live-tv";
1576
+ var _lgTestDeviceId;
1577
+ function getLgTestDeviceId() {
1578
+ if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();
1579
+ return _lgTestDeviceId;
1580
+ }
1581
+ function isLgWebOS() {
1582
+ if (typeof navigator === "undefined") return false;
1583
+ return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);
1584
+ }
1585
+ function getDefaultAppId() {
1586
+ if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
1568
1587
  var ua = navigator.userAgent;
1569
- var platform = navigator.platform;
1570
- var vendor = navigator.vendor || "";
1571
- var maxTouchPoints = navigator.maxTouchPoints || 0;
1572
- var memory = navigator.deviceMemory || null;
1573
- var hardwareConcurrency = navigator.hardwareConcurrency || 1;
1574
- var screenInfo = {
1575
- width: (_screen = screen) === null || _screen === void 0 ? void 0 : _screen.width,
1576
- height: (_screen1 = screen) === null || _screen1 === void 0 ? void 0 : _screen1.height,
1577
- availWidth: (_screen2 = screen) === null || _screen2 === void 0 ? void 0 : _screen2.availWidth,
1578
- availHeight: (_screen3 = screen) === null || _screen3 === void 0 ? void 0 : _screen3.availHeight,
1579
- orientation: ((_screen4 = screen) === null || _screen4 === void 0 ? void 0 : (_screen_orientation = _screen4.orientation) === null || _screen_orientation === void 0 ? void 0 : _screen_orientation.type) || "",
1580
- pixelDepth: (_screen5 = screen) === null || _screen5 === void 0 ? void 0 : _screen5.pixelDepth
1581
- };
1582
- var deviceType = "desktop";
1583
- var brand = "Unknown";
1584
- var os = "Unknown";
1585
- var model = "";
1586
- var isSmartTV = false;
1587
- var isAndroid = false;
1588
- var isWebView = false;
1589
- var isWebApp = false;
1590
- if (ua.includes("Web0S")) {
1591
- brand = "LG";
1592
- os = "webOS";
1593
- isSmartTV = true;
1594
- deviceType = "tv";
1595
- var webosMatch = ua.match(/Web0S\/([^\s]+)/);
1596
- model = webosMatch ? "webOS ".concat(webosMatch[1]) : "webOS TV";
1597
- } else if (ua.includes("Tizen")) {
1598
- brand = "Samsung";
1599
- os = "Tizen";
1600
- isSmartTV = true;
1601
- deviceType = "tv";
1602
- var tizenMatch = ua.match(/Tizen\/([^\s]+)/);
1603
- var tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? "Smart TV" : "";
1604
- model = tizenMatch ? "Tizen ".concat(tizenMatch[1], " ").concat(tvMatch).trim() : "Tizen TV";
1605
- } else if (ua.includes("Philips")) {
1606
- brand = "Philips";
1607
- os = "Saphi";
1608
- isSmartTV = true;
1609
- deviceType = "tv";
1610
- } else if (ua.includes("Sharp") || ua.includes("AQUOS")) {
1611
- brand = "Sharp";
1612
- os = "Android TV";
1613
- isSmartTV = true;
1614
- deviceType = "tv";
1615
- } else if (ua.includes("Android") && (ua.includes("Sony") || vendor.includes("Sony"))) {
1616
- brand = "Sony";
1617
- os = "Android TV";
1618
- isSmartTV = true;
1619
- deviceType = "tv";
1620
- } else if (ua.includes("Android") && (ua.includes("NetCast") || ua.includes("LG"))) {
1621
- brand = "LG";
1622
- os = "Android TV";
1623
- isSmartTV = true;
1624
- deviceType = "tv";
1625
- } else if (ua.includes(" Roku") || ua.includes("Roku/")) {
1626
- brand = "Roku";
1627
- os = "Roku OS";
1628
- isSmartTV = true;
1629
- deviceType = "tv";
1630
- } else if (ua.includes("AppleTV")) {
1631
- brand = "Apple";
1632
- os = "tvOS";
1633
- isSmartTV = true;
1634
- deviceType = "tv";
1588
+ if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
1589
+ if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
1590
+ if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
1591
+ return AIRY_ANDROID_APP_ID;
1592
+ }
1593
+ var DEVICE_ID_STORAGE_KEYS = [
1594
+ "rdid",
1595
+ "ifa",
1596
+ "advertisingId",
1597
+ "advertising_id",
1598
+ "deviceAdvertisingId",
1599
+ "aaid",
1600
+ "adid",
1601
+ "rida",
1602
+ "tifa",
1603
+ "lgudid"
1604
+ ];
1605
+ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
1606
+ "aaid",
1607
+ "adid"
1608
+ ]);
1609
+ function resolveVastEnvironmentSignals(isCtv) {
1610
+ var _ref;
1611
+ var bridgeSignals = readNativeBridgeSignals();
1612
+ var platformDevice = readPlatformNativeDeviceId();
1613
+ var lg = isCtv && isLgWebOS();
1614
+ var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
1615
+ var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
1616
+ var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
1617
+ var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
1618
+ if (isCtv) {
1619
+ return _object_spread_props(_object_spread({
1620
+ isCtv: true,
1621
+ contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),
1622
+ appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),
1623
+ appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),
1624
+ sessionId: getOrCreateCtvSessionId()
1625
+ }, deviceId ? {
1626
+ deviceId: deviceId
1627
+ } : {}, deviceIdType ? {
1628
+ deviceIdType: deviceIdType
1629
+ } : {}, limitAdTracking != null ? {
1630
+ limitAdTracking: limitAdTracking
1631
+ } : {}), {
1632
+ deviceTypeHint: 5
1633
+ });
1635
1634
  }
1636
- if (ua.includes("Android")) {
1637
- isAndroid = true;
1638
- os = "Android";
1639
- deviceType = /Mobile/.test(ua) ? "mobile" : "tablet";
1640
- if (ua.includes("Android") && (maxTouchPoints === 0 || ua.includes("Google TV") || ua.includes("XiaoMi"))) {
1641
- deviceType = "tv";
1642
- isSmartTV = true;
1643
- brand = brand === "Unknown" ? "Android TV" : brand;
1644
- }
1645
- var androidModelMatch = ua.match(/\(([^)]*Android[^)]*)\)/);
1646
- if (androidModelMatch && androidModelMatch[1]) {
1647
- model = androidModelMatch[1];
1648
- }
1635
+ return _object_spread({
1636
+ isCtv: false
1637
+ }, deviceId ? {
1638
+ deviceId: deviceId
1639
+ } : {}, deviceIdType ? {
1640
+ deviceIdType: deviceIdType
1641
+ } : {}, limitAdTracking != null ? {
1642
+ limitAdTracking: limitAdTracking
1643
+ } : {});
1644
+ }
1645
+ function inferDeviceIdType() {
1646
+ if (typeof navigator === "undefined") {
1647
+ return void 0;
1649
1648
  }
1650
- if (/iPad|iPhone|iPod/.test(ua)) {
1651
- os = "iOS";
1652
- deviceType = "mobile";
1653
- brand = "Apple";
1654
- if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {
1655
- deviceType = "tablet";
1656
- }
1649
+ var ua = navigator.userAgent;
1650
+ if (/Roku/i.test(ua)) return "rida";
1651
+ if (/Tizen|Samsung/i.test(ua)) return "tifa";
1652
+ if (/AppleTV|Apple TV/i.test(ua)) return "tvOS";
1653
+ if (/AFT|Fire TV|Amazon/i.test(ua)) return "afai";
1654
+ if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return "lgudid";
1655
+ if (/Android|Google TV/i.test(ua)) return "aaid";
1656
+ if (/iPhone|iPad|iPod/i.test(ua)) return "idfa";
1657
+ return void 0;
1658
+ }
1659
+ function isEquivalentDeviceIdType(tagType, runtimeType) {
1660
+ if (!tagType || !runtimeType) return false;
1661
+ var tag = tagType.toLowerCase();
1662
+ var runtime = runtimeType.toLowerCase();
1663
+ if (tag === runtime) return true;
1664
+ return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);
1665
+ }
1666
+ function resolveNativeDeviceId() {
1667
+ var bridgeSignals = readNativeBridgeSignals();
1668
+ var platformDevice = readPlatformNativeDeviceId();
1669
+ var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;
1670
+ if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {
1671
+ return void 0;
1657
1672
  }
1658
- if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {
1659
- if (ua.includes("Windows")) {
1660
- os = "Windows";
1661
- deviceType = "desktop";
1662
- } else if (ua.includes("Mac") && !/iPhone/.test(ua)) {
1663
- os = "macOS";
1664
- deviceType = "desktop";
1665
- if (maxTouchPoints > 1) deviceType = "tablet";
1666
- } else if (ua.includes("Linux")) {
1667
- os = "Linux";
1668
- deviceType = "desktop";
1669
- }
1673
+ return deviceId;
1674
+ }
1675
+ function getOrCreateStoredUuid(storageKey) {
1676
+ if (typeof window === "undefined") {
1677
+ return void 0;
1670
1678
  }
1671
- if (brand === "Unknown") {
1672
- if (vendor.includes("Google") || ua.includes("Chrome")) brand = "Google";
1673
- if (vendor.includes("Apple")) brand = "Apple";
1674
- if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
1679
+ var existing = readStoredString(storageKey);
1680
+ if (existing) {
1681
+ return existing;
1675
1682
  }
1676
- isWebView = /wv|WebView|Linux; U;/.test(ua);
1677
- if (((_window = window) === null || _window === void 0 ? void 0 : _window.outerHeight) === 0 && ((_window1 = window) === null || _window1 === void 0 ? void 0 : _window1.outerWidth) === 0) {
1678
- isWebView = true;
1683
+ var id = createUuid();
1684
+ try {
1685
+ var _window_localStorage;
1686
+ (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(storageKey, id);
1687
+ } catch (unused) {}
1688
+ return id;
1689
+ }
1690
+ function getOrCreateCtvSessionId() {
1691
+ var existing = readStoredString(CTV_SESSION_STORAGE_KEY);
1692
+ if (existing) {
1693
+ return existing;
1679
1694
  }
1680
- isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || ((_window_screen = window.screen) === null || _window_screen === void 0 ? void 0 : (_window_screen_orientation = _window_screen.orientation) === null || _window_screen_orientation === void 0 ? void 0 : _window_screen_orientation.angle) !== void 0;
1681
- return {
1682
- brand: brand,
1683
- os: os,
1684
- model: model || ua.substring(0, 50) + "...",
1685
- deviceType: deviceType,
1686
- isSmartTV: isSmartTV,
1687
- isAndroid: isAndroid,
1688
- isWebView: isWebView,
1689
- isWebApp: isWebApp,
1690
- domain: window.location.hostname,
1691
- origin: window.location.origin,
1692
- path: window.location.pathname,
1693
- userAgent: ua,
1694
- vendor: vendor,
1695
- platform: platform,
1696
- screen: screenInfo,
1697
- hardwareConcurrency: hardwareConcurrency,
1698
- deviceMemory: memory,
1699
- maxTouchPoints: maxTouchPoints,
1700
- language: navigator.language,
1701
- languages: ((_navigator_languages = navigator.languages) === null || _navigator_languages === void 0 ? void 0 : _navigator_languages.join(",")) || "",
1702
- cookieEnabled: navigator.cookieEnabled,
1703
- doNotTrack: navigator.doNotTrack || "",
1704
- referrer: document.referrer,
1705
- visibilityState: document.visibilityState
1706
- };
1695
+ var sessionId = createUuid();
1696
+ try {
1697
+ var _window_localStorage;
1698
+ (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(CTV_SESSION_STORAGE_KEY, sessionId);
1699
+ } catch (unused) {}
1700
+ return sessionId;
1707
1701
  }
1708
- function getBrowserID(clientInfo) {
1709
- return _async_to_generator(function() {
1710
- var _crypto_subtle, fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashHex, unused, hash, i1, char, fallbackHash, timestamp, random;
1711
- return _ts_generator(this, function(_state) {
1712
- switch(_state.label){
1713
- case 0:
1714
- if (cachedBrowserId) {
1715
- return [
1716
- 2,
1717
- cachedBrowserId
1718
- ];
1719
- }
1720
- fingerprintString = JSON.stringify(clientInfo);
1721
- if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
1722
- 3,
1723
- 5
1724
- ];
1725
- _state.label = 1;
1726
- case 1:
1727
- _state.trys.push([
1728
- 1,
1729
- 4,
1730
- ,
1731
- 5
1732
- ]);
1733
- return [
1734
- 4,
1735
- crypto.subtle.digest("SHA-256", new Uint8Array([
1736
- 1,
1737
- 2,
1738
- 3
1739
- ]))
1740
- ];
1741
- case 2:
1742
- _state.sent();
1743
- if (typeof TextEncoder !== "undefined") {
1744
- encodedData = new TextEncoder().encode(fingerprintString);
1745
- } else {
1746
- utf8 = unescape(encodeURIComponent(fingerprintString));
1747
- buffer = new Uint8Array(utf8.length);
1748
- for(i = 0; i < utf8.length; i++){
1749
- buffer[i] = utf8.charCodeAt(i);
1750
- }
1751
- encodedData = buffer;
1752
- }
1753
- return [
1754
- 4,
1755
- crypto.subtle.digest("SHA-256", encodedData)
1756
- ];
1757
- case 3:
1758
- hashBuffer = _state.sent();
1759
- hashHex = Array.from(new Uint8Array(hashBuffer)).map(function(b) {
1760
- return b.toString(16).padStart(2, "0");
1761
- }).join("");
1762
- cachedBrowserId = hashHex;
1763
- return [
1764
- 2,
1765
- hashHex
1766
- ];
1767
- case 4:
1768
- unused = _state.sent();
1769
- console.warn("[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash");
1770
- return [
1771
- 3,
1772
- 5
1773
- ];
1774
- case 5:
1775
- hash = 0;
1776
- for(i1 = 0; i1 < fingerprintString.length; i1++){
1777
- char = fingerprintString.charCodeAt(i1);
1778
- hash = (hash << 5) - hash + char;
1779
- hash = hash & hash;
1780
- }
1781
- fallbackHash = Math.abs(hash).toString(16).padStart(8, "0");
1782
- timestamp = Date.now().toString(16).padStart(12, "0");
1783
- random = Math.random().toString(16).substring(2, 14).padStart(12, "0");
1784
- cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, "0");
1785
- return [
1786
- 2,
1787
- cachedBrowserId
1788
- ];
1789
- }
1790
- });
1791
- })();
1792
- }
1793
- function canPublish(licenseKey) {
1794
- return Boolean(isMQTTEnabled() && licenseKey);
1702
+ function createUuid() {
1703
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
1704
+ return crypto.randomUUID();
1705
+ }
1706
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(char) {
1707
+ var value = Math.floor(Math.random() * 16);
1708
+ var nibble = char === "x" ? value : value & 3 | 8;
1709
+ return nibble.toString(16);
1710
+ });
1795
1711
  }
1796
- function buildPlayerMetricEvent() {
1797
- return _async_to_generator(function() {
1798
- var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
1799
- var _arguments = arguments;
1800
- return _ts_generator(this, function(_state) {
1801
- switch(_state.label){
1802
- case 0:
1803
- context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
1804
- clientInfo = getClientInfo();
1805
- return [
1806
- 4,
1807
- getBrowserID(clientInfo)
1808
- ];
1809
- case 1:
1810
- playerId = _state.sent();
1811
- captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
1812
- return [
1813
- 2,
1814
- _object_spread({
1815
- player_id: playerId,
1816
- device_type: clientInfo.deviceType,
1817
- os: clientInfo.os.toLowerCase(),
1818
- ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
1819
- ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
1820
- capture_at: captureAt
1821
- }, context.inputStreamType ? {
1822
- input_stream_type: context.inputStreamType
1823
- } : {})
1824
- ];
1712
+ function readPlatformNativeDeviceId() {
1713
+ if (typeof window === "undefined") return {};
1714
+ try {
1715
+ var _window_webapis;
1716
+ var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
1717
+ if (adinfo) {
1718
+ var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
1719
+ if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
1720
+ var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
1721
+ return _object_spread({
1722
+ deviceId: tifa,
1723
+ deviceIdType: "tifa"
1724
+ }, typeof lat === "boolean" ? {
1725
+ limitAdTracking: lat
1726
+ } : {});
1825
1727
  }
1826
- });
1827
- }).apply(this, arguments);
1728
+ }
1729
+ } catch (unused) {}
1730
+ try {
1731
+ var webOSDev = window.webOSDev;
1732
+ if (webOSDev) {
1733
+ var _webOSDev_lgudid;
1734
+ var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
1735
+ if (typeof lgudid === "string" && lgudid) {
1736
+ if (isZeroedAdId(lgudid)) {
1737
+ return {
1738
+ deviceIdType: "lgudid",
1739
+ limitAdTracking: true
1740
+ };
1741
+ }
1742
+ if (!isMacroPlaceholder(lgudid)) {
1743
+ return {
1744
+ deviceId: lgudid,
1745
+ deviceIdType: "lgudid",
1746
+ limitAdTracking: false
1747
+ };
1748
+ }
1749
+ }
1750
+ }
1751
+ } catch (unused) {}
1752
+ try {
1753
+ var roku = window.Roku;
1754
+ if (roku) {
1755
+ var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
1756
+ if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
1757
+ return {
1758
+ deviceId: rida,
1759
+ deviceIdType: "rida",
1760
+ limitAdTracking: false
1761
+ };
1762
+ }
1763
+ }
1764
+ } catch (unused) {}
1765
+ return {};
1828
1766
  }
1829
- function publishTracking(licenseKey, channel, body) {
1830
- ensureMQTTClient();
1831
- publishMQTT(buildPlayerTopic(licenseKey, channel), body);
1767
+ var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
1768
+ "38400000-8cf0-11bd-b23e-10b96e40000d",
1769
+ "00000000-0000-0000-0000-000000000000"
1770
+ ]);
1771
+ function isMacroPlaceholder(value) {
1772
+ var t = value.trim();
1773
+ return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
1832
1774
  }
1833
- function sendInitialTracking(_0) {
1834
- return _async_to_generator(function(licenseKey) {
1835
- var context, metricEvent, error;
1836
- var _arguments = arguments;
1837
- return _ts_generator(this, function(_state) {
1838
- switch(_state.label){
1839
- case 0:
1840
- context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
1841
- if (!canPublish(licenseKey)) return [
1842
- 2
1843
- ];
1844
- _state.label = 1;
1845
- case 1:
1846
- _state.trys.push([
1847
- 1,
1848
- 3,
1849
- ,
1850
- 4
1851
- ]);
1852
- return [
1853
- 4,
1854
- buildPlayerMetricEvent(context, {
1855
- adLoaded: false,
1856
- adDetect: false
1857
- })
1858
- ];
1859
- case 2:
1860
- metricEvent = _state.sent();
1861
- publishTracking(licenseKey, "metrics", {
1862
- events: [
1863
- metricEvent
1864
- ]
1865
- });
1866
- return [
1867
- 3,
1868
- 4
1869
- ];
1870
- case 3:
1871
- error = _state.sent();
1872
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
1873
- return [
1874
- 3,
1875
- 4
1876
- ];
1877
- case 4:
1878
- return [
1879
- 2
1880
- ];
1881
- }
1882
- });
1883
- }).apply(this, arguments);
1775
+ function isZeroedAdId(value) {
1776
+ return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
1884
1777
  }
1885
- function sendAdDetectTracking(_0, _1) {
1886
- return _async_to_generator(function(licenseKey, adDetectInfo) {
1887
- var context, error;
1888
- var _arguments = arguments;
1889
- return _ts_generator(this, function(_state) {
1890
- switch(_state.label){
1891
- case 0:
1892
- context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
1893
- _state.label = 1;
1894
- case 1:
1895
- _state.trys.push([
1896
- 1,
1897
- 3,
1898
- ,
1899
- 4
1900
- ]);
1901
- return [
1902
- 4,
1903
- sendHeartbeat(licenseKey, context, {
1904
- adDetect: true,
1905
- captureAt: adDetectInfo.timestamp
1906
- })
1907
- ];
1908
- case 2:
1909
- _state.sent();
1910
- return [
1911
- 3,
1912
- 4
1913
- ];
1914
- case 3:
1915
- error = _state.sent();
1916
- console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
1917
- return [
1918
- 3,
1919
- 4
1920
- ];
1921
- case 4:
1922
- return [
1923
- 2
1924
- ];
1778
+ function readNativeBridgeSignals() {
1779
+ if (typeof window === "undefined") {
1780
+ return {};
1781
+ }
1782
+ var candidates = [
1783
+ window.__STORMCLOUD_CTV_AD_INFO__,
1784
+ window.__STORMCLOUD_CTV__,
1785
+ window.stormcloudCtv,
1786
+ window.AiryTV,
1787
+ window.Android,
1788
+ window.webOS,
1789
+ window.tizen,
1790
+ window.amazon
1791
+ ].filter(Boolean);
1792
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1793
+ try {
1794
+ for(var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1795
+ var source = _step.value;
1796
+ var contentUrl = readBridgeValue(source, [
1797
+ "contentUrl",
1798
+ "url",
1799
+ "videoUrl",
1800
+ "canonicalUrl"
1801
+ ]) || void 0;
1802
+ var appId = readBridgeValue(source, [
1803
+ "appId",
1804
+ "msid",
1805
+ "applicationId",
1806
+ "packageName"
1807
+ ]) || void 0;
1808
+ var appName = readBridgeValue(source, [
1809
+ "appName",
1810
+ "an",
1811
+ "applicationName"
1812
+ ]) || void 0;
1813
+ var deviceId = readBridgeValue(source, [
1814
+ "rdid",
1815
+ "ifa",
1816
+ "advertisingId",
1817
+ "adId",
1818
+ "deviceId",
1819
+ "lgudid",
1820
+ "LGUDID",
1821
+ "tifa",
1822
+ "rida",
1823
+ "afai",
1824
+ "aaid"
1825
+ ]) || void 0;
1826
+ if (!contentUrl && !deviceId && !appId && !appName) continue;
1827
+ var deviceIdType = readBridgeValue(source, [
1828
+ "idtype",
1829
+ "deviceIdType",
1830
+ "advertisingIdType",
1831
+ "idType"
1832
+ ]) || inferDeviceIdType();
1833
+ var limitAdTracking = readBridgeBoolean(source, [
1834
+ "is_lat",
1835
+ "limitAdTracking",
1836
+ "limitedAdTracking",
1837
+ "lat"
1838
+ ]);
1839
+ return _object_spread({}, contentUrl ? {
1840
+ contentUrl: contentUrl
1841
+ } : {}, appId ? {
1842
+ appId: appId
1843
+ } : {}, appName ? {
1844
+ appName: appName
1845
+ } : {}, deviceId ? {
1846
+ deviceId: deviceId
1847
+ } : {}, deviceId && deviceIdType ? {
1848
+ deviceIdType: deviceIdType
1849
+ } : {}, deviceId && limitAdTracking != null ? {
1850
+ limitAdTracking: limitAdTracking
1851
+ } : {});
1852
+ }
1853
+ } catch (err) {
1854
+ _didIteratorError = true;
1855
+ _iteratorError = err;
1856
+ } finally{
1857
+ try {
1858
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1859
+ _iterator.return();
1925
1860
  }
1926
- });
1927
- }).apply(this, arguments);
1861
+ } finally{
1862
+ if (_didIteratorError) {
1863
+ throw _iteratorError;
1864
+ }
1865
+ }
1866
+ }
1867
+ return {};
1928
1868
  }
1929
- function sendAdLoadedTracking(_0, _1) {
1930
- return _async_to_generator(function(licenseKey, adLoadedInfo) {
1931
- var context, error;
1932
- var _arguments = arguments;
1933
- return _ts_generator(this, function(_state) {
1934
- switch(_state.label){
1935
- case 0:
1936
- context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
1937
- _state.label = 1;
1938
- case 1:
1939
- _state.trys.push([
1940
- 1,
1941
- 3,
1942
- ,
1943
- 4
1944
- ]);
1945
- return [
1946
- 4,
1947
- sendHeartbeat(licenseKey, context, {
1948
- adLoaded: true,
1949
- captureAt: adLoadedInfo.timestamp
1950
- })
1951
- ];
1952
- case 2:
1953
- _state.sent();
1954
- return [
1955
- 3,
1956
- 4
1957
- ];
1958
- case 3:
1959
- error = _state.sent();
1960
- console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
1961
- return [
1962
- 3,
1963
- 4
1964
- ];
1965
- case 4:
1966
- return [
1967
- 2
1968
- ];
1869
+ function readBridgeValue(source, keys) {
1870
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1871
+ try {
1872
+ for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1873
+ var key = _step.value;
1874
+ var value = source === null || source === void 0 ? void 0 : source[key];
1875
+ if (typeof value === "string" && value) {
1876
+ return value;
1969
1877
  }
1970
- });
1971
- }).apply(this, arguments);
1878
+ if (typeof value === "function") {
1879
+ try {
1880
+ var result = value.call(source);
1881
+ if (typeof result === "string" && result) {
1882
+ return result;
1883
+ }
1884
+ } catch (unused) {}
1885
+ }
1886
+ }
1887
+ } catch (err) {
1888
+ _didIteratorError = true;
1889
+ _iteratorError = err;
1890
+ } finally{
1891
+ try {
1892
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1893
+ _iterator.return();
1894
+ }
1895
+ } finally{
1896
+ if (_didIteratorError) {
1897
+ throw _iteratorError;
1898
+ }
1899
+ }
1900
+ }
1901
+ return void 0;
1902
+ }
1903
+ function readBridgeBoolean(source, keys) {
1904
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1905
+ try {
1906
+ for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1907
+ var key = _step.value;
1908
+ var value = source === null || source === void 0 ? void 0 : source[key];
1909
+ var normalized = normalizeBoolean(value);
1910
+ if (normalized != null) {
1911
+ return normalized;
1912
+ }
1913
+ if (typeof value === "function") {
1914
+ try {
1915
+ var result = normalizeBoolean(value.call(source));
1916
+ if (result != null) {
1917
+ return result;
1918
+ }
1919
+ } catch (unused) {}
1920
+ }
1921
+ }
1922
+ } catch (err) {
1923
+ _didIteratorError = true;
1924
+ _iteratorError = err;
1925
+ } finally{
1926
+ try {
1927
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1928
+ _iterator.return();
1929
+ }
1930
+ } finally{
1931
+ if (_didIteratorError) {
1932
+ throw _iteratorError;
1933
+ }
1934
+ }
1935
+ }
1936
+ return void 0;
1937
+ }
1938
+ function readStoredDeviceId() {
1939
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1940
+ try {
1941
+ for(var _iterator = DEVICE_ID_STORAGE_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1942
+ var key = _step.value;
1943
+ var value = readStoredString(key);
1944
+ if (value) {
1945
+ return value;
1946
+ }
1947
+ }
1948
+ } catch (err) {
1949
+ _didIteratorError = true;
1950
+ _iteratorError = err;
1951
+ } finally{
1952
+ try {
1953
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1954
+ _iterator.return();
1955
+ }
1956
+ } finally{
1957
+ if (_didIteratorError) {
1958
+ throw _iteratorError;
1959
+ }
1960
+ }
1961
+ }
1962
+ return void 0;
1963
+ }
1964
+ function readStoredString(key) {
1965
+ if (typeof window === "undefined") {
1966
+ return void 0;
1967
+ }
1968
+ try {
1969
+ var _window_localStorage;
1970
+ var value = (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.getItem(key);
1971
+ return value || void 0;
1972
+ } catch (unused) {
1973
+ return void 0;
1974
+ }
1975
+ }
1976
+ function readStoredLimitAdTracking() {
1977
+ return normalizeBoolean(readStoredString("limitAdTracking") || readStoredString("limitedAdTracking") || readStoredString("is_lat"));
1978
+ }
1979
+ function normalizeBoolean(value) {
1980
+ if (typeof value === "boolean") {
1981
+ return value;
1982
+ }
1983
+ if (typeof value === "number") {
1984
+ return value === 1;
1985
+ }
1986
+ if (typeof value === "string") {
1987
+ var normalized = value.toLowerCase();
1988
+ if (normalized === "1" || normalized === "true" || normalized === "yes") {
1989
+ return true;
1990
+ }
1991
+ if (normalized === "0" || normalized === "false" || normalized === "no") {
1992
+ return false;
1993
+ }
1994
+ }
1995
+ return void 0;
1996
+ }
1997
+ // src/utils/tracking.ts
1998
+ var cachedBrowserId = null;
1999
+ function getClientInfo() {
2000
+ var _screen, _screen1, _screen2, _screen3, _screen_orientation, _screen4, _screen5, _window, _window1, _window_screen_orientation, _window_screen, _navigator_languages;
2001
+ var ua = navigator.userAgent;
2002
+ var platform = navigator.platform;
2003
+ var vendor = navigator.vendor || "";
2004
+ var maxTouchPoints = navigator.maxTouchPoints || 0;
2005
+ var memory = navigator.deviceMemory || null;
2006
+ var hardwareConcurrency = navigator.hardwareConcurrency || 1;
2007
+ var screenInfo = {
2008
+ width: (_screen = screen) === null || _screen === void 0 ? void 0 : _screen.width,
2009
+ height: (_screen1 = screen) === null || _screen1 === void 0 ? void 0 : _screen1.height,
2010
+ availWidth: (_screen2 = screen) === null || _screen2 === void 0 ? void 0 : _screen2.availWidth,
2011
+ availHeight: (_screen3 = screen) === null || _screen3 === void 0 ? void 0 : _screen3.availHeight,
2012
+ orientation: ((_screen4 = screen) === null || _screen4 === void 0 ? void 0 : (_screen_orientation = _screen4.orientation) === null || _screen_orientation === void 0 ? void 0 : _screen_orientation.type) || "",
2013
+ pixelDepth: (_screen5 = screen) === null || _screen5 === void 0 ? void 0 : _screen5.pixelDepth
2014
+ };
2015
+ var deviceType = "desktop";
2016
+ var brand = "Unknown";
2017
+ var os = "Unknown";
2018
+ var model = "";
2019
+ var isSmartTV = false;
2020
+ var isAndroid = false;
2021
+ var isWebView = false;
2022
+ var isWebApp = false;
2023
+ if (ua.includes("Web0S")) {
2024
+ brand = "LG";
2025
+ os = "webOS";
2026
+ isSmartTV = true;
2027
+ deviceType = "tv";
2028
+ var webosMatch = ua.match(/Web0S\/([^\s]+)/);
2029
+ model = webosMatch ? "webOS ".concat(webosMatch[1]) : "webOS TV";
2030
+ } else if (ua.includes("Tizen")) {
2031
+ brand = "Samsung";
2032
+ os = "Tizen";
2033
+ isSmartTV = true;
2034
+ deviceType = "tv";
2035
+ var tizenMatch = ua.match(/Tizen\/([^\s]+)/);
2036
+ var tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? "Smart TV" : "";
2037
+ model = tizenMatch ? "Tizen ".concat(tizenMatch[1], " ").concat(tvMatch).trim() : "Tizen TV";
2038
+ } else if (ua.includes("Philips")) {
2039
+ brand = "Philips";
2040
+ os = "Saphi";
2041
+ isSmartTV = true;
2042
+ deviceType = "tv";
2043
+ } else if (ua.includes("Sharp") || ua.includes("AQUOS")) {
2044
+ brand = "Sharp";
2045
+ os = "Android TV";
2046
+ isSmartTV = true;
2047
+ deviceType = "tv";
2048
+ } else if (ua.includes("Android") && (ua.includes("Sony") || vendor.includes("Sony"))) {
2049
+ brand = "Sony";
2050
+ os = "Android TV";
2051
+ isSmartTV = true;
2052
+ deviceType = "tv";
2053
+ } else if (ua.includes("Android") && (ua.includes("NetCast") || ua.includes("LG"))) {
2054
+ brand = "LG";
2055
+ os = "Android TV";
2056
+ isSmartTV = true;
2057
+ deviceType = "tv";
2058
+ } else if (ua.includes(" Roku") || ua.includes("Roku/")) {
2059
+ brand = "Roku";
2060
+ os = "Roku OS";
2061
+ isSmartTV = true;
2062
+ deviceType = "tv";
2063
+ } else if (ua.includes("AppleTV")) {
2064
+ brand = "Apple";
2065
+ os = "tvOS";
2066
+ isSmartTV = true;
2067
+ deviceType = "tv";
2068
+ }
2069
+ if (ua.includes("Android")) {
2070
+ isAndroid = true;
2071
+ os = "Android";
2072
+ deviceType = /Mobile/.test(ua) ? "mobile" : "tablet";
2073
+ if (ua.includes("Android") && (maxTouchPoints === 0 || ua.includes("Google TV") || ua.includes("XiaoMi"))) {
2074
+ deviceType = "tv";
2075
+ isSmartTV = true;
2076
+ brand = brand === "Unknown" ? "Android TV" : brand;
2077
+ }
2078
+ var androidModelMatch = ua.match(/\(([^)]*Android[^)]*)\)/);
2079
+ if (androidModelMatch && androidModelMatch[1]) {
2080
+ model = androidModelMatch[1];
2081
+ }
2082
+ }
2083
+ if (/iPad|iPhone|iPod/.test(ua)) {
2084
+ os = "iOS";
2085
+ deviceType = "mobile";
2086
+ brand = "Apple";
2087
+ if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {
2088
+ deviceType = "tablet";
2089
+ }
2090
+ }
2091
+ if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {
2092
+ if (ua.includes("Windows")) {
2093
+ os = "Windows";
2094
+ deviceType = "desktop";
2095
+ } else if (ua.includes("Mac") && !/iPhone/.test(ua)) {
2096
+ os = "macOS";
2097
+ deviceType = "desktop";
2098
+ if (maxTouchPoints > 1) deviceType = "tablet";
2099
+ } else if (ua.includes("Linux")) {
2100
+ os = "Linux";
2101
+ deviceType = "desktop";
2102
+ }
2103
+ }
2104
+ if (brand === "Unknown") {
2105
+ if (vendor.includes("Google") || ua.includes("Chrome")) brand = "Google";
2106
+ if (vendor.includes("Apple")) brand = "Apple";
2107
+ if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
2108
+ }
2109
+ isWebView = /wv|WebView|Linux; U;/.test(ua);
2110
+ if (((_window = window) === null || _window === void 0 ? void 0 : _window.outerHeight) === 0 && ((_window1 = window) === null || _window1 === void 0 ? void 0 : _window1.outerWidth) === 0) {
2111
+ isWebView = true;
2112
+ }
2113
+ isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || ((_window_screen = window.screen) === null || _window_screen === void 0 ? void 0 : (_window_screen_orientation = _window_screen.orientation) === null || _window_screen_orientation === void 0 ? void 0 : _window_screen_orientation.angle) !== void 0;
2114
+ return {
2115
+ brand: brand,
2116
+ os: os,
2117
+ model: model || ua.substring(0, 50) + "...",
2118
+ deviceType: deviceType,
2119
+ isSmartTV: isSmartTV,
2120
+ isAndroid: isAndroid,
2121
+ isWebView: isWebView,
2122
+ isWebApp: isWebApp,
2123
+ domain: window.location.hostname,
2124
+ origin: window.location.origin,
2125
+ path: window.location.pathname,
2126
+ userAgent: ua,
2127
+ vendor: vendor,
2128
+ platform: platform,
2129
+ screen: screenInfo,
2130
+ hardwareConcurrency: hardwareConcurrency,
2131
+ deviceMemory: memory,
2132
+ maxTouchPoints: maxTouchPoints,
2133
+ language: navigator.language,
2134
+ languages: ((_navigator_languages = navigator.languages) === null || _navigator_languages === void 0 ? void 0 : _navigator_languages.join(",")) || "",
2135
+ cookieEnabled: navigator.cookieEnabled,
2136
+ doNotTrack: navigator.doNotTrack || "",
2137
+ referrer: document.referrer,
2138
+ visibilityState: document.visibilityState
2139
+ };
1972
2140
  }
1973
- function sendAdImpressionTracking(_0, _1) {
1974
- return _async_to_generator(function(licenseKey, adImpressionInfo) {
1975
- var context, metricEvent, error;
1976
- var _arguments = arguments;
2141
+ function sha256Hex(input) {
2142
+ return _async_to_generator(function() {
2143
+ var _crypto_subtle, encodedData, utf8, buffer, i, hashBuffer, unused, hash, i1, char, fallbackHash, timestamp, random;
1977
2144
  return _ts_generator(this, function(_state) {
1978
2145
  switch(_state.label){
1979
2146
  case 0:
1980
- context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
1981
- if (!canPublish(licenseKey)) return [
1982
- 2
1983
- ];
1984
- _state.label = 1;
1985
- case 1:
1986
- _state.trys.push([
1987
- 1,
1988
- 3,
1989
- ,
1990
- 4
1991
- ]);
1992
- return [
1993
- 4,
1994
- buildPlayerMetricEvent(context, {
1995
- captureAt: adImpressionInfo.timestamp
1996
- })
1997
- ];
1998
- case 2:
1999
- metricEvent = _state.sent();
2000
- publishTracking(licenseKey, "heartbeat", metricEvent);
2001
- publishTracking(licenseKey, "impressions", {
2002
- events: [
2003
- {
2004
- player_id: metricEvent.player_id,
2005
- ad_played_count: 1,
2006
- ad_url: adImpressionInfo.adUrl,
2007
- capture_at: adImpressionInfo.timestamp
2008
- }
2009
- ]
2010
- });
2011
- return [
2012
- 3,
2013
- 4
2014
- ];
2015
- case 3:
2016
- error = _state.sent();
2017
- console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2018
- return [
2147
+ if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
2019
2148
  3,
2020
- 4
2021
- ];
2022
- case 4:
2023
- return [
2024
- 2
2025
- ];
2026
- }
2027
- });
2028
- }).apply(this, arguments);
2029
- }
2030
- function sendHeartbeat(_0) {
2031
- return _async_to_generator(function(licenseKey) {
2032
- var context, flags, heartbeatData, error;
2033
- var _arguments = arguments;
2034
- return _ts_generator(this, function(_state) {
2035
- switch(_state.label){
2036
- case 0:
2037
- context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2038
- if (!canPublish(licenseKey)) return [
2039
- 2
2149
+ 5
2040
2150
  ];
2041
2151
  _state.label = 1;
2042
2152
  case 1:
2043
2153
  _state.trys.push([
2044
2154
  1,
2045
- 3,
2155
+ 4,
2046
2156
  ,
2047
- 4
2157
+ 5
2048
2158
  ]);
2049
2159
  return [
2050
2160
  4,
2051
- buildPlayerMetricEvent(context, flags)
2161
+ crypto.subtle.digest("SHA-256", new Uint8Array([
2162
+ 1,
2163
+ 2,
2164
+ 3
2165
+ ]))
2052
2166
  ];
2053
2167
  case 2:
2054
- heartbeatData = _state.sent();
2055
- publishTracking(licenseKey, "heartbeat", heartbeatData);
2056
- return [
2057
- 3,
2058
- 4
2059
- ];
2060
- case 3:
2061
- error = _state.sent();
2062
- console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2063
- return [
2064
- 3,
2065
- 4
2066
- ];
2067
- case 4:
2068
- return [
2069
- 2
2070
- ];
2071
- }
2072
- });
2073
- }).apply(this, arguments);
2074
- }
2075
- // src/utils/polyfills.ts
2076
- function polyfillURLSearchParams() {
2077
- if (typeof URLSearchParams !== "undefined") {
2078
- return;
2079
- }
2080
- var URLSearchParamsPolyfill = /*#__PURE__*/ function() {
2081
- function URLSearchParamsPolyfill(init) {
2082
- var _this = this;
2083
- _class_call_check(this, URLSearchParamsPolyfill);
2084
- this.params = /* @__PURE__ */ new Map();
2085
- if (typeof init === "string") {
2086
- this.parseQueryString(init);
2087
- } else if (_instanceof(init, URLSearchParamsPolyfill)) {
2088
- init.forEach(function(value, key) {
2089
- _this.append(key, value);
2090
- });
2091
- }
2092
- }
2093
- _create_class(URLSearchParamsPolyfill, [
2094
- {
2095
- key: "parseQueryString",
2096
- value: function parseQueryString(query) {
2097
- var _this = this;
2098
- var cleanQuery = query.startsWith("?") ? query.slice(1) : query;
2099
- if (!cleanQuery) return;
2100
- cleanQuery.split("&").forEach(function(param) {
2101
- var _param_split = _sliced_to_array(param.split("="), 2), key = _param_split[0], value = _param_split[1];
2102
- if (key) {
2103
- var decodedKey = _this.safeDecodeURIComponent(key);
2104
- var decodedValue = value ? _this.safeDecodeURIComponent(value) : "";
2105
- _this.append(decodedKey, decodedValue);
2106
- }
2107
- });
2108
- }
2109
- },
2110
- {
2111
- key: "safeDecodeURIComponent",
2112
- value: function safeDecodeURIComponent(str) {
2113
- try {
2114
- return decodeURIComponent(str.replace(/\+/g, " "));
2115
- } catch (e) {
2116
- return str;
2117
- }
2118
- }
2119
- },
2120
- {
2121
- key: "append",
2122
- value: function append(name, value) {
2123
- var values = this.params.get(name) || [];
2124
- values.push(String(value));
2125
- this.params.set(name, values);
2126
- }
2127
- },
2128
- {
2129
- key: "delete",
2130
- value: function _delete(name) {
2131
- this.params.delete(name);
2132
- }
2133
- },
2134
- {
2135
- key: "get",
2136
- value: function get(name) {
2137
- var values = this.params.get(name);
2138
- return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;
2139
- }
2140
- },
2141
- {
2142
- key: "getAll",
2143
- value: function getAll(name) {
2144
- return this.params.get(name) || [];
2145
- }
2146
- },
2147
- {
2148
- key: "has",
2149
- value: function has(name) {
2150
- return this.params.has(name);
2151
- }
2152
- },
2153
- {
2154
- key: "set",
2155
- value: function set(name, value) {
2156
- this.params.set(name, [
2157
- String(value)
2158
- ]);
2159
- }
2160
- },
2161
- {
2162
- key: "forEach",
2163
- value: function forEach(callback) {
2164
- var _this = this;
2165
- this.params.forEach(function(values, key) {
2166
- values.forEach(function(value) {
2167
- callback(value, key, _this);
2168
- });
2169
- });
2170
- }
2171
- },
2172
- {
2173
- key: "toString",
2174
- value: function toString() {
2175
- var parts = [];
2176
- this.params.forEach(function(values, key) {
2177
- values.forEach(function(value) {
2178
- parts.push("".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(value)));
2179
- });
2180
- });
2181
- return parts.join("&");
2182
- }
2183
- }
2184
- ]);
2185
- return URLSearchParamsPolyfill;
2186
- }();
2187
- window.URLSearchParams = URLSearchParamsPolyfill;
2188
- }
2189
- function polyfillTextEncoder() {
2190
- if (typeof TextEncoder !== "undefined") {
2191
- return;
2192
- }
2193
- var TextEncoderPolyfill = /*#__PURE__*/ function() {
2194
- function TextEncoderPolyfill() {
2195
- _class_call_check(this, TextEncoderPolyfill);
2196
- this.encoding = "utf-8";
2197
- }
2198
- _create_class(TextEncoderPolyfill, [
2199
- {
2200
- key: "encode",
2201
- value: function encode(str) {
2202
- var utf8 = [];
2203
- for(var i = 0; i < str.length; i++){
2204
- var charcode = str.charCodeAt(i);
2205
- if (charcode < 128) {
2206
- utf8.push(charcode);
2207
- } else if (charcode < 2048) {
2208
- utf8.push(192 | charcode >> 6, 128 | charcode & 63);
2209
- } else if (charcode < 55296 || charcode >= 57344) {
2210
- utf8.push(224 | charcode >> 12, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2211
- } else {
2212
- i++;
2213
- charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);
2214
- utf8.push(240 | charcode >> 18, 128 | charcode >> 12 & 63, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2168
+ _state.sent();
2169
+ if (typeof TextEncoder !== "undefined") {
2170
+ encodedData = new TextEncoder().encode(input);
2171
+ } else {
2172
+ utf8 = unescape(encodeURIComponent(input));
2173
+ buffer = new Uint8Array(utf8.length);
2174
+ for(i = 0; i < utf8.length; i++){
2175
+ buffer[i] = utf8.charCodeAt(i);
2215
2176
  }
2177
+ encodedData = buffer;
2216
2178
  }
2217
- return new Uint8Array(utf8);
2218
- }
2219
- }
2220
- ]);
2221
- return TextEncoderPolyfill;
2222
- }();
2223
- window.TextEncoder = TextEncoderPolyfill;
2224
- }
2225
- function polyfillPromiseFinally() {
2226
- if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
2227
- Promise.prototype.finally = function(callback) {
2228
- var constructor = this.constructor;
2229
- return this.then(function(value) {
2230
- return constructor.resolve(callback()).then(function() {
2231
- return value;
2232
- });
2233
- }, function(reason) {
2234
- return constructor.resolve(callback()).then(function() {
2235
- throw reason;
2236
- });
2237
- });
2238
- };
2239
- }
2240
- }
2241
- function polyfillObjectAssign() {
2242
- if (typeof Object.assign !== "function") {
2243
- Object.assign = function(target) {
2244
- for(var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
2245
- sources[_key - 1] = arguments[_key];
2246
- }
2247
- if (target == null) {
2248
- throw new TypeError("Cannot convert undefined or null to object");
2249
- }
2250
- var to = Object(target);
2251
- for(var i = 0; i < sources.length; i++){
2252
- var nextSource = sources[i];
2253
- if (nextSource != null) {
2254
- for(var nextKey in nextSource){
2255
- if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
2256
- to[nextKey] = nextSource[nextKey];
2257
- }
2179
+ return [
2180
+ 4,
2181
+ crypto.subtle.digest("SHA-256", encodedData)
2182
+ ];
2183
+ case 3:
2184
+ hashBuffer = _state.sent();
2185
+ return [
2186
+ 2,
2187
+ Array.from(new Uint8Array(hashBuffer)).map(function(b) {
2188
+ return b.toString(16).padStart(2, "0");
2189
+ }).join("")
2190
+ ];
2191
+ case 4:
2192
+ unused = _state.sent();
2193
+ console.warn("[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash");
2194
+ return [
2195
+ 3,
2196
+ 5
2197
+ ];
2198
+ case 5:
2199
+ hash = 0;
2200
+ for(i1 = 0; i1 < input.length; i1++){
2201
+ char = input.charCodeAt(i1);
2202
+ hash = (hash << 5) - hash + char;
2203
+ hash = hash & hash;
2258
2204
  }
2259
- }
2260
- }
2261
- return to;
2262
- };
2263
- }
2264
- }
2265
- function polyfillArrayFrom() {
2266
- if (!Array.from) {
2267
- Array.from = function(arrayLike, mapFn, thisArg) {
2268
- var items = Object(arrayLike);
2269
- if (arrayLike == null) {
2270
- throw new TypeError("Array.from requires an array-like object");
2271
- }
2272
- var len = items.length >>> 0;
2273
- var result = new Array(len);
2274
- for(var i = 0; i < len; i++){
2275
- if (mapFn) {
2276
- result[i] = mapFn.call(thisArg, items[i], i);
2277
- } else {
2278
- result[i] = items[i];
2279
- }
2205
+ fallbackHash = Math.abs(hash).toString(16).padStart(8, "0");
2206
+ timestamp = Date.now().toString(16).padStart(12, "0");
2207
+ random = Math.random().toString(16).substring(2, 14).padStart(12, "0");
2208
+ return [
2209
+ 2,
2210
+ (fallbackHash + timestamp + random).padEnd(64, "0")
2211
+ ];
2280
2212
  }
2281
- return result;
2282
- };
2283
- }
2213
+ });
2214
+ })();
2284
2215
  }
2285
- function polyfillStringStartsWith() {
2286
- if (!String.prototype.startsWith) {
2287
- String.prototype.startsWith = function(search, pos) {
2288
- pos = !pos || pos < 0 ? 0 : +pos;
2289
- return this.substring(pos, pos + search.length) === search;
2290
- };
2216
+ function resolvePlayerIdentitySeed(clientInfo) {
2217
+ var nativeDeviceId = resolveNativeDeviceId();
2218
+ if (nativeDeviceId) {
2219
+ return "device:".concat(nativeDeviceId);
2291
2220
  }
2292
- }
2293
- function polyfillStringEndsWith() {
2294
- if (!String.prototype.endsWith) {
2295
- String.prototype.endsWith = function(search, length) {
2296
- if (length === void 0 || length > this.length) {
2297
- length = this.length;
2298
- }
2299
- return this.substring(length - search.length, length) === search;
2300
- };
2221
+ var persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
2222
+ if (persistedId) {
2223
+ return "persisted:".concat(persistedId);
2301
2224
  }
2225
+ return "fingerprint:".concat(JSON.stringify(clientInfo));
2302
2226
  }
2303
- function polyfillStringIncludes() {
2304
- if (!String.prototype.includes) {
2305
- String.prototype.includes = function(search, start) {
2306
- if (typeof start !== "number") {
2307
- start = 0;
2308
- }
2309
- if (start + search.length > this.length) {
2310
- return false;
2227
+ function getBrowserID(clientInfo) {
2228
+ return _async_to_generator(function() {
2229
+ return _ts_generator(this, function(_state) {
2230
+ switch(_state.label){
2231
+ case 0:
2232
+ if (cachedBrowserId) {
2233
+ return [
2234
+ 2,
2235
+ cachedBrowserId
2236
+ ];
2237
+ }
2238
+ return [
2239
+ 4,
2240
+ sha256Hex(resolvePlayerIdentitySeed(clientInfo))
2241
+ ];
2242
+ case 1:
2243
+ cachedBrowserId = _state.sent();
2244
+ return [
2245
+ 2,
2246
+ cachedBrowserId
2247
+ ];
2311
2248
  }
2312
- return this.indexOf(search, start) !== -1;
2313
- };
2314
- }
2249
+ });
2250
+ })();
2315
2251
  }
2316
- function initializePolyfills() {
2317
- polyfillObjectAssign();
2318
- polyfillArrayFrom();
2319
- polyfillStringStartsWith();
2320
- polyfillStringEndsWith();
2321
- polyfillStringIncludes();
2322
- polyfillURLSearchParams();
2323
- polyfillTextEncoder();
2324
- polyfillPromiseFinally();
2252
+ function canPublish(licenseKey) {
2253
+ return Boolean(isMQTTEnabled() && licenseKey);
2325
2254
  }
2326
- // src/utils/vastEnvironmentSignals.ts
2327
- var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
2328
- var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
2329
- var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
2330
- var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
2331
- var AIRY_APP_NAME = "AiryTV Movies & TV";
2332
- var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
2333
- var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
2334
- var LG_TEST_APP_ID = "com.hulu.plus";
2335
- var LG_TEST_APP_NAME = "Hulu";
2336
- var LG_TEST_CONTENT_URL = "https://www.hulu.com/live-tv";
2337
- var _lgTestDeviceId;
2338
- function getLgTestDeviceId() {
2339
- if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();
2340
- return _lgTestDeviceId;
2255
+ function buildPlayerMetricEvent() {
2256
+ return _async_to_generator(function() {
2257
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2258
+ var _arguments = arguments;
2259
+ return _ts_generator(this, function(_state) {
2260
+ switch(_state.label){
2261
+ case 0:
2262
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2263
+ clientInfo = getClientInfo();
2264
+ return [
2265
+ 4,
2266
+ getBrowserID(clientInfo)
2267
+ ];
2268
+ case 1:
2269
+ playerId = _state.sent();
2270
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2271
+ return [
2272
+ 2,
2273
+ _object_spread({
2274
+ player_id: playerId,
2275
+ device_type: clientInfo.deviceType,
2276
+ os: clientInfo.os.toLowerCase(),
2277
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2278
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2279
+ capture_at: captureAt
2280
+ }, context.inputStreamType ? {
2281
+ input_stream_type: context.inputStreamType
2282
+ } : {})
2283
+ ];
2284
+ }
2285
+ });
2286
+ }).apply(this, arguments);
2341
2287
  }
2342
- function isLgWebOS() {
2343
- if (typeof navigator === "undefined") return false;
2344
- return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);
2288
+ function publishTracking(licenseKey, channel, body) {
2289
+ ensureMQTTClient();
2290
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2345
2291
  }
2346
- function getDefaultAppId() {
2347
- if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
2348
- var ua = navigator.userAgent;
2349
- if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
2350
- if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
2351
- if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
2352
- return AIRY_ANDROID_APP_ID;
2292
+ function sendInitialTracking(_0) {
2293
+ return _async_to_generator(function(licenseKey) {
2294
+ var context, metricEvent, error;
2295
+ var _arguments = arguments;
2296
+ return _ts_generator(this, function(_state) {
2297
+ switch(_state.label){
2298
+ case 0:
2299
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2300
+ if (!canPublish(licenseKey)) return [
2301
+ 2
2302
+ ];
2303
+ _state.label = 1;
2304
+ case 1:
2305
+ _state.trys.push([
2306
+ 1,
2307
+ 3,
2308
+ ,
2309
+ 4
2310
+ ]);
2311
+ return [
2312
+ 4,
2313
+ buildPlayerMetricEvent(context, {
2314
+ adLoaded: false,
2315
+ adDetect: false
2316
+ })
2317
+ ];
2318
+ case 2:
2319
+ metricEvent = _state.sent();
2320
+ publishTracking(licenseKey, "metrics", {
2321
+ events: [
2322
+ metricEvent
2323
+ ]
2324
+ });
2325
+ return [
2326
+ 3,
2327
+ 4
2328
+ ];
2329
+ case 3:
2330
+ error = _state.sent();
2331
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2332
+ return [
2333
+ 3,
2334
+ 4
2335
+ ];
2336
+ case 4:
2337
+ return [
2338
+ 2
2339
+ ];
2340
+ }
2341
+ });
2342
+ }).apply(this, arguments);
2353
2343
  }
2354
- var DEVICE_ID_STORAGE_KEYS = [
2355
- "rdid",
2356
- "ifa",
2357
- "advertisingId",
2358
- "advertising_id",
2359
- "deviceAdvertisingId",
2360
- "aaid",
2361
- "adid",
2362
- "rida",
2363
- "tifa",
2364
- "lgudid"
2365
- ];
2366
- var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
2367
- "aaid",
2368
- "adid"
2369
- ]);
2370
- function resolveVastEnvironmentSignals(isCtv) {
2371
- var _ref;
2372
- var bridgeSignals = readNativeBridgeSignals();
2373
- var platformDevice = readPlatformNativeDeviceId();
2374
- var lg = isCtv && isLgWebOS();
2375
- var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
2376
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
2377
- var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
2378
- var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
2379
- if (isCtv) {
2380
- return _object_spread_props(_object_spread({
2381
- isCtv: true,
2382
- contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),
2383
- appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),
2384
- appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),
2385
- sessionId: getOrCreateCtvSessionId()
2386
- }, deviceId ? {
2387
- deviceId: deviceId
2388
- } : {}, deviceIdType ? {
2389
- deviceIdType: deviceIdType
2390
- } : {}, limitAdTracking != null ? {
2391
- limitAdTracking: limitAdTracking
2392
- } : {}), {
2393
- deviceTypeHint: 5
2344
+ function sendAdDetectTracking(_0, _1) {
2345
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2346
+ var context, error;
2347
+ var _arguments = arguments;
2348
+ return _ts_generator(this, function(_state) {
2349
+ switch(_state.label){
2350
+ case 0:
2351
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2352
+ _state.label = 1;
2353
+ case 1:
2354
+ _state.trys.push([
2355
+ 1,
2356
+ 3,
2357
+ ,
2358
+ 4
2359
+ ]);
2360
+ return [
2361
+ 4,
2362
+ sendHeartbeat(licenseKey, context, {
2363
+ adDetect: true,
2364
+ captureAt: adDetectInfo.timestamp
2365
+ })
2366
+ ];
2367
+ case 2:
2368
+ _state.sent();
2369
+ return [
2370
+ 3,
2371
+ 4
2372
+ ];
2373
+ case 3:
2374
+ error = _state.sent();
2375
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2376
+ return [
2377
+ 3,
2378
+ 4
2379
+ ];
2380
+ case 4:
2381
+ return [
2382
+ 2
2383
+ ];
2384
+ }
2394
2385
  });
2395
- }
2396
- return _object_spread({
2397
- isCtv: false
2398
- }, deviceId ? {
2399
- deviceId: deviceId
2400
- } : {}, deviceIdType ? {
2401
- deviceIdType: deviceIdType
2402
- } : {}, limitAdTracking != null ? {
2403
- limitAdTracking: limitAdTracking
2404
- } : {});
2386
+ }).apply(this, arguments);
2405
2387
  }
2406
- function inferDeviceIdType() {
2407
- if (typeof navigator === "undefined") {
2408
- return void 0;
2409
- }
2410
- var ua = navigator.userAgent;
2411
- if (/Roku/i.test(ua)) return "rida";
2412
- if (/Tizen|Samsung/i.test(ua)) return "tifa";
2413
- if (/AppleTV|Apple TV/i.test(ua)) return "tvOS";
2414
- if (/AFT|Fire TV|Amazon/i.test(ua)) return "afai";
2415
- if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return "lgudid";
2416
- if (/Android|Google TV/i.test(ua)) return "aaid";
2417
- if (/iPhone|iPad|iPod/i.test(ua)) return "idfa";
2418
- return void 0;
2388
+ function sendAdLoadedTracking(_0, _1) {
2389
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2390
+ var context, error;
2391
+ var _arguments = arguments;
2392
+ return _ts_generator(this, function(_state) {
2393
+ switch(_state.label){
2394
+ case 0:
2395
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2396
+ _state.label = 1;
2397
+ case 1:
2398
+ _state.trys.push([
2399
+ 1,
2400
+ 3,
2401
+ ,
2402
+ 4
2403
+ ]);
2404
+ return [
2405
+ 4,
2406
+ sendHeartbeat(licenseKey, context, {
2407
+ adLoaded: true,
2408
+ captureAt: adLoadedInfo.timestamp
2409
+ })
2410
+ ];
2411
+ case 2:
2412
+ _state.sent();
2413
+ return [
2414
+ 3,
2415
+ 4
2416
+ ];
2417
+ case 3:
2418
+ error = _state.sent();
2419
+ console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
2420
+ return [
2421
+ 3,
2422
+ 4
2423
+ ];
2424
+ case 4:
2425
+ return [
2426
+ 2
2427
+ ];
2428
+ }
2429
+ });
2430
+ }).apply(this, arguments);
2419
2431
  }
2420
- function isEquivalentDeviceIdType(tagType, runtimeType) {
2421
- if (!tagType || !runtimeType) return false;
2422
- var tag = tagType.toLowerCase();
2423
- var runtime = runtimeType.toLowerCase();
2424
- if (tag === runtime) return true;
2425
- return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);
2432
+ function sendAdImpressionTracking(_0, _1) {
2433
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2434
+ var context, metricEvent, error;
2435
+ var _arguments = arguments;
2436
+ return _ts_generator(this, function(_state) {
2437
+ switch(_state.label){
2438
+ case 0:
2439
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2440
+ if (!canPublish(licenseKey)) return [
2441
+ 2
2442
+ ];
2443
+ _state.label = 1;
2444
+ case 1:
2445
+ _state.trys.push([
2446
+ 1,
2447
+ 3,
2448
+ ,
2449
+ 4
2450
+ ]);
2451
+ return [
2452
+ 4,
2453
+ buildPlayerMetricEvent(context, {
2454
+ captureAt: adImpressionInfo.timestamp
2455
+ })
2456
+ ];
2457
+ case 2:
2458
+ metricEvent = _state.sent();
2459
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2460
+ publishTracking(licenseKey, "impressions", {
2461
+ events: [
2462
+ {
2463
+ player_id: metricEvent.player_id,
2464
+ ad_played_count: 1,
2465
+ ad_url: adImpressionInfo.adUrl,
2466
+ capture_at: adImpressionInfo.timestamp
2467
+ }
2468
+ ]
2469
+ });
2470
+ return [
2471
+ 3,
2472
+ 4
2473
+ ];
2474
+ case 3:
2475
+ error = _state.sent();
2476
+ console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2477
+ return [
2478
+ 3,
2479
+ 4
2480
+ ];
2481
+ case 4:
2482
+ return [
2483
+ 2
2484
+ ];
2485
+ }
2486
+ });
2487
+ }).apply(this, arguments);
2426
2488
  }
2427
- function getOrCreateCtvSessionId() {
2428
- var existing = readStoredString(CTV_SESSION_STORAGE_KEY);
2429
- if (existing) {
2430
- return existing;
2431
- }
2432
- var sessionId = createUuid();
2433
- try {
2434
- var _window_localStorage;
2435
- (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(CTV_SESSION_STORAGE_KEY, sessionId);
2436
- } catch (unused) {}
2437
- return sessionId;
2489
+ function sendHeartbeat(_0) {
2490
+ return _async_to_generator(function(licenseKey) {
2491
+ var context, flags, heartbeatData, error;
2492
+ var _arguments = arguments;
2493
+ return _ts_generator(this, function(_state) {
2494
+ switch(_state.label){
2495
+ case 0:
2496
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2497
+ if (!canPublish(licenseKey)) return [
2498
+ 2
2499
+ ];
2500
+ _state.label = 1;
2501
+ case 1:
2502
+ _state.trys.push([
2503
+ 1,
2504
+ 3,
2505
+ ,
2506
+ 4
2507
+ ]);
2508
+ return [
2509
+ 4,
2510
+ buildPlayerMetricEvent(context, flags)
2511
+ ];
2512
+ case 2:
2513
+ heartbeatData = _state.sent();
2514
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
2515
+ return [
2516
+ 3,
2517
+ 4
2518
+ ];
2519
+ case 3:
2520
+ error = _state.sent();
2521
+ console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2522
+ return [
2523
+ 3,
2524
+ 4
2525
+ ];
2526
+ case 4:
2527
+ return [
2528
+ 2
2529
+ ];
2530
+ }
2531
+ });
2532
+ }).apply(this, arguments);
2438
2533
  }
2439
- function createUuid() {
2440
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
2441
- return crypto.randomUUID();
2534
+ // src/utils/polyfills.ts
2535
+ function polyfillURLSearchParams() {
2536
+ if (typeof URLSearchParams !== "undefined") {
2537
+ return;
2442
2538
  }
2443
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(char) {
2444
- var value = Math.floor(Math.random() * 16);
2445
- var nibble = char === "x" ? value : value & 3 | 8;
2446
- return nibble.toString(16);
2447
- });
2448
- }
2449
- function readPlatformNativeDeviceId() {
2450
- if (typeof window === "undefined") return {};
2451
- try {
2452
- var _window_webapis;
2453
- var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
2454
- if (adinfo) {
2455
- var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
2456
- if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
2457
- var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
2458
- return _object_spread({
2459
- deviceId: tifa,
2460
- deviceIdType: "tifa"
2461
- }, typeof lat === "boolean" ? {
2462
- limitAdTracking: lat
2463
- } : {});
2539
+ var URLSearchParamsPolyfill = /*#__PURE__*/ function() {
2540
+ function URLSearchParamsPolyfill(init) {
2541
+ var _this = this;
2542
+ _class_call_check(this, URLSearchParamsPolyfill);
2543
+ this.params = /* @__PURE__ */ new Map();
2544
+ if (typeof init === "string") {
2545
+ this.parseQueryString(init);
2546
+ } else if (_instanceof(init, URLSearchParamsPolyfill)) {
2547
+ init.forEach(function(value, key) {
2548
+ _this.append(key, value);
2549
+ });
2464
2550
  }
2465
2551
  }
2466
- } catch (unused) {}
2467
- try {
2468
- var webOSDev = window.webOSDev;
2469
- if (webOSDev) {
2470
- var _webOSDev_lgudid;
2471
- var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
2472
- if (typeof lgudid === "string" && lgudid) {
2473
- if (isZeroedAdId(lgudid)) {
2474
- return {
2475
- deviceIdType: "lgudid",
2476
- limitAdTracking: true
2477
- };
2552
+ _create_class(URLSearchParamsPolyfill, [
2553
+ {
2554
+ key: "parseQueryString",
2555
+ value: function parseQueryString(query) {
2556
+ var _this = this;
2557
+ var cleanQuery = query.startsWith("?") ? query.slice(1) : query;
2558
+ if (!cleanQuery) return;
2559
+ cleanQuery.split("&").forEach(function(param) {
2560
+ var _param_split = _sliced_to_array(param.split("="), 2), key = _param_split[0], value = _param_split[1];
2561
+ if (key) {
2562
+ var decodedKey = _this.safeDecodeURIComponent(key);
2563
+ var decodedValue = value ? _this.safeDecodeURIComponent(value) : "";
2564
+ _this.append(decodedKey, decodedValue);
2565
+ }
2566
+ });
2478
2567
  }
2479
- if (!isMacroPlaceholder(lgudid)) {
2480
- return {
2481
- deviceId: lgudid,
2482
- deviceIdType: "lgudid",
2483
- limitAdTracking: false
2484
- };
2568
+ },
2569
+ {
2570
+ key: "safeDecodeURIComponent",
2571
+ value: function safeDecodeURIComponent(str) {
2572
+ try {
2573
+ return decodeURIComponent(str.replace(/\+/g, " "));
2574
+ } catch (e) {
2575
+ return str;
2576
+ }
2577
+ }
2578
+ },
2579
+ {
2580
+ key: "append",
2581
+ value: function append(name, value) {
2582
+ var values = this.params.get(name) || [];
2583
+ values.push(String(value));
2584
+ this.params.set(name, values);
2585
+ }
2586
+ },
2587
+ {
2588
+ key: "delete",
2589
+ value: function _delete(name) {
2590
+ this.params.delete(name);
2591
+ }
2592
+ },
2593
+ {
2594
+ key: "get",
2595
+ value: function get(name) {
2596
+ var values = this.params.get(name);
2597
+ return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;
2598
+ }
2599
+ },
2600
+ {
2601
+ key: "getAll",
2602
+ value: function getAll(name) {
2603
+ return this.params.get(name) || [];
2604
+ }
2605
+ },
2606
+ {
2607
+ key: "has",
2608
+ value: function has(name) {
2609
+ return this.params.has(name);
2610
+ }
2611
+ },
2612
+ {
2613
+ key: "set",
2614
+ value: function set(name, value) {
2615
+ this.params.set(name, [
2616
+ String(value)
2617
+ ]);
2618
+ }
2619
+ },
2620
+ {
2621
+ key: "forEach",
2622
+ value: function forEach(callback) {
2623
+ var _this = this;
2624
+ this.params.forEach(function(values, key) {
2625
+ values.forEach(function(value) {
2626
+ callback(value, key, _this);
2627
+ });
2628
+ });
2629
+ }
2630
+ },
2631
+ {
2632
+ key: "toString",
2633
+ value: function toString() {
2634
+ var parts = [];
2635
+ this.params.forEach(function(values, key) {
2636
+ values.forEach(function(value) {
2637
+ parts.push("".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(value)));
2638
+ });
2639
+ });
2640
+ return parts.join("&");
2485
2641
  }
2486
2642
  }
2487
- }
2488
- } catch (unused) {}
2489
- try {
2490
- var roku = window.Roku;
2491
- if (roku) {
2492
- var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
2493
- if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
2494
- return {
2495
- deviceId: rida,
2496
- deviceIdType: "rida",
2497
- limitAdTracking: false
2498
- };
2499
- }
2500
- }
2501
- } catch (unused) {}
2502
- return {};
2503
- }
2504
- var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
2505
- "38400000-8cf0-11bd-b23e-10b96e40000d",
2506
- "00000000-0000-0000-0000-000000000000"
2507
- ]);
2508
- function isMacroPlaceholder(value) {
2509
- var t = value.trim();
2510
- return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
2511
- }
2512
- function isZeroedAdId(value) {
2513
- return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
2514
- }
2515
- function readNativeBridgeSignals() {
2516
- if (typeof window === "undefined") {
2517
- return {};
2518
- }
2519
- var candidates = [
2520
- window.__STORMCLOUD_CTV_AD_INFO__,
2521
- window.__STORMCLOUD_CTV__,
2522
- window.stormcloudCtv,
2523
- window.AiryTV,
2524
- window.Android,
2525
- window.webOS,
2526
- window.tizen,
2527
- window.amazon
2528
- ].filter(Boolean);
2529
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2530
- try {
2531
- for(var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2532
- var source = _step.value;
2533
- var contentUrl = readBridgeValue(source, [
2534
- "contentUrl",
2535
- "url",
2536
- "videoUrl",
2537
- "canonicalUrl"
2538
- ]) || void 0;
2539
- var appId = readBridgeValue(source, [
2540
- "appId",
2541
- "msid",
2542
- "applicationId",
2543
- "packageName"
2544
- ]) || void 0;
2545
- var appName = readBridgeValue(source, [
2546
- "appName",
2547
- "an",
2548
- "applicationName"
2549
- ]) || void 0;
2550
- var deviceId = readBridgeValue(source, [
2551
- "rdid",
2552
- "ifa",
2553
- "advertisingId",
2554
- "adId",
2555
- "deviceId",
2556
- "lgudid",
2557
- "LGUDID",
2558
- "tifa",
2559
- "rida",
2560
- "afai",
2561
- "aaid"
2562
- ]) || void 0;
2563
- if (!contentUrl && !deviceId && !appId && !appName) continue;
2564
- var deviceIdType = readBridgeValue(source, [
2565
- "idtype",
2566
- "deviceIdType",
2567
- "advertisingIdType",
2568
- "idType"
2569
- ]) || inferDeviceIdType();
2570
- var limitAdTracking = readBridgeBoolean(source, [
2571
- "is_lat",
2572
- "limitAdTracking",
2573
- "limitedAdTracking",
2574
- "lat"
2575
- ]);
2576
- return _object_spread({}, contentUrl ? {
2577
- contentUrl: contentUrl
2578
- } : {}, appId ? {
2579
- appId: appId
2580
- } : {}, appName ? {
2581
- appName: appName
2582
- } : {}, deviceId ? {
2583
- deviceId: deviceId
2584
- } : {}, deviceId && deviceIdType ? {
2585
- deviceIdType: deviceIdType
2586
- } : {}, deviceId && limitAdTracking != null ? {
2587
- limitAdTracking: limitAdTracking
2588
- } : {});
2589
- }
2590
- } catch (err) {
2591
- _didIteratorError = true;
2592
- _iteratorError = err;
2593
- } finally{
2594
- try {
2595
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2596
- _iterator.return();
2597
- }
2598
- } finally{
2599
- if (_didIteratorError) {
2600
- throw _iteratorError;
2601
- }
2602
- }
2603
- }
2604
- return {};
2643
+ ]);
2644
+ return URLSearchParamsPolyfill;
2645
+ }();
2646
+ window.URLSearchParams = URLSearchParamsPolyfill;
2605
2647
  }
2606
- function readBridgeValue(source, keys) {
2607
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2608
- try {
2609
- for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2610
- var key = _step.value;
2611
- var value = source === null || source === void 0 ? void 0 : source[key];
2612
- if (typeof value === "string" && value) {
2613
- return value;
2614
- }
2615
- if (typeof value === "function") {
2616
- try {
2617
- var result = value.call(source);
2618
- if (typeof result === "string" && result) {
2619
- return result;
2620
- }
2621
- } catch (unused) {}
2622
- }
2648
+ function polyfillTextEncoder() {
2649
+ if (typeof TextEncoder !== "undefined") {
2650
+ return;
2651
+ }
2652
+ var TextEncoderPolyfill = /*#__PURE__*/ function() {
2653
+ function TextEncoderPolyfill() {
2654
+ _class_call_check(this, TextEncoderPolyfill);
2655
+ this.encoding = "utf-8";
2623
2656
  }
2624
- } catch (err) {
2625
- _didIteratorError = true;
2626
- _iteratorError = err;
2627
- } finally{
2628
- try {
2629
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2630
- _iterator.return();
2631
- }
2632
- } finally{
2633
- if (_didIteratorError) {
2634
- throw _iteratorError;
2657
+ _create_class(TextEncoderPolyfill, [
2658
+ {
2659
+ key: "encode",
2660
+ value: function encode(str) {
2661
+ var utf8 = [];
2662
+ for(var i = 0; i < str.length; i++){
2663
+ var charcode = str.charCodeAt(i);
2664
+ if (charcode < 128) {
2665
+ utf8.push(charcode);
2666
+ } else if (charcode < 2048) {
2667
+ utf8.push(192 | charcode >> 6, 128 | charcode & 63);
2668
+ } else if (charcode < 55296 || charcode >= 57344) {
2669
+ utf8.push(224 | charcode >> 12, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2670
+ } else {
2671
+ i++;
2672
+ charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);
2673
+ utf8.push(240 | charcode >> 18, 128 | charcode >> 12 & 63, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2674
+ }
2675
+ }
2676
+ return new Uint8Array(utf8);
2677
+ }
2635
2678
  }
2636
- }
2679
+ ]);
2680
+ return TextEncoderPolyfill;
2681
+ }();
2682
+ window.TextEncoder = TextEncoderPolyfill;
2683
+ }
2684
+ function polyfillPromiseFinally() {
2685
+ if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
2686
+ Promise.prototype.finally = function(callback) {
2687
+ var constructor = this.constructor;
2688
+ return this.then(function(value) {
2689
+ return constructor.resolve(callback()).then(function() {
2690
+ return value;
2691
+ });
2692
+ }, function(reason) {
2693
+ return constructor.resolve(callback()).then(function() {
2694
+ throw reason;
2695
+ });
2696
+ });
2697
+ };
2637
2698
  }
2638
- return void 0;
2639
2699
  }
2640
- function readBridgeBoolean(source, keys) {
2641
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2642
- try {
2643
- for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2644
- var key = _step.value;
2645
- var value = source === null || source === void 0 ? void 0 : source[key];
2646
- var normalized = normalizeBoolean(value);
2647
- if (normalized != null) {
2648
- return normalized;
2649
- }
2650
- if (typeof value === "function") {
2651
- try {
2652
- var result = normalizeBoolean(value.call(source));
2653
- if (result != null) {
2654
- return result;
2655
- }
2656
- } catch (unused) {}
2700
+ function polyfillObjectAssign() {
2701
+ if (typeof Object.assign !== "function") {
2702
+ Object.assign = function(target) {
2703
+ for(var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
2704
+ sources[_key - 1] = arguments[_key];
2657
2705
  }
2658
- }
2659
- } catch (err) {
2660
- _didIteratorError = true;
2661
- _iteratorError = err;
2662
- } finally{
2663
- try {
2664
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2665
- _iterator.return();
2706
+ if (target == null) {
2707
+ throw new TypeError("Cannot convert undefined or null to object");
2666
2708
  }
2667
- } finally{
2668
- if (_didIteratorError) {
2669
- throw _iteratorError;
2709
+ var to = Object(target);
2710
+ for(var i = 0; i < sources.length; i++){
2711
+ var nextSource = sources[i];
2712
+ if (nextSource != null) {
2713
+ for(var nextKey in nextSource){
2714
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
2715
+ to[nextKey] = nextSource[nextKey];
2716
+ }
2717
+ }
2718
+ }
2670
2719
  }
2671
- }
2720
+ return to;
2721
+ };
2672
2722
  }
2673
- return void 0;
2674
2723
  }
2675
- function readStoredDeviceId() {
2676
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2677
- try {
2678
- for(var _iterator = DEVICE_ID_STORAGE_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2679
- var key = _step.value;
2680
- var value = readStoredString(key);
2681
- if (value) {
2682
- return value;
2683
- }
2684
- }
2685
- } catch (err) {
2686
- _didIteratorError = true;
2687
- _iteratorError = err;
2688
- } finally{
2689
- try {
2690
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2691
- _iterator.return();
2724
+ function polyfillArrayFrom() {
2725
+ if (!Array.from) {
2726
+ Array.from = function(arrayLike, mapFn, thisArg) {
2727
+ var items = Object(arrayLike);
2728
+ if (arrayLike == null) {
2729
+ throw new TypeError("Array.from requires an array-like object");
2692
2730
  }
2693
- } finally{
2694
- if (_didIteratorError) {
2695
- throw _iteratorError;
2731
+ var len = items.length >>> 0;
2732
+ var result = new Array(len);
2733
+ for(var i = 0; i < len; i++){
2734
+ if (mapFn) {
2735
+ result[i] = mapFn.call(thisArg, items[i], i);
2736
+ } else {
2737
+ result[i] = items[i];
2738
+ }
2696
2739
  }
2697
- }
2740
+ return result;
2741
+ };
2698
2742
  }
2699
- return void 0;
2700
2743
  }
2701
- function readStoredString(key) {
2702
- if (typeof window === "undefined") {
2703
- return void 0;
2704
- }
2705
- try {
2706
- var _window_localStorage;
2707
- var value = (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.getItem(key);
2708
- return value || void 0;
2709
- } catch (unused) {
2710
- return void 0;
2744
+ function polyfillStringStartsWith() {
2745
+ if (!String.prototype.startsWith) {
2746
+ String.prototype.startsWith = function(search, pos) {
2747
+ pos = !pos || pos < 0 ? 0 : +pos;
2748
+ return this.substring(pos, pos + search.length) === search;
2749
+ };
2711
2750
  }
2712
2751
  }
2713
- function readStoredLimitAdTracking() {
2714
- return normalizeBoolean(readStoredString("limitAdTracking") || readStoredString("limitedAdTracking") || readStoredString("is_lat"));
2715
- }
2716
- function normalizeBoolean(value) {
2717
- if (typeof value === "boolean") {
2718
- return value;
2719
- }
2720
- if (typeof value === "number") {
2721
- return value === 1;
2752
+ function polyfillStringEndsWith() {
2753
+ if (!String.prototype.endsWith) {
2754
+ String.prototype.endsWith = function(search, length) {
2755
+ if (length === void 0 || length > this.length) {
2756
+ length = this.length;
2757
+ }
2758
+ return this.substring(length - search.length, length) === search;
2759
+ };
2722
2760
  }
2723
- if (typeof value === "string") {
2724
- var normalized = value.toLowerCase();
2725
- if (normalized === "1" || normalized === "true" || normalized === "yes") {
2726
- return true;
2727
- }
2728
- if (normalized === "0" || normalized === "false" || normalized === "no") {
2729
- return false;
2730
- }
2761
+ }
2762
+ function polyfillStringIncludes() {
2763
+ if (!String.prototype.includes) {
2764
+ String.prototype.includes = function(search, start) {
2765
+ if (typeof start !== "number") {
2766
+ start = 0;
2767
+ }
2768
+ if (start + search.length > this.length) {
2769
+ return false;
2770
+ }
2771
+ return this.indexOf(search, start) !== -1;
2772
+ };
2731
2773
  }
2732
- return void 0;
2774
+ }
2775
+ function initializePolyfills() {
2776
+ polyfillObjectAssign();
2777
+ polyfillArrayFrom();
2778
+ polyfillStringStartsWith();
2779
+ polyfillStringEndsWith();
2780
+ polyfillStringIncludes();
2781
+ polyfillURLSearchParams();
2782
+ polyfillTextEncoder();
2783
+ polyfillPromiseFinally();
2733
2784
  }
2734
2785
  // src/utils/vastMacros.ts
2735
2786
  var UNEXPANDED_MACRO_PATTERN = /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/;