adgent-sdk 0.1.3 → 0.1.4
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/dist/adgent-sdk.es.js +147 -91
- package/dist/adgent-sdk.umd.js +40 -20
- package/dist/index.d.ts +14 -0
- package/package.json +1 -1
package/dist/adgent-sdk.es.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { XMLParser as T } from "fast-xml-parser";
|
|
2
|
-
var
|
|
3
|
-
class
|
|
2
|
+
var c = /* @__PURE__ */ ((r) => (r.Idle = "idle", r.Loading = "loading", r.Ready = "ready", r.Playing = "playing", r.Paused = "paused", r.Completed = "completed", r.Error = "error", r.WaitingForInteraction = "waiting_for_interaction", r))(c || {}), p = /* @__PURE__ */ ((r) => (r[r.XML_PARSING_ERROR = 100] = "XML_PARSING_ERROR", r[r.VAST_SCHEMA_VALIDATION_ERROR = 101] = "VAST_SCHEMA_VALIDATION_ERROR", r[r.VAST_VERSION_NOT_SUPPORTED = 102] = "VAST_VERSION_NOT_SUPPORTED", r[r.GENERAL_WRAPPER_ERROR = 300] = "GENERAL_WRAPPER_ERROR", r[r.WRAPPER_TIMEOUT = 301] = "WRAPPER_TIMEOUT", r[r.WRAPPER_LIMIT_REACHED = 302] = "WRAPPER_LIMIT_REACHED", r[r.NO_VAST_RESPONSE = 303] = "NO_VAST_RESPONSE", r[r.GENERAL_LINEAR_ERROR = 400] = "GENERAL_LINEAR_ERROR", r[r.FILE_NOT_FOUND = 401] = "FILE_NOT_FOUND", r[r.MEDIA_TIMEOUT = 402] = "MEDIA_TIMEOUT", r[r.MEDIA_NOT_SUPPORTED = 403] = "MEDIA_NOT_SUPPORTED", r[r.GENERAL_COMPANION_ERROR = 600] = "GENERAL_COMPANION_ERROR", r[r.UNDEFINED_ERROR = 900] = "UNDEFINED_ERROR", r))(p || {}), P = Object.defineProperty, x = (r, e, t) => e in r ? P(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t, b = (r, e, t) => x(r, typeof e != "symbol" ? e + "" : e, t);
|
|
3
|
+
class A {
|
|
4
4
|
constructor(e = {}) {
|
|
5
|
-
|
|
5
|
+
b(this, "config"), b(this, "xmlParser");
|
|
6
6
|
var t, i, s, a;
|
|
7
7
|
this.config = {
|
|
8
8
|
maxWrapperDepth: (t = e.maxWrapperDepth) != null ? t : 5,
|
|
@@ -29,7 +29,7 @@ class O {
|
|
|
29
29
|
return {
|
|
30
30
|
success: !1,
|
|
31
31
|
error: {
|
|
32
|
-
code:
|
|
32
|
+
code: p.GENERAL_WRAPPER_ERROR,
|
|
33
33
|
message: i
|
|
34
34
|
}
|
|
35
35
|
};
|
|
@@ -46,8 +46,8 @@ class O {
|
|
|
46
46
|
this.log(`Fetching VAST (depth: ${t}): ${e}`);
|
|
47
47
|
const i = await this.fetchWithTimeout(e), s = this.parseXml(i), a = await Promise.all(
|
|
48
48
|
s.ads.map(async (n) => {
|
|
49
|
-
var
|
|
50
|
-
return (
|
|
49
|
+
var d;
|
|
50
|
+
return (d = n.wrapper) != null && d.vastAdTagURI ? this.resolveWrapper(n, t + 1) : n;
|
|
51
51
|
})
|
|
52
52
|
);
|
|
53
53
|
return {
|
|
@@ -278,8 +278,8 @@ class O {
|
|
|
278
278
|
const i = e.filter(
|
|
279
279
|
(n) => n.type.includes("mp4") || n.type.includes("video/mp4")
|
|
280
280
|
);
|
|
281
|
-
return [...i.length > 0 ? i : e].sort((n,
|
|
282
|
-
const
|
|
281
|
+
return [...i.length > 0 ? i : e].sort((n, d) => {
|
|
282
|
+
const f = n.bitrate || 0, v = d.bitrate || 0, w = n.height > 1080 ? 1e4 : 0, k = d.height > 1080 ? 1e4 : 0, R = Math.abs(f - t) + w, S = Math.abs(v - t) + k;
|
|
283
283
|
return R - S;
|
|
284
284
|
})[0] || null;
|
|
285
285
|
}
|
|
@@ -321,21 +321,21 @@ function g(r, e = {}) {
|
|
|
321
321
|
encodeURIComponent(e.assetUri)
|
|
322
322
|
)), e.contentPlayhead !== void 0 && (t = t.replace(
|
|
323
323
|
/\[CONTENTPLAYHEAD\]/g,
|
|
324
|
-
|
|
324
|
+
E(e.contentPlayhead)
|
|
325
325
|
)), e.adPlayhead !== void 0 && (t = t.replace(
|
|
326
326
|
/\[ADPLAYHEAD\]/g,
|
|
327
|
-
|
|
327
|
+
E(e.adPlayhead)
|
|
328
328
|
)), e.errorCode !== void 0 && (t = t.replace(/\[ERRORCODE\]/g, e.errorCode.toString())), e.breakPosition !== void 0 && (t = t.replace(
|
|
329
329
|
/\[BREAKPOSITION\]/g,
|
|
330
330
|
e.breakPosition.toString()
|
|
331
331
|
)), e.adType && (t = t.replace(/\[ADTYPE\]/g, e.adType)), t;
|
|
332
332
|
}
|
|
333
|
-
function
|
|
333
|
+
function E(r) {
|
|
334
334
|
const e = Math.floor(r / 3600), t = Math.floor(r % 3600 / 60), i = Math.floor(r % 60), s = Math.floor(r % 1 * 1e3);
|
|
335
335
|
return e.toString().padStart(2, "0") + ":" + t.toString().padStart(2, "0") + ":" + i.toString().padStart(2, "0") + "." + s.toString().padStart(3, "0");
|
|
336
336
|
}
|
|
337
|
-
var o = /* @__PURE__ */ ((r) => (r.WebOS = "webos", r.Tizen = "tizen", r.Vidaa = "vidaa", r.WhaleOS = "whaleos", r.FireTV = "firetv", r.Roku = "roku", r.Xbox = "xbox", r.PlayStation = "playstation", r.AndroidTV = "androidtv", r.Vizio = "vizio", r.Generic = "generic", r))(o || {}),
|
|
338
|
-
const
|
|
337
|
+
var o = /* @__PURE__ */ ((r) => (r.WebOS = "webos", r.Tizen = "tizen", r.Vidaa = "vidaa", r.WhaleOS = "whaleos", r.FireTV = "firetv", r.Roku = "roku", r.Xbox = "xbox", r.PlayStation = "playstation", r.AndroidTV = "androidtv", r.Vizio = "vizio", r.Generic = "generic", r))(o || {}), u = /* @__PURE__ */ ((r) => (r.Enter = "enter", r.Back = "back", r.Left = "left", r.Right = "right", r.Up = "up", r.Down = "down", r.Play = "play", r.Pause = "pause", r.PlayPause = "playPause", r.Stop = "stop", r.FastForward = "fastForward", r.Rewind = "rewind", r.Menu = "menu", r.Info = "info", r.Red = "red", r.Green = "green", r.Yellow = "yellow", r.Blue = "blue", r.ChannelUp = "channelUp", r.ChannelDown = "channelDown", r.VolumeUp = "volumeUp", r.VolumeDown = "volumeDown", r.Mute = "mute", r))(u || {});
|
|
338
|
+
const O = {
|
|
339
339
|
webos: {
|
|
340
340
|
13: "enter",
|
|
341
341
|
461: "back",
|
|
@@ -517,7 +517,7 @@ const I = {
|
|
|
517
517
|
/* Mute */
|
|
518
518
|
// M key
|
|
519
519
|
}
|
|
520
|
-
},
|
|
520
|
+
}, I = {
|
|
521
521
|
tizen: [
|
|
522
522
|
/Tizen/i,
|
|
523
523
|
/SMART-TV.*Samsung/i
|
|
@@ -572,10 +572,10 @@ const I = {
|
|
|
572
572
|
],
|
|
573
573
|
generic: []
|
|
574
574
|
};
|
|
575
|
-
var C = Object.defineProperty,
|
|
576
|
-
class
|
|
575
|
+
var C = Object.defineProperty, M = (r, e, t) => e in r ? C(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t, h = (r, e, t) => M(r, typeof e != "symbol" ? e + "" : e, t);
|
|
576
|
+
class N {
|
|
577
577
|
constructor() {
|
|
578
|
-
|
|
578
|
+
h(this, "platform"), h(this, "capabilities"), h(this, "deviceInfo"), h(this, "keyMap"), h(this, "reverseKeyMap"), this.platform = this.detectPlatform(), this.keyMap = O[this.platform], this.reverseKeyMap = this.buildReverseKeyMap(), this.capabilities = this.detectCapabilities(), this.deviceInfo = this.detectDeviceInfo();
|
|
579
579
|
}
|
|
580
580
|
/**
|
|
581
581
|
* Detect the current Smart TV platform using userAgent and global objects
|
|
@@ -588,7 +588,7 @@ class F {
|
|
|
588
588
|
return o.Tizen;
|
|
589
589
|
if (t.webOS || t.PalmSystem)
|
|
590
590
|
return o.WebOS;
|
|
591
|
-
for (const [i, s] of Object.entries(
|
|
591
|
+
for (const [i, s] of Object.entries(I))
|
|
592
592
|
if (i !== o.Generic) {
|
|
593
593
|
for (const a of s)
|
|
594
594
|
if (a.test(e))
|
|
@@ -862,15 +862,34 @@ class F {
|
|
|
862
862
|
};
|
|
863
863
|
}
|
|
864
864
|
}
|
|
865
|
+
/**
|
|
866
|
+
* Show debug message using platform-specific native notifications
|
|
867
|
+
* Falls back to console.log
|
|
868
|
+
*/
|
|
869
|
+
debug(e) {
|
|
870
|
+
if (console.log(`[Adgent] ${e}`), this.platform === o.WebOS && typeof window < "u") {
|
|
871
|
+
const t = window;
|
|
872
|
+
t.webOS && t.webOS.service && t.webOS.service.request("luna://com.webos.notification", {
|
|
873
|
+
method: "createToast",
|
|
874
|
+
parameters: {
|
|
875
|
+
message: `[Adgent] ${e}`
|
|
876
|
+
},
|
|
877
|
+
onSuccess: () => {
|
|
878
|
+
},
|
|
879
|
+
onFailure: () => {
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
}
|
|
865
884
|
}
|
|
866
885
|
let y = null;
|
|
867
886
|
function _() {
|
|
868
|
-
return y || (y = new
|
|
887
|
+
return y || (y = new N()), y;
|
|
869
888
|
}
|
|
870
|
-
var
|
|
889
|
+
var F = Object.defineProperty, D = (r, e, t) => e in r ? F(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t, m = (r, e, t) => D(r, typeof e != "symbol" ? e + "" : e, t);
|
|
871
890
|
class L {
|
|
872
891
|
constructor(e = [], t = {}) {
|
|
873
|
-
|
|
892
|
+
m(this, "config"), m(this, "trackingEvents"), m(this, "firedEvents"), m(this, "macroContext");
|
|
874
893
|
var i, s, a;
|
|
875
894
|
this.config = {
|
|
876
895
|
debug: (i = t.debug) != null ? i : !1,
|
|
@@ -983,7 +1002,7 @@ class L {
|
|
|
983
1002
|
this.config.debug && console.log(`[AdTracker] ${e}`);
|
|
984
1003
|
}
|
|
985
1004
|
}
|
|
986
|
-
var
|
|
1005
|
+
var U = Object.defineProperty, W = (r, e, t) => e in r ? U(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t, l = (r, e, t) => W(r, typeof e != "symbol" ? e + "" : e, t);
|
|
987
1006
|
const B = {
|
|
988
1007
|
targetBitrate: 2500,
|
|
989
1008
|
maxWrapperDepth: 5,
|
|
@@ -991,14 +1010,14 @@ const B = {
|
|
|
991
1010
|
debug: !1,
|
|
992
1011
|
skipButtonText: "Skip Ad"
|
|
993
1012
|
};
|
|
994
|
-
class
|
|
1013
|
+
class V {
|
|
995
1014
|
constructor(e) {
|
|
996
|
-
l(this, "config"), l(this, "platform"), l(this, "parser"), l(this, "videoElement", null), l(this, "overlayElement", null), l(this, "skipButtonElement", null), l(this, "tracker", null), l(this, "state"), l(this, "ads", []), l(this, "listeners", /* @__PURE__ */ new Set()), l(this, "quartilesFired", /* @__PURE__ */ new Set()), l(this, "boundKeyHandler", null), l(this, "focusTrap", null), this.config = { ...B, ...e }, this.platform = _(), this.parser = new
|
|
1015
|
+
l(this, "config"), l(this, "platform"), l(this, "parser"), l(this, "videoElement", null), l(this, "overlayElement", null), l(this, "skipButtonElement", null), l(this, "progressElement", null), l(this, "tracker", null), l(this, "state"), l(this, "ads", []), l(this, "listeners", /* @__PURE__ */ new Set()), l(this, "quartilesFired", /* @__PURE__ */ new Set()), l(this, "boundKeyHandler", null), l(this, "focusTrap", null), this.config = { ...B, ...e }, this.platform = _(), this.parser = new A({
|
|
997
1016
|
maxWrapperDepth: this.config.maxWrapperDepth,
|
|
998
1017
|
timeout: this.config.timeout,
|
|
999
1018
|
debug: this.config.debug
|
|
1000
1019
|
}), this.state = {
|
|
1001
|
-
status:
|
|
1020
|
+
status: c.Idle,
|
|
1002
1021
|
currentTime: 0,
|
|
1003
1022
|
duration: 0,
|
|
1004
1023
|
muted: !0,
|
|
@@ -1016,23 +1035,23 @@ class $ {
|
|
|
1016
1035
|
var e, t;
|
|
1017
1036
|
if (!this.config.container)
|
|
1018
1037
|
throw new Error("Container element not found");
|
|
1019
|
-
this.updateState({ status:
|
|
1038
|
+
this.updateState({ status: c.Loading });
|
|
1020
1039
|
try {
|
|
1021
1040
|
const i = await this.parser.parse(this.config.vastUrl);
|
|
1022
1041
|
if (!i.success || !i.response)
|
|
1023
1042
|
throw this.createError(
|
|
1024
|
-
((e = i.error) == null ? void 0 : e.code) ||
|
|
1043
|
+
((e = i.error) == null ? void 0 : e.code) || p.NO_VAST_RESPONSE,
|
|
1025
1044
|
((t = i.error) == null ? void 0 : t.message) || "Failed to parse VAST"
|
|
1026
1045
|
);
|
|
1027
1046
|
if (this.ads = i.response.ads, this.ads.length === 0)
|
|
1028
1047
|
throw this.createError(
|
|
1029
|
-
|
|
1048
|
+
p.NO_VAST_RESPONSE,
|
|
1030
1049
|
"No ads in VAST response"
|
|
1031
1050
|
);
|
|
1032
1051
|
const s = this.getFirstLinearCreative();
|
|
1033
1052
|
if (!s)
|
|
1034
1053
|
throw this.createError(
|
|
1035
|
-
|
|
1054
|
+
p.GENERAL_LINEAR_ERROR,
|
|
1036
1055
|
"No linear creative found"
|
|
1037
1056
|
);
|
|
1038
1057
|
const a = this.parser.selectBestMediaFile(
|
|
@@ -1041,14 +1060,14 @@ class $ {
|
|
|
1041
1060
|
);
|
|
1042
1061
|
if (!a)
|
|
1043
1062
|
throw this.createError(
|
|
1044
|
-
|
|
1063
|
+
p.FILE_NOT_FOUND,
|
|
1045
1064
|
"No suitable media file found"
|
|
1046
1065
|
);
|
|
1047
1066
|
this.updateState({ mediaFile: a });
|
|
1048
1067
|
const n = this.parser.aggregateTrackingEvents(this.ads);
|
|
1049
1068
|
this.tracker = new L(n, { debug: this.config.debug }), this.tracker.updateMacroContext({ assetUri: a.url }), this.createVideoElement(a), this.setupFocusManagement(), await this.attemptAutoplay();
|
|
1050
1069
|
} catch (i) {
|
|
1051
|
-
const s = i instanceof Error ? this.createError(
|
|
1070
|
+
const s = i instanceof Error ? this.createError(p.UNDEFINED_ERROR, i.message) : i;
|
|
1052
1071
|
this.handleError(s);
|
|
1053
1072
|
}
|
|
1054
1073
|
}
|
|
@@ -1068,9 +1087,11 @@ class $ {
|
|
|
1068
1087
|
*/
|
|
1069
1088
|
createVideoElement(e) {
|
|
1070
1089
|
const t = document.createElement("video"), i = this.platform.getVideoAttributes();
|
|
1071
|
-
Object.entries(i).forEach(([
|
|
1072
|
-
typeof
|
|
1073
|
-
}), t.src
|
|
1090
|
+
Object.entries(i).forEach(([a, n]) => {
|
|
1091
|
+
typeof n == "boolean" ? n && t.setAttribute(a, "") : t.setAttribute(a, n);
|
|
1092
|
+
}), t.removeAttribute("src"), t.innerHTML = "";
|
|
1093
|
+
const s = document.createElement("source");
|
|
1094
|
+
s.src = e.url, s.type = e.type || "video/mp4", t.appendChild(s), t.setAttribute("crossorigin", "anonymous"), t.style.cssText = `
|
|
1074
1095
|
width: 100%;
|
|
1075
1096
|
height: 100%;
|
|
1076
1097
|
object-fit: contain;
|
|
@@ -1078,25 +1099,25 @@ class $ {
|
|
|
1078
1099
|
`, t.addEventListener("loadedmetadata", () => {
|
|
1079
1100
|
this.updateState({
|
|
1080
1101
|
duration: t.duration,
|
|
1081
|
-
status:
|
|
1102
|
+
status: c.Ready
|
|
1082
1103
|
}), this.emit({ type: "loaded" });
|
|
1083
1104
|
}), t.addEventListener("timeupdate", () => {
|
|
1084
1105
|
this.handleTimeUpdate(t);
|
|
1085
1106
|
}), t.addEventListener("ended", () => {
|
|
1086
1107
|
this.handleComplete();
|
|
1087
1108
|
}), t.addEventListener("error", () => {
|
|
1088
|
-
const
|
|
1109
|
+
const a = t.error;
|
|
1089
1110
|
this.handleError(
|
|
1090
1111
|
this.createError(
|
|
1091
|
-
|
|
1092
|
-
(
|
|
1112
|
+
p.MEDIA_NOT_SUPPORTED,
|
|
1113
|
+
(a == null ? void 0 : a.message) || "Video playback error"
|
|
1093
1114
|
)
|
|
1094
1115
|
);
|
|
1095
1116
|
}), t.addEventListener("play", () => {
|
|
1096
|
-
this.updateState({ status:
|
|
1117
|
+
this.updateState({ status: c.Playing });
|
|
1097
1118
|
}), t.addEventListener("pause", () => {
|
|
1098
|
-
var
|
|
1099
|
-
this.state.status !==
|
|
1119
|
+
var a;
|
|
1120
|
+
this.state.status !== c.Completed && (this.updateState({ status: c.Paused }), this.emit({ type: "pause" }), (a = this.tracker) == null || a.track("pause"));
|
|
1100
1121
|
}), this.config.container.appendChild(t), this.videoElement = t, this.log(`Video element created with src: ${e.url}`);
|
|
1101
1122
|
}
|
|
1102
1123
|
/**
|
|
@@ -1115,7 +1136,7 @@ class $ {
|
|
|
1115
1136
|
* Show interactive overlay for manual ad start (autoplay fallback)
|
|
1116
1137
|
*/
|
|
1117
1138
|
showStartOverlay() {
|
|
1118
|
-
if (this.updateState({ status:
|
|
1139
|
+
if (this.updateState({ status: c.WaitingForInteraction }), this.config.customStartOverlay) {
|
|
1119
1140
|
this.overlayElement = this.config.customStartOverlay, this.config.container.appendChild(this.overlayElement);
|
|
1120
1141
|
return;
|
|
1121
1142
|
}
|
|
@@ -1127,24 +1148,28 @@ class $ {
|
|
|
1127
1148
|
left: 0;
|
|
1128
1149
|
width: 100%;
|
|
1129
1150
|
height: 100%;
|
|
1130
|
-
display:
|
|
1131
|
-
|
|
1132
|
-
justify-content: center;
|
|
1133
|
-
background: rgba(0, 0, 0, 0.7);
|
|
1151
|
+
display: table;
|
|
1152
|
+
background: rgba(0, 0, 0, 0.5);
|
|
1134
1153
|
z-index: 100;
|
|
1135
1154
|
">
|
|
1136
|
-
<
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1155
|
+
<div style="display: table-cell; vertical-align: middle; text-align: center;">
|
|
1156
|
+
<button id="adgent-start-btn" style="
|
|
1157
|
+
width: 80px;
|
|
1158
|
+
height: 80px;
|
|
1159
|
+
background: rgba(0, 0, 0, 0.7);
|
|
1160
|
+
border: 3px solid #fff;
|
|
1161
|
+
border-radius: 50%;
|
|
1162
|
+
cursor: pointer;
|
|
1163
|
+
display: inline-block;
|
|
1164
|
+
line-height: 80px;
|
|
1165
|
+
text-align: center;
|
|
1166
|
+
color: #fff;
|
|
1167
|
+
font-size: 40px;
|
|
1168
|
+
padding: 0 0 0 8px; /* Optical center for triangle */
|
|
1169
|
+
">
|
|
1170
|
+
▶
|
|
1171
|
+
</button>
|
|
1172
|
+
</div>
|
|
1148
1173
|
</div>
|
|
1149
1174
|
`, e.style.cssText = "position: absolute; top: 0; left: 0; width: 100%; height: 100%;";
|
|
1150
1175
|
const t = e.querySelector("#adgent-start-btn");
|
|
@@ -1160,7 +1185,7 @@ class $ {
|
|
|
1160
1185
|
} catch (e) {
|
|
1161
1186
|
this.handleError(
|
|
1162
1187
|
this.createError(
|
|
1163
|
-
|
|
1188
|
+
p.GENERAL_LINEAR_ERROR,
|
|
1164
1189
|
`Playback failed: ${e}`
|
|
1165
1190
|
)
|
|
1166
1191
|
);
|
|
@@ -1177,9 +1202,9 @@ class $ {
|
|
|
1177
1202
|
*/
|
|
1178
1203
|
handlePlaybackStart() {
|
|
1179
1204
|
var e, t, i, s, a;
|
|
1180
|
-
this.updateState({ status:
|
|
1205
|
+
this.updateState({ status: c.Playing }), this.emit({ type: "start" }), (t = (e = this.config).onStart) == null || t.call(e);
|
|
1181
1206
|
const n = this.parser.aggregateImpressions(this.ads);
|
|
1182
|
-
(i = this.tracker) == null || i.fireImpressions(n), (s = this.tracker) == null || s.track("start"), (a = this.tracker) == null || a.track("creativeView"), this.setupSkipButton(), this.log("Playback started");
|
|
1207
|
+
(i = this.tracker) == null || i.fireImpressions(n), (s = this.tracker) == null || s.track("start"), (a = this.tracker) == null || a.track("creativeView"), this.setupSkipButton(), this.setupProgressUI(), this.log("Playback started");
|
|
1183
1208
|
}
|
|
1184
1209
|
/**
|
|
1185
1210
|
* Handle time updates for progress tracking
|
|
@@ -1188,18 +1213,18 @@ class $ {
|
|
|
1188
1213
|
var t, i, s;
|
|
1189
1214
|
const a = e.currentTime, n = e.duration;
|
|
1190
1215
|
if (!n || isNaN(n)) return;
|
|
1191
|
-
const
|
|
1216
|
+
const d = a / n * 100, f = this.calculateQuartile(d);
|
|
1192
1217
|
this.updateState({
|
|
1193
1218
|
currentTime: a,
|
|
1194
1219
|
duration: n
|
|
1195
|
-
}), this.updateSkipCountdown(a), (t = this.tracker) == null || t.updateMacroContext({ adPlayhead: a });
|
|
1196
|
-
const
|
|
1220
|
+
}), this.updateSkipCountdown(a), (t = this.tracker) == null || t.updateMacroContext({ adPlayhead: a }), this.updateProgressUI(a, n);
|
|
1221
|
+
const v = {
|
|
1197
1222
|
currentTime: a,
|
|
1198
1223
|
duration: n,
|
|
1199
|
-
percentage:
|
|
1200
|
-
quartile:
|
|
1224
|
+
percentage: d,
|
|
1225
|
+
quartile: f
|
|
1201
1226
|
};
|
|
1202
|
-
this.emit({ type: "progress", data:
|
|
1227
|
+
this.emit({ type: "progress", data: v }), (s = (i = this.config).onProgress) == null || s.call(i, v), this.fireQuartileEvents(d);
|
|
1203
1228
|
}
|
|
1204
1229
|
/**
|
|
1205
1230
|
* Calculate current quartile (0-4)
|
|
@@ -1253,7 +1278,7 @@ class $ {
|
|
|
1253
1278
|
const i = this.getFirstLinearCreative(), s = (t = this.config.skipOffset) != null ? t : i == null ? void 0 : i.skipOffset;
|
|
1254
1279
|
if (!s || !this.skipButtonElement) return;
|
|
1255
1280
|
const a = Math.max(0, s - e);
|
|
1256
|
-
this.updateState({ skipCountdown: a }), a <= 0 && !this.state.canSkip ? (this.updateState({ canSkip: !0 }), this.skipButtonElement.textContent = this.config.skipButtonText, this.skipButtonElement.style.opacity = "1") : a > 0 && (this.skipButtonElement.textContent = `Skip in ${Math.ceil(a)}s`, this.skipButtonElement.style.opacity = "0.6");
|
|
1281
|
+
this.updateState({ skipCountdown: a }), a <= 0 && !this.state.canSkip ? (this.updateState({ canSkip: !0 }), this.skipButtonElement.textContent = this.config.skipButtonText, this.skipButtonElement.style.opacity = "1", this.skipButtonElement.focus()) : a > 0 && (this.skipButtonElement.textContent = `Skip in ${Math.ceil(a)}s`, this.skipButtonElement.style.opacity = "0.6");
|
|
1257
1282
|
}
|
|
1258
1283
|
/**
|
|
1259
1284
|
* Skip the ad
|
|
@@ -1271,7 +1296,7 @@ class $ {
|
|
|
1271
1296
|
*/
|
|
1272
1297
|
handleComplete() {
|
|
1273
1298
|
var e, t, i;
|
|
1274
|
-
this.updateState({ status:
|
|
1299
|
+
this.updateState({ status: c.Completed }), (e = this.tracker) == null || e.track("complete"), this.emit({ type: "complete" }), (i = (t = this.config).onComplete) == null || i.call(t), this.log("Ad completed");
|
|
1275
1300
|
}
|
|
1276
1301
|
/**
|
|
1277
1302
|
* Handle errors with recovery attempt or callback
|
|
@@ -1279,7 +1304,7 @@ class $ {
|
|
|
1279
1304
|
handleError(e) {
|
|
1280
1305
|
var t, i, s;
|
|
1281
1306
|
this.updateState({
|
|
1282
|
-
status:
|
|
1307
|
+
status: c.Error,
|
|
1283
1308
|
error: e
|
|
1284
1309
|
});
|
|
1285
1310
|
const a = [];
|
|
@@ -1296,28 +1321,59 @@ class $ {
|
|
|
1296
1321
|
t && (e.preventDefault(), e.stopPropagation(), this.handleKeyAction(t));
|
|
1297
1322
|
}, document.addEventListener("keydown", this.boundKeyHandler, !0);
|
|
1298
1323
|
}
|
|
1324
|
+
/**
|
|
1325
|
+
* Set up progress UI in top-left
|
|
1326
|
+
*/
|
|
1327
|
+
setupProgressUI() {
|
|
1328
|
+
const e = document.createElement("div");
|
|
1329
|
+
e.style.cssText = `
|
|
1330
|
+
position: absolute;
|
|
1331
|
+
top: 20px;
|
|
1332
|
+
left: 20px;
|
|
1333
|
+
background: rgba(0, 0, 0, 0.7);
|
|
1334
|
+
color: #fff;
|
|
1335
|
+
padding: 6px 12px;
|
|
1336
|
+
border-radius: 4px;
|
|
1337
|
+
font-size: 14px;
|
|
1338
|
+
font-family: sans-serif;
|
|
1339
|
+
z-index: 101;
|
|
1340
|
+
display: block;
|
|
1341
|
+
white-space: nowrap;
|
|
1342
|
+
`, e.innerHTML = `
|
|
1343
|
+
<span style="display: inline-block; vertical-align: middle; margin-right: 8px; background: #f4b400; color: #000; padding: 2px 4px; border-radius: 2px; font-weight: bold; font-size: 12px;">Ad</span>
|
|
1344
|
+
<span id="adgent-progress-text" style="display: inline-block; vertical-align: middle;">1 of ${this.ads.length} • 0:00</span>
|
|
1345
|
+
`, this.config.container.appendChild(e), this.progressElement = e;
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Update progress UI text
|
|
1349
|
+
*/
|
|
1350
|
+
updateProgressUI(e, t) {
|
|
1351
|
+
if (!this.progressElement) return;
|
|
1352
|
+
const i = Math.ceil(t - e), s = Math.floor(i / 60), a = i % 60, n = `${s}:${a.toString().padStart(2, "0")}`, d = this.progressElement.querySelector("#adgent-progress-text");
|
|
1353
|
+
d && (d.textContent = `1 of ${this.ads.length} • ${n}`);
|
|
1354
|
+
}
|
|
1299
1355
|
/**
|
|
1300
1356
|
* Handle key actions from remote control
|
|
1301
1357
|
*/
|
|
1302
1358
|
handleKeyAction(e) {
|
|
1303
1359
|
var t, i;
|
|
1304
1360
|
switch (this.log(`Key action: ${e}`), e) {
|
|
1305
|
-
case
|
|
1306
|
-
this.state.status ===
|
|
1361
|
+
case u.Enter:
|
|
1362
|
+
this.state.status === c.WaitingForInteraction ? this.onStartClick() : this.state.canSkip && this.skip();
|
|
1307
1363
|
break;
|
|
1308
|
-
case
|
|
1364
|
+
case u.Back:
|
|
1309
1365
|
this.log("Back pressed - ignoring during ad");
|
|
1310
1366
|
break;
|
|
1311
|
-
case
|
|
1367
|
+
case u.Play:
|
|
1312
1368
|
(t = this.videoElement) == null || t.play();
|
|
1313
1369
|
break;
|
|
1314
|
-
case
|
|
1370
|
+
case u.Pause:
|
|
1315
1371
|
(i = this.videoElement) == null || i.pause();
|
|
1316
1372
|
break;
|
|
1317
|
-
case
|
|
1318
|
-
case
|
|
1319
|
-
case
|
|
1320
|
-
case
|
|
1373
|
+
case u.Left:
|
|
1374
|
+
case u.Right:
|
|
1375
|
+
case u.Up:
|
|
1376
|
+
case u.Down:
|
|
1321
1377
|
break;
|
|
1322
1378
|
}
|
|
1323
1379
|
}
|
|
@@ -1351,8 +1407,8 @@ class $ {
|
|
|
1351
1407
|
* Clean up all resources
|
|
1352
1408
|
*/
|
|
1353
1409
|
destroy() {
|
|
1354
|
-
var e, t, i, s, a;
|
|
1355
|
-
this.boundKeyHandler && (document.removeEventListener("keydown", this.boundKeyHandler, !0), this.boundKeyHandler = null), (e = this.videoElement) == null || e.remove(), (t = this.overlayElement) == null || t.remove(), (i = this.skipButtonElement) == null || i.remove(), (s = this.
|
|
1410
|
+
var e, t, i, s, a, n;
|
|
1411
|
+
this.boundKeyHandler && (document.removeEventListener("keydown", this.boundKeyHandler, !0), this.boundKeyHandler = null), (e = this.videoElement) == null || e.remove(), (t = this.overlayElement) == null || t.remove(), (i = this.skipButtonElement) == null || i.remove(), (s = this.progressElement) == null || s.remove(), (a = this.focusTrap) == null || a.remove(), this.videoElement = null, this.overlayElement = null, this.skipButtonElement = null, this.progressElement = null, this.focusTrap = null, (n = this.tracker) == null || n.reset(), this.quartilesFired.clear(), this.listeners.clear(), this.ads = [], this.emit({ type: "destroy" }), this.log("Player destroyed");
|
|
1356
1412
|
}
|
|
1357
1413
|
/**
|
|
1358
1414
|
* Update internal state
|
|
@@ -1381,21 +1437,21 @@ class $ {
|
|
|
1381
1437
|
* Debug logging
|
|
1382
1438
|
*/
|
|
1383
1439
|
log(e) {
|
|
1384
|
-
this.config.debug &&
|
|
1440
|
+
this.config.debug && this.platform.debug(e);
|
|
1385
1441
|
}
|
|
1386
1442
|
}
|
|
1387
1443
|
export {
|
|
1388
|
-
|
|
1444
|
+
V as AdPlayer,
|
|
1389
1445
|
L as AdTracker,
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1446
|
+
V as AdgentSDK,
|
|
1447
|
+
O as DEFAULT_KEY_CODES,
|
|
1448
|
+
u as KeyAction,
|
|
1449
|
+
I as PLATFORM_DETECTION_PATTERNS,
|
|
1394
1450
|
o as Platform,
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1451
|
+
N as PlatformAdapter,
|
|
1452
|
+
c as PlaybackStatus,
|
|
1453
|
+
p as VASTErrorCode,
|
|
1454
|
+
A as VASTParser,
|
|
1399
1455
|
_ as getPlatformAdapter,
|
|
1400
1456
|
g as replaceMacros
|
|
1401
1457
|
};
|
package/dist/adgent-sdk.umd.js
CHANGED
|
@@ -1,35 +1,39 @@
|
|
|
1
|
-
(function(l,f){typeof exports=="object"&&typeof module<"u"?f(exports,require("fast-xml-parser")):typeof define=="function"&&define.amd?define(["exports","fast-xml-parser"],f):(l=typeof globalThis<"u"?globalThis:l||self,f(l.AdgentSDK={},l.FastXMLParser))})(this,function(l,f){"use strict";var d=(r=>(r.Idle="idle",r.Loading="loading",r.Ready="ready",r.Playing="playing",r.Paused="paused",r.Completed="completed",r.Error="error",r.WaitingForInteraction="waiting_for_interaction",r))(d||{}),c=(r=>(r[r.XML_PARSING_ERROR=100]="XML_PARSING_ERROR",r[r.VAST_SCHEMA_VALIDATION_ERROR=101]="VAST_SCHEMA_VALIDATION_ERROR",r[r.VAST_VERSION_NOT_SUPPORTED=102]="VAST_VERSION_NOT_SUPPORTED",r[r.GENERAL_WRAPPER_ERROR=300]="GENERAL_WRAPPER_ERROR",r[r.WRAPPER_TIMEOUT=301]="WRAPPER_TIMEOUT",r[r.WRAPPER_LIMIT_REACHED=302]="WRAPPER_LIMIT_REACHED",r[r.NO_VAST_RESPONSE=303]="NO_VAST_RESPONSE",r[r.GENERAL_LINEAR_ERROR=400]="GENERAL_LINEAR_ERROR",r[r.FILE_NOT_FOUND=401]="FILE_NOT_FOUND",r[r.MEDIA_TIMEOUT=402]="MEDIA_TIMEOUT",r[r.MEDIA_NOT_SUPPORTED=403]="MEDIA_NOT_SUPPORTED",r[r.GENERAL_COMPANION_ERROR=600]="GENERAL_COMPANION_ERROR",r[r.UNDEFINED_ERROR=900]="UNDEFINED_ERROR",r))(c||{}),I=Object.defineProperty,x=(r,e,t)=>e in r?I(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,k=(r,e,t)=>x(r,typeof e!="symbol"?e+"":e,t);class w{constructor(e={}){k(this,"config"),k(this,"xmlParser");var t,i,s,a;this.config={maxWrapperDepth:(t=e.maxWrapperDepth)!=null?t:5,timeout:(i=e.timeout)!=null?i:1e4,debug:(s=e.debug)!=null?s:!1,fetchFn:(a=e.fetchFn)!=null?a:fetch.bind(globalThis)},this.xmlParser=new f.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text",parseAttributeValue:!0,trimValues:!0})}async parse(e){try{return{success:!0,response:await this.fetchAndParse(e,0)}}catch(t){const i=t instanceof Error?t.message:"Unknown error";return{success:!1,error:{code:c.GENERAL_WRAPPER_ERROR,message:i}}}}async fetchAndParse(e,t){if(t>=this.config.maxWrapperDepth)throw new Error(`Wrapper limit exceeded (max: ${this.config.maxWrapperDepth})`);this.log(`Fetching VAST (depth: ${t}): ${e}`);const i=await this.fetchWithTimeout(e),s=this.parseXml(i),a=await Promise.all(s.ads.map(async n=>{var p;return(p=n.wrapper)!=null&&p.vastAdTagURI?this.resolveWrapper(n,t+1):n}));return{...s,ads:a.flat()}}async resolveWrapper(e,t){var i;if(!((i=e.wrapper)!=null&&i.vastAdTagURI))return[e];try{return(await this.fetchAndParse(e.wrapper.vastAdTagURI,t)).ads.map(a=>this.mergeWrapperTracking(e,a))}catch(s){if(this.log(`Wrapper resolution failed: ${s}`),e.wrapper.fallbackOnNoAd)return[];throw s}}mergeWrapperTracking(e,t){return{...t,impressions:[...e.impressions,...t.impressions],errors:[...e.errors,...t.errors],creatives:t.creatives.map(i=>({...i,linear:i.linear?{...i.linear,trackingEvents:[...this.getWrapperTrackingEvents(e),...i.linear.trackingEvents]}:void 0}))}}getWrapperTrackingEvents(e){var t;const i=[];for(const s of e.creatives)(t=s.linear)!=null&&t.trackingEvents&&i.push(...s.linear.trackingEvents);return i}async fetchWithTimeout(e){const t=new AbortController,i=setTimeout(()=>t.abort(),this.config.timeout);try{const s=await this.config.fetchFn(e,{signal:t.signal});if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);return s.text()}finally{clearTimeout(i)}}parseXml(e){const i=this.xmlParser.parse(e).VAST;if(!i)throw new Error("Invalid VAST: missing VAST element");const s=i["@_version"]||"4.0",a=this.parseAds(i.Ad);return{version:s,ads:a,errors:this.parseErrors(i.Error)}}parseAds(e){return e?(Array.isArray(e)?e:[e]).map(i=>this.parseAd(i)):[]}parseAd(e){var t,i,s;const a=!!e.Wrapper,n=e.InLine||e.Wrapper;return{id:e["@_id"]||"",sequence:e["@_sequence"],adSystem:n!=null&&n.AdSystem?{name:typeof n.AdSystem=="string"?n.AdSystem:n.AdSystem["#text"]||"",version:(t=n.AdSystem)==null?void 0:t["@_version"]}:void 0,adTitle:n==null?void 0:n.AdTitle,impressions:this.parseImpressions(n==null?void 0:n.Impression),errors:this.parseErrors(n==null?void 0:n.Error),creatives:this.parseCreatives((i=n==null?void 0:n.Creatives)==null?void 0:i.Creative),wrapper:a?{vastAdTagURI:n.VASTAdTagURI,followAdditionalWrappers:n["@_followAdditionalWrappers"]!==!1,allowMultipleAds:n["@_allowMultipleAds"],fallbackOnNoAd:n["@_fallbackOnNoAd"]}:void 0,inLine:a?void 0:{adTitle:(n==null?void 0:n.AdTitle)||"",description:n==null?void 0:n.Description,advertiser:n==null?void 0:n.Advertiser,creatives:this.parseCreatives((s=n==null?void 0:n.Creatives)==null?void 0:s.Creative)}}}parseImpressions(e){return e?(Array.isArray(e)?e:[e]).map(i=>({id:i["@_id"],url:typeof i=="string"?i:i["#text"]||""})):[]}parseCreatives(e){return e?(Array.isArray(e)?e:[e]).map(i=>({id:i["@_id"],sequence:i["@_sequence"],adId:i["@_adId"],linear:i.Linear?this.parseLinear(i.Linear):void 0})):[]}parseLinear(e){var t,i;return{duration:this.parseDuration(e.Duration),skipOffset:e["@_skipoffset"]?this.parseDuration(e["@_skipoffset"]):void 0,mediaFiles:this.parseMediaFiles((t=e.MediaFiles)==null?void 0:t.MediaFile),trackingEvents:this.parseTrackingEvents((i=e.TrackingEvents)==null?void 0:i.Tracking),videoClicks:e.VideoClicks?{clickThrough:e.VideoClicks.ClickThrough?{id:e.VideoClicks.ClickThrough["@_id"],url:typeof e.VideoClicks.ClickThrough=="string"?e.VideoClicks.ClickThrough:e.VideoClicks.ClickThrough["#text"]||""}:void 0}:void 0,adParameters:e.AdParameters}}parseMediaFiles(e){return e?(Array.isArray(e)?e:[e]).map(i=>({id:i["@_id"],url:typeof i=="string"?i:i["#text"]||"",delivery:i["@_delivery"]||"progressive",type:i["@_type"]||"video/mp4",width:parseInt(i["@_width"],10)||0,height:parseInt(i["@_height"],10)||0,bitrate:i["@_bitrate"]?parseInt(i["@_bitrate"],10):void 0,codec:i["@_codec"],scalable:i["@_scalable"],maintainAspectRatio:i["@_maintainAspectRatio"]})):[]}parseTrackingEvents(e){return e?(Array.isArray(e)?e:[e]).map(i=>({event:i["@_event"],url:typeof i=="string"?i:i["#text"]||"",offset:i["@_offset"]?this.parseDuration(i["@_offset"]):void 0})):[]}parseErrors(e){return e?(Array.isArray(e)?e:[e]).map(i=>typeof i=="string"?i:i["#text"]||""):[]}parseDuration(e){if(typeof e=="number")return e;if(typeof e!="string")return 0;if(e.endsWith("%"))return parseFloat(e)/100;const t=e.match(/(\d+):(\d+):(\d+(?:\.\d+)?)/);if(t){const[,i,s,a]=t;return parseInt(i,10)*3600+parseInt(s,10)*60+parseFloat(a)}return parseFloat(e)||0}selectBestMediaFile(e,t=2500){if(e.length===0)return null;const i=e.filter(n=>n.type.includes("mp4")||n.type.includes("video/mp4"));return[...i.length>0?i:e].sort((n,p)=>{const _=n.bitrate||0,y=p.bitrate||0,W=n.height>1080?1e4:0,B=p.height>1080?1e4:0,V=Math.abs(_-t)+W,$=Math.abs(y-t)+B;return V-$})[0]||null}aggregateTrackingEvents(e){var t;const i=[];for(const s of e)for(const a of s.creatives)(t=a.linear)!=null&&t.trackingEvents&&i.push(...a.linear.trackingEvents);return i}aggregateImpressions(e){const t=[];for(const i of e)for(const s of i.impressions)t.push(s.url);return t}log(e){this.config.debug&&console.log(`[VASTParser] ${e}`)}}function m(r,e={}){let t=r;return t=t.replace(/\[TIMESTAMP\]/g,Date.now().toString()),t=t.replace(/\[CACHEBUSTING\]/g,Math.random().toString(36).substring(2,15)),e.assetUri&&(t=t.replace(/\[ASSETURI\]/g,encodeURIComponent(e.assetUri))),e.contentPlayhead!==void 0&&(t=t.replace(/\[CONTENTPLAYHEAD\]/g,R(e.contentPlayhead))),e.adPlayhead!==void 0&&(t=t.replace(/\[ADPLAYHEAD\]/g,R(e.adPlayhead))),e.errorCode!==void 0&&(t=t.replace(/\[ERRORCODE\]/g,e.errorCode.toString())),e.breakPosition!==void 0&&(t=t.replace(/\[BREAKPOSITION\]/g,e.breakPosition.toString())),e.adType&&(t=t.replace(/\[ADTYPE\]/g,e.adType)),t}function R(r){const e=Math.floor(r/3600),t=Math.floor(r%3600/60),i=Math.floor(r%60),s=Math.floor(r%1*1e3);return e.toString().padStart(2,"0")+":"+t.toString().padStart(2,"0")+":"+i.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")}var o=(r=>(r.WebOS="webos",r.Tizen="tizen",r.Vidaa="vidaa",r.WhaleOS="whaleos",r.FireTV="firetv",r.Roku="roku",r.Xbox="xbox",r.PlayStation="playstation",r.AndroidTV="androidtv",r.Vizio="vizio",r.Generic="generic",r))(o||{}),h=(r=>(r.Enter="enter",r.Back="back",r.Left="left",r.Right="right",r.Up="up",r.Down="down",r.Play="play",r.Pause="pause",r.PlayPause="playPause",r.Stop="stop",r.FastForward="fastForward",r.Rewind="rewind",r.Menu="menu",r.Info="info",r.Red="red",r.Green="green",r.Yellow="yellow",r.Blue="blue",r.ChannelUp="channelUp",r.ChannelDown="channelDown",r.VolumeUp="volumeUp",r.VolumeDown="volumeDown",r.Mute="mute",r))(h||{});const T={webos:{13:"enter",461:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop",417:"fastForward",412:"rewind",457:"info",403:"red",404:"green",405:"yellow",406:"blue",33:"channelUp",34:"channelDown"},tizen:{13:"enter",10009:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",10252:"playPause",413:"stop",417:"fastForward",412:"rewind",457:"info",403:"red",404:"green",405:"yellow",406:"blue",427:"channelUp",428:"channelDown",447:"volumeUp",448:"volumeDown",449:"mute"},vidaa:{13:"enter",8:"back",27:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop",417:"fastForward",412:"rewind"},whaleos:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop"},firetv:{13:"enter",4:"back",27:"back",37:"left",38:"up",39:"right",40:"down",85:"playPause",126:"play",127:"pause",89:"rewind",90:"fastForward",82:"menu"},roku:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",179:"playPause",178:"stop",228:"fastForward",227:"rewind"},xbox:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down",195:"menu",196:"menu"},playstation:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down"},androidtv:{13:"enter",4:"back",27:"back",37:"left",38:"up",39:"right",40:"down",85:"playPause",126:"play",127:"pause",89:"rewind",90:"fastForward",82:"menu"},vizio:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause"},generic:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",32:"playPause",80:"play",83:"stop",77:"mute"}},S={tizen:[/Tizen/i,/SMART-TV.*Samsung/i],webos:[/Web0S/i,/WebOS/i,/LG.*NetCast/i,/LGE.*TV/i],vidaa:[/Vidaa/i,/VIDAA/i,/Hisense/i],whaleos:[/WhaleTV/i,/Whale/i],firetv:[/AFT/i,/AFTS/i,/AFTM/i,/Amazon.*Fire/i],roku:[/Roku/i],xbox:[/Xbox/i,/Edge.*Xbox/i],playstation:[/PlayStation/i,/PS4/i,/PS5/i],androidtv:[/Android.*TV/i,/Chromecast/i,/BRAVIA/i,/SHIELD/i],vizio:[/VIZIO/i,/SmartCast/i],generic:[]};var C=Object.defineProperty,N=(r,e,t)=>e in r?C(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,v=(r,e,t)=>N(r,typeof e!="symbol"?e+"":e,t);class P{constructor(){v(this,"platform"),v(this,"capabilities"),v(this,"deviceInfo"),v(this,"keyMap"),v(this,"reverseKeyMap"),this.platform=this.detectPlatform(),this.keyMap=T[this.platform],this.reverseKeyMap=this.buildReverseKeyMap(),this.capabilities=this.detectCapabilities(),this.deviceInfo=this.detectDeviceInfo()}detectPlatform(){if(typeof window>"u"||typeof navigator>"u")return o.Generic;const e=navigator.userAgent,t=window;if(t.tizen)return o.Tizen;if(t.webOS||t.PalmSystem)return o.WebOS;for(const[i,s]of Object.entries(S))if(i!==o.Generic){for(const a of s)if(a.test(e))return i}return o.Generic}detectCapabilities(){const e=typeof navigator<"u",t=typeof document<"u",i=typeof window<"u",s={sendBeacon:e&&"sendBeacon"in navigator,fetchKeepalive:typeof fetch<"u",mutedAutoplayRequired:!0,fullscreen:t&&("fullscreenEnabled"in document||"webkitFullscreenEnabled"in document),hardwareDecodeInfo:!1,hdr:!1,hdr10Plus:!1,dolbyVision:!1,dolbyAtmos:!1,hevc:this.isCodecSupported('video/mp4; codecs="hvc1"'),vp9:this.isCodecSupported('video/webm; codecs="vp9"'),av1:this.isCodecSupported('video/mp4; codecs="av01.0.05M.08"'),maxResolution:this.detectMaxResolution(),touch:i&&"ontouchstart"in window,voice:!1};switch(this.platform){case o.Tizen:return{...s,hardwareDecodeInfo:!0,hdr:!0,hevc:!0,voice:!0};case o.WebOS:return{...s,hardwareDecodeInfo:!0,hdr:!0,dolbyVision:!0,dolbyAtmos:!0,hevc:!0,voice:!0};case o.FireTV:return{...s,hdr:!0,hdr10Plus:!0,dolbyVision:!0,hevc:!0,voice:!0};case o.Roku:return{...s,hdr:!0,dolbyVision:!0,hevc:!0,voice:!0};case o.Xbox:return{...s,hdr:!0,dolbyVision:!0,dolbyAtmos:!0,hevc:!0,av1:!0,voice:!0};case o.PlayStation:return{...s,hdr:!0,hevc:!0};case o.AndroidTV:return{...s,hdr:!0,dolbyVision:!0,hevc:!0,vp9:!0,voice:!0};default:return s}}detectDeviceInfo(){var e,t,i;const s={platform:this.platform};typeof window<"u"&&(s.screenWidth=(e=window.screen)==null?void 0:e.width,s.screenHeight=(t=window.screen)==null?void 0:t.height,s.devicePixelRatio=window.devicePixelRatio);const a=window;if(this.platform===o.Tizen&&((i=a.tizen)!=null&&i.systeminfo))try{a.tizen.systeminfo.getPropertyValue("BUILD",n=>{s.model=n.model,s.manufacturer=n.manufacturer||"Samsung"})}catch{s.manufacturer="Samsung"}if(this.platform===o.WebOS&&a.webOSSystem)try{const n=a.webOSSystem.deviceInfo;s.model=n==null?void 0:n.modelName,s.manufacturer="LG",s.osVersion=n==null?void 0:n.version}catch{s.manufacturer="LG"}return s}detectMaxResolution(){var e,t;if(typeof window>"u")return"unknown";const i=((e=window.screen)==null?void 0:e.width)||0,s=((t=window.screen)==null?void 0:t.height)||0,a=Math.max(i,s);return a>=3840?"4k":a>=1920?"1080p":a>=1280?"720p":"unknown"}buildReverseKeyMap(){const e=new Map;for(const[t,i]of Object.entries(this.keyMap)){const s=parseInt(t,10),a=e.get(i)||[];a.push(s),e.set(i,a)}return e}normalizeKeyCode(e){var t;return(t=this.keyMap[e])!=null?t:null}getKeyCodesForAction(e){return this.reverseKeyMap.get(e)||[]}isCodecSupported(e){if(typeof document>"u")return!1;try{const i=document.createElement("video").canPlayType(e);return i==="probably"||i==="maybe"}catch{return!1}}registerTizenKeys(){if(this.platform!==o.Tizen)return;const e=window.tizen;e!=null&&e.tvinputdevice&&["MediaPlay","MediaPause","MediaStop","MediaFastForward","MediaRewind","MediaPlayPause","ColorF0Red","ColorF1Green","ColorF2Yellow","ColorF3Blue","Info"].forEach(i=>{try{e.tvinputdevice.registerKey(i)}catch{}})}registerWebOSKeys(){this.platform,o.WebOS}getVideoAttributes(){const e={muted:!0,playsinline:!0,autoplay:!0,"webkit-playsinline":!0};switch(this.platform){case o.Tizen:e["data-samsung-immersive"]="true";break;case o.WebOS:e["data-lg-immersive"]="true";break;case o.FireTV:case o.AndroidTV:e["x-webkit-airplay"]="allow";break}return e}getRecommendedVideoSettings(){switch(this.platform){case o.Tizen:case o.WebOS:return{maxBitrate:15e3,preferredCodec:"hevc",maxResolution:"4k"};case o.FireTV:return{maxBitrate:1e4,preferredCodec:"hevc",maxResolution:"4k"};case o.Roku:return{maxBitrate:8e3,preferredCodec:"h264",maxResolution:"4k"};case o.Xbox:case o.PlayStation:return{maxBitrate:2e4,preferredCodec:"hevc",maxResolution:"4k"};default:return{maxBitrate:5e3,preferredCodec:"h264",maxResolution:"1080p"}}}}let E=null;function b(){return E||(E=new P),E}var M=Object.defineProperty,D=(r,e,t)=>e in r?M(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,g=(r,e,t)=>D(r,typeof e!="symbol"?e+"":e,t);class A{constructor(e=[],t={}){g(this,"config"),g(this,"trackingEvents"),g(this,"firedEvents"),g(this,"macroContext");var i,s,a;this.config={debug:(i=t.debug)!=null?i:!1,retry:(s=t.retry)!=null?s:!1,maxRetries:(a=t.maxRetries)!=null?a:3},this.trackingEvents=this.groupEventsByType(e),this.firedEvents=new Set,this.macroContext={}}groupEventsByType(e){const t=new Map;for(const i of e){const s=t.get(i.event)||[];s.push(i),t.set(i.event,s)}return t}updateMacroContext(e){this.macroContext={...this.macroContext,...e}}track(e,t=!0){const i=this.trackingEvents.get(e);if(!i){this.log(`No tracking URLs for event: ${e}`);return}for(const s of i){const a=`${e}:${s.url}`;if(t&&this.firedEvents.has(a)){this.log(`Skipping duplicate event: ${e}`);continue}const n=m(s.url,this.macroContext);this.firePixel(n),t&&this.firedEvents.add(a)}}firePixel(e){const t=b();this.log(`Firing pixel: ${e}`);try{if(t.capabilities.sendBeacon&&navigator.sendBeacon(e))return;if(t.capabilities.fetchKeepalive){fetch(e,{method:"GET",keepalive:!0,mode:"no-cors",credentials:"omit"}).catch(()=>{});return}this.fireImageBeacon(e)}catch{this.log(`Failed to fire pixel: ${e}`)}}fireImageBeacon(e){const t=new Image(1,1);t.src=e}fireImpressions(e){for(const t of e){const i=m(t,this.macroContext);this.firePixel(i)}}fireError(e,t){const i={...this.macroContext,errorCode:t};for(const s of e){const a=m(s,i);this.firePixel(a)}}reset(){this.firedEvents.clear()}log(e){this.config.debug&&console.log(`[AdTracker] ${e}`)}}var F=Object.defineProperty,L=(r,e,t)=>e in r?F(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,u=(r,e,t)=>L(r,typeof e!="symbol"?e+"":e,t);const U={targetBitrate:2500,maxWrapperDepth:5,timeout:1e4,debug:!1,skipButtonText:"Skip Ad"};class O{constructor(e){u(this,"config"),u(this,"platform"),u(this,"parser"),u(this,"videoElement",null),u(this,"overlayElement",null),u(this,"skipButtonElement",null),u(this,"tracker",null),u(this,"state"),u(this,"ads",[]),u(this,"listeners",new Set),u(this,"quartilesFired",new Set),u(this,"boundKeyHandler",null),u(this,"focusTrap",null),this.config={...U,...e},this.platform=b(),this.parser=new w({maxWrapperDepth:this.config.maxWrapperDepth,timeout:this.config.timeout,debug:this.config.debug}),this.state={status:d.Idle,currentTime:0,duration:0,muted:!0,volume:1,canSkip:!1,skipCountdown:0,mediaFile:null,error:null},this.platform.platform==="tizen"&&this.platform.registerTizenKeys()}async init(){var e,t;if(!this.config.container)throw new Error("Container element not found");this.updateState({status:d.Loading});try{const i=await this.parser.parse(this.config.vastUrl);if(!i.success||!i.response)throw this.createError(((e=i.error)==null?void 0:e.code)||c.NO_VAST_RESPONSE,((t=i.error)==null?void 0:t.message)||"Failed to parse VAST");if(this.ads=i.response.ads,this.ads.length===0)throw this.createError(c.NO_VAST_RESPONSE,"No ads in VAST response");const s=this.getFirstLinearCreative();if(!s)throw this.createError(c.GENERAL_LINEAR_ERROR,"No linear creative found");const a=this.parser.selectBestMediaFile(s.mediaFiles,this.config.targetBitrate);if(!a)throw this.createError(c.FILE_NOT_FOUND,"No suitable media file found");this.updateState({mediaFile:a});const n=this.parser.aggregateTrackingEvents(this.ads);this.tracker=new A(n,{debug:this.config.debug}),this.tracker.updateMacroContext({assetUri:a.url}),this.createVideoElement(a),this.setupFocusManagement(),await this.attemptAutoplay()}catch(i){const s=i instanceof Error?this.createError(c.UNDEFINED_ERROR,i.message):i;this.handleError(s)}}getFirstLinearCreative(){for(const e of this.ads)for(const t of e.creatives)if(t.linear)return t.linear;return null}createVideoElement(e){const t=document.createElement("video"),i=this.platform.getVideoAttributes();Object.entries(i).forEach(([s,a])=>{typeof a=="boolean"?a&&t.setAttribute(s,""):t.setAttribute(s,a)}),t.src=e.url,t.style.cssText=`
|
|
1
|
+
(function(l,f){typeof exports=="object"&&typeof module<"u"?f(exports,require("fast-xml-parser")):typeof define=="function"&&define.amd?define(["exports","fast-xml-parser"],f):(l=typeof globalThis<"u"?globalThis:l||self,f(l.AdgentSDK={},l.FastXMLParser))})(this,function(l,f){"use strict";var c=(r=>(r.Idle="idle",r.Loading="loading",r.Ready="ready",r.Playing="playing",r.Paused="paused",r.Completed="completed",r.Error="error",r.WaitingForInteraction="waiting_for_interaction",r))(c||{}),p=(r=>(r[r.XML_PARSING_ERROR=100]="XML_PARSING_ERROR",r[r.VAST_SCHEMA_VALIDATION_ERROR=101]="VAST_SCHEMA_VALIDATION_ERROR",r[r.VAST_VERSION_NOT_SUPPORTED=102]="VAST_VERSION_NOT_SUPPORTED",r[r.GENERAL_WRAPPER_ERROR=300]="GENERAL_WRAPPER_ERROR",r[r.WRAPPER_TIMEOUT=301]="WRAPPER_TIMEOUT",r[r.WRAPPER_LIMIT_REACHED=302]="WRAPPER_LIMIT_REACHED",r[r.NO_VAST_RESPONSE=303]="NO_VAST_RESPONSE",r[r.GENERAL_LINEAR_ERROR=400]="GENERAL_LINEAR_ERROR",r[r.FILE_NOT_FOUND=401]="FILE_NOT_FOUND",r[r.MEDIA_TIMEOUT=402]="MEDIA_TIMEOUT",r[r.MEDIA_NOT_SUPPORTED=403]="MEDIA_NOT_SUPPORTED",r[r.GENERAL_COMPANION_ERROR=600]="GENERAL_COMPANION_ERROR",r[r.UNDEFINED_ERROR=900]="UNDEFINED_ERROR",r))(p||{}),x=Object.defineProperty,I=(r,e,t)=>e in r?x(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,w=(r,e,t)=>I(r,typeof e!="symbol"?e+"":e,t);class k{constructor(e={}){w(this,"config"),w(this,"xmlParser");var t,i,s,a;this.config={maxWrapperDepth:(t=e.maxWrapperDepth)!=null?t:5,timeout:(i=e.timeout)!=null?i:1e4,debug:(s=e.debug)!=null?s:!1,fetchFn:(a=e.fetchFn)!=null?a:fetch.bind(globalThis)},this.xmlParser=new f.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text",parseAttributeValue:!0,trimValues:!0})}async parse(e){try{return{success:!0,response:await this.fetchAndParse(e,0)}}catch(t){const i=t instanceof Error?t.message:"Unknown error";return{success:!1,error:{code:p.GENERAL_WRAPPER_ERROR,message:i}}}}async fetchAndParse(e,t){if(t>=this.config.maxWrapperDepth)throw new Error(`Wrapper limit exceeded (max: ${this.config.maxWrapperDepth})`);this.log(`Fetching VAST (depth: ${t}): ${e}`);const i=await this.fetchWithTimeout(e),s=this.parseXml(i),a=await Promise.all(s.ads.map(async n=>{var u;return(u=n.wrapper)!=null&&u.vastAdTagURI?this.resolveWrapper(n,t+1):n}));return{...s,ads:a.flat()}}async resolveWrapper(e,t){var i;if(!((i=e.wrapper)!=null&&i.vastAdTagURI))return[e];try{return(await this.fetchAndParse(e.wrapper.vastAdTagURI,t)).ads.map(a=>this.mergeWrapperTracking(e,a))}catch(s){if(this.log(`Wrapper resolution failed: ${s}`),e.wrapper.fallbackOnNoAd)return[];throw s}}mergeWrapperTracking(e,t){return{...t,impressions:[...e.impressions,...t.impressions],errors:[...e.errors,...t.errors],creatives:t.creatives.map(i=>({...i,linear:i.linear?{...i.linear,trackingEvents:[...this.getWrapperTrackingEvents(e),...i.linear.trackingEvents]}:void 0}))}}getWrapperTrackingEvents(e){var t;const i=[];for(const s of e.creatives)(t=s.linear)!=null&&t.trackingEvents&&i.push(...s.linear.trackingEvents);return i}async fetchWithTimeout(e){const t=new AbortController,i=setTimeout(()=>t.abort(),this.config.timeout);try{const s=await this.config.fetchFn(e,{signal:t.signal});if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);return s.text()}finally{clearTimeout(i)}}parseXml(e){const i=this.xmlParser.parse(e).VAST;if(!i)throw new Error("Invalid VAST: missing VAST element");const s=i["@_version"]||"4.0",a=this.parseAds(i.Ad);return{version:s,ads:a,errors:this.parseErrors(i.Error)}}parseAds(e){return e?(Array.isArray(e)?e:[e]).map(i=>this.parseAd(i)):[]}parseAd(e){var t,i,s;const a=!!e.Wrapper,n=e.InLine||e.Wrapper;return{id:e["@_id"]||"",sequence:e["@_sequence"],adSystem:n!=null&&n.AdSystem?{name:typeof n.AdSystem=="string"?n.AdSystem:n.AdSystem["#text"]||"",version:(t=n.AdSystem)==null?void 0:t["@_version"]}:void 0,adTitle:n==null?void 0:n.AdTitle,impressions:this.parseImpressions(n==null?void 0:n.Impression),errors:this.parseErrors(n==null?void 0:n.Error),creatives:this.parseCreatives((i=n==null?void 0:n.Creatives)==null?void 0:i.Creative),wrapper:a?{vastAdTagURI:n.VASTAdTagURI,followAdditionalWrappers:n["@_followAdditionalWrappers"]!==!1,allowMultipleAds:n["@_allowMultipleAds"],fallbackOnNoAd:n["@_fallbackOnNoAd"]}:void 0,inLine:a?void 0:{adTitle:(n==null?void 0:n.AdTitle)||"",description:n==null?void 0:n.Description,advertiser:n==null?void 0:n.Advertiser,creatives:this.parseCreatives((s=n==null?void 0:n.Creatives)==null?void 0:s.Creative)}}}parseImpressions(e){return e?(Array.isArray(e)?e:[e]).map(i=>({id:i["@_id"],url:typeof i=="string"?i:i["#text"]||""})):[]}parseCreatives(e){return e?(Array.isArray(e)?e:[e]).map(i=>({id:i["@_id"],sequence:i["@_sequence"],adId:i["@_adId"],linear:i.Linear?this.parseLinear(i.Linear):void 0})):[]}parseLinear(e){var t,i;return{duration:this.parseDuration(e.Duration),skipOffset:e["@_skipoffset"]?this.parseDuration(e["@_skipoffset"]):void 0,mediaFiles:this.parseMediaFiles((t=e.MediaFiles)==null?void 0:t.MediaFile),trackingEvents:this.parseTrackingEvents((i=e.TrackingEvents)==null?void 0:i.Tracking),videoClicks:e.VideoClicks?{clickThrough:e.VideoClicks.ClickThrough?{id:e.VideoClicks.ClickThrough["@_id"],url:typeof e.VideoClicks.ClickThrough=="string"?e.VideoClicks.ClickThrough:e.VideoClicks.ClickThrough["#text"]||""}:void 0}:void 0,adParameters:e.AdParameters}}parseMediaFiles(e){return e?(Array.isArray(e)?e:[e]).map(i=>({id:i["@_id"],url:typeof i=="string"?i:i["#text"]||"",delivery:i["@_delivery"]||"progressive",type:i["@_type"]||"video/mp4",width:parseInt(i["@_width"],10)||0,height:parseInt(i["@_height"],10)||0,bitrate:i["@_bitrate"]?parseInt(i["@_bitrate"],10):void 0,codec:i["@_codec"],scalable:i["@_scalable"],maintainAspectRatio:i["@_maintainAspectRatio"]})):[]}parseTrackingEvents(e){return e?(Array.isArray(e)?e:[e]).map(i=>({event:i["@_event"],url:typeof i=="string"?i:i["#text"]||"",offset:i["@_offset"]?this.parseDuration(i["@_offset"]):void 0})):[]}parseErrors(e){return e?(Array.isArray(e)?e:[e]).map(i=>typeof i=="string"?i:i["#text"]||""):[]}parseDuration(e){if(typeof e=="number")return e;if(typeof e!="string")return 0;if(e.endsWith("%"))return parseFloat(e)/100;const t=e.match(/(\d+):(\d+):(\d+(?:\.\d+)?)/);if(t){const[,i,s,a]=t;return parseInt(i,10)*3600+parseInt(s,10)*60+parseFloat(a)}return parseFloat(e)||0}selectBestMediaFile(e,t=2500){if(e.length===0)return null;const i=e.filter(n=>n.type.includes("mp4")||n.type.includes("video/mp4"));return[...i.length>0?i:e].sort((n,u)=>{const y=n.bitrate||0,b=u.bitrate||0,W=n.height>1080?1e4:0,B=u.height>1080?1e4:0,V=Math.abs(y-t)+W,$=Math.abs(b-t)+B;return V-$})[0]||null}aggregateTrackingEvents(e){var t;const i=[];for(const s of e)for(const a of s.creatives)(t=a.linear)!=null&&t.trackingEvents&&i.push(...a.linear.trackingEvents);return i}aggregateImpressions(e){const t=[];for(const i of e)for(const s of i.impressions)t.push(s.url);return t}log(e){this.config.debug&&console.log(`[VASTParser] ${e}`)}}function m(r,e={}){let t=r;return t=t.replace(/\[TIMESTAMP\]/g,Date.now().toString()),t=t.replace(/\[CACHEBUSTING\]/g,Math.random().toString(36).substring(2,15)),e.assetUri&&(t=t.replace(/\[ASSETURI\]/g,encodeURIComponent(e.assetUri))),e.contentPlayhead!==void 0&&(t=t.replace(/\[CONTENTPLAYHEAD\]/g,R(e.contentPlayhead))),e.adPlayhead!==void 0&&(t=t.replace(/\[ADPLAYHEAD\]/g,R(e.adPlayhead))),e.errorCode!==void 0&&(t=t.replace(/\[ERRORCODE\]/g,e.errorCode.toString())),e.breakPosition!==void 0&&(t=t.replace(/\[BREAKPOSITION\]/g,e.breakPosition.toString())),e.adType&&(t=t.replace(/\[ADTYPE\]/g,e.adType)),t}function R(r){const e=Math.floor(r/3600),t=Math.floor(r%3600/60),i=Math.floor(r%60),s=Math.floor(r%1*1e3);return e.toString().padStart(2,"0")+":"+t.toString().padStart(2,"0")+":"+i.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")}var o=(r=>(r.WebOS="webos",r.Tizen="tizen",r.Vidaa="vidaa",r.WhaleOS="whaleos",r.FireTV="firetv",r.Roku="roku",r.Xbox="xbox",r.PlayStation="playstation",r.AndroidTV="androidtv",r.Vizio="vizio",r.Generic="generic",r))(o||{}),h=(r=>(r.Enter="enter",r.Back="back",r.Left="left",r.Right="right",r.Up="up",r.Down="down",r.Play="play",r.Pause="pause",r.PlayPause="playPause",r.Stop="stop",r.FastForward="fastForward",r.Rewind="rewind",r.Menu="menu",r.Info="info",r.Red="red",r.Green="green",r.Yellow="yellow",r.Blue="blue",r.ChannelUp="channelUp",r.ChannelDown="channelDown",r.VolumeUp="volumeUp",r.VolumeDown="volumeDown",r.Mute="mute",r))(h||{});const T={webos:{13:"enter",461:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop",417:"fastForward",412:"rewind",457:"info",403:"red",404:"green",405:"yellow",406:"blue",33:"channelUp",34:"channelDown"},tizen:{13:"enter",10009:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",10252:"playPause",413:"stop",417:"fastForward",412:"rewind",457:"info",403:"red",404:"green",405:"yellow",406:"blue",427:"channelUp",428:"channelDown",447:"volumeUp",448:"volumeDown",449:"mute"},vidaa:{13:"enter",8:"back",27:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop",417:"fastForward",412:"rewind"},whaleos:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause",413:"stop"},firetv:{13:"enter",4:"back",27:"back",37:"left",38:"up",39:"right",40:"down",85:"playPause",126:"play",127:"pause",89:"rewind",90:"fastForward",82:"menu"},roku:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",179:"playPause",178:"stop",228:"fastForward",227:"rewind"},xbox:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down",195:"menu",196:"menu"},playstation:{13:"enter",27:"back",37:"left",38:"up",39:"right",40:"down"},androidtv:{13:"enter",4:"back",27:"back",37:"left",38:"up",39:"right",40:"down",85:"playPause",126:"play",127:"pause",89:"rewind",90:"fastForward",82:"menu"},vizio:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",415:"play",19:"pause"},generic:{13:"enter",27:"back",8:"back",37:"left",38:"up",39:"right",40:"down",32:"playPause",80:"play",83:"stop",77:"mute"}},S={tizen:[/Tizen/i,/SMART-TV.*Samsung/i],webos:[/Web0S/i,/WebOS/i,/LG.*NetCast/i,/LGE.*TV/i],vidaa:[/Vidaa/i,/VIDAA/i,/Hisense/i],whaleos:[/WhaleTV/i,/Whale/i],firetv:[/AFT/i,/AFTS/i,/AFTM/i,/Amazon.*Fire/i],roku:[/Roku/i],xbox:[/Xbox/i,/Edge.*Xbox/i],playstation:[/PlayStation/i,/PS4/i,/PS5/i],androidtv:[/Android.*TV/i,/Chromecast/i,/BRAVIA/i,/SHIELD/i],vizio:[/VIZIO/i,/SmartCast/i],generic:[]};var C=Object.defineProperty,M=(r,e,t)=>e in r?C(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,v=(r,e,t)=>M(r,typeof e!="symbol"?e+"":e,t);class P{constructor(){v(this,"platform"),v(this,"capabilities"),v(this,"deviceInfo"),v(this,"keyMap"),v(this,"reverseKeyMap"),this.platform=this.detectPlatform(),this.keyMap=T[this.platform],this.reverseKeyMap=this.buildReverseKeyMap(),this.capabilities=this.detectCapabilities(),this.deviceInfo=this.detectDeviceInfo()}detectPlatform(){if(typeof window>"u"||typeof navigator>"u")return o.Generic;const e=navigator.userAgent,t=window;if(t.tizen)return o.Tizen;if(t.webOS||t.PalmSystem)return o.WebOS;for(const[i,s]of Object.entries(S))if(i!==o.Generic){for(const a of s)if(a.test(e))return i}return o.Generic}detectCapabilities(){const e=typeof navigator<"u",t=typeof document<"u",i=typeof window<"u",s={sendBeacon:e&&"sendBeacon"in navigator,fetchKeepalive:typeof fetch<"u",mutedAutoplayRequired:!0,fullscreen:t&&("fullscreenEnabled"in document||"webkitFullscreenEnabled"in document),hardwareDecodeInfo:!1,hdr:!1,hdr10Plus:!1,dolbyVision:!1,dolbyAtmos:!1,hevc:this.isCodecSupported('video/mp4; codecs="hvc1"'),vp9:this.isCodecSupported('video/webm; codecs="vp9"'),av1:this.isCodecSupported('video/mp4; codecs="av01.0.05M.08"'),maxResolution:this.detectMaxResolution(),touch:i&&"ontouchstart"in window,voice:!1};switch(this.platform){case o.Tizen:return{...s,hardwareDecodeInfo:!0,hdr:!0,hevc:!0,voice:!0};case o.WebOS:return{...s,hardwareDecodeInfo:!0,hdr:!0,dolbyVision:!0,dolbyAtmos:!0,hevc:!0,voice:!0};case o.FireTV:return{...s,hdr:!0,hdr10Plus:!0,dolbyVision:!0,hevc:!0,voice:!0};case o.Roku:return{...s,hdr:!0,dolbyVision:!0,hevc:!0,voice:!0};case o.Xbox:return{...s,hdr:!0,dolbyVision:!0,dolbyAtmos:!0,hevc:!0,av1:!0,voice:!0};case o.PlayStation:return{...s,hdr:!0,hevc:!0};case o.AndroidTV:return{...s,hdr:!0,dolbyVision:!0,hevc:!0,vp9:!0,voice:!0};default:return s}}detectDeviceInfo(){var e,t,i;const s={platform:this.platform};typeof window<"u"&&(s.screenWidth=(e=window.screen)==null?void 0:e.width,s.screenHeight=(t=window.screen)==null?void 0:t.height,s.devicePixelRatio=window.devicePixelRatio);const a=window;if(this.platform===o.Tizen&&((i=a.tizen)!=null&&i.systeminfo))try{a.tizen.systeminfo.getPropertyValue("BUILD",n=>{s.model=n.model,s.manufacturer=n.manufacturer||"Samsung"})}catch{s.manufacturer="Samsung"}if(this.platform===o.WebOS&&a.webOSSystem)try{const n=a.webOSSystem.deviceInfo;s.model=n==null?void 0:n.modelName,s.manufacturer="LG",s.osVersion=n==null?void 0:n.version}catch{s.manufacturer="LG"}return s}detectMaxResolution(){var e,t;if(typeof window>"u")return"unknown";const i=((e=window.screen)==null?void 0:e.width)||0,s=((t=window.screen)==null?void 0:t.height)||0,a=Math.max(i,s);return a>=3840?"4k":a>=1920?"1080p":a>=1280?"720p":"unknown"}buildReverseKeyMap(){const e=new Map;for(const[t,i]of Object.entries(this.keyMap)){const s=parseInt(t,10),a=e.get(i)||[];a.push(s),e.set(i,a)}return e}normalizeKeyCode(e){var t;return(t=this.keyMap[e])!=null?t:null}getKeyCodesForAction(e){return this.reverseKeyMap.get(e)||[]}isCodecSupported(e){if(typeof document>"u")return!1;try{const i=document.createElement("video").canPlayType(e);return i==="probably"||i==="maybe"}catch{return!1}}registerTizenKeys(){if(this.platform!==o.Tizen)return;const e=window.tizen;e!=null&&e.tvinputdevice&&["MediaPlay","MediaPause","MediaStop","MediaFastForward","MediaRewind","MediaPlayPause","ColorF0Red","ColorF1Green","ColorF2Yellow","ColorF3Blue","Info"].forEach(i=>{try{e.tvinputdevice.registerKey(i)}catch{}})}registerWebOSKeys(){this.platform,o.WebOS}getVideoAttributes(){const e={muted:!0,playsinline:!0,autoplay:!0,"webkit-playsinline":!0};switch(this.platform){case o.Tizen:e["data-samsung-immersive"]="true";break;case o.WebOS:e["data-lg-immersive"]="true";break;case o.FireTV:case o.AndroidTV:e["x-webkit-airplay"]="allow";break}return e}getRecommendedVideoSettings(){switch(this.platform){case o.Tizen:case o.WebOS:return{maxBitrate:15e3,preferredCodec:"hevc",maxResolution:"4k"};case o.FireTV:return{maxBitrate:1e4,preferredCodec:"hevc",maxResolution:"4k"};case o.Roku:return{maxBitrate:8e3,preferredCodec:"h264",maxResolution:"4k"};case o.Xbox:case o.PlayStation:return{maxBitrate:2e4,preferredCodec:"hevc",maxResolution:"4k"};default:return{maxBitrate:5e3,preferredCodec:"h264",maxResolution:"1080p"}}}debug(e){if(console.log(`[Adgent] ${e}`),this.platform===o.WebOS&&typeof window<"u"){const t=window;t.webOS&&t.webOS.service&&t.webOS.service.request("luna://com.webos.notification",{method:"createToast",parameters:{message:`[Adgent] ${e}`},onSuccess:()=>{},onFailure:()=>{}})}}}let E=null;function _(){return E||(E=new P),E}var N=Object.defineProperty,D=(r,e,t)=>e in r?N(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,g=(r,e,t)=>D(r,typeof e!="symbol"?e+"":e,t);class A{constructor(e=[],t={}){g(this,"config"),g(this,"trackingEvents"),g(this,"firedEvents"),g(this,"macroContext");var i,s,a;this.config={debug:(i=t.debug)!=null?i:!1,retry:(s=t.retry)!=null?s:!1,maxRetries:(a=t.maxRetries)!=null?a:3},this.trackingEvents=this.groupEventsByType(e),this.firedEvents=new Set,this.macroContext={}}groupEventsByType(e){const t=new Map;for(const i of e){const s=t.get(i.event)||[];s.push(i),t.set(i.event,s)}return t}updateMacroContext(e){this.macroContext={...this.macroContext,...e}}track(e,t=!0){const i=this.trackingEvents.get(e);if(!i){this.log(`No tracking URLs for event: ${e}`);return}for(const s of i){const a=`${e}:${s.url}`;if(t&&this.firedEvents.has(a)){this.log(`Skipping duplicate event: ${e}`);continue}const n=m(s.url,this.macroContext);this.firePixel(n),t&&this.firedEvents.add(a)}}firePixel(e){const t=_();this.log(`Firing pixel: ${e}`);try{if(t.capabilities.sendBeacon&&navigator.sendBeacon(e))return;if(t.capabilities.fetchKeepalive){fetch(e,{method:"GET",keepalive:!0,mode:"no-cors",credentials:"omit"}).catch(()=>{});return}this.fireImageBeacon(e)}catch{this.log(`Failed to fire pixel: ${e}`)}}fireImageBeacon(e){const t=new Image(1,1);t.src=e}fireImpressions(e){for(const t of e){const i=m(t,this.macroContext);this.firePixel(i)}}fireError(e,t){const i={...this.macroContext,errorCode:t};for(const s of e){const a=m(s,i);this.firePixel(a)}}reset(){this.firedEvents.clear()}log(e){this.config.debug&&console.log(`[AdTracker] ${e}`)}}var F=Object.defineProperty,L=(r,e,t)=>e in r?F(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,d=(r,e,t)=>L(r,typeof e!="symbol"?e+"":e,t);const U={targetBitrate:2500,maxWrapperDepth:5,timeout:1e4,debug:!1,skipButtonText:"Skip Ad"};class O{constructor(e){d(this,"config"),d(this,"platform"),d(this,"parser"),d(this,"videoElement",null),d(this,"overlayElement",null),d(this,"skipButtonElement",null),d(this,"progressElement",null),d(this,"tracker",null),d(this,"state"),d(this,"ads",[]),d(this,"listeners",new Set),d(this,"quartilesFired",new Set),d(this,"boundKeyHandler",null),d(this,"focusTrap",null),this.config={...U,...e},this.platform=_(),this.parser=new k({maxWrapperDepth:this.config.maxWrapperDepth,timeout:this.config.timeout,debug:this.config.debug}),this.state={status:c.Idle,currentTime:0,duration:0,muted:!0,volume:1,canSkip:!1,skipCountdown:0,mediaFile:null,error:null},this.platform.platform==="tizen"&&this.platform.registerTizenKeys()}async init(){var e,t;if(!this.config.container)throw new Error("Container element not found");this.updateState({status:c.Loading});try{const i=await this.parser.parse(this.config.vastUrl);if(!i.success||!i.response)throw this.createError(((e=i.error)==null?void 0:e.code)||p.NO_VAST_RESPONSE,((t=i.error)==null?void 0:t.message)||"Failed to parse VAST");if(this.ads=i.response.ads,this.ads.length===0)throw this.createError(p.NO_VAST_RESPONSE,"No ads in VAST response");const s=this.getFirstLinearCreative();if(!s)throw this.createError(p.GENERAL_LINEAR_ERROR,"No linear creative found");const a=this.parser.selectBestMediaFile(s.mediaFiles,this.config.targetBitrate);if(!a)throw this.createError(p.FILE_NOT_FOUND,"No suitable media file found");this.updateState({mediaFile:a});const n=this.parser.aggregateTrackingEvents(this.ads);this.tracker=new A(n,{debug:this.config.debug}),this.tracker.updateMacroContext({assetUri:a.url}),this.createVideoElement(a),this.setupFocusManagement(),await this.attemptAutoplay()}catch(i){const s=i instanceof Error?this.createError(p.UNDEFINED_ERROR,i.message):i;this.handleError(s)}}getFirstLinearCreative(){for(const e of this.ads)for(const t of e.creatives)if(t.linear)return t.linear;return null}createVideoElement(e){const t=document.createElement("video"),i=this.platform.getVideoAttributes();Object.entries(i).forEach(([a,n])=>{typeof n=="boolean"?n&&t.setAttribute(a,""):t.setAttribute(a,n)}),t.removeAttribute("src"),t.innerHTML="";const s=document.createElement("source");s.src=e.url,s.type=e.type||"video/mp4",t.appendChild(s),t.setAttribute("crossorigin","anonymous"),t.style.cssText=`
|
|
2
2
|
width: 100%;
|
|
3
3
|
height: 100%;
|
|
4
4
|
object-fit: contain;
|
|
5
5
|
background: #000;
|
|
6
|
-
`,t.addEventListener("loadedmetadata",()=>{this.updateState({duration:t.duration,status:
|
|
6
|
+
`,t.addEventListener("loadedmetadata",()=>{this.updateState({duration:t.duration,status:c.Ready}),this.emit({type:"loaded"})}),t.addEventListener("timeupdate",()=>{this.handleTimeUpdate(t)}),t.addEventListener("ended",()=>{this.handleComplete()}),t.addEventListener("error",()=>{const a=t.error;this.handleError(this.createError(p.MEDIA_NOT_SUPPORTED,(a==null?void 0:a.message)||"Video playback error"))}),t.addEventListener("play",()=>{this.updateState({status:c.Playing})}),t.addEventListener("pause",()=>{var a;this.state.status!==c.Completed&&(this.updateState({status:c.Paused}),this.emit({type:"pause"}),(a=this.tracker)==null||a.track("pause"))}),this.config.container.appendChild(t),this.videoElement=t,this.log(`Video element created with src: ${e.url}`)}async attemptAutoplay(){if(this.videoElement)try{await this.videoElement.play(),this.handlePlaybackStart()}catch(e){this.log(`Autoplay failed: ${e}`),this.showStartOverlay()}}showStartOverlay(){if(this.updateState({status:c.WaitingForInteraction}),this.config.customStartOverlay){this.overlayElement=this.config.customStartOverlay,this.config.container.appendChild(this.overlayElement);return}const e=document.createElement("div");e.innerHTML=`
|
|
7
7
|
<div style="
|
|
8
8
|
position: absolute;
|
|
9
9
|
top: 0;
|
|
10
10
|
left: 0;
|
|
11
11
|
width: 100%;
|
|
12
12
|
height: 100%;
|
|
13
|
-
display:
|
|
14
|
-
|
|
15
|
-
justify-content: center;
|
|
16
|
-
background: rgba(0, 0, 0, 0.7);
|
|
13
|
+
display: table;
|
|
14
|
+
background: rgba(0, 0, 0, 0.5);
|
|
17
15
|
z-index: 100;
|
|
18
16
|
">
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
17
|
+
<div style="display: table-cell; vertical-align: middle; text-align: center;">
|
|
18
|
+
<button id="adgent-start-btn" style="
|
|
19
|
+
width: 80px;
|
|
20
|
+
height: 80px;
|
|
21
|
+
background: rgba(0, 0, 0, 0.7);
|
|
22
|
+
border: 3px solid #fff;
|
|
23
|
+
border-radius: 50%;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
display: inline-block;
|
|
26
|
+
line-height: 80px;
|
|
27
|
+
text-align: center;
|
|
28
|
+
color: #fff;
|
|
29
|
+
font-size: 40px;
|
|
30
|
+
padding: 0 0 0 8px; /* Optical center for triangle */
|
|
31
|
+
">
|
|
32
|
+
▶
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
31
35
|
</div>
|
|
32
|
-
`,e.style.cssText="position: absolute; top: 0; left: 0; width: 100%; height: 100%;";const t=e.querySelector("#adgent-start-btn");t==null||t.addEventListener("click",()=>this.onStartClick()),this.config.container.style.position="relative",this.config.container.appendChild(e),this.overlayElement=e,t==null||t.focus()}async onStartClick(){if(this.removeOverlay(),this.videoElement)try{await this.videoElement.play(),this.handlePlaybackStart()}catch(e){this.handleError(this.createError(
|
|
36
|
+
`,e.style.cssText="position: absolute; top: 0; left: 0; width: 100%; height: 100%;";const t=e.querySelector("#adgent-start-btn");t==null||t.addEventListener("click",()=>this.onStartClick()),this.config.container.style.position="relative",this.config.container.appendChild(e),this.overlayElement=e,t==null||t.focus()}async onStartClick(){if(this.removeOverlay(),this.videoElement)try{await this.videoElement.play(),this.handlePlaybackStart()}catch(e){this.handleError(this.createError(p.GENERAL_LINEAR_ERROR,`Playback failed: ${e}`))}}removeOverlay(){this.overlayElement&&(this.overlayElement.remove(),this.overlayElement=null)}handlePlaybackStart(){var e,t,i,s,a;this.updateState({status:c.Playing}),this.emit({type:"start"}),(t=(e=this.config).onStart)==null||t.call(e);const n=this.parser.aggregateImpressions(this.ads);(i=this.tracker)==null||i.fireImpressions(n),(s=this.tracker)==null||s.track("start"),(a=this.tracker)==null||a.track("creativeView"),this.setupSkipButton(),this.setupProgressUI(),this.log("Playback started")}handleTimeUpdate(e){var t,i,s;const a=e.currentTime,n=e.duration;if(!n||isNaN(n))return;const u=a/n*100,y=this.calculateQuartile(u);this.updateState({currentTime:a,duration:n}),this.updateSkipCountdown(a),(t=this.tracker)==null||t.updateMacroContext({adPlayhead:a}),this.updateProgressUI(a,n);const b={currentTime:a,duration:n,percentage:u,quartile:y};this.emit({type:"progress",data:b}),(s=(i=this.config).onProgress)==null||s.call(i,b),this.fireQuartileEvents(u)}calculateQuartile(e){return e>=100?4:e>=75?3:e>=50?2:e>=25?1:0}fireQuartileEvents(e){var t;const i=[{threshold:25,event:"firstQuartile"},{threshold:50,event:"midpoint"},{threshold:75,event:"thirdQuartile"}];for(const{threshold:s,event:a}of i)e>=s&&!this.quartilesFired.has(s)&&(this.quartilesFired.add(s),(t=this.tracker)==null||t.track(a),this.emit({type:"quartile",data:{quartile:a}}),this.log(`Quartile fired: ${a}`))}setupSkipButton(){var e;const t=this.getFirstLinearCreative(),i=(e=this.config.skipOffset)!=null?e:t==null?void 0:t.skipOffset;if(!i||i<=0)return;this.updateState({skipCountdown:i,canSkip:!1});const s=document.createElement("button");s.id="adgent-skip-btn",s.style.cssText=`
|
|
33
37
|
position: absolute;
|
|
34
38
|
bottom: 20px;
|
|
35
39
|
right: 20px;
|
|
@@ -42,4 +46,20 @@
|
|
|
42
46
|
cursor: pointer;
|
|
43
47
|
z-index: 101;
|
|
44
48
|
transition: opacity 0.3s;
|
|
45
|
-
`,s.textContent=`Skip in ${i}s`,s.addEventListener("click",()=>this.skip()),this.config.container.appendChild(s),this.skipButtonElement=s}updateSkipCountdown(e){var t;const i=this.getFirstLinearCreative(),s=(t=this.config.skipOffset)!=null?t:i==null?void 0:i.skipOffset;if(!s||!this.skipButtonElement)return;const a=Math.max(0,s-e);this.updateState({skipCountdown:a}),a<=0&&!this.state.canSkip?(this.updateState({canSkip:!0}),this.skipButtonElement.textContent=this.config.skipButtonText,this.skipButtonElement.style.opacity="1"):a>0&&(this.skipButtonElement.textContent=`Skip in ${Math.ceil(a)}s`,this.skipButtonElement.style.opacity="0.6")}skip(){var e,t,i;if(!this.state.canSkip){this.log("Skip not available yet");return}(e=this.tracker)==null||e.track("skip"),this.emit({type:"skip"}),(i=(t=this.config).onSkip)==null||i.call(t),this.destroy(),this.log("Ad skipped")}handleComplete(){var e,t,i;this.updateState({status:
|
|
49
|
+
`,s.textContent=`Skip in ${i}s`,s.addEventListener("click",()=>this.skip()),this.config.container.appendChild(s),this.skipButtonElement=s}updateSkipCountdown(e){var t;const i=this.getFirstLinearCreative(),s=(t=this.config.skipOffset)!=null?t:i==null?void 0:i.skipOffset;if(!s||!this.skipButtonElement)return;const a=Math.max(0,s-e);this.updateState({skipCountdown:a}),a<=0&&!this.state.canSkip?(this.updateState({canSkip:!0}),this.skipButtonElement.textContent=this.config.skipButtonText,this.skipButtonElement.style.opacity="1",this.skipButtonElement.focus()):a>0&&(this.skipButtonElement.textContent=`Skip in ${Math.ceil(a)}s`,this.skipButtonElement.style.opacity="0.6")}skip(){var e,t,i;if(!this.state.canSkip){this.log("Skip not available yet");return}(e=this.tracker)==null||e.track("skip"),this.emit({type:"skip"}),(i=(t=this.config).onSkip)==null||i.call(t),this.destroy(),this.log("Ad skipped")}handleComplete(){var e,t,i;this.updateState({status:c.Completed}),(e=this.tracker)==null||e.track("complete"),this.emit({type:"complete"}),(i=(t=this.config).onComplete)==null||i.call(t),this.log("Ad completed")}handleError(e){var t,i,s;this.updateState({status:c.Error,error:e});const a=[];for(const n of this.ads)a.push(...n.errors);(t=this.tracker)==null||t.fireError(a,e.code),this.emit({type:"error",data:e}),(s=(i=this.config).onError)==null||s.call(i,e),this.log(`Error: ${e.message}`)}setupFocusManagement(){this.focusTrap=document.createElement("div"),this.focusTrap.tabIndex=0,this.focusTrap.style.cssText="position: absolute; opacity: 0; width: 0; height: 0;",this.config.container.appendChild(this.focusTrap),this.focusTrap.focus(),this.boundKeyHandler=e=>{const t=this.platform.normalizeKeyCode(e.keyCode);t&&(e.preventDefault(),e.stopPropagation(),this.handleKeyAction(t))},document.addEventListener("keydown",this.boundKeyHandler,!0)}setupProgressUI(){const e=document.createElement("div");e.style.cssText=`
|
|
50
|
+
position: absolute;
|
|
51
|
+
top: 20px;
|
|
52
|
+
left: 20px;
|
|
53
|
+
background: rgba(0, 0, 0, 0.7);
|
|
54
|
+
color: #fff;
|
|
55
|
+
padding: 6px 12px;
|
|
56
|
+
border-radius: 4px;
|
|
57
|
+
font-size: 14px;
|
|
58
|
+
font-family: sans-serif;
|
|
59
|
+
z-index: 101;
|
|
60
|
+
display: block;
|
|
61
|
+
white-space: nowrap;
|
|
62
|
+
`,e.innerHTML=`
|
|
63
|
+
<span style="display: inline-block; vertical-align: middle; margin-right: 8px; background: #f4b400; color: #000; padding: 2px 4px; border-radius: 2px; font-weight: bold; font-size: 12px;">Ad</span>
|
|
64
|
+
<span id="adgent-progress-text" style="display: inline-block; vertical-align: middle;">1 of ${this.ads.length} • 0:00</span>
|
|
65
|
+
`,this.config.container.appendChild(e),this.progressElement=e}updateProgressUI(e,t){if(!this.progressElement)return;const i=Math.ceil(t-e),s=Math.floor(i/60),a=i%60,n=`${s}:${a.toString().padStart(2,"0")}`,u=this.progressElement.querySelector("#adgent-progress-text");u&&(u.textContent=`1 of ${this.ads.length} • ${n}`)}handleKeyAction(e){var t,i;switch(this.log(`Key action: ${e}`),e){case h.Enter:this.state.status===c.WaitingForInteraction?this.onStartClick():this.state.canSkip&&this.skip();break;case h.Back:this.log("Back pressed - ignoring during ad");break;case h.Play:(t=this.videoElement)==null||t.play();break;case h.Pause:(i=this.videoElement)==null||i.pause();break;case h.Left:case h.Right:case h.Up:case h.Down:break}}unmute(){var e;this.videoElement&&(this.videoElement.muted=!1,this.updateState({muted:!1}),(e=this.tracker)==null||e.track("unmute"),this.emit({type:"unmute"}))}mute(){var e;this.videoElement&&(this.videoElement.muted=!0,this.updateState({muted:!0}),(e=this.tracker)==null||e.track("mute"),this.emit({type:"mute"}))}on(e){return this.listeners.add(e),()=>this.listeners.delete(e)}getState(){return{...this.state}}destroy(){var e,t,i,s,a,n;this.boundKeyHandler&&(document.removeEventListener("keydown",this.boundKeyHandler,!0),this.boundKeyHandler=null),(e=this.videoElement)==null||e.remove(),(t=this.overlayElement)==null||t.remove(),(i=this.skipButtonElement)==null||i.remove(),(s=this.progressElement)==null||s.remove(),(a=this.focusTrap)==null||a.remove(),this.videoElement=null,this.overlayElement=null,this.skipButtonElement=null,this.progressElement=null,this.focusTrap=null,(n=this.tracker)==null||n.reset(),this.quartilesFired.clear(),this.listeners.clear(),this.ads=[],this.emit({type:"destroy"}),this.log("Player destroyed")}updateState(e){this.state={...this.state,...e}}emit(e){for(const t of this.listeners)try{t(e)}catch(i){this.log(`Listener error: ${i}`)}}createError(e,t,i=!1){return{code:e,message:t,recoverable:i}}log(e){this.config.debug&&this.platform.debug(e)}}l.AdPlayer=O,l.AdTracker=A,l.AdgentSDK=O,l.DEFAULT_KEY_CODES=T,l.KeyAction=h,l.PLATFORM_DETECTION_PATTERNS=S,l.Platform=o,l.PlatformAdapter=P,l.PlaybackStatus=c,l.VASTErrorCode=p,l.VASTParser=k,l.getPlatformAdapter=_,l.replaceMacros=m,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ declare class AdPlayer {
|
|
|
36
36
|
private videoElement;
|
|
37
37
|
private overlayElement;
|
|
38
38
|
private skipButtonElement;
|
|
39
|
+
private progressElement;
|
|
39
40
|
private tracker;
|
|
40
41
|
private state;
|
|
41
42
|
private ads;
|
|
@@ -114,6 +115,14 @@ declare class AdPlayer {
|
|
|
114
115
|
* Set up focus management to capture remote keys
|
|
115
116
|
*/
|
|
116
117
|
private setupFocusManagement;
|
|
118
|
+
/**
|
|
119
|
+
* Set up progress UI in top-left
|
|
120
|
+
*/
|
|
121
|
+
private setupProgressUI;
|
|
122
|
+
/**
|
|
123
|
+
* Update progress UI text
|
|
124
|
+
*/
|
|
125
|
+
private updateProgressUI;
|
|
117
126
|
/**
|
|
118
127
|
* Handle key actions from remote control
|
|
119
128
|
*/
|
|
@@ -630,6 +639,11 @@ export declare class PlatformAdapter implements IPlatformAdapter {
|
|
|
630
639
|
preferredCodec: string;
|
|
631
640
|
maxResolution: string;
|
|
632
641
|
};
|
|
642
|
+
/**
|
|
643
|
+
* Show debug message using platform-specific native notifications
|
|
644
|
+
* Falls back to console.log
|
|
645
|
+
*/
|
|
646
|
+
debug(message: string): void;
|
|
633
647
|
}
|
|
634
648
|
|
|
635
649
|
/** Platform capability flags */
|