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.
package/lib/index.cjs CHANGED
@@ -1769,1175 +1769,1226 @@ function disconnectMQTT() {
1769
1769
  status = "disconnected";
1770
1770
  }
1771
1771
  }
1772
- // src/utils/tracking.ts
1773
- var cachedBrowserId = null;
1774
- function getClientInfo() {
1775
- var _screen, _screen1, _screen2, _screen3, _screen_orientation, _screen4, _screen5, _window, _window1, _window_screen_orientation, _window_screen, _navigator_languages;
1772
+ // src/utils/vastEnvironmentSignals.ts
1773
+ var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
1774
+ var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
1775
+ var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
1776
+ var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
1777
+ var AIRY_APP_NAME = "AiryTV Movies & TV";
1778
+ var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
1779
+ var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
1780
+ var PLAYER_ID_STORAGE_KEY = "stormcloud.player.id";
1781
+ var LG_TEST_APP_ID = "com.hulu.plus";
1782
+ var LG_TEST_APP_NAME = "Hulu";
1783
+ var LG_TEST_CONTENT_URL = "https://www.hulu.com/live-tv";
1784
+ var _lgTestDeviceId;
1785
+ function getLgTestDeviceId() {
1786
+ if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();
1787
+ return _lgTestDeviceId;
1788
+ }
1789
+ function isLgWebOS() {
1790
+ if (typeof navigator === "undefined") return false;
1791
+ return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);
1792
+ }
1793
+ function getDefaultAppId() {
1794
+ if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
1776
1795
  var ua = navigator.userAgent;
1777
- var platform = navigator.platform;
1778
- var vendor = navigator.vendor || "";
1779
- var maxTouchPoints = navigator.maxTouchPoints || 0;
1780
- var memory = navigator.deviceMemory || null;
1781
- var hardwareConcurrency = navigator.hardwareConcurrency || 1;
1782
- var screenInfo = {
1783
- width: (_screen = screen) === null || _screen === void 0 ? void 0 : _screen.width,
1784
- height: (_screen1 = screen) === null || _screen1 === void 0 ? void 0 : _screen1.height,
1785
- availWidth: (_screen2 = screen) === null || _screen2 === void 0 ? void 0 : _screen2.availWidth,
1786
- availHeight: (_screen3 = screen) === null || _screen3 === void 0 ? void 0 : _screen3.availHeight,
1787
- orientation: ((_screen4 = screen) === null || _screen4 === void 0 ? void 0 : (_screen_orientation = _screen4.orientation) === null || _screen_orientation === void 0 ? void 0 : _screen_orientation.type) || "",
1788
- pixelDepth: (_screen5 = screen) === null || _screen5 === void 0 ? void 0 : _screen5.pixelDepth
1789
- };
1790
- var deviceType = "desktop";
1791
- var brand = "Unknown";
1792
- var os = "Unknown";
1793
- var model = "";
1794
- var isSmartTV = false;
1795
- var isAndroid = false;
1796
- var isWebView = false;
1797
- var isWebApp = false;
1798
- if (ua.includes("Web0S")) {
1799
- brand = "LG";
1800
- os = "webOS";
1801
- isSmartTV = true;
1802
- deviceType = "tv";
1803
- var webosMatch = ua.match(/Web0S\/([^\s]+)/);
1804
- model = webosMatch ? "webOS ".concat(webosMatch[1]) : "webOS TV";
1805
- } else if (ua.includes("Tizen")) {
1806
- brand = "Samsung";
1807
- os = "Tizen";
1808
- isSmartTV = true;
1809
- deviceType = "tv";
1810
- var tizenMatch = ua.match(/Tizen\/([^\s]+)/);
1811
- var tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? "Smart TV" : "";
1812
- model = tizenMatch ? "Tizen ".concat(tizenMatch[1], " ").concat(tvMatch).trim() : "Tizen TV";
1813
- } else if (ua.includes("Philips")) {
1814
- brand = "Philips";
1815
- os = "Saphi";
1816
- isSmartTV = true;
1817
- deviceType = "tv";
1818
- } else if (ua.includes("Sharp") || ua.includes("AQUOS")) {
1819
- brand = "Sharp";
1820
- os = "Android TV";
1821
- isSmartTV = true;
1822
- deviceType = "tv";
1823
- } else if (ua.includes("Android") && (ua.includes("Sony") || vendor.includes("Sony"))) {
1824
- brand = "Sony";
1825
- os = "Android TV";
1826
- isSmartTV = true;
1827
- deviceType = "tv";
1828
- } else if (ua.includes("Android") && (ua.includes("NetCast") || ua.includes("LG"))) {
1829
- brand = "LG";
1830
- os = "Android TV";
1831
- isSmartTV = true;
1832
- deviceType = "tv";
1833
- } else if (ua.includes(" Roku") || ua.includes("Roku/")) {
1834
- brand = "Roku";
1835
- os = "Roku OS";
1836
- isSmartTV = true;
1837
- deviceType = "tv";
1838
- } else if (ua.includes("AppleTV")) {
1839
- brand = "Apple";
1840
- os = "tvOS";
1841
- isSmartTV = true;
1842
- deviceType = "tv";
1796
+ if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
1797
+ if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
1798
+ if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
1799
+ return AIRY_ANDROID_APP_ID;
1800
+ }
1801
+ var DEVICE_ID_STORAGE_KEYS = [
1802
+ "rdid",
1803
+ "ifa",
1804
+ "advertisingId",
1805
+ "advertising_id",
1806
+ "deviceAdvertisingId",
1807
+ "aaid",
1808
+ "adid",
1809
+ "rida",
1810
+ "tifa",
1811
+ "lgudid"
1812
+ ];
1813
+ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
1814
+ "aaid",
1815
+ "adid"
1816
+ ]);
1817
+ function resolveVastEnvironmentSignals(isCtv) {
1818
+ var _ref;
1819
+ var bridgeSignals = readNativeBridgeSignals();
1820
+ var platformDevice = readPlatformNativeDeviceId();
1821
+ var lg = isCtv && isLgWebOS();
1822
+ var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
1823
+ var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
1824
+ var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
1825
+ var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
1826
+ if (isCtv) {
1827
+ return _object_spread_props(_object_spread({
1828
+ isCtv: true,
1829
+ contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),
1830
+ appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),
1831
+ appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),
1832
+ sessionId: getOrCreateCtvSessionId()
1833
+ }, deviceId ? {
1834
+ deviceId: deviceId
1835
+ } : {}, deviceIdType ? {
1836
+ deviceIdType: deviceIdType
1837
+ } : {}, limitAdTracking != null ? {
1838
+ limitAdTracking: limitAdTracking
1839
+ } : {}), {
1840
+ deviceTypeHint: 5
1841
+ });
1843
1842
  }
