adgent-sdk 0.1.2 → 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 +383 -344
- 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,17 +1,14 @@
|
|
|
1
|
-
var R = Object.defineProperty;
|
|
2
|
-
var S = (i, e, r) => e in i ? R(i, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : i[e] = r;
|
|
3
|
-
var l = (i, e, r) => S(i, typeof e != "symbol" ? e + "" : e, r);
|
|
4
1
|
import { XMLParser as T } from "fast-xml-parser";
|
|
5
|
-
var
|
|
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);
|
|
6
3
|
class A {
|
|
7
4
|
constructor(e = {}) {
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
b(this, "config"), b(this, "xmlParser");
|
|
6
|
+
var t, i, s, a;
|
|
10
7
|
this.config = {
|
|
11
|
-
maxWrapperDepth: e.maxWrapperDepth
|
|
12
|
-
timeout: e.timeout
|
|
13
|
-
debug: e.debug
|
|
14
|
-
fetchFn: e.fetchFn
|
|
8
|
+
maxWrapperDepth: (t = e.maxWrapperDepth) != null ? t : 5,
|
|
9
|
+
timeout: (i = e.timeout) != null ? i : 1e4,
|
|
10
|
+
debug: (s = e.debug) != null ? s : !1,
|
|
11
|
+
fetchFn: (a = e.fetchFn) != null ? a : fetch.bind(globalThis)
|
|
15
12
|
}, this.xmlParser = new T({
|
|
16
13
|
ignoreAttributes: !1,
|
|
17
14
|
attributeNamePrefix: "@_",
|
|
@@ -27,13 +24,13 @@ class A {
|
|
|
27
24
|
async parse(e) {
|
|
28
25
|
try {
|
|
29
26
|
return { success: !0, response: await this.fetchAndParse(e, 0) };
|
|
30
|
-
} catch (
|
|
31
|
-
const
|
|
27
|
+
} catch (t) {
|
|
28
|
+
const i = t instanceof Error ? t.message : "Unknown error";
|
|
32
29
|
return {
|
|
33
30
|
success: !1,
|
|
34
31
|
error: {
|
|
35
|
-
code:
|
|
36
|
-
message:
|
|
32
|
+
code: p.GENERAL_WRAPPER_ERROR,
|
|
33
|
+
message: i
|
|
37
34
|
}
|
|
38
35
|
};
|
|
39
36
|
}
|
|
@@ -41,16 +38,16 @@ class A {
|
|
|
41
38
|
/**
|
|
42
39
|
* Fetch and parse VAST document with wrapper resolution
|
|
43
40
|
*/
|
|
44
|
-
async fetchAndParse(e,
|
|
45
|
-
if (
|
|
41
|
+
async fetchAndParse(e, t) {
|
|
42
|
+
if (t >= this.config.maxWrapperDepth)
|
|
46
43
|
throw new Error(
|
|
47
44
|
`Wrapper limit exceeded (max: ${this.config.maxWrapperDepth})`
|
|
48
45
|
);
|
|
49
|
-
this.log(`Fetching VAST (depth: ${
|
|
50
|
-
const
|
|
46
|
+
this.log(`Fetching VAST (depth: ${t}): ${e}`);
|
|
47
|
+
const i = await this.fetchWithTimeout(e), s = this.parseXml(i), a = await Promise.all(
|
|
51
48
|
s.ads.map(async (n) => {
|
|
52
|
-
var
|
|
53
|
-
return (
|
|
49
|
+
var d;
|
|
50
|
+
return (d = n.wrapper) != null && d.vastAdTagURI ? this.resolveWrapper(n, t + 1) : n;
|
|
54
51
|
})
|
|
55
52
|
);
|
|
56
53
|
return {
|
|
@@ -61,14 +58,14 @@ class A {
|
|
|
61
58
|
/**
|
|
62
59
|
* Resolve a wrapper ad by fetching the nested VAST
|
|
63
60
|
*/
|
|
64
|
-
async resolveWrapper(e,
|
|
65
|
-
var
|
|
66
|
-
if (!((
|
|
61
|
+
async resolveWrapper(e, t) {
|
|
62
|
+
var i;
|
|
63
|
+
if (!((i = e.wrapper) != null && i.vastAdTagURI))
|
|
67
64
|
return [e];
|
|
68
65
|
try {
|
|
69
66
|
return (await this.fetchAndParse(
|
|
70
67
|
e.wrapper.vastAdTagURI,
|
|
71
|
-
|
|
68
|
+
t
|
|
72
69
|
)).ads.map(
|
|
73
70
|
(a) => this.mergeWrapperTracking(e, a)
|
|
74
71
|
);
|
|
@@ -81,21 +78,21 @@ class A {
|
|
|
81
78
|
/**
|
|
82
79
|
* Merge tracking events from wrapper into nested ad
|
|
83
80
|
*/
|
|
84
|
-
mergeWrapperTracking(e,
|
|
81
|
+
mergeWrapperTracking(e, t) {
|
|
85
82
|
return {
|
|
86
|
-
...
|
|
83
|
+
...t,
|
|
87
84
|
impressions: [
|
|
88
85
|
...e.impressions,
|
|
89
|
-
...
|
|
86
|
+
...t.impressions
|
|
90
87
|
],
|
|
91
|
-
errors: [...e.errors, ...
|
|
92
|
-
creatives:
|
|
93
|
-
...
|
|
94
|
-
linear:
|
|
95
|
-
...
|
|
88
|
+
errors: [...e.errors, ...t.errors],
|
|
89
|
+
creatives: t.creatives.map((i) => ({
|
|
90
|
+
...i,
|
|
91
|
+
linear: i.linear ? {
|
|
92
|
+
...i.linear,
|
|
96
93
|
trackingEvents: [
|
|
97
94
|
...this.getWrapperTrackingEvents(e),
|
|
98
|
-
...
|
|
95
|
+
...i.linear.trackingEvents
|
|
99
96
|
]
|
|
100
97
|
} : void 0
|
|
101
98
|
}))
|
|
@@ -106,79 +103,79 @@ class A {
|
|
|
106
103
|
*/
|
|
107
104
|
getWrapperTrackingEvents(e) {
|
|
108
105
|
var t;
|
|
109
|
-
const
|
|
106
|
+
const i = [];
|
|
110
107
|
for (const s of e.creatives)
|
|
111
|
-
(t = s.linear) != null && t.trackingEvents &&
|
|
112
|
-
return
|
|
108
|
+
(t = s.linear) != null && t.trackingEvents && i.push(...s.linear.trackingEvents);
|
|
109
|
+
return i;
|
|
113
110
|
}
|
|
114
111
|
/**
|
|
115
112
|
* Fetch URL with timeout
|
|
116
113
|
*/
|
|
117
114
|
async fetchWithTimeout(e) {
|
|
118
|
-
const
|
|
119
|
-
() =>
|
|
115
|
+
const t = new AbortController(), i = setTimeout(
|
|
116
|
+
() => t.abort(),
|
|
120
117
|
this.config.timeout
|
|
121
118
|
);
|
|
122
119
|
try {
|
|
123
120
|
const s = await this.config.fetchFn(e, {
|
|
124
|
-
signal:
|
|
121
|
+
signal: t.signal
|
|
125
122
|
});
|
|
126
123
|
if (!s.ok)
|
|
127
124
|
throw new Error(`HTTP ${s.status}: ${s.statusText}`);
|
|
128
125
|
return s.text();
|
|
129
126
|
} finally {
|
|
130
|
-
clearTimeout(
|
|
127
|
+
clearTimeout(i);
|
|
131
128
|
}
|
|
132
129
|
}
|
|
133
130
|
/**
|
|
134
131
|
* Parse raw VAST XML into structured response
|
|
135
132
|
*/
|
|
136
133
|
parseXml(e) {
|
|
137
|
-
const
|
|
138
|
-
if (!
|
|
134
|
+
const i = this.xmlParser.parse(e).VAST;
|
|
135
|
+
if (!i)
|
|
139
136
|
throw new Error("Invalid VAST: missing VAST element");
|
|
140
|
-
const s =
|
|
137
|
+
const s = i["@_version"] || "4.0", a = this.parseAds(i.Ad);
|
|
141
138
|
return {
|
|
142
139
|
version: s,
|
|
143
140
|
ads: a,
|
|
144
|
-
errors: this.parseErrors(
|
|
141
|
+
errors: this.parseErrors(i.Error)
|
|
145
142
|
};
|
|
146
143
|
}
|
|
147
144
|
/**
|
|
148
145
|
* Parse Ad elements
|
|
149
146
|
*/
|
|
150
147
|
parseAds(e) {
|
|
151
|
-
return e ? (Array.isArray(e) ? e : [e]).map((
|
|
148
|
+
return e ? (Array.isArray(e) ? e : [e]).map((i) => this.parseAd(i)) : [];
|
|
152
149
|
}
|
|
153
150
|
/**
|
|
154
151
|
* Parse a single Ad element
|
|
155
152
|
*/
|
|
156
153
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
157
154
|
parseAd(e) {
|
|
158
|
-
var
|
|
159
|
-
const
|
|
155
|
+
var t, i, s;
|
|
156
|
+
const a = !!e.Wrapper, n = e.InLine || e.Wrapper;
|
|
160
157
|
return {
|
|
161
158
|
id: e["@_id"] || "",
|
|
162
159
|
sequence: e["@_sequence"],
|
|
163
|
-
adSystem:
|
|
164
|
-
name: typeof
|
|
165
|
-
version: (
|
|
160
|
+
adSystem: n != null && n.AdSystem ? {
|
|
161
|
+
name: typeof n.AdSystem == "string" ? n.AdSystem : n.AdSystem["#text"] || "",
|
|
162
|
+
version: (t = n.AdSystem) == null ? void 0 : t["@_version"]
|
|
166
163
|
} : void 0,
|
|
167
|
-
adTitle:
|
|
168
|
-
impressions: this.parseImpressions(
|
|
169
|
-
errors: this.parseErrors(
|
|
170
|
-
creatives: this.parseCreatives((
|
|
171
|
-
wrapper:
|
|
172
|
-
vastAdTagURI:
|
|
173
|
-
followAdditionalWrappers:
|
|
174
|
-
allowMultipleAds:
|
|
175
|
-
fallbackOnNoAd:
|
|
164
|
+
adTitle: n == null ? void 0 : n.AdTitle,
|
|
165
|
+
impressions: this.parseImpressions(n == null ? void 0 : n.Impression),
|
|
166
|
+
errors: this.parseErrors(n == null ? void 0 : n.Error),
|
|
167
|
+
creatives: this.parseCreatives((i = n == null ? void 0 : n.Creatives) == null ? void 0 : i.Creative),
|
|
168
|
+
wrapper: a ? {
|
|
169
|
+
vastAdTagURI: n.VASTAdTagURI,
|
|
170
|
+
followAdditionalWrappers: n["@_followAdditionalWrappers"] !== !1,
|
|
171
|
+
allowMultipleAds: n["@_allowMultipleAds"],
|
|
172
|
+
fallbackOnNoAd: n["@_fallbackOnNoAd"]
|
|
176
173
|
} : void 0,
|
|
177
|
-
inLine:
|
|
178
|
-
adTitle: (
|
|
179
|
-
description:
|
|
180
|
-
advertiser:
|
|
181
|
-
creatives: this.parseCreatives((
|
|
174
|
+
inLine: a ? void 0 : {
|
|
175
|
+
adTitle: (n == null ? void 0 : n.AdTitle) || "",
|
|
176
|
+
description: n == null ? void 0 : n.Description,
|
|
177
|
+
advertiser: n == null ? void 0 : n.Advertiser,
|
|
178
|
+
creatives: this.parseCreatives((s = n == null ? void 0 : n.Creatives) == null ? void 0 : s.Creative)
|
|
182
179
|
}
|
|
183
180
|
};
|
|
184
181
|
}
|
|
@@ -186,20 +183,20 @@ class A {
|
|
|
186
183
|
* Parse Impression elements
|
|
187
184
|
*/
|
|
188
185
|
parseImpressions(e) {
|
|
189
|
-
return e ? (Array.isArray(e) ? e : [e]).map((
|
|
190
|
-
id:
|
|
191
|
-
url: typeof
|
|
186
|
+
return e ? (Array.isArray(e) ? e : [e]).map((i) => ({
|
|
187
|
+
id: i["@_id"],
|
|
188
|
+
url: typeof i == "string" ? i : i["#text"] || ""
|
|
192
189
|
})) : [];
|
|
193
190
|
}
|
|
194
191
|
/**
|
|
195
192
|
* Parse Creative elements
|
|
196
193
|
*/
|
|
197
194
|
parseCreatives(e) {
|
|
198
|
-
return e ? (Array.isArray(e) ? e : [e]).map((
|
|
199
|
-
id:
|
|
200
|
-
sequence:
|
|
201
|
-
adId:
|
|
202
|
-
linear:
|
|
195
|
+
return e ? (Array.isArray(e) ? e : [e]).map((i) => ({
|
|
196
|
+
id: i["@_id"],
|
|
197
|
+
sequence: i["@_sequence"],
|
|
198
|
+
adId: i["@_adId"],
|
|
199
|
+
linear: i.Linear ? this.parseLinear(i.Linear) : void 0
|
|
203
200
|
})) : [];
|
|
204
201
|
}
|
|
205
202
|
/**
|
|
@@ -207,13 +204,13 @@ class A {
|
|
|
207
204
|
*/
|
|
208
205
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
209
206
|
parseLinear(e) {
|
|
210
|
-
var
|
|
207
|
+
var t, i;
|
|
211
208
|
return {
|
|
212
209
|
duration: this.parseDuration(e.Duration),
|
|
213
210
|
skipOffset: e["@_skipoffset"] ? this.parseDuration(e["@_skipoffset"]) : void 0,
|
|
214
|
-
mediaFiles: this.parseMediaFiles((
|
|
211
|
+
mediaFiles: this.parseMediaFiles((t = e.MediaFiles) == null ? void 0 : t.MediaFile),
|
|
215
212
|
trackingEvents: this.parseTrackingEvents(
|
|
216
|
-
(
|
|
213
|
+
(i = e.TrackingEvents) == null ? void 0 : i.Tracking
|
|
217
214
|
),
|
|
218
215
|
videoClicks: e.VideoClicks ? {
|
|
219
216
|
clickThrough: e.VideoClicks.ClickThrough ? {
|
|
@@ -228,34 +225,34 @@ class A {
|
|
|
228
225
|
* Parse MediaFile elements
|
|
229
226
|
*/
|
|
230
227
|
parseMediaFiles(e) {
|
|
231
|
-
return e ? (Array.isArray(e) ? e : [e]).map((
|
|
232
|
-
id:
|
|
233
|
-
url: typeof
|
|
234
|
-
delivery:
|
|
235
|
-
type:
|
|
236
|
-
width: parseInt(
|
|
237
|
-
height: parseInt(
|
|
238
|
-
bitrate:
|
|
239
|
-
codec:
|
|
240
|
-
scalable:
|
|
241
|
-
maintainAspectRatio:
|
|
228
|
+
return e ? (Array.isArray(e) ? e : [e]).map((i) => ({
|
|
229
|
+
id: i["@_id"],
|
|
230
|
+
url: typeof i == "string" ? i : i["#text"] || "",
|
|
231
|
+
delivery: i["@_delivery"] || "progressive",
|
|
232
|
+
type: i["@_type"] || "video/mp4",
|
|
233
|
+
width: parseInt(i["@_width"], 10) || 0,
|
|
234
|
+
height: parseInt(i["@_height"], 10) || 0,
|
|
235
|
+
bitrate: i["@_bitrate"] ? parseInt(i["@_bitrate"], 10) : void 0,
|
|
236
|
+
codec: i["@_codec"],
|
|
237
|
+
scalable: i["@_scalable"],
|
|
238
|
+
maintainAspectRatio: i["@_maintainAspectRatio"]
|
|
242
239
|
})) : [];
|
|
243
240
|
}
|
|
244
241
|
/**
|
|
245
242
|
* Parse Tracking elements
|
|
246
243
|
*/
|
|
247
244
|
parseTrackingEvents(e) {
|
|
248
|
-
return e ? (Array.isArray(e) ? e : [e]).map((
|
|
249
|
-
event:
|
|
250
|
-
url: typeof
|
|
251
|
-
offset:
|
|
245
|
+
return e ? (Array.isArray(e) ? e : [e]).map((i) => ({
|
|
246
|
+
event: i["@_event"],
|
|
247
|
+
url: typeof i == "string" ? i : i["#text"] || "",
|
|
248
|
+
offset: i["@_offset"] ? this.parseDuration(i["@_offset"]) : void 0
|
|
252
249
|
})) : [];
|
|
253
250
|
}
|
|
254
251
|
/**
|
|
255
252
|
* Parse Error elements
|
|
256
253
|
*/
|
|
257
254
|
parseErrors(e) {
|
|
258
|
-
return e ? (Array.isArray(e) ? e : [e]).map((
|
|
255
|
+
return e ? (Array.isArray(e) ? e : [e]).map((i) => typeof i == "string" ? i : i["#text"] || "") : [];
|
|
259
256
|
}
|
|
260
257
|
/**
|
|
261
258
|
* Parse duration string (HH:MM:SS or seconds) to seconds
|
|
@@ -265,10 +262,10 @@ class A {
|
|
|
265
262
|
if (typeof e != "string") return 0;
|
|
266
263
|
if (e.endsWith("%"))
|
|
267
264
|
return parseFloat(e) / 100;
|
|
268
|
-
const
|
|
269
|
-
if (
|
|
270
|
-
const [,
|
|
271
|
-
return parseInt(
|
|
265
|
+
const t = e.match(/(\d+):(\d+):(\d+(?:\.\d+)?)/);
|
|
266
|
+
if (t) {
|
|
267
|
+
const [, i, s, a] = t;
|
|
268
|
+
return parseInt(i, 10) * 3600 + parseInt(s, 10) * 60 + parseFloat(a);
|
|
272
269
|
}
|
|
273
270
|
return parseFloat(e) || 0;
|
|
274
271
|
}
|
|
@@ -276,14 +273,14 @@ class A {
|
|
|
276
273
|
* Select the best media file based on target bitrate
|
|
277
274
|
* Prefers 1080p/720p over 4K for TV compatibility
|
|
278
275
|
*/
|
|
279
|
-
selectBestMediaFile(e,
|
|
276
|
+
selectBestMediaFile(e, t = 2500) {
|
|
280
277
|
if (e.length === 0) return null;
|
|
281
|
-
const
|
|
278
|
+
const i = e.filter(
|
|
282
279
|
(n) => n.type.includes("mp4") || n.type.includes("video/mp4")
|
|
283
280
|
);
|
|
284
|
-
return [...
|
|
285
|
-
const
|
|
286
|
-
return
|
|
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
|
+
return R - S;
|
|
287
284
|
})[0] || null;
|
|
288
285
|
}
|
|
289
286
|
/**
|
|
@@ -291,21 +288,21 @@ class A {
|
|
|
291
288
|
*/
|
|
292
289
|
aggregateTrackingEvents(e) {
|
|
293
290
|
var t;
|
|
294
|
-
const
|
|
291
|
+
const i = [];
|
|
295
292
|
for (const s of e)
|
|
296
293
|
for (const a of s.creatives)
|
|
297
|
-
(t = a.linear) != null && t.trackingEvents &&
|
|
298
|
-
return
|
|
294
|
+
(t = a.linear) != null && t.trackingEvents && i.push(...a.linear.trackingEvents);
|
|
295
|
+
return i;
|
|
299
296
|
}
|
|
300
297
|
/**
|
|
301
298
|
* Get all impression URLs from parsed ads
|
|
302
299
|
*/
|
|
303
300
|
aggregateImpressions(e) {
|
|
304
|
-
const
|
|
305
|
-
for (const
|
|
306
|
-
for (const s of
|
|
307
|
-
|
|
308
|
-
return
|
|
301
|
+
const t = [];
|
|
302
|
+
for (const i of e)
|
|
303
|
+
for (const s of i.impressions)
|
|
304
|
+
t.push(s.url);
|
|
305
|
+
return t;
|
|
309
306
|
}
|
|
310
307
|
/**
|
|
311
308
|
* Debug logging
|
|
@@ -314,31 +311,31 @@ class A {
|
|
|
314
311
|
this.config.debug && console.log(`[VASTParser] ${e}`);
|
|
315
312
|
}
|
|
316
313
|
}
|
|
317
|
-
function
|
|
318
|
-
let
|
|
319
|
-
return
|
|
314
|
+
function g(r, e = {}) {
|
|
315
|
+
let t = r;
|
|
316
|
+
return t = t.replace(/\[TIMESTAMP\]/g, Date.now().toString()), t = t.replace(
|
|
320
317
|
/\[CACHEBUSTING\]/g,
|
|
321
318
|
Math.random().toString(36).substring(2, 15)
|
|
322
|
-
), e.assetUri && (
|
|
319
|
+
), e.assetUri && (t = t.replace(
|
|
323
320
|
/\[ASSETURI\]/g,
|
|
324
321
|
encodeURIComponent(e.assetUri)
|
|
325
|
-
)), e.contentPlayhead !== void 0 && (
|
|
322
|
+
)), e.contentPlayhead !== void 0 && (t = t.replace(
|
|
326
323
|
/\[CONTENTPLAYHEAD\]/g,
|
|
327
|
-
|
|
328
|
-
)), e.adPlayhead !== void 0 && (
|
|
324
|
+
E(e.contentPlayhead)
|
|
325
|
+
)), e.adPlayhead !== void 0 && (t = t.replace(
|
|
329
326
|
/\[ADPLAYHEAD\]/g,
|
|
330
|
-
|
|
331
|
-
)), e.errorCode !== void 0 && (
|
|
327
|
+
E(e.adPlayhead)
|
|
328
|
+
)), e.errorCode !== void 0 && (t = t.replace(/\[ERRORCODE\]/g, e.errorCode.toString())), e.breakPosition !== void 0 && (t = t.replace(
|
|
332
329
|
/\[BREAKPOSITION\]/g,
|
|
333
330
|
e.breakPosition.toString()
|
|
334
|
-
)), e.adType && (
|
|
331
|
+
)), e.adType && (t = t.replace(/\[ADTYPE\]/g, e.adType)), t;
|
|
335
332
|
}
|
|
336
|
-
function
|
|
337
|
-
const e = Math.floor(
|
|
338
|
-
return e.toString().padStart(2, "0") + ":" +
|
|
333
|
+
function E(r) {
|
|
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
|
+
return e.toString().padStart(2, "0") + ":" + t.toString().padStart(2, "0") + ":" + i.toString().padStart(2, "0") + "." + s.toString().padStart(3, "0");
|
|
339
336
|
}
|
|
340
|
-
var o = /* @__PURE__ */ ((
|
|
341
|
-
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 = {
|
|
342
339
|
webos: {
|
|
343
340
|
13: "enter",
|
|
344
341
|
461: "back",
|
|
@@ -520,7 +517,7 @@ const _ = {
|
|
|
520
517
|
/* Mute */
|
|
521
518
|
// M key
|
|
522
519
|
}
|
|
523
|
-
},
|
|
520
|
+
}, I = {
|
|
524
521
|
tizen: [
|
|
525
522
|
/Tizen/i,
|
|
526
523
|
/SMART-TV.*Samsung/i
|
|
@@ -575,14 +572,10 @@ const _ = {
|
|
|
575
572
|
],
|
|
576
573
|
generic: []
|
|
577
574
|
};
|
|
578
|
-
|
|
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 {
|
|
579
577
|
constructor() {
|
|
580
|
-
|
|
581
|
-
l(this, "capabilities");
|
|
582
|
-
l(this, "deviceInfo");
|
|
583
|
-
l(this, "keyMap");
|
|
584
|
-
l(this, "reverseKeyMap");
|
|
585
|
-
this.platform = this.detectPlatform(), this.keyMap = _[this.platform], this.reverseKeyMap = this.buildReverseKeyMap(), this.capabilities = this.detectCapabilities(), this.deviceInfo = this.detectDeviceInfo();
|
|
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();
|
|
586
579
|
}
|
|
587
580
|
/**
|
|
588
581
|
* Detect the current Smart TV platform using userAgent and global objects
|
|
@@ -590,16 +583,16 @@ class O {
|
|
|
590
583
|
detectPlatform() {
|
|
591
584
|
if (typeof window > "u" || typeof navigator > "u")
|
|
592
585
|
return o.Generic;
|
|
593
|
-
const e = navigator.userAgent,
|
|
594
|
-
if (
|
|
586
|
+
const e = navigator.userAgent, t = window;
|
|
587
|
+
if (t.tizen)
|
|
595
588
|
return o.Tizen;
|
|
596
|
-
if (
|
|
589
|
+
if (t.webOS || t.PalmSystem)
|
|
597
590
|
return o.WebOS;
|
|
598
|
-
for (const [
|
|
599
|
-
if (
|
|
591
|
+
for (const [i, s] of Object.entries(I))
|
|
592
|
+
if (i !== o.Generic) {
|
|
600
593
|
for (const a of s)
|
|
601
594
|
if (a.test(e))
|
|
602
|
-
return
|
|
595
|
+
return i;
|
|
603
596
|
}
|
|
604
597
|
return o.Generic;
|
|
605
598
|
}
|
|
@@ -607,11 +600,11 @@ class O {
|
|
|
607
600
|
* Detect platform capabilities
|
|
608
601
|
*/
|
|
609
602
|
detectCapabilities() {
|
|
610
|
-
const e = typeof navigator < "u",
|
|
603
|
+
const e = typeof navigator < "u", t = typeof document < "u", i = typeof window < "u", s = {
|
|
611
604
|
sendBeacon: e && "sendBeacon" in navigator,
|
|
612
605
|
fetchKeepalive: typeof fetch < "u",
|
|
613
606
|
mutedAutoplayRequired: !0,
|
|
614
|
-
fullscreen:
|
|
607
|
+
fullscreen: t && ("fullscreenEnabled" in document || "webkitFullscreenEnabled" in document),
|
|
615
608
|
hardwareDecodeInfo: !1,
|
|
616
609
|
hdr: !1,
|
|
617
610
|
hdr10Plus: !1,
|
|
@@ -621,7 +614,7 @@ class O {
|
|
|
621
614
|
vp9: this.isCodecSupported('video/webm; codecs="vp9"'),
|
|
622
615
|
av1: this.isCodecSupported('video/mp4; codecs="av01.0.05M.08"'),
|
|
623
616
|
maxResolution: this.detectMaxResolution(),
|
|
624
|
-
touch:
|
|
617
|
+
touch: i && "ontouchstart" in window,
|
|
625
618
|
voice: !1
|
|
626
619
|
};
|
|
627
620
|
switch (this.platform) {
|
|
@@ -693,46 +686,46 @@ class O {
|
|
|
693
686
|
* Detect device information
|
|
694
687
|
*/
|
|
695
688
|
detectDeviceInfo() {
|
|
696
|
-
var
|
|
697
|
-
const
|
|
689
|
+
var e, t, i;
|
|
690
|
+
const s = {
|
|
698
691
|
platform: this.platform
|
|
699
692
|
};
|
|
700
|
-
typeof window < "u" && (
|
|
701
|
-
const
|
|
702
|
-
if (this.platform === o.Tizen && ((
|
|
693
|
+
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);
|
|
694
|
+
const a = window;
|
|
695
|
+
if (this.platform === o.Tizen && ((i = a.tizen) != null && i.systeminfo))
|
|
703
696
|
try {
|
|
704
|
-
|
|
705
|
-
|
|
697
|
+
a.tizen.systeminfo.getPropertyValue("BUILD", (n) => {
|
|
698
|
+
s.model = n.model, s.manufacturer = n.manufacturer || "Samsung";
|
|
706
699
|
});
|
|
707
700
|
} catch {
|
|
708
|
-
|
|
701
|
+
s.manufacturer = "Samsung";
|
|
709
702
|
}
|
|
710
|
-
if (this.platform === o.WebOS &&
|
|
703
|
+
if (this.platform === o.WebOS && a.webOSSystem)
|
|
711
704
|
try {
|
|
712
|
-
const n =
|
|
713
|
-
|
|
705
|
+
const n = a.webOSSystem.deviceInfo;
|
|
706
|
+
s.model = n == null ? void 0 : n.modelName, s.manufacturer = "LG", s.osVersion = n == null ? void 0 : n.version;
|
|
714
707
|
} catch {
|
|
715
|
-
|
|
708
|
+
s.manufacturer = "LG";
|
|
716
709
|
}
|
|
717
|
-
return
|
|
710
|
+
return s;
|
|
718
711
|
}
|
|
719
712
|
/**
|
|
720
713
|
* Detect maximum supported resolution
|
|
721
714
|
*/
|
|
722
715
|
detectMaxResolution() {
|
|
723
|
-
var
|
|
716
|
+
var e, t;
|
|
724
717
|
if (typeof window > "u") return "unknown";
|
|
725
|
-
const
|
|
726
|
-
return
|
|
718
|
+
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);
|
|
719
|
+
return a >= 3840 ? "4k" : a >= 1920 ? "1080p" : a >= 1280 ? "720p" : "unknown";
|
|
727
720
|
}
|
|
728
721
|
/**
|
|
729
722
|
* Build reverse mapping from KeyAction to key codes
|
|
730
723
|
*/
|
|
731
724
|
buildReverseKeyMap() {
|
|
732
725
|
const e = /* @__PURE__ */ new Map();
|
|
733
|
-
for (const [
|
|
734
|
-
const s = parseInt(
|
|
735
|
-
a.push(s), e.set(
|
|
726
|
+
for (const [t, i] of Object.entries(this.keyMap)) {
|
|
727
|
+
const s = parseInt(t, 10), a = e.get(i) || [];
|
|
728
|
+
a.push(s), e.set(i, a);
|
|
736
729
|
}
|
|
737
730
|
return e;
|
|
738
731
|
}
|
|
@@ -742,7 +735,8 @@ class O {
|
|
|
742
735
|
* @returns KeyAction or null if not mapped
|
|
743
736
|
*/
|
|
744
737
|
normalizeKeyCode(e) {
|
|
745
|
-
|
|
738
|
+
var t;
|
|
739
|
+
return (t = this.keyMap[e]) != null ? t : null;
|
|
746
740
|
}
|
|
747
741
|
/**
|
|
748
742
|
* Get all key codes that map to a specific action
|
|
@@ -760,8 +754,8 @@ class O {
|
|
|
760
754
|
isCodecSupported(e) {
|
|
761
755
|
if (typeof document > "u") return !1;
|
|
762
756
|
try {
|
|
763
|
-
const
|
|
764
|
-
return
|
|
757
|
+
const i = document.createElement("video").canPlayType(e);
|
|
758
|
+
return i === "probably" || i === "maybe";
|
|
765
759
|
} catch {
|
|
766
760
|
return !1;
|
|
767
761
|
}
|
|
@@ -785,9 +779,9 @@ class O {
|
|
|
785
779
|
"ColorF2Yellow",
|
|
786
780
|
"ColorF3Blue",
|
|
787
781
|
"Info"
|
|
788
|
-
].forEach((
|
|
782
|
+
].forEach((i) => {
|
|
789
783
|
try {
|
|
790
|
-
e.tvinputdevice.registerKey(
|
|
784
|
+
e.tvinputdevice.registerKey(i);
|
|
791
785
|
} catch {
|
|
792
786
|
}
|
|
793
787
|
});
|
|
@@ -868,33 +862,51 @@ class O {
|
|
|
868
862
|
};
|
|
869
863
|
}
|
|
870
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
|
+
}
|
|
871
884
|
}
|
|
872
|
-
let
|
|
873
|
-
function
|
|
874
|
-
return
|
|
885
|
+
let y = null;
|
|
886
|
+
function _() {
|
|
887
|
+
return y || (y = new N()), y;
|
|
875
888
|
}
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
l(this, "macroContext");
|
|
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);
|
|
890
|
+
class L {
|
|
891
|
+
constructor(e = [], t = {}) {
|
|
892
|
+
m(this, "config"), m(this, "trackingEvents"), m(this, "firedEvents"), m(this, "macroContext");
|
|
893
|
+
var i, s, a;
|
|
882
894
|
this.config = {
|
|
883
|
-
debug:
|
|
884
|
-
retry:
|
|
885
|
-
maxRetries:
|
|
895
|
+
debug: (i = t.debug) != null ? i : !1,
|
|
896
|
+
retry: (s = t.retry) != null ? s : !1,
|
|
897
|
+
maxRetries: (a = t.maxRetries) != null ? a : 3
|
|
886
898
|
}, this.trackingEvents = this.groupEventsByType(e), this.firedEvents = /* @__PURE__ */ new Set(), this.macroContext = {};
|
|
887
899
|
}
|
|
888
900
|
/**
|
|
889
901
|
* Group tracking events by their event type
|
|
890
902
|
*/
|
|
891
903
|
groupEventsByType(e) {
|
|
892
|
-
const
|
|
893
|
-
for (const
|
|
894
|
-
const s =
|
|
895
|
-
s.push(
|
|
904
|
+
const t = /* @__PURE__ */ new Map();
|
|
905
|
+
for (const i of e) {
|
|
906
|
+
const s = t.get(i.event) || [];
|
|
907
|
+
s.push(i), t.set(i.event, s);
|
|
896
908
|
}
|
|
897
|
-
return
|
|
909
|
+
return t;
|
|
898
910
|
}
|
|
899
911
|
/**
|
|
900
912
|
* Update macro context for URL replacement
|
|
@@ -907,20 +919,20 @@ class x {
|
|
|
907
919
|
* @param eventType - The VAST event type to track
|
|
908
920
|
* @param once - Only fire once per event type (default: true)
|
|
909
921
|
*/
|
|
910
|
-
track(e,
|
|
911
|
-
const
|
|
912
|
-
if (!
|
|
922
|
+
track(e, t = !0) {
|
|
923
|
+
const i = this.trackingEvents.get(e);
|
|
924
|
+
if (!i) {
|
|
913
925
|
this.log(`No tracking URLs for event: ${e}`);
|
|
914
926
|
return;
|
|
915
927
|
}
|
|
916
|
-
for (const s of
|
|
928
|
+
for (const s of i) {
|
|
917
929
|
const a = `${e}:${s.url}`;
|
|
918
|
-
if (
|
|
930
|
+
if (t && this.firedEvents.has(a)) {
|
|
919
931
|
this.log(`Skipping duplicate event: ${e}`);
|
|
920
932
|
continue;
|
|
921
933
|
}
|
|
922
|
-
const n =
|
|
923
|
-
this.firePixel(n),
|
|
934
|
+
const n = g(s.url, this.macroContext);
|
|
935
|
+
this.firePixel(n), t && this.firedEvents.add(a);
|
|
924
936
|
}
|
|
925
937
|
}
|
|
926
938
|
/**
|
|
@@ -928,12 +940,12 @@ class x {
|
|
|
928
940
|
* Uses sendBeacon when available, falls back to fetch with keepalive
|
|
929
941
|
*/
|
|
930
942
|
firePixel(e) {
|
|
931
|
-
const
|
|
943
|
+
const t = _();
|
|
932
944
|
this.log(`Firing pixel: ${e}`);
|
|
933
945
|
try {
|
|
934
|
-
if (
|
|
946
|
+
if (t.capabilities.sendBeacon && navigator.sendBeacon(e))
|
|
935
947
|
return;
|
|
936
|
-
if (
|
|
948
|
+
if (t.capabilities.fetchKeepalive) {
|
|
937
949
|
fetch(e, {
|
|
938
950
|
method: "GET",
|
|
939
951
|
keepalive: !0,
|
|
@@ -952,17 +964,17 @@ class x {
|
|
|
952
964
|
* Image beacon fallback
|
|
953
965
|
*/
|
|
954
966
|
fireImageBeacon(e) {
|
|
955
|
-
const
|
|
956
|
-
|
|
967
|
+
const t = new Image(1, 1);
|
|
968
|
+
t.src = e;
|
|
957
969
|
}
|
|
958
970
|
/**
|
|
959
971
|
* Fire impression pixels
|
|
960
972
|
* @param impressionUrls - Array of impression URLs
|
|
961
973
|
*/
|
|
962
974
|
fireImpressions(e) {
|
|
963
|
-
for (const
|
|
964
|
-
const
|
|
965
|
-
this.firePixel(
|
|
975
|
+
for (const t of e) {
|
|
976
|
+
const i = g(t, this.macroContext);
|
|
977
|
+
this.firePixel(i);
|
|
966
978
|
}
|
|
967
979
|
}
|
|
968
980
|
/**
|
|
@@ -970,10 +982,10 @@ class x {
|
|
|
970
982
|
* @param errorUrls - Array of error tracking URLs
|
|
971
983
|
* @param errorCode - VAST error code
|
|
972
984
|
*/
|
|
973
|
-
fireError(e,
|
|
974
|
-
const
|
|
985
|
+
fireError(e, t) {
|
|
986
|
+
const i = { ...this.macroContext, errorCode: t };
|
|
975
987
|
for (const s of e) {
|
|
976
|
-
const a =
|
|
988
|
+
const a = g(s, i);
|
|
977
989
|
this.firePixel(a);
|
|
978
990
|
}
|
|
979
991
|
}
|
|
@@ -990,34 +1002,22 @@ class x {
|
|
|
990
1002
|
this.config.debug && console.log(`[AdTracker] ${e}`);
|
|
991
1003
|
}
|
|
992
1004
|
}
|
|
993
|
-
|
|
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);
|
|
1006
|
+
const B = {
|
|
994
1007
|
targetBitrate: 2500,
|
|
995
1008
|
maxWrapperDepth: 5,
|
|
996
1009
|
timeout: 1e4,
|
|
997
1010
|
debug: !1,
|
|
998
1011
|
skipButtonText: "Skip Ad"
|
|
999
1012
|
};
|
|
1000
|
-
class
|
|
1013
|
+
class V {
|
|
1001
1014
|
constructor(e) {
|
|
1002
|
-
l(this, "config")
|
|
1003
|
-
l(this, "platform");
|
|
1004
|
-
l(this, "parser");
|
|
1005
|
-
l(this, "videoElement", null);
|
|
1006
|
-
l(this, "overlayElement", null);
|
|
1007
|
-
l(this, "skipButtonElement", null);
|
|
1008
|
-
l(this, "tracker", null);
|
|
1009
|
-
l(this, "state");
|
|
1010
|
-
l(this, "ads", []);
|
|
1011
|
-
l(this, "listeners", /* @__PURE__ */ new Set());
|
|
1012
|
-
l(this, "quartilesFired", /* @__PURE__ */ new Set());
|
|
1013
|
-
l(this, "boundKeyHandler", null);
|
|
1014
|
-
l(this, "focusTrap", null);
|
|
1015
|
-
this.config = { ...I, ...e }, this.platform = y(), this.parser = new A({
|
|
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({
|
|
1016
1016
|
maxWrapperDepth: this.config.maxWrapperDepth,
|
|
1017
1017
|
timeout: this.config.timeout,
|
|
1018
1018
|
debug: this.config.debug
|
|
1019
1019
|
}), this.state = {
|
|
1020
|
-
status:
|
|
1020
|
+
status: c.Idle,
|
|
1021
1021
|
currentTime: 0,
|
|
1022
1022
|
duration: 0,
|
|
1023
1023
|
muted: !0,
|
|
@@ -1032,26 +1032,26 @@ class N {
|
|
|
1032
1032
|
* Initialize the SDK: fetch VAST, create video element, attempt autoplay
|
|
1033
1033
|
*/
|
|
1034
1034
|
async init() {
|
|
1035
|
-
var e,
|
|
1035
|
+
var e, t;
|
|
1036
1036
|
if (!this.config.container)
|
|
1037
1037
|
throw new Error("Container element not found");
|
|
1038
|
-
this.updateState({ status:
|
|
1038
|
+
this.updateState({ status: c.Loading });
|
|
1039
1039
|
try {
|
|
1040
|
-
const
|
|
1041
|
-
if (!
|
|
1040
|
+
const i = await this.parser.parse(this.config.vastUrl);
|
|
1041
|
+
if (!i.success || !i.response)
|
|
1042
1042
|
throw this.createError(
|
|
1043
|
-
((e =
|
|
1044
|
-
((
|
|
1043
|
+
((e = i.error) == null ? void 0 : e.code) || p.NO_VAST_RESPONSE,
|
|
1044
|
+
((t = i.error) == null ? void 0 : t.message) || "Failed to parse VAST"
|
|
1045
1045
|
);
|
|
1046
|
-
if (this.ads =
|
|
1046
|
+
if (this.ads = i.response.ads, this.ads.length === 0)
|
|
1047
1047
|
throw this.createError(
|
|
1048
|
-
|
|
1048
|
+
p.NO_VAST_RESPONSE,
|
|
1049
1049
|
"No ads in VAST response"
|
|
1050
1050
|
);
|
|
1051
1051
|
const s = this.getFirstLinearCreative();
|
|
1052
1052
|
if (!s)
|
|
1053
1053
|
throw this.createError(
|
|
1054
|
-
|
|
1054
|
+
p.GENERAL_LINEAR_ERROR,
|
|
1055
1055
|
"No linear creative found"
|
|
1056
1056
|
);
|
|
1057
1057
|
const a = this.parser.selectBestMediaFile(
|
|
@@ -1060,14 +1060,14 @@ class N {
|
|
|
1060
1060
|
);
|
|
1061
1061
|
if (!a)
|
|
1062
1062
|
throw this.createError(
|
|
1063
|
-
|
|
1063
|
+
p.FILE_NOT_FOUND,
|
|
1064
1064
|
"No suitable media file found"
|
|
1065
1065
|
);
|
|
1066
1066
|
this.updateState({ mediaFile: a });
|
|
1067
1067
|
const n = this.parser.aggregateTrackingEvents(this.ads);
|
|
1068
|
-
this.tracker = new
|
|
1069
|
-
} catch (
|
|
1070
|
-
const s =
|
|
1068
|
+
this.tracker = new L(n, { debug: this.config.debug }), this.tracker.updateMacroContext({ assetUri: a.url }), this.createVideoElement(a), this.setupFocusManagement(), await this.attemptAutoplay();
|
|
1069
|
+
} catch (i) {
|
|
1070
|
+
const s = i instanceof Error ? this.createError(p.UNDEFINED_ERROR, i.message) : i;
|
|
1071
1071
|
this.handleError(s);
|
|
1072
1072
|
}
|
|
1073
1073
|
}
|
|
@@ -1076,9 +1076,9 @@ class N {
|
|
|
1076
1076
|
*/
|
|
1077
1077
|
getFirstLinearCreative() {
|
|
1078
1078
|
for (const e of this.ads)
|
|
1079
|
-
for (const
|
|
1080
|
-
if (
|
|
1081
|
-
return
|
|
1079
|
+
for (const t of e.creatives)
|
|
1080
|
+
if (t.linear)
|
|
1081
|
+
return t.linear;
|
|
1082
1082
|
return null;
|
|
1083
1083
|
}
|
|
1084
1084
|
/**
|
|
@@ -1086,37 +1086,39 @@ class N {
|
|
|
1086
1086
|
* Applies muted, playsinline, autoplay for maximum TV compatibility
|
|
1087
1087
|
*/
|
|
1088
1088
|
createVideoElement(e) {
|
|
1089
|
-
const
|
|
1090
|
-
Object.entries(
|
|
1091
|
-
typeof
|
|
1092
|
-
}),
|
|
1089
|
+
const t = document.createElement("video"), i = this.platform.getVideoAttributes();
|
|
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 = `
|
|
1093
1095
|
width: 100%;
|
|
1094
1096
|
height: 100%;
|
|
1095
1097
|
object-fit: contain;
|
|
1096
1098
|
background: #000;
|
|
1097
|
-
`,
|
|
1099
|
+
`, t.addEventListener("loadedmetadata", () => {
|
|
1098
1100
|
this.updateState({
|
|
1099
|
-
duration:
|
|
1100
|
-
status:
|
|
1101
|
+
duration: t.duration,
|
|
1102
|
+
status: c.Ready
|
|
1101
1103
|
}), this.emit({ type: "loaded" });
|
|
1102
|
-
}),
|
|
1103
|
-
this.handleTimeUpdate(
|
|
1104
|
-
}),
|
|
1104
|
+
}), t.addEventListener("timeupdate", () => {
|
|
1105
|
+
this.handleTimeUpdate(t);
|
|
1106
|
+
}), t.addEventListener("ended", () => {
|
|
1105
1107
|
this.handleComplete();
|
|
1106
|
-
}),
|
|
1107
|
-
const
|
|
1108
|
+
}), t.addEventListener("error", () => {
|
|
1109
|
+
const a = t.error;
|
|
1108
1110
|
this.handleError(
|
|
1109
1111
|
this.createError(
|
|
1110
|
-
|
|
1111
|
-
(
|
|
1112
|
+
p.MEDIA_NOT_SUPPORTED,
|
|
1113
|
+
(a == null ? void 0 : a.message) || "Video playback error"
|
|
1112
1114
|
)
|
|
1113
1115
|
);
|
|
1114
|
-
}),
|
|
1115
|
-
this.updateState({ status:
|
|
1116
|
-
}),
|
|
1117
|
-
var
|
|
1118
|
-
this.state.status !==
|
|
1119
|
-
}), this.config.container.appendChild(
|
|
1116
|
+
}), t.addEventListener("play", () => {
|
|
1117
|
+
this.updateState({ status: c.Playing });
|
|
1118
|
+
}), t.addEventListener("pause", () => {
|
|
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"));
|
|
1121
|
+
}), this.config.container.appendChild(t), this.videoElement = t, this.log(`Video element created with src: ${e.url}`);
|
|
1120
1122
|
}
|
|
1121
1123
|
/**
|
|
1122
1124
|
* Attempt autoplay with soft-fail handling
|
|
@@ -1134,7 +1136,7 @@ class N {
|
|
|
1134
1136
|
* Show interactive overlay for manual ad start (autoplay fallback)
|
|
1135
1137
|
*/
|
|
1136
1138
|
showStartOverlay() {
|
|
1137
|
-
if (this.updateState({ status:
|
|
1139
|
+
if (this.updateState({ status: c.WaitingForInteraction }), this.config.customStartOverlay) {
|
|
1138
1140
|
this.overlayElement = this.config.customStartOverlay, this.config.container.appendChild(this.overlayElement);
|
|
1139
1141
|
return;
|
|
1140
1142
|
}
|
|
@@ -1146,28 +1148,32 @@ class N {
|
|
|
1146
1148
|
left: 0;
|
|
1147
1149
|
width: 100%;
|
|
1148
1150
|
height: 100%;
|
|
1149
|
-
display:
|
|
1150
|
-
|
|
1151
|
-
justify-content: center;
|
|
1152
|
-
background: rgba(0, 0, 0, 0.7);
|
|
1151
|
+
display: table;
|
|
1152
|
+
background: rgba(0, 0, 0, 0.5);
|
|
1153
1153
|
z-index: 100;
|
|
1154
1154
|
">
|
|
1155
|
-
<
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
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>
|
|
1167
1173
|
</div>
|
|
1168
1174
|
`, e.style.cssText = "position: absolute; top: 0; left: 0; width: 100%; height: 100%;";
|
|
1169
|
-
const
|
|
1170
|
-
|
|
1175
|
+
const t = e.querySelector("#adgent-start-btn");
|
|
1176
|
+
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();
|
|
1171
1177
|
}
|
|
1172
1178
|
/**
|
|
1173
1179
|
* Handle start button click (from overlay)
|
|
@@ -1179,7 +1185,7 @@ class N {
|
|
|
1179
1185
|
} catch (e) {
|
|
1180
1186
|
this.handleError(
|
|
1181
1187
|
this.createError(
|
|
1182
|
-
|
|
1188
|
+
p.GENERAL_LINEAR_ERROR,
|
|
1183
1189
|
`Playback failed: ${e}`
|
|
1184
1190
|
)
|
|
1185
1191
|
);
|
|
@@ -1195,30 +1201,30 @@ class N {
|
|
|
1195
1201
|
* Handle successful playback start
|
|
1196
1202
|
*/
|
|
1197
1203
|
handlePlaybackStart() {
|
|
1198
|
-
var
|
|
1199
|
-
this.updateState({ status:
|
|
1200
|
-
const
|
|
1201
|
-
(
|
|
1204
|
+
var e, t, i, s, a;
|
|
1205
|
+
this.updateState({ status: c.Playing }), this.emit({ type: "start" }), (t = (e = this.config).onStart) == null || t.call(e);
|
|
1206
|
+
const n = this.parser.aggregateImpressions(this.ads);
|
|
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");
|
|
1202
1208
|
}
|
|
1203
1209
|
/**
|
|
1204
1210
|
* Handle time updates for progress tracking
|
|
1205
1211
|
*/
|
|
1206
1212
|
handleTimeUpdate(e) {
|
|
1207
|
-
var
|
|
1208
|
-
const
|
|
1209
|
-
if (!
|
|
1210
|
-
const
|
|
1213
|
+
var t, i, s;
|
|
1214
|
+
const a = e.currentTime, n = e.duration;
|
|
1215
|
+
if (!n || isNaN(n)) return;
|
|
1216
|
+
const d = a / n * 100, f = this.calculateQuartile(d);
|
|
1211
1217
|
this.updateState({
|
|
1212
|
-
currentTime:
|
|
1213
|
-
duration:
|
|
1214
|
-
}), this.updateSkipCountdown(
|
|
1215
|
-
const
|
|
1216
|
-
currentTime:
|
|
1217
|
-
duration:
|
|
1218
|
-
percentage:
|
|
1219
|
-
quartile:
|
|
1218
|
+
currentTime: a,
|
|
1219
|
+
duration: n
|
|
1220
|
+
}), this.updateSkipCountdown(a), (t = this.tracker) == null || t.updateMacroContext({ adPlayhead: a }), this.updateProgressUI(a, n);
|
|
1221
|
+
const v = {
|
|
1222
|
+
currentTime: a,
|
|
1223
|
+
duration: n,
|
|
1224
|
+
percentage: d,
|
|
1225
|
+
quartile: f
|
|
1220
1226
|
};
|
|
1221
|
-
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);
|
|
1222
1228
|
}
|
|
1223
1229
|
/**
|
|
1224
1230
|
* Calculate current quartile (0-4)
|
|
@@ -1231,24 +1237,25 @@ class N {
|
|
|
1231
1237
|
*/
|
|
1232
1238
|
fireQuartileEvents(e) {
|
|
1233
1239
|
var t;
|
|
1234
|
-
const
|
|
1240
|
+
const i = [
|
|
1235
1241
|
{ threshold: 25, event: "firstQuartile" },
|
|
1236
1242
|
{ threshold: 50, event: "midpoint" },
|
|
1237
1243
|
{ threshold: 75, event: "thirdQuartile" }
|
|
1238
1244
|
];
|
|
1239
|
-
for (const { threshold: s, event: a } of
|
|
1245
|
+
for (const { threshold: s, event: a } of i)
|
|
1240
1246
|
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}`));
|
|
1241
1247
|
}
|
|
1242
1248
|
/**
|
|
1243
1249
|
* Set up skip button
|
|
1244
1250
|
*/
|
|
1245
1251
|
setupSkipButton() {
|
|
1246
|
-
|
|
1247
|
-
|
|
1252
|
+
var e;
|
|
1253
|
+
const t = this.getFirstLinearCreative(), i = (e = this.config.skipOffset) != null ? e : t == null ? void 0 : t.skipOffset;
|
|
1254
|
+
if (!i || i <= 0)
|
|
1248
1255
|
return;
|
|
1249
|
-
this.updateState({ skipCountdown:
|
|
1250
|
-
const
|
|
1251
|
-
|
|
1256
|
+
this.updateState({ skipCountdown: i, canSkip: !1 });
|
|
1257
|
+
const s = document.createElement("button");
|
|
1258
|
+
s.id = "adgent-skip-btn", s.style.cssText = `
|
|
1252
1259
|
position: absolute;
|
|
1253
1260
|
bottom: 20px;
|
|
1254
1261
|
right: 20px;
|
|
@@ -1261,80 +1268,112 @@ class N {
|
|
|
1261
1268
|
cursor: pointer;
|
|
1262
1269
|
z-index: 101;
|
|
1263
1270
|
transition: opacity 0.3s;
|
|
1264
|
-
`,
|
|
1271
|
+
`, s.textContent = `Skip in ${i}s`, s.addEventListener("click", () => this.skip()), this.config.container.appendChild(s), this.skipButtonElement = s;
|
|
1265
1272
|
}
|
|
1266
1273
|
/**
|
|
1267
1274
|
* Update skip countdown
|
|
1268
1275
|
*/
|
|
1269
1276
|
updateSkipCountdown(e) {
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1277
|
+
var t;
|
|
1278
|
+
const i = this.getFirstLinearCreative(), s = (t = this.config.skipOffset) != null ? t : i == null ? void 0 : i.skipOffset;
|
|
1279
|
+
if (!s || !this.skipButtonElement) return;
|
|
1280
|
+
const a = Math.max(0, s - e);
|
|
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");
|
|
1274
1282
|
}
|
|
1275
1283
|
/**
|
|
1276
1284
|
* Skip the ad
|
|
1277
1285
|
*/
|
|
1278
1286
|
skip() {
|
|
1279
|
-
var e,
|
|
1287
|
+
var e, t, i;
|
|
1280
1288
|
if (!this.state.canSkip) {
|
|
1281
1289
|
this.log("Skip not available yet");
|
|
1282
1290
|
return;
|
|
1283
1291
|
}
|
|
1284
|
-
(e = this.tracker) == null || e.track("skip"), this.emit({ type: "skip" }), (
|
|
1292
|
+
(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");
|
|
1285
1293
|
}
|
|
1286
1294
|
/**
|
|
1287
1295
|
* Handle ad completion
|
|
1288
1296
|
*/
|
|
1289
1297
|
handleComplete() {
|
|
1290
|
-
var e,
|
|
1291
|
-
this.updateState({ status:
|
|
1298
|
+
var e, t, i;
|
|
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");
|
|
1292
1300
|
}
|
|
1293
1301
|
/**
|
|
1294
1302
|
* Handle errors with recovery attempt or callback
|
|
1295
1303
|
*/
|
|
1296
1304
|
handleError(e) {
|
|
1297
|
-
var t,
|
|
1305
|
+
var t, i, s;
|
|
1298
1306
|
this.updateState({
|
|
1299
|
-
status:
|
|
1307
|
+
status: c.Error,
|
|
1300
1308
|
error: e
|
|
1301
1309
|
});
|
|
1302
|
-
const
|
|
1310
|
+
const a = [];
|
|
1303
1311
|
for (const n of this.ads)
|
|
1304
|
-
|
|
1305
|
-
(t = this.tracker) == null || t.fireError(
|
|
1312
|
+
a.push(...n.errors);
|
|
1313
|
+
(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}`);
|
|
1306
1314
|
}
|
|
1307
1315
|
/**
|
|
1308
1316
|
* Set up focus management to capture remote keys
|
|
1309
1317
|
*/
|
|
1310
1318
|
setupFocusManagement() {
|
|
1311
1319
|
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) => {
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1320
|
+
const t = this.platform.normalizeKeyCode(e.keyCode);
|
|
1321
|
+
t && (e.preventDefault(), e.stopPropagation(), this.handleKeyAction(t));
|
|
1314
1322
|
}, document.addEventListener("keydown", this.boundKeyHandler, !0);
|
|
1315
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
|
+
}
|
|
1316
1355
|
/**
|
|
1317
1356
|
* Handle key actions from remote control
|
|
1318
1357
|
*/
|
|
1319
1358
|
handleKeyAction(e) {
|
|
1320
|
-
var
|
|
1359
|
+
var t, i;
|
|
1321
1360
|
switch (this.log(`Key action: ${e}`), e) {
|
|
1322
|
-
case
|
|
1323
|
-
this.state.status ===
|
|
1361
|
+
case u.Enter:
|
|
1362
|
+
this.state.status === c.WaitingForInteraction ? this.onStartClick() : this.state.canSkip && this.skip();
|
|
1324
1363
|
break;
|
|
1325
|
-
case
|
|
1364
|
+
case u.Back:
|
|
1326
1365
|
this.log("Back pressed - ignoring during ad");
|
|
1327
1366
|
break;
|
|
1328
|
-
case
|
|
1329
|
-
(
|
|
1367
|
+
case u.Play:
|
|
1368
|
+
(t = this.videoElement) == null || t.play();
|
|
1330
1369
|
break;
|
|
1331
|
-
case
|
|
1332
|
-
(
|
|
1370
|
+
case u.Pause:
|
|
1371
|
+
(i = this.videoElement) == null || i.pause();
|
|
1333
1372
|
break;
|
|
1334
|
-
case
|
|
1335
|
-
case
|
|
1336
|
-
case
|
|
1337
|
-
case
|
|
1373
|
+
case u.Left:
|
|
1374
|
+
case u.Right:
|
|
1375
|
+
case u.Up:
|
|
1376
|
+
case u.Down:
|
|
1338
1377
|
break;
|
|
1339
1378
|
}
|
|
1340
1379
|
}
|
|
@@ -1368,8 +1407,8 @@ class N {
|
|
|
1368
1407
|
* Clean up all resources
|
|
1369
1408
|
*/
|
|
1370
1409
|
destroy() {
|
|
1371
|
-
var e,
|
|
1372
|
-
this.boundKeyHandler && (document.removeEventListener("keydown", this.boundKeyHandler, !0), this.boundKeyHandler = null), (e = this.videoElement) == null || e.remove(), (
|
|
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");
|
|
1373
1412
|
}
|
|
1374
1413
|
/**
|
|
1375
1414
|
* Update internal state
|
|
@@ -1381,38 +1420,38 @@ class N {
|
|
|
1381
1420
|
* Emit event to listeners
|
|
1382
1421
|
*/
|
|
1383
1422
|
emit(e) {
|
|
1384
|
-
for (const
|
|
1423
|
+
for (const t of this.listeners)
|
|
1385
1424
|
try {
|
|
1386
|
-
|
|
1387
|
-
} catch (
|
|
1388
|
-
this.log(`Listener error: ${
|
|
1425
|
+
t(e);
|
|
1426
|
+
} catch (i) {
|
|
1427
|
+
this.log(`Listener error: ${i}`);
|
|
1389
1428
|
}
|
|
1390
1429
|
}
|
|
1391
1430
|
/**
|
|
1392
1431
|
* Create error object
|
|
1393
1432
|
*/
|
|
1394
|
-
createError(e,
|
|
1395
|
-
return { code: e, message:
|
|
1433
|
+
createError(e, t, i = !1) {
|
|
1434
|
+
return { code: e, message: t, recoverable: i };
|
|
1396
1435
|
}
|
|
1397
1436
|
/**
|
|
1398
1437
|
* Debug logging
|
|
1399
1438
|
*/
|
|
1400
1439
|
log(e) {
|
|
1401
|
-
this.config.debug &&
|
|
1440
|
+
this.config.debug && this.platform.debug(e);
|
|
1402
1441
|
}
|
|
1403
1442
|
}
|
|
1404
1443
|
export {
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1444
|
+
V as AdPlayer,
|
|
1445
|
+
L as AdTracker,
|
|
1446
|
+
V as AdgentSDK,
|
|
1447
|
+
O as DEFAULT_KEY_CODES,
|
|
1448
|
+
u as KeyAction,
|
|
1449
|
+
I as PLATFORM_DETECTION_PATTERNS,
|
|
1411
1450
|
o as Platform,
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1451
|
+
N as PlatformAdapter,
|
|
1452
|
+
c as PlaybackStatus,
|
|
1453
|
+
p as VASTErrorCode,
|
|
1415
1454
|
A as VASTParser,
|
|
1416
|
-
|
|
1417
|
-
|
|
1455
|
+
_ as getPlatformAdapter,
|
|
1456
|
+
g as replaceMacros
|
|
1418
1457
|
};
|