1844
- if (ua.includes("Android")) {
1845
- isAndroid = true;
1846
- os = "Android";
1847
- deviceType = /Mobile/.test(ua) ? "mobile" : "tablet";
1848
- if (ua.includes("Android") && (maxTouchPoints === 0 || ua.includes("Google TV") || ua.includes("XiaoMi"))) {
1849
- deviceType = "tv";
1850
- isSmartTV = true;
1851
- brand = brand === "Unknown" ? "Android TV" : brand;
1852
- }
1853
- var androidModelMatch = ua.match(/\(([^)]*Android[^)]*)\)/);
1854
- if (androidModelMatch && androidModelMatch[1]) {
1855
- model = androidModelMatch[1];
1856
- }
1843
+ return _object_spread({
1844
+ isCtv: false
1845
+ }, deviceId ? {
1846
+ deviceId: deviceId
1847
+ } : {}, deviceIdType ? {
1848
+ deviceIdType: deviceIdType
1849
+ } : {}, limitAdTracking != null ? {
1850
+ limitAdTracking: limitAdTracking
1851
+ } : {});
1852
+ }
1853
+ function inferDeviceIdType() {
1854
+ if (typeof navigator === "undefined") {
1855
+ return void 0;
1857
1856
  }
1858
- if (/iPad|iPhone|iPod/.test(ua)) {
1859
- os = "iOS";
1860
- deviceType = "mobile";
1861
- brand = "Apple";
1862
- if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {
1863
- deviceType = "tablet";
1864
- }
1857
+ var ua = navigator.userAgent;
1858
+ if (/Roku/i.test(ua)) return "rida";
1859
+ if (/Tizen|Samsung/i.test(ua)) return "tifa";
1860
+ if (/AppleTV|Apple TV/i.test(ua)) return "tvOS";
1861
+ if (/AFT|Fire TV|Amazon/i.test(ua)) return "afai";
1862
+ if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return "lgudid";
1863
+ if (/Android|Google TV/i.test(ua)) return "aaid";
1864
+ if (/iPhone|iPad|iPod/i.test(ua)) return "idfa";
1865
+ return void 0;
1866
+ }
1867
+ function isEquivalentDeviceIdType(tagType, runtimeType) {
1868
+ if (!tagType || !runtimeType) return false;
1869
+ var tag = tagType.toLowerCase();
1870
+ var runtime = runtimeType.toLowerCase();
1871
+ if (tag === runtime) return true;
1872
+ return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);
1873
+ }
1874
+ function resolveNativeDeviceId() {
1875
+ var bridgeSignals = readNativeBridgeSignals();
1876
+ var platformDevice = readPlatformNativeDeviceId();
1877
+ var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;
1878
+ if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {
1879
+ return void 0;
1865
1880
  }
1866
- if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {
1867
- if (ua.includes("Windows")) {
1868
- os = "Windows";
1869
- deviceType = "desktop";
1870
- } else if (ua.includes("Mac") && !/iPhone/.test(ua)) {
1871
- os = "macOS";
1872
- deviceType = "desktop";
1873
- if (maxTouchPoints > 1) deviceType = "tablet";
1874
- } else if (ua.includes("Linux")) {
1875
- os = "Linux";
1876
- deviceType = "desktop";
1877
- }
1881
+ return deviceId;
1882
+ }
1883
+ function getOrCreateStoredUuid(storageKey) {
1884
+ if (typeof window === "undefined") {
1885
+ return void 0;
1878
1886
  }
1879
- if (brand === "Unknown") {
1880
- if (vendor.includes("Google") || ua.includes("Chrome")) brand = "Google";
1881
- if (vendor.includes("Apple")) brand = "Apple";
1882
- if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
1887
+ var existing = readStoredString(storageKey);
1888
+ if (existing) {
1889
+ return existing;
1883
1890
  }
1884
- isWebView = /wv|WebView|Linux; U;/.test(ua);
1885
- if (((_window = window) === null || _window === void 0 ? void 0 : _window.outerHeight) === 0 && ((_window1 = window) === null || _window1 === void 0 ? void 0 : _window1.outerWidth) === 0) {
1886
- isWebView = true;
1891
+ var id = createUuid();
1892
+ try {
1893
+ var _window_localStorage;
1894
+ (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(storageKey, id);
1895
+ } catch (unused) {}
1896
+ return id;
1897
+ }
1898
+ function getOrCreateCtvSessionId() {
1899
+ var existing = readStoredString(CTV_SESSION_STORAGE_KEY);
1900
+ if (existing) {
1901
+ return existing;
1887
1902
  }
1888
- 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;
1889
- return {
1890
- brand: brand,
1891
- os: os,
1892
- model: model || ua.substring(0, 50) + "...",
1893
- deviceType: deviceType,
1894
- isSmartTV: isSmartTV,
1895
- isAndroid: isAndroid,
1896
- isWebView: isWebView,
1897
- isWebApp: isWebApp,
1898
- domain: window.location.hostname,
1899
- origin: window.location.origin,
1900
- path: window.location.pathname,
1901
- userAgent: ua,
1902
- vendor: vendor,
1903
- platform: platform,
1904
- screen: screenInfo,
1905
- hardwareConcurrency: hardwareConcurrency,
1906
- deviceMemory: memory,
1907
- maxTouchPoints: maxTouchPoints,
1908
- language: navigator.language,
1909
- languages: ((_navigator_languages = navigator.languages) === null || _navigator_languages === void 0 ? void 0 : _navigator_languages.join(",")) || "",
1910
- cookieEnabled: navigator.cookieEnabled,
1911
- doNotTrack: navigator.doNotTrack || "",
1912
- referrer: document.referrer,
1913
- visibilityState: document.visibilityState
1914
- };
1903
+ var sessionId = createUuid();
1904
+ try {
1905
+ var _window_localStorage;
1906
+ (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(CTV_SESSION_STORAGE_KEY, sessionId);
1907
+ } catch (unused) {}
1908
+ return sessionId;
1915
1909
  }
1916
- function getBrowserID(clientInfo) {
1917
- return _async_to_generator(function() {
1918
- var _crypto_subtle, fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashHex, unused, hash, i1, char, fallbackHash, timestamp, random;
1919
- return _ts_generator(this, function(_state) {
1920
- switch(_state.label){
1921
- case 0:
1922
- if (cachedBrowserId) {
1923
- return [
1924
- 2,
1925
- cachedBrowserId
1926
- ];
1927
- }
1928
- fingerprintString = JSON.stringify(clientInfo);
1929
- if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
1930
- 3,
1931
- 5
1932
- ];
1933
- _state.label = 1;
1934
- case 1:
1935
- _state.trys.push([
1936
- 1,
1937
- 4,
1938
- ,
1939
- 5
1940
- ]);
1941
- return [
1942
- 4,
1943
- crypto.subtle.digest("SHA-256", new Uint8Array([
1944
- 1,
1945
- 2,
1946
- 3
1947
- ]))
1948
- ];
1949
- case 2:
1950
- _state.sent();
1951
- if (typeof TextEncoder !== "undefined") {
1952
- encodedData = new TextEncoder().encode(fingerprintString);
1953
- } else {
1954
- utf8 = unescape(encodeURIComponent(fingerprintString));
1955
- buffer = new Uint8Array(utf8.length);
1956
- for(i = 0; i < utf8.length; i++){
1957
- buffer[i] = utf8.charCodeAt(i);
1958
- }
1959
- encodedData = buffer;
1960
- }
1961
- return [
1962
- 4,
1963
- crypto.subtle.digest("SHA-256", encodedData)
1964
- ];
1965
- case 3:
1966
- hashBuffer = _state.sent();
1967
- hashHex = Array.from(new Uint8Array(hashBuffer)).map(function(b) {
1968
- return b.toString(16).padStart(2, "0");
1969
- }).join("");
1970
- cachedBrowserId = hashHex;
1971
- return [
1972
- 2,
1973
- hashHex
1974
- ];
1975
- case 4:
1976
- unused = _state.sent();
1977
- console.warn("[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash");
1978
- return [
1979
- 3,
1980
- 5
1981
- ];
1982
- case 5:
1983
- hash = 0;
1984
- for(i1 = 0; i1 < fingerprintString.length; i1++){
1985
- char = fingerprintString.charCodeAt(i1);
1986
- hash = (hash << 5) - hash + char;
1987
- hash = hash & hash;
1988
- }
1989
- fallbackHash = Math.abs(hash).toString(16).padStart(8, "0");
1990
- timestamp = Date.now().toString(16).padStart(12, "0");
1991
- random = Math.random().toString(16).substring(2, 14).padStart(12, "0");
1992
- cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, "0");
1993
- return [
1994
- 2,
1995
- cachedBrowserId
1996
- ];
1997
- }
1998
- });
1999
- })();
2000
- }
2001
- function canPublish(licenseKey) {
2002
- return Boolean(isMQTTEnabled() && licenseKey);
1910
+ function createUuid() {
1911
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
1912
+ return crypto.randomUUID();
1913
+ }
1914
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(char) {
1915
+ var value = Math.floor(Math.random() * 16);
1916
+ var nibble = char === "x" ? value : value & 3 | 8;
1917
+ return nibble.toString(16);
1918
+ });
2003
1919
  }
2004
- function buildPlayerMetricEvent() {
2005
- return _async_to_generator(function() {
2006
- var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2007
- var _arguments = arguments;
2008
- return _ts_generator(this, function(_state) {
2009
- switch(_state.label){
2010
- case 0:
2011
- context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2012
- clientInfo = getClientInfo();
2013
- return [
2014
- 4,
2015
- getBrowserID(clientInfo)
2016
- ];
2017
- case 1:
2018
- playerId = _state.sent();
2019
- captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2020
- return [
2021
- 2,
2022
- _object_spread({
2023
- player_id: playerId,
2024
- device_type: clientInfo.deviceType,
2025
- os: clientInfo.os.toLowerCase(),
2026
- ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2027
- ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2028
- capture_at: captureAt
2029
- }, context.inputStreamType ? {
2030
- input_stream_type: context.inputStreamType
2031
- } : {})
2032
- ];
1920
+ function readPlatformNativeDeviceId() {
1921
+ if (typeof window === "undefined") return {};
1922
+ try {
1923
+ var _window_webapis;
1924
+ var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
1925
+ if (adinfo) {
1926
+ var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
1927
+ if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
1928
+ var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
1929
+ return _object_spread({
1930
+ deviceId: tifa,
1931
+ deviceIdType: "tifa"
1932
+ }, typeof lat === "boolean" ? {
1933
+ limitAdTracking: lat
1934
+ } : {});
2033
1935
  }
2034
- });
2035
- }).apply(this, arguments);
1936
+ }
1937
+ } catch (unused) {}
1938
+ try {
1939
+ var webOSDev = window.webOSDev;
1940
+ if (webOSDev) {
1941
+ var _webOSDev_lgudid;
1942
+ var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
1943
+ if (typeof lgudid === "string" && lgudid) {
1944
+ if (isZeroedAdId(lgudid)) {
1945
+ return {
1946
+ deviceIdType: "lgudid",
1947
+ limitAdTracking: true
1948
+ };
1949
+ }
1950
+ if (!isMacroPlaceholder(lgudid)) {
1951
+ return {
1952
+ deviceId: lgudid,
1953
+ deviceIdType: "lgudid",
1954
+ limitAdTracking: false
1955
+ };
1956
+ }
1957
+ }
1958
+ }
1959
+ } catch (unused) {}
1960
+ try {
1961
+ var roku = window.Roku;
1962
+ if (roku) {
1963
+ var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
1964
+ if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
1965
+ return {
1966
+ deviceId: rida,
1967
+ deviceIdType: "rida",
1968
+ limitAdTracking: false
1969
+ };
1970
+ }
1971
+ }
1972
+ } catch (unused) {}
1973
+ return {};
2036
1974
  }
2037
- function publishTracking(licenseKey, channel, body) {
2038
- ensureMQTTClient();
2039
- publishMQTT(buildPlayerTopic(licenseKey, channel), body);
1975
+ var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
1976
+ "38400000-8cf0-11bd-b23e-10b96e40000d",
1977
+ "00000000-0000-0000-0000-000000000000"
1978
+ ]);
1979
+ function isMacroPlaceholder(value) {
1980
+ var t = value.trim();
1981
+ return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
2040
1982
  }
2041
- function sendInitialTracking(_0) {
2042
- return _async_to_generator(function(licenseKey) {
2043
- var context, metricEvent, error;
2044
- var _arguments = arguments;
2045
- return _ts_generator(this, function(_state) {
2046
- switch(_state.label){
2047
- case 0:
2048
- context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2049
- if (!canPublish(licenseKey)) return [
2050
- 2
2051
- ];
2052
- _state.label = 1;
2053
- case 1:
2054
- _state.trys.push([
2055
- 1,
2056
- 3,
2057
- ,
2058
- 4
2059
- ]);
2060
- return [
2061
- 4,
2062
- buildPlayerMetricEvent(context, {
2063
- adLoaded: false,
2064
- adDetect: false
2065
- })
2066
- ];
2067
- case 2:
2068
- metricEvent = _state.sent();
2069
- publishTracking(licenseKey, "metrics", {
2070
- events: [
2071
- metricEvent
2072
- ]
2073
- });
2074
- return [
2075
- 3,
2076
- 4
2077
- ];
2078
- case 3:
2079
- error = _state.sent();
2080
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2081
- return [
2082
- 3,
2083
- 4
2084
- ];
2085
- case 4:
2086
- return [
2087
- 2
2088
- ];
2089
- }
2090
- });
2091
- }).apply(this, arguments);
1983
+ function isZeroedAdId(value) {
1984
+ return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
2092
1985
  }
2093
- function sendAdDetectTracking(_0, _1) {
2094
- return _async_to_generator(function(licenseKey, adDetectInfo) {
2095
- var context, error;
2096
- var _arguments = arguments;
2097
- return _ts_generator(this, function(_state) {
2098
- switch(_state.label){
2099
- case 0:
2100
- context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2101
- _state.label = 1;
2102
- case 1:
2103
- _state.trys.push([
2104
- 1,
2105
- 3,
2106
- ,
2107
- 4
2108
- ]);
2109
- return [
2110
- 4,
2111
- sendHeartbeat(licenseKey, context, {
2112
- adDetect: true,
2113
- captureAt: adDetectInfo.timestamp
2114
- })
2115
- ];
2116
- case 2:
2117
- _state.sent();
2118
- return [
2119
- 3,
2120
- 4
2121
- ];
2122
- case 3:
2123
- error = _state.sent();
2124
- console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2125
- return [
2126
- 3,
2127
- 4
2128
- ];
2129
- case 4:
2130
- return [
2131
- 2
2132
- ];
1986
+ function readNativeBridgeSignals() {
1987
+ if (typeof window === "undefined") {
1988
+ return {};
1989
+ }
1990
+ var candidates = [
1991
+ window.__STORMCLOUD_CTV_AD_INFO__,
1992
+ window.__STORMCLOUD_CTV__,
1993
+ window.stormcloudCtv,
1994
+ window.AiryTV,
1995
+ window.Android,
1996
+ window.webOS,
1997
+ window.tizen,
1998
+ window.amazon
1999
+ ].filter(Boolean);
2000
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2001
+ try {
2002
+ for(var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2003
+ var source = _step.value;
2004
+ var contentUrl = readBridgeValue(source, [
2005
+ "contentUrl",
2006
+ "url",
2007
+ "videoUrl",
2008
+ "canonicalUrl"
2009
+ ]) || void 0;
2010
+ var appId = readBridgeValue(source, [
2011
+ "appId",
2012
+ "msid",
2013
+ "applicationId",
2014
+ "packageName"
2015
+ ]) || void 0;
2016
+ var appName = readBridgeValue(source, [
2017
+ "appName",
2018
+ "an",
2019
+ "applicationName"
2020
+ ]) || void 0;
2021
+ var deviceId = readBridgeValue(source, [
2022
+ "rdid",
2023
+ "ifa",
2024
+ "advertisingId",
2025
+ "adId",
2026
+ "deviceId",
2027
+ "lgudid",
2028
+ "LGUDID",
2029
+ "tifa",
2030
+ "rida",
2031
+ "afai",
2032
+ "aaid"
2033
+ ]) || void 0;
2034
+ if (!contentUrl && !deviceId && !appId && !appName) continue;
2035
+ var deviceIdType = readBridgeValue(source, [
2036
+ "idtype",
2037
+ "deviceIdType",
2038
+ "advertisingIdType",
2039
+ "idType"
2040
+ ]) || inferDeviceIdType();
2041
+ var limitAdTracking = readBridgeBoolean(source, [
2042
+ "is_lat",
2043
+ "limitAdTracking",
2044
+ "limitedAdTracking",
2045
+ "lat"
2046
+ ]);
2047
+ return _object_spread({}, contentUrl ? {
2048
+ contentUrl: contentUrl
2049
+ } : {}, appId ? {
2050
+ appId: appId
2051
+ } : {}, appName ? {
2052
+ appName: appName
2053
+ } : {}, deviceId ? {
2054
+ deviceId: deviceId
2055
+ } : {}, deviceId && deviceIdType ? {
2056
+ deviceIdType: deviceIdType
2057
+ } : {}, deviceId && limitAdTracking != null ? {
2058
+ limitAdTracking: limitAdTracking
2059
+ } : {});
2060
+ }
2061
+ } catch (err) {
2062
+ _didIteratorError = true;
2063
+ _iteratorError = err;
2064
+ } finally{
2065
+ try {
2066
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2067
+ _iterator.return();
2133
2068
  }
2134
- });
2135
- }).apply(this, arguments);
2069
+ } finally{
2070
+ if (_didIteratorError) {
2071
+ throw _iteratorError;
2072
+ }
2073
+ }
2074
+ }
2075
+ return {};
2136
2076
  }
2137
- function sendAdLoadedTracking(_0, _1) {
2138
- return _async_to_generator(function(licenseKey, adLoadedInfo) {
2139
- var context, error;
2140
- var _arguments = arguments;
2141
- return _ts_generator(this, function(_state) {
2142
- switch(_state.label){
2143
- case 0:
2144
- context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2145
- _state.label = 1;
2146
- case 1:
2147
- _state.trys.push([
2148
- 1,
2149
- 3,
2150
- ,
2151
- 4
2152
- ]);
2153
- return [
2154
- 4,
2155
- sendHeartbeat(licenseKey, context, {
2156
- adLoaded: true,
2157
- captureAt: adLoadedInfo.timestamp
2158
- })
2159
- ];
2160
- case 2:
2161
- _state.sent();
2162
- return [
2163
- 3,
2164
- 4
2165
- ];
2166
- case 3:
2167
- error = _state.sent();
2168
- console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
2169
- return [
2170
- 3,
2171
- 4
2172
- ];
2173
- case 4:
2174
- return [
2175
- 2
2176
- ];
2077
+ function readBridgeValue(source, keys) {
2078
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2079
+ try {
2080
+ for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2081
+ var key = _step.value;
2082
+ var value = source === null || source === void 0 ? void 0 : source[key];
2083
+ if (typeof value === "string" && value) {
2084
+ return value;
2177
2085
  }
2178
- });
2179
- }).apply(this, arguments);
2086
+ if (typeof value === "function") {
2087
+ try {
2088
+ var result = value.call(source);
2089
+ if (typeof result === "string" && result) {
2090
+ return result;
2091
+ }
2092
+ } catch (unused) {}
2093
+ }
2094
+ }
2095
+ } catch (err) {
2096
+ _didIteratorError = true;
2097
+ _iteratorError = err;
2098
+ } finally{
2099
+ try {
2100
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2101
+ _iterator.return();
2102
+ }
2103
+ } finally{
2104
+ if (_didIteratorError) {
2105
+ throw _iteratorError;
2106
+ }
2107
+ }
2108
+ }
2109
+ return void 0;
2110
+ }
2111
+ function readBridgeBoolean(source, keys) {
2112
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2113
+ try {
2114
+ for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2115
+ var key = _step.value;
2116
+ var value = source === null || source === void 0 ? void 0 : source[key];
2117
+ var normalized = normalizeBoolean(value);
2118
+ if (normalized != null) {
2119
+ return normalized;
2120
+ }
2121
+ if (typeof value === "function") {
2122
+ try {
2123
+ var result = normalizeBoolean(value.call(source));
2124
+ if (result != null) {
2125
+ return result;
2126
+ }
2127
+ } catch (unused) {}
2128
+ }
2129
+ }
2130
+ } catch (err) {
2131
+ _didIteratorError = true;
2132
+ _iteratorError = err;
2133
+ } finally{
2134
+ try {
2135
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2136
+ _iterator.return();
2137
+ }
2138
+ } finally{
2139
+ if (_didIteratorError) {
2140
+ throw _iteratorError;
2141
+ }
2142
+ }
2143
+ }
2144
+ return void 0;
2145
+ }
2146
+ function readStoredDeviceId() {
2147
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2148
+ try {
2149
+ for(var _iterator = DEVICE_ID_STORAGE_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2150
+ var key = _step.value;
2151
+ var value = readStoredString(key);
2152
+ if (value) {
2153
+ return value;
2154
+ }
2155
+ }
2156
+ } catch (err) {
2157
+ _didIteratorError = true;
2158
+ _iteratorError = err;
2159
+ } finally{
2160
+ try {
2161
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2162
+ _iterator.return();
2163
+ }
2164
+ } finally{
2165
+ if (_didIteratorError) {
2166
+ throw _iteratorError;
2167
+ }
2168
+ }
2169
+ }
2170
+ return void 0;
2171
+ }
2172
+ function readStoredString(key) {
2173
+ if (typeof window === "undefined") {
2174
+ return void 0;
2175
+ }
2176
+ try {
2177
+ var _window_localStorage;
2178
+ var value = (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.getItem(key);
2179
+ return value || void 0;
2180
+ } catch (unused) {
2181
+ return void 0;
2182
+ }
2183
+ }
2184
+ function readStoredLimitAdTracking() {
2185
+ return normalizeBoolean(readStoredString("limitAdTracking") || readStoredString("limitedAdTracking") || readStoredString("is_lat"));
2186
+ }
2187
+ function normalizeBoolean(value) {
2188
+ if (typeof value === "boolean") {
2189
+ return value;
2190
+ }
2191
+ if (typeof value === "number") {
2192
+ return value === 1;
2193
+ }
2194
+ if (typeof value === "string") {
2195
+ var normalized = value.toLowerCase();
2196
+ if (normalized === "1" || normalized === "true" || normalized === "yes") {
2197
+ return true;
2198
+ }
2199
+ if (normalized === "0" || normalized === "false" || normalized === "no") {
2200
+ return false;
2201
+ }
2202
+ }
2203
+ return void 0;
2204
+ }
2205
+ // src/utils/tracking.ts
2206
+ var cachedBrowserId = null;
2207
+ function getClientInfo() {
2208
+ var _screen, _screen1, _screen2, _screen3, _screen_orientation, _screen4, _screen5, _window, _window1, _window_screen_orientation, _window_screen, _navigator_languages;
2209
+ var ua = navigator.userAgent;
2210
+ var platform = navigator.platform;
2211
+ var vendor = navigator.vendor || "";
2212
+ var maxTouchPoints = navigator.maxTouchPoints || 0;
2213
+ var memory = navigator.deviceMemory || null;
2214
+ var hardwareConcurrency = navigator.hardwareConcurrency || 1;
2215
+ var screenInfo = {
2216
+ width: (_screen = screen) === null || _screen === void 0 ? void 0 : _screen.width,
2217
+ height: (_screen1 = screen) === null || _screen1 === void 0 ? void 0 : _screen1.height,
2218
+ availWidth: (_screen2 = screen) === null || _screen2 === void 0 ? void 0 : _screen2.availWidth,
2219
+ availHeight: (_screen3 = screen) === null || _screen3 === void 0 ? void 0 : _screen3.availHeight,
2220
+ orientation: ((_screen4 = screen) === null || _screen4 === void 0 ? void 0 : (_screen_orientation = _screen4.orientation) === null || _screen_orientation === void 0 ? void 0 : _screen_orientation.type) || "",
2221
+ pixelDepth: (_screen5 = screen) === null || _screen5 === void 0 ? void 0 : _screen5.pixelDepth
2222
+ };
2223
+ var deviceType = "desktop";
2224
+ var brand = "Unknown";
2225
+ var os = "Unknown";
2226
+ var model = "";
2227
+ var isSmartTV = false;
2228
+ var isAndroid = false;
2229
+ var isWebView = false;
2230
+ var isWebApp = false;
2231
+ if (ua.includes("Web0S")) {
2232
+ brand = "LG";
2233
+ os = "webOS";
2234
+ isSmartTV = true;
2235
+ deviceType = "tv";
2236
+ var webosMatch = ua.match(/Web0S\/([^\s]+)/);
2237
+ model = webosMatch ? "webOS ".concat(webosMatch[1]) : "webOS TV";
2238
+ } else if (ua.includes("Tizen")) {
2239
+ brand = "Samsung";
2240
+ os = "Tizen";
2241
+ isSmartTV = true;
2242
+ deviceType = "tv";
2243
+ var tizenMatch = ua.match(/Tizen\/([^\s]+)/);
2244
+ var tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? "Smart TV" : "";
2245
+ model = tizenMatch ? "Tizen ".concat(tizenMatch[1], " ").concat(tvMatch).trim() : "Tizen TV";
2246
+ } else if (ua.includes("Philips")) {
2247
+ brand = "Philips";
2248
+ os = "Saphi";
2249
+ isSmartTV = true;
2250
+ deviceType = "tv";
2251
+ } else if (ua.includes("Sharp") || ua.includes("AQUOS")) {
2252
+ brand = "Sharp";
2253
+ os = "Android TV";
2254
+ isSmartTV = true;
2255
+ deviceType = "tv";
2256
+ } else if (ua.includes("Android") && (ua.includes("Sony") || vendor.includes("Sony"))) {
2257
+ brand = "Sony";
2258
+ os = "Android TV";
2259
+ isSmartTV = true;
2260
+ deviceType = "tv";
2261
+ } else if (ua.includes("Android") && (ua.includes("NetCast") || ua.includes("LG"))) {
2262
+ brand = "LG";
2263
+ os = "Android TV";
2264
+ isSmartTV = true;
2265
+ deviceType = "tv";
2266
+ } else if (ua.includes(" Roku") || ua.includes("Roku/")) {
2267
+ brand = "Roku";
2268
+ os = "Roku OS";
2269
+ isSmartTV = true;
2270
+ deviceType = "tv";
2271
+ } else if (ua.includes("AppleTV")) {
2272
+ brand = "Apple";
2273
+ os = "tvOS";
2274
+ isSmartTV = true;
2275
+ deviceType = "tv";
2276
+ }
2277
+ if (ua.includes("Android")) {
2278
+ isAndroid = true;
2279
+ os = "Android";
2280
+ deviceType = /Mobile/.test(ua) ? "mobile" : "tablet";
2281
+ if (ua.includes("Android") && (maxTouchPoints === 0 || ua.includes("Google TV") || ua.includes("XiaoMi"))) {
2282
+ deviceType = "tv";
2283
+ isSmartTV = true;
2284
+ brand = brand === "Unknown" ? "Android TV" : brand;
2285
+ }
2286
+ var androidModelMatch = ua.match(/\(([^)]*Android[^)]*)\)/);
2287
+ if (androidModelMatch && androidModelMatch[1]) {
2288
+ model = androidModelMatch[1];
2289
+ }
2290
+ }
2291
+ if (/iPad|iPhone|iPod/.test(ua)) {
2292
+ os = "iOS";
2293
+ deviceType = "mobile";
2294
+ brand = "Apple";
2295
+ if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {
2296
+ deviceType = "tablet";
2297
+ }
2298
+ }
2299
+ if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {
2300
+ if (ua.includes("Windows")) {
2301
+ os = "Windows";
2302
+ deviceType = "desktop";
2303
+ } else if (ua.includes("Mac") && !/iPhone/.test(ua)) {
2304
+ os = "macOS";
2305
+ deviceType = "desktop";
2306
+ if (maxTouchPoints > 1) deviceType = "tablet";
2307
+ } else if (ua.includes("Linux")) {
2308
+ os = "Linux";
2309
+ deviceType = "desktop";
2310
+ }
2311
+ }
2312
+ if (brand === "Unknown") {
2313
+ if (vendor.includes("Google") || ua.includes("Chrome")) brand = "Google";
2314
+ if (vendor.includes("Apple")) brand = "Apple";
2315
+ if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
2316
+ }
2317
+ isWebView = /wv|WebView|Linux; U;/.test(ua);
2318
+ if (((_window = window) === null || _window === void 0 ? void 0 : _window.outerHeight) === 0 && ((_window1 = window) === null || _window1 === void 0 ? void 0 : _window1.outerWidth) === 0) {
2319
+ isWebView = true;
2320
+ }
2321
+ 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;
2322
+ return {
2323
+ brand: brand,
2324
+ os: os,
2325
+ model: model || ua.substring(0, 50) + "...",
2326
+ deviceType: deviceType,
2327
+ isSmartTV: isSmartTV,
2328
+ isAndroid: isAndroid,
2329
+ isWebView: isWebView,
2330
+ isWebApp: isWebApp,
2331
+ domain: window.location.hostname,
2332
+ origin: window.location.origin,
2333
+ path: window.location.pathname,
2334
+ userAgent: ua,
2335
+ vendor: vendor,
2336
+ platform: platform,
2337
+ screen: screenInfo,
2338
+ hardwareConcurrency: hardwareConcurrency,
2339
+ deviceMemory: memory,
2340
+ maxTouchPoints: maxTouchPoints,
2341
+ language: navigator.language,
2342
+ languages: ((_navigator_languages = navigator.languages) === null || _navigator_languages === void 0 ? void 0 : _navigator_languages.join(",")) || "",
2343
+ cookieEnabled: navigator.cookieEnabled,
2344
+ doNotTrack: navigator.doNotTrack || "",
2345
+ referrer: document.referrer,
2346
+ visibilityState: document.visibilityState
2347
+ };
2180
2348
  }
2181
- function sendAdImpressionTracking(_0, _1) {
2182
- return _async_to_generator(function(licenseKey, adImpressionInfo) {
2183
- var context, metricEvent, error;
2184
- var _arguments = arguments;
2349
+ function sha256Hex(input) {
2350
+ return _async_to_generator(function() {
2351
+ var _crypto_subtle, encodedData, utf8, buffer, i, hashBuffer, unused, hash, i1, char, fallbackHash, timestamp, random;
2185
2352
  return _ts_generator(this, function(_state) {
2186
2353
  switch(_state.label){
2187
2354
  case 0:
2188
- context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2189
- if (!canPublish(licenseKey)) return [
2190
- 2
2191
- ];
2192
- _state.label = 1;
2193
- case 1:
2194
- _state.trys.push([
2195
- 1,
2196
- 3,
2197
- ,
2198
- 4
2199
- ]);
2200
- return [
2201
- 4,
2202
- buildPlayerMetricEvent(context, {
2203
- captureAt: adImpressionInfo.timestamp
2204
- })
2205
- ];
2206
- case 2:
2207
- metricEvent = _state.sent();
2208
- publishTracking(licenseKey, "heartbeat", metricEvent);
2209
- publishTracking(licenseKey, "impressions", {
2210
- events: [
2211
- {
2212
- player_id: metricEvent.player_id,
2213
- ad_played_count: 1,
2214
- ad_url: adImpressionInfo.adUrl,
2215
- capture_at: adImpressionInfo.timestamp
2216
- }
2217
- ]
2218
- });
2219
- return [
2220
- 3,
2221
- 4
2222
- ];
2223
- case 3:
2224
- error = _state.sent();
2225
- console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2226
- return [
2355
+ if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
2227
2356
  3,
2228
- 4
2229
- ];
2230
- case 4:
2231
- return [
2232
- 2
2233
- ];
2234
- }
2235
- });
2236
- }).apply(this, arguments);
2237
- }
2238
- function sendHeartbeat(_0) {
2239
- return _async_to_generator(function(licenseKey) {
2240
- var context, flags, heartbeatData, error;
2241
- var _arguments = arguments;
2242
- return _ts_generator(this, function(_state) {
2243
- switch(_state.label){
2244
- case 0:
2245
- context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2246
- if (!canPublish(licenseKey)) return [
2247
- 2
2357
+ 5
2248
2358
  ];
2249
2359
  _state.label = 1;
2250
2360
  case 1:
2251
2361
  _state.trys.push([
2252
2362
  1,
2253
- 3,
2363
+ 4,
2254
2364
  ,
2255
- 4
2365
+ 5
2256
2366
  ]);
2257
2367
  return [
2258
2368
  4,
2259
- buildPlayerMetricEvent(context, flags)
2369
+ crypto.subtle.digest("SHA-256", new Uint8Array([
2370
+ 1,
2371
+ 2,
2372
+ 3
2373
+ ]))
2260
2374
  ];
2261
2375
  case 2:
2262
- heartbeatData = _state.sent();
2263
- publishTracking(licenseKey, "heartbeat", heartbeatData);
2264
- return [
2265
- 3,
2266
- 4
2267
- ];
2268
- case 3:
2269
- error = _state.sent();
2270
- console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2271
- return [
2272
- 3,
2273
- 4
2274
- ];
2275
- case 4:
2276
- return [
2277
- 2
2278
- ];
2279
- }
2280
- });
2281
- }).apply(this, arguments);
2282
- }
2283
- // src/utils/polyfills.ts
2284
- function polyfillURLSearchParams() {
2285
- if (typeof URLSearchParams !== "undefined") {
2286
- return;
2287
- }
2288
- var URLSearchParamsPolyfill = /*#__PURE__*/ function() {
2289
- function URLSearchParamsPolyfill(init) {
2290
- var _this = this;
2291
- _class_call_check(this, URLSearchParamsPolyfill);
2292
- this.params = /* @__PURE__ */ new Map();
2293
- if (typeof init === "string") {
2294
- this.parseQueryString(init);
2295
- } else if (_instanceof(init, URLSearchParamsPolyfill)) {
2296
- init.forEach(function(value, key) {
2297
- _this.append(key, value);
2298
- });
2299
- }
2300
- }
2301
- _create_class(URLSearchParamsPolyfill, [
2302
- {
2303
- key: "parseQueryString",
2304
- value: function parseQueryString(query) {
2305
- var _this = this;
2306
- var cleanQuery = query.startsWith("?") ? query.slice(1) : query;
2307
- if (!cleanQuery) return;
2308
- cleanQuery.split("&").forEach(function(param) {
2309
- var _param_split = _sliced_to_array(param.split("="), 2), key = _param_split[0], value = _param_split[1];
2310
- if (key) {
2311
- var decodedKey = _this.safeDecodeURIComponent(key);
2312
- var decodedValue = value ? _this.safeDecodeURIComponent(value) : "";
2313
- _this.append(decodedKey, decodedValue);
2314
- }
2315
- });
2316
- }
2317
- },
2318
- {
2319
- key: "safeDecodeURIComponent",
2320
- value: function safeDecodeURIComponent(str) {
2321
- try {
2322
- return decodeURIComponent(str.replace(/\+/g, " "));
2323
- } catch (e) {
2324
- return str;
2325
- }
2326
- }
2327
- },
2328
- {
2329
- key: "append",
2330
- value: function append(name, value) {
2331
- var values = this.params.get(name) || [];
2332
- values.push(String(value));
2333
- this.params.set(name, values);
2334
- }
2335
- },
2336
- {
2337
- key: "delete",
2338
- value: function _delete(name) {
2339
- this.params.delete(name);
2340
- }
2341
- },
2342
- {
2343
- key: "get",
2344
- value: function get(name) {
2345
- var values = this.params.get(name);
2346
- return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;
2347
- }
2348
- },
2349
- {
2350
- key: "getAll",
2351
- value: function getAll(name) {
2352
- return this.params.get(name) || [];
2353
- }
2354
- },
2355
- {
2356
- key: "has",
2357
- value: function has(name) {
2358
- return this.params.has(name);
2359
- }
2360
- },
2361
- {
2362
- key: "set",
2363
- value: function set(name, value) {
2364
- this.params.set(name, [
2365
- String(value)
2366
- ]);
2367
- }
2368
- },
2369
- {
2370
- key: "forEach",
2371
- value: function forEach(callback) {
2372
- var _this = this;
2373
- this.params.forEach(function(values, key) {
2374
- values.forEach(function(value) {
2375
- callback(value, key, _this);
2376
- });
2377
- });
2378
- }
2379
- },
2380
- {
2381
- key: "toString",
2382
- value: function toString() {
2383
- var parts = [];
2384
- this.params.forEach(function(values, key) {
2385
- values.forEach(function(value) {
2386
- parts.push("".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(value)));
2387
- });
2388
- });
2389
- return parts.join("&");
2390
- }
2391
- }
2392
- ]);
2393
- return URLSearchParamsPolyfill;
2394
- }();
2395
- window.URLSearchParams = URLSearchParamsPolyfill;
2396
- }
2397
- function polyfillTextEncoder() {
2398
- if (typeof TextEncoder !== "undefined") {
2399
- return;
2400
- }
2401
- var TextEncoderPolyfill = /*#__PURE__*/ function() {
2402
- function TextEncoderPolyfill() {
2403
- _class_call_check(this, TextEncoderPolyfill);
2404
- this.encoding = "utf-8";
2405
- }
2406
- _create_class(TextEncoderPolyfill, [
2407
- {
2408
- key: "encode",
2409
- value: function encode(str) {
2410
- var utf8 = [];
2411
- for(var i = 0; i < str.length; i++){
2412
- var charcode = str.charCodeAt(i);
2413
- if (charcode < 128) {
2414
- utf8.push(charcode);
2415
- } else if (charcode < 2048) {
2416
- utf8.push(192 | charcode >> 6, 128 | charcode & 63);
2417
- } else if (charcode < 55296 || charcode >= 57344) {
2418
- utf8.push(224 | charcode >> 12, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2419
- } else {
2420
- i++;
2421
- charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);
2422
- utf8.push(240 | charcode >> 18, 128 | charcode >> 12 & 63, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2376
+ _state.sent();
2377
+ if (typeof TextEncoder !== "undefined") {
2378
+ encodedData = new TextEncoder().encode(input);
2379
+ } else {
2380
+ utf8 = unescape(encodeURIComponent(input));
2381
+ buffer = new Uint8Array(utf8.length);
2382
+ for(i = 0; i < utf8.length; i++){
2383
+ buffer[i] = utf8.charCodeAt(i);
2423
2384
  }
2385
+ encodedData = buffer;
2424
2386
  }
2425
- return new Uint8Array(utf8);
2426
- }
2427
- }
2428
- ]);
2429
- return TextEncoderPolyfill;
2430
- }();
2431
- window.TextEncoder = TextEncoderPolyfill;
2432
- }
2433
- function polyfillPromiseFinally() {
2434
- if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
2435
- Promise.prototype.finally = function(callback) {
2436
- var constructor = this.constructor;
2437
- return this.then(function(value) {
2438
- return constructor.resolve(callback()).then(function() {
2439
- return value;
2440
- });
2441
- }, function(reason) {
2442
- return constructor.resolve(callback()).then(function() {
2443
- throw reason;
2444
- });
2445
- });
2446
- };
2447
- }
2448
- }
2449
- function polyfillObjectAssign() {
2450
- if (typeof Object.assign !== "function") {
2451
- Object.assign = function(target) {
2452
- for(var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
2453
- sources[_key - 1] = arguments[_key];
2454
- }
2455
- if (target == null) {
2456
- throw new TypeError("Cannot convert undefined or null to object");
2457
- }
2458
- var to = Object(target);
2459
- for(var i = 0; i < sources.length; i++){
2460
- var nextSource = sources[i];
2461
- if (nextSource != null) {
2462
- for(var nextKey in nextSource){
2463
- if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
2464
- to[nextKey] = nextSource[nextKey];
2465
- }
2387
+ return [
2388
+ 4,
2389
+ crypto.subtle.digest("SHA-256", encodedData)
2390
+ ];
2391
+ case 3:
2392
+ hashBuffer = _state.sent();
2393
+ return [
2394
+ 2,
2395
+ Array.from(new Uint8Array(hashBuffer)).map(function(b) {
2396
+ return b.toString(16).padStart(2, "0");
2397
+ }).join("")
2398
+ ];
2399
+ case 4:
2400
+ unused = _state.sent();
2401
+ console.warn("[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash");
2402
+ return [
2403
+ 3,
2404
+ 5
2405
+ ];
2406
+ case 5:
2407
+ hash = 0;
2408
+ for(i1 = 0; i1 < input.length; i1++){
2409
+ char = input.charCodeAt(i1);
2410
+ hash = (hash << 5) - hash + char;
2411
+ hash = hash & hash;
2466
2412
  }
2467
- }
2468
- }
2469
- return to;
2470
- };
2471
- }
2472
- }
2473
- function polyfillArrayFrom() {
2474
- if (!Array.from) {
2475
- Array.from = function(arrayLike, mapFn, thisArg) {
2476
- var items = Object(arrayLike);
2477
- if (arrayLike == null) {
2478
- throw new TypeError("Array.from requires an array-like object");
2479
- }
2480
- var len = items.length >>> 0;
2481
- var result = new Array(len);
2482
- for(var i = 0; i < len; i++){
2483
- if (mapFn) {
2484
- result[i] = mapFn.call(thisArg, items[i], i);
2485
- } else {
2486
- result[i] = items[i];
2487
- }
2413
+ fallbackHash = Math.abs(hash).toString(16).padStart(8, "0");
2414
+ timestamp = Date.now().toString(16).padStart(12, "0");
2415
+ random = Math.random().toString(16).substring(2, 14).padStart(12, "0");
2416
+ return [
2417
+ 2,
2418
+ (fallbackHash + timestamp + random).padEnd(64, "0")
2419
+ ];
2488
2420
  }
2489
- return result;
2490
- };
2491
- }
2421
+ });
2422
+ })();
2492
2423
  }
2493
- function polyfillStringStartsWith() {
2494
- if (!String.prototype.startsWith) {
2495
- String.prototype.startsWith = function(search, pos) {
2496
- pos = !pos || pos < 0 ? 0 : +pos;
2497
- return this.substring(pos, pos + search.length) === search;
2498
- };
2424
+ function resolvePlayerIdentitySeed(clientInfo) {
2425
+ var nativeDeviceId = resolveNativeDeviceId();
2426
+ if (nativeDeviceId) {
2427
+ return "device:".concat(nativeDeviceId);
2499
2428
  }
2500
- }
2501
- function polyfillStringEndsWith() {
2502
- if (!String.prototype.endsWith) {
2503
- String.prototype.endsWith = function(search, length) {
2504
- if (length === void 0 || length > this.length) {
2505
- length = this.length;
2506
- }
2507
- return this.substring(length - search.length, length) === search;
2508
- };
2429
+ var persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
2430
+ if (persistedId) {
2431
+ return "persisted:".concat(persistedId);
2509
2432
  }
2433
+ return "fingerprint:".concat(JSON.stringify(clientInfo));
2510
2434
  }
2511
- function polyfillStringIncludes() {
2512
- if (!String.prototype.includes) {
2513
- String.prototype.includes = function(search, start) {
2514
- if (typeof start !== "number") {
2515
- start = 0;
2516
- }
2517
- if (start + search.length > this.length) {
2518
- return false;
2435
+ function getBrowserID(clientInfo) {
2436
+ return _async_to_generator(function() {
2437
+ return _ts_generator(this, function(_state) {
2438
+ switch(_state.label){
2439
+ case 0:
2440
+ if (cachedBrowserId) {
2441
+ return [
2442
+ 2,
2443
+ cachedBrowserId
2444
+ ];
2445
+ }
2446
+ return [
2447
+ 4,
2448
+ sha256Hex(resolvePlayerIdentitySeed(clientInfo))
2449
+ ];
2450
+ case 1:
2451
+ cachedBrowserId = _state.sent();
2452
+ return [
2453
+ 2,
2454
+ cachedBrowserId
2455
+ ];
2519
2456
  }
2520
- return this.indexOf(search, start) !== -1;
2521
- };
2522
- }
2457
+ });
2458
+ })();
2523
2459
  }
2524
- function initializePolyfills() {
2525
- polyfillObjectAssign();
2526
- polyfillArrayFrom();
2527
- polyfillStringStartsWith();
2528
- polyfillStringEndsWith();
2529
- polyfillStringIncludes();
2530
- polyfillURLSearchParams();
2531
- polyfillTextEncoder();
2532
- polyfillPromiseFinally();
2460
+ function canPublish(licenseKey) {
2461
+ return Boolean(isMQTTEnabled() && licenseKey);
2533
2462
  }
2534
- // src/utils/vastEnvironmentSignals.ts
2535
- var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
2536
- var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
2537
- var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
2538
- var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
2539
- var AIRY_APP_NAME = "AiryTV Movies & TV";
2540
- var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
2541
- var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
2542
- var LG_TEST_APP_ID = "com.hulu.plus";
2543
- var LG_TEST_APP_NAME = "Hulu";
2544
- var LG_TEST_CONTENT_URL = "https://www.hulu.com/live-tv";
2545
- var _lgTestDeviceId;
2546
- function getLgTestDeviceId() {
2547
- if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();
2548
- return _lgTestDeviceId;
2463
+ function buildPlayerMetricEvent() {
2464
+ return _async_to_generator(function() {
2465
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2466
+ var _arguments = arguments;
2467
+ return _ts_generator(this, function(_state) {
2468
+ switch(_state.label){
2469
+ case 0:
2470
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2471
+ clientInfo = getClientInfo();
2472
+ return [
2473
+ 4,
2474
+ getBrowserID(clientInfo)
2475
+ ];
2476
+ case 1:
2477
+ playerId = _state.sent();
2478
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2479
+ return [
2480
+ 2,
2481
+ _object_spread({
2482
+ player_id: playerId,
2483
+ device_type: clientInfo.deviceType,
2484
+ os: clientInfo.os.toLowerCase(),
2485
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2486
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2487
+ capture_at: captureAt
2488
+ }, context.inputStreamType ? {
2489
+ input_stream_type: context.inputStreamType
2490
+ } : {})
2491
+ ];
2492
+ }
2493
+ });
2494
+ }).apply(this, arguments);
2549
2495
  }
2550
- function isLgWebOS() {
2551
- if (typeof navigator === "undefined") return false;
2552
- return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);
2496
+ function publishTracking(licenseKey, channel, body) {
2497
+ ensureMQTTClient();
2498
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2553
2499
  }
2554
- function getDefaultAppId() {
2555
- if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
2556
- var ua = navigator.userAgent;
2557
- if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
2558
- if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
2559
- if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
2560
- return AIRY_ANDROID_APP_ID;
2500
+ function sendInitialTracking(_0) {
2501
+ return _async_to_generator(function(licenseKey) {
2502
+ var context, metricEvent, error;
2503
+ var _arguments = arguments;
2504
+ return _ts_generator(this, function(_state) {
2505
+ switch(_state.label){
2506
+ case 0:
2507
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2508
+ if (!canPublish(licenseKey)) return [
2509
+ 2
2510
+ ];
2511
+ _state.label = 1;
2512
+ case 1:
2513
+ _state.trys.push([
2514
+ 1,
2515
+ 3,
2516
+ ,
2517
+ 4
2518
+ ]);
2519
+ return [
2520
+ 4,
2521
+ buildPlayerMetricEvent(context, {
2522
+ adLoaded: false,
2523
+ adDetect: false
2524
+ })
2525
+ ];
2526
+ case 2:
2527
+ metricEvent = _state.sent();
2528
+ publishTracking(licenseKey, "metrics", {
2529
+ events: [
2530
+ metricEvent
2531
+ ]
2532
+ });
2533
+ return [
2534
+ 3,
2535
+ 4
2536
+ ];
2537
+ case 3:
2538
+ error = _state.sent();
2539
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2540
+ return [
2541
+ 3,
2542
+ 4
2543
+ ];
2544
+ case 4:
2545
+ return [
2546
+ 2
2547
+ ];
2548
+ }
2549
+ });
2550
+ }).apply(this, arguments);
2561
2551
  }
2562
- var DEVICE_ID_STORAGE_KEYS = [
2563
- "rdid",
2564
- "ifa",
2565
- "advertisingId",
2566
- "advertising_id",
2567
- "deviceAdvertisingId",
2568
- "aaid",
2569
- "adid",
2570
- "rida",
2571
- "tifa",
2572
- "lgudid"
2573
- ];
2574
- var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
2575
- "aaid",
2576
- "adid"
2577
- ]);
2578
- function resolveVastEnvironmentSignals(isCtv) {
2579
- var _ref;
2580
- var bridgeSignals = readNativeBridgeSignals();
2581
- var platformDevice = readPlatformNativeDeviceId();
2582
- var lg = isCtv && isLgWebOS();
2583
- var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
2584
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
2585
- var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
2586
- var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
2587
- if (isCtv) {
2588
- return _object_spread_props(_object_spread({
2589
- isCtv: true,
2590
- contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),
2591
- appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),
2592
- appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),
2593
- sessionId: getOrCreateCtvSessionId()
2594
- }, deviceId ? {
2595
- deviceId: deviceId
2596
- } : {}, deviceIdType ? {
2597
- deviceIdType: deviceIdType
2598
- } : {}, limitAdTracking != null ? {
2599
- limitAdTracking: limitAdTracking
2600
- } : {}), {
2601
- deviceTypeHint: 5
2552
+ function sendAdDetectTracking(_0, _1) {
2553
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2554
+ var context, error;
2555
+ var _arguments = arguments;
2556
+ return _ts_generator(this, function(_state) {
2557
+ switch(_state.label){
2558
+ case 0:
2559
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2560
+ _state.label = 1;
2561
+ case 1:
2562
+ _state.trys.push([
2563
+ 1,
2564
+ 3,
2565
+ ,
2566
+ 4
2567
+ ]);
2568
+ return [
2569
+ 4,
2570
+ sendHeartbeat(licenseKey, context, {
2571
+ adDetect: true,
2572
+ captureAt: adDetectInfo.timestamp
2573
+ })
2574
+ ];
2575
+ case 2:
2576
+ _state.sent();
2577
+ return [
2578
+ 3,
2579
+ 4
2580
+ ];
2581
+ case 3:
2582
+ error = _state.sent();
2583
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2584
+ return [
2585
+ 3,
2586
+ 4
2587
+ ];
2588
+ case 4:
2589
+ return [
2590
+ 2
2591
+ ];
2592
+ }
2602
2593
  });
2603
- }
2604
- return _object_spread({
2605
- isCtv: false
2606
- }, deviceId ? {
2607
- deviceId: deviceId
2608
- } : {}, deviceIdType ? {
2609
- deviceIdType: deviceIdType
2610
- } : {}, limitAdTracking != null ? {
2611
- limitAdTracking: limitAdTracking
2612
- } : {});
2594
+ }).apply(this, arguments);
2613
2595
  }
2614
- function inferDeviceIdType() {
2615
- if (typeof navigator === "undefined") {
2616
- return void 0;
2617
- }
2618
- var ua = navigator.userAgent;
2619
- if (/Roku/i.test(ua)) return "rida";
2620
- if (/Tizen|Samsung/i.test(ua)) return "tifa";
2621
- if (/AppleTV|Apple TV/i.test(ua)) return "tvOS";
2622
- if (/AFT|Fire TV|Amazon/i.test(ua)) return "afai";
2623
- if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return "lgudid";
2624
- if (/Android|Google TV/i.test(ua)) return "aaid";
2625
- if (/iPhone|iPad|iPod/i.test(ua)) return "idfa";
2626
- return void 0;
2596
+ function sendAdLoadedTracking(_0, _1) {
2597
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2598
+ var context, error;
2599
+ var _arguments = arguments;
2600
+ return _ts_generator(this, function(_state) {
2601
+ switch(_state.label){
2602
+ case 0:
2603
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2604
+ _state.label = 1;
2605
+ case 1:
2606
+ _state.trys.push([
2607
+ 1,
2608
+ 3,
2609
+ ,
2610
+ 4
2611
+ ]);
2612
+ return [
2613
+ 4,
2614
+ sendHeartbeat(licenseKey, context, {
2615
+ adLoaded: true,
2616
+ captureAt: adLoadedInfo.timestamp
2617
+ })
2618
+ ];
2619
+ case 2:
2620
+ _state.sent();
2621
+ return [
2622
+ 3,
2623
+ 4
2624
+ ];
2625
+ case 3:
2626
+ error = _state.sent();
2627
+ console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
2628
+ return [
2629
+ 3,
2630
+ 4
2631
+ ];
2632
+ case 4:
2633
+ return [
2634
+ 2
2635
+ ];
2636
+ }
2637
+ });
2638
+ }).apply(this, arguments);
2627
2639
  }
2628
- function isEquivalentDeviceIdType(tagType, runtimeType) {
2629
- if (!tagType || !runtimeType) return false;
2630
- var tag = tagType.toLowerCase();
2631
- var runtime = runtimeType.toLowerCase();
2632
- if (tag === runtime) return true;
2633
- return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);
2640
+ function sendAdImpressionTracking(_0, _1) {
2641
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2642
+ var context, metricEvent, error;
2643
+ var _arguments = arguments;
2644
+ return _ts_generator(this, function(_state) {
2645
+ switch(_state.label){
2646
+ case 0:
2647
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2648
+ if (!canPublish(licenseKey)) return [
2649
+ 2
2650
+ ];
2651
+ _state.label = 1;
2652
+ case 1:
2653
+ _state.trys.push([
2654
+ 1,
2655
+ 3,
2656
+ ,
2657
+ 4
2658
+ ]);
2659
+ return [
2660
+ 4,
2661
+ buildPlayerMetricEvent(context, {
2662
+ captureAt: adImpressionInfo.timestamp
2663
+ })
2664
+ ];
2665
+ case 2:
2666
+ metricEvent = _state.sent();
2667
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2668
+ publishTracking(licenseKey, "impressions", {
2669
+ events: [
2670
+ {
2671
+ player_id: metricEvent.player_id,
2672
+ ad_played_count: 1,
2673
+ ad_url: adImpressionInfo.adUrl,
2674
+ capture_at: adImpressionInfo.timestamp
2675
+ }
2676
+ ]
2677
+ });
2678
+ return [
2679
+ 3,
2680
+ 4
2681
+ ];
2682
+ case 3:
2683
+ error = _state.sent();
2684
+ console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2685
+ return [
2686
+ 3,
2687
+ 4
2688
+ ];
2689
+ case 4:
2690
+ return [
2691
+ 2
2692
+ ];
2693
+ }
2694
+ });
2695
+ }).apply(this, arguments);
2634
2696
  }
2635
- function getOrCreateCtvSessionId() {
2636
- var existing = readStoredString(CTV_SESSION_STORAGE_KEY);
2637
- if (existing) {
2638
- return existing;
2639
- }
2640
- var sessionId = createUuid();
2641
- try {
2642
- var _window_localStorage;
2643
- (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(CTV_SESSION_STORAGE_KEY, sessionId);
2644
- } catch (unused) {}
2645
- return sessionId;
2697
+ function sendHeartbeat(_0) {
2698
+ return _async_to_generator(function(licenseKey) {
2699
+ var context, flags, heartbeatData, error;
2700
+ var _arguments = arguments;
2701
+ return _ts_generator(this, function(_state) {
2702
+ switch(_state.label){
2703
+ case 0:
2704
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2705
+ if (!canPublish(licenseKey)) return [
2706
+ 2
2707
+ ];
2708
+ _state.label = 1;
2709
+ case 1:
2710
+ _state.trys.push([
2711
+ 1,
2712
+ 3,
2713
+ ,
2714
+ 4
2715
+ ]);
2716
+ return [
2717
+ 4,
2718
+ buildPlayerMetricEvent(context, flags)
2719
+ ];
2720
+ case 2:
2721
+ heartbeatData = _state.sent();
2722
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
2723
+ return [
2724
+ 3,
2725
+ 4
2726
+ ];
2727
+ case 3:
2728
+ error = _state.sent();
2729
+ console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2730
+ return [
2731
+ 3,
2732
+ 4
2733
+ ];
2734
+ case 4:
2735
+ return [
2736
+ 2
2737
+ ];
2738
+ }
2739
+ });
2740
+ }).apply(this, arguments);
2646
2741
  }
2647
- function createUuid() {
2648
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
2649
- return crypto.randomUUID();
2742
+ // src/utils/polyfills.ts
2743
+ function polyfillURLSearchParams() {
2744
+ if (typeof URLSearchParams !== "undefined") {
2745
+ return;
2650
2746
  }
2651
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(char) {
2652
- var value = Math.floor(Math.random() * 16);
2653
- var nibble = char === "x" ? value : value & 3 | 8;
2654
- return nibble.toString(16);
2655
- });
2656
- }
2657
- function readPlatformNativeDeviceId() {
2658
- if (typeof window === "undefined") return {};
2659
- try {
2660
- var _window_webapis;
2661
- var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
2662
- if (adinfo) {
2663
- var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
2664
- if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
2665
- var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
2666
- return _object_spread({
2667
- deviceId: tifa,
2668
- deviceIdType: "tifa"
2669
- }, typeof lat === "boolean" ? {
2670
- limitAdTracking: lat
2671
- } : {});
2747
+ var URLSearchParamsPolyfill = /*#__PURE__*/ function() {
2748
+ function URLSearchParamsPolyfill(init) {
2749
+ var _this = this;
2750
+ _class_call_check(this, URLSearchParamsPolyfill);
2751
+ this.params = /* @__PURE__ */ new Map();
2752
+ if (typeof init === "string") {
2753
+ this.parseQueryString(init);
2754
+ } else if (_instanceof(init, URLSearchParamsPolyfill)) {
2755
+ init.forEach(function(value, key) {
2756
+ _this.append(key, value);
2757
+ });
2672
2758
  }
2673
2759
  }
2674
- } catch (unused) {}
2675
- try {
2676
- var webOSDev = window.webOSDev;
2677
- if (webOSDev) {
2678
- var _webOSDev_lgudid;
2679
- var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
2680
- if (typeof lgudid === "string" && lgudid) {
2681
- if (isZeroedAdId(lgudid)) {
2682
- return {
2683
- deviceIdType: "lgudid",
2684
- limitAdTracking: true
2685
- };
2760
+ _create_class(URLSearchParamsPolyfill, [
2761
+ {
2762
+ key: "parseQueryString",
2763
+ value: function parseQueryString(query) {
2764
+ var _this = this;
2765
+ var cleanQuery = query.startsWith("?") ? query.slice(1) : query;
2766
+ if (!cleanQuery) return;
2767
+ cleanQuery.split("&").forEach(function(param) {
2768
+ var _param_split = _sliced_to_array(param.split("="), 2), key = _param_split[0], value = _param_split[1];
2769
+ if (key) {
2770
+ var decodedKey = _this.safeDecodeURIComponent(key);
2771
+ var decodedValue = value ? _this.safeDecodeURIComponent(value) : "";
2772
+ _this.append(decodedKey, decodedValue);
2773
+ }
2774
+ });
2686
2775
  }
2687
- if (!isMacroPlaceholder(lgudid)) {
2688
- return {
2689
- deviceId: lgudid,
2690
- deviceIdType: "lgudid",
2691
- limitAdTracking: false
2692
- };
2776
+ },
2777
+ {
2778
+ key: "safeDecodeURIComponent",
2779
+ value: function safeDecodeURIComponent(str) {
2780
+ try {
2781
+ return decodeURIComponent(str.replace(/\+/g, " "));
2782
+ } catch (e) {
2783
+ return str;
2784
+ }
2785
+ }
2786
+ },
2787
+ {
2788
+ key: "append",
2789
+ value: function append(name, value) {
2790
+ var values = this.params.get(name) || [];
2791
+ values.push(String(value));
2792
+ this.params.set(name, values);
2793
+ }
2794
+ },
2795
+ {
2796
+ key: "delete",
2797
+ value: function _delete(name) {
2798
+ this.params.delete(name);
2799
+ }
2800
+ },
2801
+ {
2802
+ key: "get",
2803
+ value: function get(name) {
2804
+ var values = this.params.get(name);
2805
+ return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;
2806
+ }
2807
+ },
2808
+ {
2809
+ key: "getAll",
2810
+ value: function getAll(name) {
2811
+ return this.params.get(name) || [];
2812
+ }
2813
+ },
2814
+ {
2815
+ key: "has",
2816
+ value: function has(name) {
2817
+ return this.params.has(name);
2818
+ }
2819
+ },
2820
+ {
2821
+ key: "set",
2822
+ value: function set(name, value) {
2823
+ this.params.set(name, [
2824
+ String(value)
2825
+ ]);
2826
+ }
2827
+ },
2828
+ {
2829
+ key: "forEach",
2830
+ value: function forEach(callback) {
2831
+ var _this = this;
2832
+ this.params.forEach(function(values, key) {
2833
+ values.forEach(function(value) {
2834
+ callback(value, key, _this);
2835
+ });
2836
+ });
2837
+ }
2838
+ },
2839
+ {
2840
+ key: "toString",
2841
+ value: function toString() {
2842
+ var parts = [];
2843
+ this.params.forEach(function(values, key) {
2844
+ values.forEach(function(value) {
2845
+ parts.push("".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(value)));
2846
+ });
2847
+ });
2848
+ return parts.join("&");
2693
2849
  }
2694
2850
  }
2695
- }
2696
- } catch (unused) {}
2697
- try {
2698
- var roku = window.Roku;
2699
- if (roku) {
2700
- var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
2701
- if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
2702
- return {
2703
- deviceId: rida,
2704
- deviceIdType: "rida",
2705
- limitAdTracking: false
2706
- };
2707
- }
2708
- }
2709
- } catch (unused) {}
2710
- return {};
2711
- }
2712
- var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
2713
- "38400000-8cf0-11bd-b23e-10b96e40000d",
2714
- "00000000-0000-0000-0000-000000000000"
2715
- ]);
2716
- function isMacroPlaceholder(value) {
2717
- var t = value.trim();
2718
- return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
2719
- }
2720
- function isZeroedAdId(value) {
2721
- return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
2722
- }
2723
- function readNativeBridgeSignals() {
2724
- if (typeof window === "undefined") {
2725
- return {};
2726
- }
2727
- var candidates = [
2728
- window.__STORMCLOUD_CTV_AD_INFO__,
2729
- window.__STORMCLOUD_CTV__,
2730
- window.stormcloudCtv,
2731
- window.AiryTV,
2732
- window.Android,
2733
- window.webOS,
2734
- window.tizen,
2735
- window.amazon
2736
- ].filter(Boolean);
2737
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2738
- try {
2739
- for(var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2740
- var source = _step.value;
2741
- var contentUrl = readBridgeValue(source, [
2742
- "contentUrl",
2743
- "url",
2744
- "videoUrl",
2745
- "canonicalUrl"
2746
- ]) || void 0;
2747
- var appId = readBridgeValue(source, [
2748
- "appId",
2749
- "msid",
2750
- "applicationId",
2751
- "packageName"
2752
- ]) || void 0;
2753
- var appName = readBridgeValue(source, [
2754
- "appName",
2755
- "an",
2756
- "applicationName"
2757
- ]) || void 0;
2758
- var deviceId = readBridgeValue(source, [
2759
- "rdid",
2760
- "ifa",
2761
- "advertisingId",
2762
- "adId",
2763
- "deviceId",
2764
- "lgudid",
2765
- "LGUDID",
2766
- "tifa",
2767
- "rida",
2768
- "afai",
2769
- "aaid"
2770
- ]) || void 0;
2771
- if (!contentUrl && !deviceId && !appId && !appName) continue;
2772
- var deviceIdType = readBridgeValue(source, [
2773
- "idtype",
2774
- "deviceIdType",
2775
- "advertisingIdType",
2776
- "idType"
2777
- ]) || inferDeviceIdType();
2778
- var limitAdTracking = readBridgeBoolean(source, [
2779
- "is_lat",
2780
- "limitAdTracking",
2781
- "limitedAdTracking",
2782
- "lat"
2783
- ]);
2784
- return _object_spread({}, contentUrl ? {
2785
- contentUrl: contentUrl
2786
- } : {}, appId ? {
2787
- appId: appId
2788
- } : {}, appName ? {
2789
- appName: appName
2790
- } : {}, deviceId ? {
2791
- deviceId: deviceId
2792
- } : {}, deviceId && deviceIdType ? {
2793
- deviceIdType: deviceIdType
2794
- } : {}, deviceId && limitAdTracking != null ? {
2795
- limitAdTracking: limitAdTracking
2796
- } : {});
2797
- }
2798
- } catch (err) {
2799
- _didIteratorError = true;
2800
- _iteratorError = err;
2801
- } finally{
2802
- try {
2803
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2804
- _iterator.return();
2805
- }
2806
- } finally{
2807
- if (_didIteratorError) {
2808
- throw _iteratorError;
2809
- }
2810
- }
2811
- }
2812
- return {};
2851
+ ]);
2852
+ return URLSearchParamsPolyfill;
2853
+ }();
2854
+ window.URLSearchParams = URLSearchParamsPolyfill;
2813
2855
  }
2814
- function readBridgeValue(source, keys) {
2815
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2816
- try {
2817
- for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2818
- var key = _step.value;
2819
- var value = source === null || source === void 0 ? void 0 : source[key];
2820
- if (typeof value === "string" && value) {
2821
- return value;
2822
- }
2823
- if (typeof value === "function") {
2824
- try {
2825
- var result = value.call(source);
2826
- if (typeof result === "string" && result) {
2827
- return result;
2828
- }
2829
- } catch (unused) {}
2830
- }
2856
+ function polyfillTextEncoder() {
2857
+ if (typeof TextEncoder !== "undefined") {
2858
+ return;
2859
+ }
2860
+ var TextEncoderPolyfill = /*#__PURE__*/ function() {
2861
+ function TextEncoderPolyfill() {
2862
+ _class_call_check(this, TextEncoderPolyfill);
2863
+ this.encoding = "utf-8";
2831
2864
  }
2832
- } catch (err) {
2833
- _didIteratorError = true;
2834
- _iteratorError = err;
2835
- } finally{
2836
- try {
2837
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2838
- _iterator.return();
2839
- }
2840
- } finally{
2841
- if (_didIteratorError) {
2842
- throw _iteratorError;
2865
+ _create_class(TextEncoderPolyfill, [
2866
+ {
2867
+ key: "encode",
2868
+ value: function encode(str) {
2869
+ var utf8 = [];
2870
+ for(var i = 0; i < str.length; i++){
2871
+ var charcode = str.charCodeAt(i);
2872
+ if (charcode < 128) {
2873
+ utf8.push(charcode);
2874
+ } else if (charcode < 2048) {
2875
+ utf8.push(192 | charcode >> 6, 128 | charcode & 63);
2876
+ } else if (charcode < 55296 || charcode >= 57344) {
2877
+ utf8.push(224 | charcode >> 12, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2878
+ } else {
2879
+ i++;
2880
+ charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);
2881
+ utf8.push(240 | charcode >> 18, 128 | charcode >> 12 & 63, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2882
+ }
2883
+ }
2884
+ return new Uint8Array(utf8);
2885
+ }
2843
2886
  }
2844
- }
2887
+ ]);
2888
+ return TextEncoderPolyfill;
2889
+ }();
2890
+ window.TextEncoder = TextEncoderPolyfill;
2891
+ }
2892
+ function polyfillPromiseFinally() {
2893
+ if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
2894
+ Promise.prototype.finally = function(callback) {
2895
+ var constructor = this.constructor;
2896
+ return this.then(function(value) {
2897
+ return constructor.resolve(callback()).then(function() {
2898
+ return value;
2899
+ });
2900
+ }, function(reason) {
2901
+ return constructor.resolve(callback()).then(function() {
2902
+ throw reason;
2903
+ });
2904
+ });
2905
+ };
2845
2906
  }
2846
- return void 0;
2847
2907
  }
2848
- function readBridgeBoolean(source, keys) {
2849
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2850
- try {
2851
- for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2852
- var key = _step.value;
2853
- var value = source === null || source === void 0 ? void 0 : source[key];
2854
- var normalized = normalizeBoolean(value);
2855
- if (normalized != null) {
2856
- return normalized;
2857
- }
2858
- if (typeof value === "function") {
2859
- try {
2860
- var result = normalizeBoolean(value.call(source));
2861
- if (result != null) {
2862
- return result;
2863
- }
2864
- } catch (unused) {}
2908
+ function polyfillObjectAssign() {
2909
+ if (typeof Object.assign !== "function") {
2910
+ Object.assign = function(target) {
2911
+ for(var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
2912
+ sources[_key - 1] = arguments[_key];
2865
2913
  }
2866
- }
2867
- } catch (err) {
2868
- _didIteratorError = true;
2869
- _iteratorError = err;
2870
- } finally{
2871
- try {
2872
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2873
- _iterator.return();
2914
+ if (target == null) {
2915
+ throw new TypeError("Cannot convert undefined or null to object");
2874
2916
  }
2875
- } finally{
2876
- if (_didIteratorError) {
2877
- throw _iteratorError;
2917
+ var to = Object(target);
2918
+ for(var i = 0; i < sources.length; i++){
2919
+ var nextSource = sources[i];
2920
+ if (nextSource != null) {
2921
+ for(var nextKey in nextSource){
2922
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
2923
+ to[nextKey] = nextSource[nextKey];
2924
+ }
2925
+ }
2926
+ }
2878
2927
  }
2879
- }
2928
+ return to;
2929
+ };
2880
2930
  }
2881
- return void 0;
2882
2931
  }
2883
- function readStoredDeviceId() {
2884
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2885
- try {
2886
- for(var _iterator = DEVICE_ID_STORAGE_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2887
- var key = _step.value;
2888
- var value = readStoredString(key);
2889
- if (value) {
2890
- return value;
2891
- }
2892
- }
2893
- } catch (err) {
2894
- _didIteratorError = true;
2895
- _iteratorError = err;
2896
- } finally{
2897
- try {
2898
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2899
- _iterator.return();
2932
+ function polyfillArrayFrom() {
2933
+ if (!Array.from) {
2934
+ Array.from = function(arrayLike, mapFn, thisArg) {
2935
+ var items = Object(arrayLike);
2936
+ if (arrayLike == null) {
2937
+ throw new TypeError("Array.from requires an array-like object");
2900
2938
  }
2901
- } finally{
2902
- if (_didIteratorError) {
2903
- throw _iteratorError;
2939
+ var len = items.length >>> 0;
2940
+ var result = new Array(len);
2941
+ for(var i = 0; i < len; i++){
2942
+ if (mapFn) {
2943
+ result[i] = mapFn.call(thisArg, items[i], i);
2944
+ } else {
2945
+ result[i] = items[i];
2946
+ }
2904
2947
  }
2905
- }
2948
+ return result;
2949
+ };
2906
2950
  }
2907
- return void 0;
2908
2951
  }
2909
- function readStoredString(key) {
2910
- if (typeof window === "undefined") {
2911
- return void 0;
2912
- }
2913
- try {
2914
- var _window_localStorage;
2915
- var value = (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.getItem(key);
2916
- return value || void 0;
2917
- } catch (unused) {
2918
- return void 0;
2952
+ function polyfillStringStartsWith() {
2953
+ if (!String.prototype.startsWith) {
2954
+ String.prototype.startsWith = function(search, pos) {
2955
+ pos = !pos || pos < 0 ? 0 : +pos;
2956
+ return this.substring(pos, pos + search.length) === search;
2957
+ };
2919
2958
  }
2920
2959
  }
2921
- function readStoredLimitAdTracking() {
2922
- return normalizeBoolean(readStoredString("limitAdTracking") || readStoredString("limitedAdTracking") || readStoredString("is_lat"));
2923
- }
2924
- function normalizeBoolean(value) {
2925
- if (typeof value === "boolean") {
2926
- return value;
2927
- }
2928
- if (typeof value === "number") {
2929
- return value === 1;
2960
+ function polyfillStringEndsWith() {
2961
+ if (!String.prototype.endsWith) {
2962
+ String.prototype.endsWith = function(search, length) {
2963
+ if (length === void 0 || length > this.length) {
2964
+ length = this.length;
2965
+ }
2966
+ return this.substring(length - search.length, length) === search;
2967
+ };
2930
2968
  }
2931
- if (typeof value === "string") {
2932
- var normalized = value.toLowerCase();
2933
- if (normalized === "1" || normalized === "true" || normalized === "yes") {
2934
- return true;
2935
- }
2936
- if (normalized === "0" || normalized === "false" || normalized === "no") {
2937
- return false;
2938
- }
2969
+ }
2970
+ function polyfillStringIncludes() {
2971
+ if (!String.prototype.includes) {
2972
+ String.prototype.includes = function(search, start) {
2973
+ if (typeof start !== "number") {
2974
+ start = 0;
2975
+ }
2976
+ if (start + search.length > this.length) {
2977
+ return false;
2978
+ }
2979
+ return this.indexOf(search, start) !== -1;
2980
+ };
2939
2981
  }
2940
- return void 0;
2982
+ }
2983
+ function initializePolyfills() {
2984
+ polyfillObjectAssign();
2985
+ polyfillArrayFrom();
2986
+ polyfillStringStartsWith();
2987
+ polyfillStringEndsWith();
2988
+ polyfillStringIncludes();
2989
+ polyfillURLSearchParams();
2990
+ polyfillTextEncoder();
2991
+ polyfillPromiseFinally();
2941
2992
  }
2942
2993
  // src/utils/vastMacros.ts
2943
2994
  var UNEXPANDED_MACRO_PATTERN = /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/;