@aranova/tracking-react 1.17.0 → 1.19.0
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/README.md +16 -0
- package/dist/{bookings-2ZKfenQ7.d.ts → bookings-BDLyF70h.d.ts} +61 -5
- package/dist/{bookings-DOh1WMhH.d.mts → bookings-v3HA8gsC.d.mts} +61 -5
- package/dist/client.d.mts +122 -5
- package/dist/client.d.ts +122 -5
- package/dist/client.js +1917 -193
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +1919 -193
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +17 -41
- package/dist/index.d.ts +17 -41
- package/dist/index.js +220 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +218 -39
- package/dist/index.mjs.map +1 -1
- package/dist/{ingest-typed-D7I4aQ7p.d.ts → ingest-typed-BEFQd3WM.d.mts} +290 -2
- package/dist/{ingest-typed-BO6Arbw-.d.mts → ingest-typed-DChvvgwd.d.ts} +290 -2
- package/dist/{phone-utils-CYr6AmEP.d.mts → phone-utils-BlWj8oxq.d.mts} +1 -0
- package/dist/{phone-utils-CYr6AmEP.d.ts → phone-utils-BlWj8oxq.d.ts} +1 -0
- package/dist/phone.d.mts +1 -1
- package/dist/phone.d.ts +1 -1
- package/dist/{sales-B1u_IHLZ.d.mts → sales-Cu8M8I8k.d.ts} +1 -1
- package/dist/{sales-I2jXSS-l.d.ts → sales-DriCnCbM.d.mts} +1 -1
- package/dist/sales.d.mts +3 -3
- package/dist/sales.d.ts +3 -3
- package/dist/sales.js +150 -38
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +150 -38
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/dist/client.mjs
CHANGED
|
@@ -255,7 +255,8 @@ var TRACKING_CAPABILITIES = [
|
|
|
255
255
|
"form_capture",
|
|
256
256
|
"phone_click_capture",
|
|
257
257
|
"phone_fields",
|
|
258
|
-
"typed_form_submit"
|
|
258
|
+
"typed_form_submit",
|
|
259
|
+
"video_tracking"
|
|
259
260
|
];
|
|
260
261
|
var CAPABILITY_DOM_ATTRIBUTE = "data-aranova-capability";
|
|
261
262
|
var registered = /* @__PURE__ */ new Set();
|
|
@@ -1036,8 +1037,48 @@ function parseTrigger(value) {
|
|
|
1036
1037
|
if (typeof t.threshold_seconds === "number") spec.threshold_seconds = t.threshold_seconds;
|
|
1037
1038
|
if (typeof t.page_threshold === "number") spec.page_threshold = t.page_threshold;
|
|
1038
1039
|
if (typeof t.page_name === "string") spec.page_name = t.page_name;
|
|
1040
|
+
if (t.metric === "percent" || t.metric === "seconds") spec.metric = t.metric;
|
|
1041
|
+
if (typeof t.threshold === "number") spec.threshold = t.threshold;
|
|
1042
|
+
if (typeof t.video_id === "string" || t.video_id === null) spec.video_id = t.video_id;
|
|
1039
1043
|
return spec;
|
|
1040
1044
|
}
|
|
1045
|
+
function parseVideoEntry(fallbackKey2, entry) {
|
|
1046
|
+
const key = typeof entry.key === "string" && entry.key ? entry.key : fallbackKey2;
|
|
1047
|
+
if (!key) return null;
|
|
1048
|
+
const host = typeof entry.host === "string" ? entry.host : "";
|
|
1049
|
+
const title = typeof entry.title === "string" && entry.title ? entry.title : key;
|
|
1050
|
+
const sourcesRaw = isRecord(entry.sources) ? entry.sources : null;
|
|
1051
|
+
const desktop = sourcesRaw && typeof sourcesRaw.desktop === "string" ? sourcesRaw.desktop : typeof entry.desktop_uid === "string" ? entry.desktop_uid : "";
|
|
1052
|
+
if (!host || !desktop) return null;
|
|
1053
|
+
const mobile = sourcesRaw && typeof sourcesRaw.mobile === "string" ? sourcesRaw.mobile : typeof entry.mobile_uid === "string" ? entry.mobile_uid : null;
|
|
1054
|
+
const posterTime = typeof entry.poster_time === "number" ? entry.poster_time : typeof entry.poster_time_s === "number" ? entry.poster_time_s : 4;
|
|
1055
|
+
return {
|
|
1056
|
+
key,
|
|
1057
|
+
title,
|
|
1058
|
+
host,
|
|
1059
|
+
sources: { desktop, mobile },
|
|
1060
|
+
poster_time: posterTime,
|
|
1061
|
+
duration_s: typeof entry.duration_s === "number" ? entry.duration_s : null
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
function parseVideos(value) {
|
|
1065
|
+
const out = {};
|
|
1066
|
+
if (Array.isArray(value)) {
|
|
1067
|
+
for (const item of value) {
|
|
1068
|
+
if (!isRecord(item)) continue;
|
|
1069
|
+
const parsed = parseVideoEntry("", item);
|
|
1070
|
+
if (parsed) out[parsed.key] = parsed;
|
|
1071
|
+
}
|
|
1072
|
+
return out;
|
|
1073
|
+
}
|
|
1074
|
+
if (!isRecord(value)) return out;
|
|
1075
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
1076
|
+
if (!isRecord(entry)) continue;
|
|
1077
|
+
const parsed = parseVideoEntry(key, entry);
|
|
1078
|
+
if (parsed) out[parsed.key] = parsed;
|
|
1079
|
+
}
|
|
1080
|
+
return out;
|
|
1081
|
+
}
|
|
1041
1082
|
function parseConversionConfig(raw) {
|
|
1042
1083
|
if (!raw || typeof raw !== "object") return null;
|
|
1043
1084
|
const obj = raw;
|
|
@@ -1088,7 +1129,8 @@ function parseConversionConfig(raw) {
|
|
|
1088
1129
|
goals,
|
|
1089
1130
|
linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : [],
|
|
1090
1131
|
integrations: parseIntegrations(obj.integrations),
|
|
1091
|
-
lead_forms: parseLeadForms(obj.lead_forms)
|
|
1132
|
+
lead_forms: parseLeadForms(obj.lead_forms),
|
|
1133
|
+
videos: parseVideos(obj.videos)
|
|
1092
1134
|
};
|
|
1093
1135
|
}
|
|
1094
1136
|
function parseLeadForms(value) {
|
|
@@ -1334,6 +1376,21 @@ function automaticThresholdMet(goal, eventType, metadata) {
|
|
|
1334
1376
|
case "form_start":
|
|
1335
1377
|
case "phone_click":
|
|
1336
1378
|
return true;
|
|
1379
|
+
case "video_play":
|
|
1380
|
+
return trigger.video_id == null || hasStringField(metadata, "video_id") && metadata.video_id === trigger.video_id;
|
|
1381
|
+
case "video_progress": {
|
|
1382
|
+
if (trigger.video_id != null && (!hasStringField(metadata, "video_id") || metadata.video_id !== trigger.video_id)) {
|
|
1383
|
+
return false;
|
|
1384
|
+
}
|
|
1385
|
+
if (typeof trigger.threshold !== "number") return false;
|
|
1386
|
+
if (trigger.metric === "seconds") {
|
|
1387
|
+
return hasNumberField(metadata, "watched_s") && metadata.watched_s >= trigger.threshold;
|
|
1388
|
+
}
|
|
1389
|
+
if (trigger.metric === "percent") {
|
|
1390
|
+
return hasNumberField(metadata, "max_percent") && metadata.max_percent >= trigger.threshold || hasNumberField(metadata, "watched_percent") && metadata.watched_percent >= trigger.threshold;
|
|
1391
|
+
}
|
|
1392
|
+
return false;
|
|
1393
|
+
}
|
|
1337
1394
|
default:
|
|
1338
1395
|
return false;
|
|
1339
1396
|
}
|
|
@@ -1370,6 +1427,9 @@ var RETRY_BASE_MS = 5e3;
|
|
|
1370
1427
|
var RETRY_MAX_MS = 5 * 6e4;
|
|
1371
1428
|
var runtimes = /* @__PURE__ */ new Map();
|
|
1372
1429
|
var configuredIds = /* @__PURE__ */ new Set();
|
|
1430
|
+
var EMPTY_GOALS = [];
|
|
1431
|
+
var EMPTY_STRINGS = [];
|
|
1432
|
+
var EMPTY_VIDEOS = {};
|
|
1373
1433
|
var scriptLoad = null;
|
|
1374
1434
|
var jsInitialized = false;
|
|
1375
1435
|
function cacheKey2(url) {
|
|
@@ -1560,11 +1620,11 @@ var TrackingConfigRuntime = class {
|
|
|
1560
1620
|
void this.flush();
|
|
1561
1621
|
}
|
|
1562
1622
|
listGoals() {
|
|
1563
|
-
return this.current?.goals ??
|
|
1623
|
+
return this.current?.goals ?? EMPTY_GOALS;
|
|
1564
1624
|
}
|
|
1565
1625
|
/** Sibling hostnames for the linker — read from the cached object even while unconfirmed. */
|
|
1566
1626
|
linkedHostnames() {
|
|
1567
|
-
return this.current?.linked_hostnames ??
|
|
1627
|
+
return this.current?.linked_hostnames ?? EMPTY_STRINGS;
|
|
1568
1628
|
}
|
|
1569
1629
|
/**
|
|
1570
1630
|
* Integration blocks, from the cached object even while unconfirmed: the booking fallback
|
|
@@ -1577,6 +1637,14 @@ var TrackingConfigRuntime = class {
|
|
|
1577
1637
|
leadForms() {
|
|
1578
1638
|
return this.current?.lead_forms ?? null;
|
|
1579
1639
|
}
|
|
1640
|
+
/** Configured Cloudflare Stream tracked videos for this site. */
|
|
1641
|
+
videos() {
|
|
1642
|
+
return this.current?.videos ?? EMPTY_VIDEOS;
|
|
1643
|
+
}
|
|
1644
|
+
/** Look up one configured Cloudflare Stream tracked video by key. */
|
|
1645
|
+
getVideo(key) {
|
|
1646
|
+
return this.current?.videos?.[key] ?? null;
|
|
1647
|
+
}
|
|
1580
1648
|
async revalidateNow() {
|
|
1581
1649
|
try {
|
|
1582
1650
|
const headers = {};
|
|
@@ -1733,6 +1801,16 @@ var TrackingConfigRuntime = class {
|
|
|
1733
1801
|
this.scheduleRetry();
|
|
1734
1802
|
return;
|
|
1735
1803
|
}
|
|
1804
|
+
if (outcome === "fired" && typeof window !== "undefined" && typeof window.fbq === "function") {
|
|
1805
|
+
try {
|
|
1806
|
+
window.fbq("trackCustom", item.key, {
|
|
1807
|
+
...value != null ? { value } : {},
|
|
1808
|
+
...currency ? { currency } : {},
|
|
1809
|
+
...item.transactionId ? { transaction_id: item.transactionId } : {}
|
|
1810
|
+
});
|
|
1811
|
+
} catch {
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1736
1814
|
this.conversionQueue.shift();
|
|
1737
1815
|
}
|
|
1738
1816
|
}
|
|
@@ -1876,12 +1954,24 @@ function createConversionAutoFire(store) {
|
|
|
1876
1954
|
const firing = goal.firing;
|
|
1877
1955
|
const cents = firing.value_cents ?? null;
|
|
1878
1956
|
const currency = firing.currency ?? null;
|
|
1879
|
-
|
|
1957
|
+
const value = cents != null && currency ? fromMinor(cents, currency) : null;
|
|
1958
|
+
const outcome = fireConversionWithConsent({
|
|
1880
1959
|
sendTo: firing.send_to,
|
|
1881
|
-
value
|
|
1960
|
+
value,
|
|
1882
1961
|
currency,
|
|
1883
1962
|
transactionId
|
|
1884
1963
|
});
|
|
1964
|
+
if (outcome === "fired" && typeof window !== "undefined" && typeof window.fbq === "function") {
|
|
1965
|
+
try {
|
|
1966
|
+
window.fbq("trackCustom", goal.key, {
|
|
1967
|
+
event_type: eventType,
|
|
1968
|
+
...value != null ? { value } : {},
|
|
1969
|
+
...currency ? { currency } : {},
|
|
1970
|
+
transaction_id: transactionId
|
|
1971
|
+
});
|
|
1972
|
+
} catch {
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1885
1975
|
}
|
|
1886
1976
|
}
|
|
1887
1977
|
return {
|
|
@@ -1978,6 +2068,13 @@ var EVENT_SEMANTICS = {
|
|
|
1978
2068
|
outcomeRole: "engagement",
|
|
1979
2069
|
clientVisibility: "detailed"
|
|
1980
2070
|
},
|
|
2071
|
+
// Adds to the submit it names; counting it as a lead would double every lead.
|
|
2072
|
+
form_details: {
|
|
2073
|
+
label: "Form details added",
|
|
2074
|
+
category: "lead",
|
|
2075
|
+
outcomeRole: "engagement",
|
|
2076
|
+
clientVisibility: "detailed"
|
|
2077
|
+
},
|
|
1981
2078
|
form_submit: {
|
|
1982
2079
|
label: "Form submitted",
|
|
1983
2080
|
category: "lead",
|
|
@@ -2007,6 +2104,18 @@ var EVENT_SEMANTICS = {
|
|
|
2007
2104
|
category: "page",
|
|
2008
2105
|
outcomeRole: "navigation",
|
|
2009
2106
|
clientVisibility: "simple"
|
|
2107
|
+
},
|
|
2108
|
+
video_play: {
|
|
2109
|
+
label: "Video played",
|
|
2110
|
+
category: "engagement",
|
|
2111
|
+
outcomeRole: "engagement",
|
|
2112
|
+
clientVisibility: "simple"
|
|
2113
|
+
},
|
|
2114
|
+
video_progress: {
|
|
2115
|
+
label: "Video watched",
|
|
2116
|
+
category: "engagement",
|
|
2117
|
+
outcomeRole: "engagement",
|
|
2118
|
+
clientVisibility: "detailed"
|
|
2010
2119
|
}
|
|
2011
2120
|
};
|
|
2012
2121
|
function getEventSemantics(eventName) {
|
|
@@ -2594,14 +2703,31 @@ function createTrackingClient(config) {
|
|
|
2594
2703
|
metadata: input.metadata ?? null,
|
|
2595
2704
|
occurred_at: occurredAt
|
|
2596
2705
|
});
|
|
2597
|
-
|
|
2706
|
+
const triggerReason = input.metadata?.trigger;
|
|
2707
|
+
const isUrgentVideoEvent = input.eventType === "video_play" || input.eventType === "video_progress" && (triggerReason === "ended" || triggerReason === "goal" || triggerReason === "checkpoint");
|
|
2708
|
+
if (queue.length >= maxQueueSize || input.eventType === "form_details" || getEventSemantics(input.eventType)?.outcomeRole === "lead" || isUrgentVideoEvent) {
|
|
2598
2709
|
void flush();
|
|
2599
2710
|
} else {
|
|
2600
2711
|
scheduleFlush();
|
|
2601
2712
|
}
|
|
2602
2713
|
}
|
|
2714
|
+
const beforeUnloadListeners = /* @__PURE__ */ new Set();
|
|
2715
|
+
let runningBeforeUnload = false;
|
|
2603
2716
|
function flushOnUnload() {
|
|
2604
2717
|
if (destroyed) return;
|
|
2718
|
+
if (!runningBeforeUnload && beforeUnloadListeners.size > 0) {
|
|
2719
|
+
runningBeforeUnload = true;
|
|
2720
|
+
try {
|
|
2721
|
+
for (const listener of beforeUnloadListeners) {
|
|
2722
|
+
try {
|
|
2723
|
+
listener();
|
|
2724
|
+
} catch {
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
} finally {
|
|
2728
|
+
runningBeforeUnload = false;
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2605
2731
|
bufferQueued();
|
|
2606
2732
|
clearScheduledFlush();
|
|
2607
2733
|
if (pending.length === 0) return;
|
|
@@ -2622,6 +2748,12 @@ function createTrackingClient(config) {
|
|
|
2622
2748
|
trackEvent,
|
|
2623
2749
|
flush,
|
|
2624
2750
|
flushBeacon: flushOnUnload,
|
|
2751
|
+
onBeforeUnload: (listener) => {
|
|
2752
|
+
beforeUnloadListeners.add(listener);
|
|
2753
|
+
return () => {
|
|
2754
|
+
beforeUnloadListeners.delete(listener);
|
|
2755
|
+
};
|
|
2756
|
+
},
|
|
2625
2757
|
getSessionId: () => sessionId,
|
|
2626
2758
|
getVisitorId: () => visitorId,
|
|
2627
2759
|
destroy: () => {
|
|
@@ -2632,6 +2764,7 @@ function createTrackingClient(config) {
|
|
|
2632
2764
|
destroyed = true;
|
|
2633
2765
|
clearScheduledFlush();
|
|
2634
2766
|
queue = [];
|
|
2767
|
+
beforeUnloadListeners.clear();
|
|
2635
2768
|
if (typeof window !== "undefined") {
|
|
2636
2769
|
window.removeEventListener("pagehide", flushOnUnload);
|
|
2637
2770
|
window.removeEventListener("visibilitychange", onVisibilityChange);
|
|
@@ -2698,110 +2831,133 @@ var formStartConfigSchema = z5.strictObject({
|
|
|
2698
2831
|
selector: z5.optional(z5.string())
|
|
2699
2832
|
});
|
|
2700
2833
|
|
|
2701
|
-
// ../tracking-core/src/events/form-
|
|
2834
|
+
// ../tracking-core/src/events/form-details.ts
|
|
2835
|
+
import * as z7 from "zod/mini";
|
|
2836
|
+
|
|
2837
|
+
// ../tracking-core/src/events/form-submit.ts
|
|
2702
2838
|
import * as z6 from "zod/mini";
|
|
2703
|
-
var
|
|
2839
|
+
var jsonValueSchema = z6.lazy(
|
|
2840
|
+
() => z6.union([
|
|
2841
|
+
z6.string(),
|
|
2842
|
+
z6.number(),
|
|
2843
|
+
z6.boolean(),
|
|
2844
|
+
z6.null(),
|
|
2845
|
+
z6.array(jsonValueSchema),
|
|
2846
|
+
z6.record(z6.string(), jsonValueSchema)
|
|
2847
|
+
])
|
|
2848
|
+
).register(z6.globalRegistry, { id: "JsonSerializableValue" });
|
|
2849
|
+
var contractNameSchema = z6.string().check(z6.regex(/^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?$/));
|
|
2850
|
+
var violationRole = z6.string().check(
|
|
2851
|
+
z6.maxLength(200),
|
|
2852
|
+
z6.regex(
|
|
2853
|
+
/^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?(\|[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?)*$/
|
|
2854
|
+
)
|
|
2855
|
+
);
|
|
2856
|
+
var MAX_CONTRACT_VIOLATIONS = 50;
|
|
2857
|
+
var contractViolationSchema = z6.strictObject({
|
|
2858
|
+
role: z6.nullable(violationRole),
|
|
2859
|
+
rule: z6.string().check(z6.regex(/^[a-z][a-z_]{0,47}$/))
|
|
2860
|
+
});
|
|
2861
|
+
var formFieldSchema = z6.strictObject({
|
|
2862
|
+
name: z6.string(),
|
|
2863
|
+
type: z6.string(),
|
|
2864
|
+
label: z6.nullable(z6.string()),
|
|
2865
|
+
value: jsonValueSchema,
|
|
2866
|
+
role: z6.optional(z6.nullable(contractNameSchema))
|
|
2867
|
+
});
|
|
2868
|
+
var formExtraSchema = z6.optional(
|
|
2869
|
+
z6.nullable(
|
|
2870
|
+
z6.array(
|
|
2871
|
+
z6.strictObject({
|
|
2872
|
+
key: z6.string().check(z6.maxLength(64)),
|
|
2873
|
+
label: z6.string().check(z6.maxLength(200)),
|
|
2874
|
+
value: jsonValueSchema
|
|
2875
|
+
})
|
|
2876
|
+
).check(z6.maxLength(20))
|
|
2877
|
+
)
|
|
2878
|
+
);
|
|
2879
|
+
var contractVersionSchema = z6.optional(z6.nullable(z6.int().check(z6.gte(1))));
|
|
2880
|
+
var contractHashSchema = z6.optional(z6.nullable(z6.string().check(z6.maxLength(64))));
|
|
2881
|
+
var formContractViolationsSchema = z6.optional(
|
|
2882
|
+
z6.nullable(z6.array(contractViolationSchema).check(z6.maxLength(MAX_CONTRACT_VIOLATIONS)))
|
|
2883
|
+
);
|
|
2884
|
+
var formSubmitMetadataSchema = z6.strictObject({
|
|
2704
2885
|
form: z6.strictObject({
|
|
2705
2886
|
id: z6.string(),
|
|
2706
|
-
action: z6.nullable(z6.string())
|
|
2887
|
+
action: z6.nullable(z6.string()),
|
|
2888
|
+
fields: z6.optional(z6.array(formFieldSchema)),
|
|
2889
|
+
kind: z6.optional(z6.nullable(contractNameSchema)),
|
|
2890
|
+
contract_version: contractVersionSchema,
|
|
2891
|
+
contract_hash: contractHashSchema,
|
|
2892
|
+
extra: formExtraSchema,
|
|
2893
|
+
contract_violations: formContractViolationsSchema,
|
|
2894
|
+
// Minted per submit; a later `form_details` names it to add answers to this lead.
|
|
2895
|
+
submission_id: z6.optional(z6.nullable(z6.uuidv4()))
|
|
2707
2896
|
}),
|
|
2708
|
-
step: z6.strictObject({
|
|
2709
|
-
id: z6.string().check(z6.minLength(1), z6.maxLength(64), z6.regex(/^[A-Za-z0-9_-]+$/)),
|
|
2710
|
-
// 1-based position in the flow the visitor is on right now.
|
|
2711
|
-
index: z6.int().check(z6.gte(1), z6.lte(50)),
|
|
2712
|
-
// Null when the number of steps depends on earlier answers.
|
|
2713
|
-
total: z6.nullable(z6.int().check(z6.gte(1), z6.lte(50)))
|
|
2714
|
-
}),
|
|
2715
|
-
direction: z6.enum(["forward", "back"]),
|
|
2716
2897
|
page: z6.strictObject({
|
|
2717
2898
|
path: z6.string()
|
|
2718
2899
|
})
|
|
2719
2900
|
});
|
|
2720
|
-
var
|
|
2901
|
+
var formSubmitConfigSchema = z6.strictObject({});
|
|
2721
2902
|
|
|
2722
|
-
// ../tracking-core/src/events/form-
|
|
2723
|
-
|
|
2724
|
-
var jsonValueSchema = z7.lazy(
|
|
2725
|
-
() => z7.union([
|
|
2726
|
-
z7.string(),
|
|
2727
|
-
z7.number(),
|
|
2728
|
-
z7.boolean(),
|
|
2729
|
-
z7.null(),
|
|
2730
|
-
z7.array(jsonValueSchema),
|
|
2731
|
-
z7.record(z7.string(), jsonValueSchema)
|
|
2732
|
-
])
|
|
2733
|
-
).register(z7.globalRegistry, { id: "JsonSerializableValue" });
|
|
2734
|
-
var contractNameSchema = z7.string().check(z7.regex(/^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?$/));
|
|
2735
|
-
var contractName = contractNameSchema;
|
|
2736
|
-
var violationRole = z7.string().check(
|
|
2737
|
-
z7.maxLength(200),
|
|
2738
|
-
z7.regex(
|
|
2739
|
-
/^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?(\|[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?)*$/
|
|
2740
|
-
)
|
|
2741
|
-
);
|
|
2742
|
-
var MAX_CONTRACT_VIOLATIONS = 50;
|
|
2743
|
-
var contractViolationSchema = z7.strictObject({
|
|
2744
|
-
role: z7.nullable(violationRole),
|
|
2745
|
-
rule: z7.string().check(z7.regex(/^[a-z][a-z_]{0,47}$/))
|
|
2746
|
-
});
|
|
2747
|
-
var formSubmitMetadataSchema = z7.strictObject({
|
|
2903
|
+
// ../tracking-core/src/events/form-details.ts
|
|
2904
|
+
var formDetailsMetadataSchema = z7.strictObject({
|
|
2748
2905
|
form: z7.strictObject({
|
|
2749
2906
|
id: z7.string(),
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
value: jsonValueSchema,
|
|
2758
|
-
role: z7.optional(z7.nullable(contractName))
|
|
2759
|
-
})
|
|
2760
|
-
)
|
|
2761
|
-
),
|
|
2762
|
-
kind: z7.optional(z7.nullable(contractName)),
|
|
2763
|
-
contract_version: z7.optional(z7.nullable(z7.int().check(z7.gte(1)))),
|
|
2764
|
-
contract_hash: z7.optional(z7.nullable(z7.string().check(z7.maxLength(64)))),
|
|
2765
|
-
extra: z7.optional(
|
|
2766
|
-
z7.nullable(
|
|
2767
|
-
z7.array(
|
|
2768
|
-
z7.strictObject({
|
|
2769
|
-
key: z7.string().check(z7.maxLength(64)),
|
|
2770
|
-
label: z7.string().check(z7.maxLength(200)),
|
|
2771
|
-
value: jsonValueSchema
|
|
2772
|
-
})
|
|
2773
|
-
).check(z7.maxLength(20))
|
|
2774
|
-
)
|
|
2775
|
-
),
|
|
2776
|
-
contract_violations: z7.optional(
|
|
2777
|
-
z7.nullable(z7.array(contractViolationSchema).check(z7.maxLength(MAX_CONTRACT_VIOLATIONS)))
|
|
2778
|
-
)
|
|
2907
|
+
submission_id: z7.uuidv4(),
|
|
2908
|
+
kind: z7.optional(z7.nullable(contractNameSchema)),
|
|
2909
|
+
fields: z7.array(formFieldSchema),
|
|
2910
|
+
contract_version: contractVersionSchema,
|
|
2911
|
+
contract_hash: contractHashSchema,
|
|
2912
|
+
extra: formExtraSchema,
|
|
2913
|
+
contract_violations: formContractViolationsSchema
|
|
2779
2914
|
}),
|
|
2780
2915
|
page: z7.strictObject({
|
|
2781
2916
|
path: z7.string()
|
|
2782
2917
|
})
|
|
2783
2918
|
});
|
|
2784
|
-
var
|
|
2919
|
+
var formDetailsConfigSchema = z7.strictObject({});
|
|
2785
2920
|
|
|
2786
|
-
// ../tracking-core/src/events/
|
|
2921
|
+
// ../tracking-core/src/events/form-step.ts
|
|
2787
2922
|
import * as z8 from "zod/mini";
|
|
2788
|
-
var
|
|
2789
|
-
|
|
2923
|
+
var formStepMetadataSchema = z8.strictObject({
|
|
2924
|
+
form: z8.strictObject({
|
|
2925
|
+
id: z8.string(),
|
|
2926
|
+
action: z8.nullable(z8.string())
|
|
2927
|
+
}),
|
|
2928
|
+
step: z8.strictObject({
|
|
2929
|
+
id: z8.string().check(z8.minLength(1), z8.maxLength(64), z8.regex(/^[A-Za-z0-9_-]+$/)),
|
|
2930
|
+
// 1-based position in the flow the visitor is on right now.
|
|
2931
|
+
index: z8.int().check(z8.gte(1), z8.lte(50)),
|
|
2932
|
+
// Null when the number of steps depends on earlier answers.
|
|
2933
|
+
total: z8.nullable(z8.int().check(z8.gte(1), z8.lte(50)))
|
|
2934
|
+
}),
|
|
2935
|
+
direction: z8.enum(["forward", "back"]),
|
|
2790
2936
|
page: z8.strictObject({
|
|
2791
2937
|
path: z8.string()
|
|
2792
2938
|
})
|
|
2793
2939
|
});
|
|
2794
|
-
var
|
|
2795
|
-
|
|
2940
|
+
var formStepConfigSchema = z8.strictObject({});
|
|
2941
|
+
|
|
2942
|
+
// ../tracking-core/src/events/multi-page-session.ts
|
|
2943
|
+
import * as z9 from "zod/mini";
|
|
2944
|
+
var multiPageSessionMetadataSchema = z9.strictObject({
|
|
2945
|
+
page_count: z9.int().check(z9.gte(2)),
|
|
2946
|
+
page: z9.strictObject({
|
|
2947
|
+
path: z9.string()
|
|
2948
|
+
})
|
|
2949
|
+
});
|
|
2950
|
+
var multiPageSessionConfigSchema = z9.strictObject({
|
|
2951
|
+
pageThreshold: z9.int().check(z9.gte(2))
|
|
2796
2952
|
});
|
|
2797
2953
|
|
|
2798
2954
|
// ../tracking-core/src/events/page-exit.ts
|
|
2799
|
-
import * as
|
|
2800
|
-
var pageExitMetadataSchema =
|
|
2801
|
-
dwell_ms:
|
|
2955
|
+
import * as z10 from "zod/mini";
|
|
2956
|
+
var pageExitMetadataSchema = z10.strictObject({
|
|
2957
|
+
dwell_ms: z10.int().check(z10.gte(0)),
|
|
2802
2958
|
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
2803
2959
|
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
2804
|
-
max_scroll_percent:
|
|
2960
|
+
max_scroll_percent: z10.nullable(z10.int().check(z10.gte(0), z10.lte(100))),
|
|
2805
2961
|
// The gating baseline: the fraction of the page visible at load with
|
|
2806
2962
|
// zero scrolling — or, for pages that grew after the post-paint snapshot
|
|
2807
2963
|
// (skeleton/streaming renders), the first-scroll position that
|
|
@@ -2809,106 +2965,186 @@ var pageExitMetadataSchema = z9.strictObject({
|
|
|
2809
2965
|
// ended before the snapshot. Optionality is load-bearing: SDK builds
|
|
2810
2966
|
// predating this field keep POSTing page_exit without the key —
|
|
2811
2967
|
// requiring it would 422 whole keepalive beacon batches.
|
|
2812
|
-
scroll_baseline_percent:
|
|
2813
|
-
page:
|
|
2814
|
-
path:
|
|
2968
|
+
scroll_baseline_percent: z10.optional(z10.nullable(z10.int().check(z10.gte(0), z10.lte(100)))),
|
|
2969
|
+
page: z10.strictObject({
|
|
2970
|
+
path: z10.string()
|
|
2815
2971
|
})
|
|
2816
2972
|
});
|
|
2817
|
-
var pageExitConfigSchema =
|
|
2973
|
+
var pageExitConfigSchema = z10.strictObject({});
|
|
2818
2974
|
|
|
2819
2975
|
// ../tracking-core/src/events/phone-click.ts
|
|
2820
|
-
import * as
|
|
2821
|
-
var phoneClickMetadataSchema =
|
|
2822
|
-
phone_number:
|
|
2823
|
-
page:
|
|
2824
|
-
path:
|
|
2976
|
+
import * as z11 from "zod/mini";
|
|
2977
|
+
var phoneClickMetadataSchema = z11.strictObject({
|
|
2978
|
+
phone_number: z11.string(),
|
|
2979
|
+
page: z11.strictObject({
|
|
2980
|
+
path: z11.string()
|
|
2825
2981
|
}),
|
|
2826
|
-
section:
|
|
2982
|
+
section: z11.optional(z11.nullable(z11.string()))
|
|
2827
2983
|
});
|
|
2828
|
-
var phoneClickConfigSchema =
|
|
2829
|
-
autoCapture:
|
|
2830
|
-
|
|
2831
|
-
selector:
|
|
2984
|
+
var phoneClickConfigSchema = z11.strictObject({
|
|
2985
|
+
autoCapture: z11.optional(
|
|
2986
|
+
z11.strictObject({
|
|
2987
|
+
selector: z11.optional(z11.string())
|
|
2832
2988
|
})
|
|
2833
2989
|
)
|
|
2834
2990
|
});
|
|
2835
2991
|
|
|
2836
2992
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
2837
|
-
import * as
|
|
2838
|
-
var scrollDepthMetadataSchema =
|
|
2839
|
-
depth_percent:
|
|
2840
|
-
page:
|
|
2841
|
-
path:
|
|
2993
|
+
import * as z12 from "zod/mini";
|
|
2994
|
+
var scrollDepthMetadataSchema = z12.strictObject({
|
|
2995
|
+
depth_percent: z12.int().check(z12.gte(1), z12.lte(100)),
|
|
2996
|
+
page: z12.strictObject({
|
|
2997
|
+
path: z12.string()
|
|
2842
2998
|
})
|
|
2843
2999
|
});
|
|
2844
|
-
var scrollDepthConfigSchema =
|
|
2845
|
-
thresholds:
|
|
3000
|
+
var scrollDepthConfigSchema = z12.strictObject({
|
|
3001
|
+
thresholds: z12.array(z12.int().check(z12.gte(1), z12.lte(100))).check(z12.minLength(1))
|
|
2846
3002
|
});
|
|
2847
3003
|
|
|
2848
3004
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
2849
|
-
import * as
|
|
3005
|
+
import * as z13 from "zod/mini";
|
|
2850
3006
|
var PAGE_IDENTITY_MAX_LENGTH = 64;
|
|
2851
3007
|
var PAGE_IDENTITY_PATTERN = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
|
|
2852
|
-
var pageIdentitySchema =
|
|
2853
|
-
|
|
2854
|
-
|
|
3008
|
+
var pageIdentitySchema = z13.string().check(
|
|
3009
|
+
z13.maxLength(PAGE_IDENTITY_MAX_LENGTH),
|
|
3010
|
+
z13.regex(PAGE_IDENTITY_PATTERN, {
|
|
2855
3011
|
message: "page identity must be lowercase snake_case, start with a letter, and contain at most 64 characters"
|
|
2856
3012
|
})
|
|
2857
3013
|
);
|
|
2858
3014
|
var specificPageNameSchema = pageIdentitySchema;
|
|
2859
|
-
var specificPageVisitMetadataSchema =
|
|
3015
|
+
var specificPageVisitMetadataSchema = z13.strictObject({
|
|
2860
3016
|
page_name: specificPageNameSchema,
|
|
2861
|
-
page:
|
|
2862
|
-
path:
|
|
3017
|
+
page: z13.strictObject({
|
|
3018
|
+
path: z13.string()
|
|
2863
3019
|
})
|
|
2864
3020
|
});
|
|
2865
|
-
var specificPageVisitConfigSchema =
|
|
2866
|
-
pages:
|
|
2867
|
-
|
|
3021
|
+
var specificPageVisitConfigSchema = z13.strictObject({
|
|
3022
|
+
pages: z13.array(
|
|
3023
|
+
z13.strictObject({
|
|
2868
3024
|
name: specificPageNameSchema,
|
|
2869
|
-
pathPattern:
|
|
3025
|
+
pathPattern: z13.custom((value) => value instanceof RegExp, {
|
|
2870
3026
|
message: "pathPattern must be a RegExp"
|
|
2871
3027
|
})
|
|
2872
3028
|
})
|
|
2873
|
-
).check(
|
|
3029
|
+
).check(z13.minLength(1))
|
|
2874
3030
|
});
|
|
2875
3031
|
|
|
2876
3032
|
// ../tracking-core/src/events/site-link.ts
|
|
2877
|
-
import * as
|
|
2878
|
-
var siteLinkClickMetadataSchema =
|
|
2879
|
-
destination_host:
|
|
2880
|
-
destination_url:
|
|
2881
|
-
page:
|
|
2882
|
-
path:
|
|
3033
|
+
import * as z14 from "zod/mini";
|
|
3034
|
+
var siteLinkClickMetadataSchema = z14.strictObject({
|
|
3035
|
+
destination_host: z14.string(),
|
|
3036
|
+
destination_url: z14.string(),
|
|
3037
|
+
page: z14.strictObject({
|
|
3038
|
+
path: z14.string()
|
|
2883
3039
|
})
|
|
2884
3040
|
});
|
|
2885
|
-
var siteLinkClickConfigSchema =
|
|
2886
|
-
var siteLinkArrivalMetadataSchema =
|
|
2887
|
-
outcome:
|
|
2888
|
-
origin_session_id:
|
|
2889
|
-
origin_visitor_id:
|
|
3041
|
+
var siteLinkClickConfigSchema = z14.strictObject({});
|
|
3042
|
+
var siteLinkArrivalMetadataSchema = z14.strictObject({
|
|
3043
|
+
outcome: z14.enum(["linked", "stale", "invalid"]),
|
|
3044
|
+
origin_session_id: z14.optional(z14.nullable(z14.string())),
|
|
3045
|
+
origin_visitor_id: z14.optional(z14.nullable(z14.string())),
|
|
2890
3046
|
// Milliseconds between the origin click and this page load.
|
|
2891
|
-
transit_ms:
|
|
3047
|
+
transit_ms: z14.optional(z14.nullable(z14.number())),
|
|
2892
3048
|
// True when this browser had no visitor id and took the origin's.
|
|
2893
|
-
adopted_visitor:
|
|
2894
|
-
page:
|
|
2895
|
-
path:
|
|
3049
|
+
adopted_visitor: z14.boolean(),
|
|
3050
|
+
page: z14.strictObject({
|
|
3051
|
+
path: z14.string()
|
|
2896
3052
|
})
|
|
2897
3053
|
});
|
|
2898
|
-
var siteLinkArrivalConfigSchema =
|
|
3054
|
+
var siteLinkArrivalConfigSchema = z14.strictObject({});
|
|
2899
3055
|
|
|
2900
3056
|
// ../tracking-core/src/events/time-on-site.ts
|
|
2901
|
-
import * as
|
|
2902
|
-
var timeOnSiteMetadataSchema =
|
|
2903
|
-
duration_ms:
|
|
2904
|
-
page:
|
|
2905
|
-
path:
|
|
3057
|
+
import * as z15 from "zod/mini";
|
|
3058
|
+
var timeOnSiteMetadataSchema = z15.strictObject({
|
|
3059
|
+
duration_ms: z15.int().check(z15.nonnegative()),
|
|
3060
|
+
page: z15.strictObject({
|
|
3061
|
+
path: z15.string()
|
|
2906
3062
|
})
|
|
2907
3063
|
});
|
|
2908
|
-
var timeOnSiteConfigSchema =
|
|
2909
|
-
thresholdSeconds:
|
|
3064
|
+
var timeOnSiteConfigSchema = z15.strictObject({
|
|
3065
|
+
thresholdSeconds: z15.int().check(z15.positive())
|
|
2910
3066
|
});
|
|
2911
3067
|
|
|
3068
|
+
// ../tracking-core/src/events/video.ts
|
|
3069
|
+
import * as z16 from "zod/mini";
|
|
3070
|
+
|
|
3071
|
+
// ../tracking-core/src/video-ranges.ts
|
|
3072
|
+
var VIDEO_ID_MAX_LENGTH = 64;
|
|
3073
|
+
var VIDEO_ID_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
3074
|
+
function roundVideoSeconds(value) {
|
|
3075
|
+
if (!Number.isFinite(value) || value < 0) return 0;
|
|
3076
|
+
return Math.round(value * 100) / 100;
|
|
3077
|
+
}
|
|
3078
|
+
function mergeVideoRanges(ranges, epsilonSeconds = 0.25) {
|
|
3079
|
+
const valid2 = ranges.filter((r) => Number.isFinite(r.start_s) && Number.isFinite(r.end_s) && r.end_s > r.start_s).map((r) => ({
|
|
3080
|
+
start_s: roundVideoSeconds(r.start_s),
|
|
3081
|
+
end_s: roundVideoSeconds(r.end_s)
|
|
3082
|
+
})).filter((r) => r.end_s - r.start_s >= 0.05).sort((a, b) => a.start_s - b.start_s || a.end_s - b.end_s);
|
|
3083
|
+
if (valid2.length === 0) return [];
|
|
3084
|
+
const merged = [{ ...valid2[0] }];
|
|
3085
|
+
for (let i = 1; i < valid2.length; i += 1) {
|
|
3086
|
+
const cur = valid2[i];
|
|
3087
|
+
const last = merged[merged.length - 1];
|
|
3088
|
+
if (cur.start_s <= last.end_s + epsilonSeconds) {
|
|
3089
|
+
last.end_s = roundVideoSeconds(Math.max(last.end_s, cur.end_s));
|
|
3090
|
+
} else {
|
|
3091
|
+
merged.push({ ...cur });
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
return merged;
|
|
3095
|
+
}
|
|
3096
|
+
function sumVideoRangesSeconds(ranges, durationSeconds = 0) {
|
|
3097
|
+
const merged = mergeVideoRanges(ranges);
|
|
3098
|
+
const raw = merged.reduce((acc, r) => acc + Math.max(0, r.end_s - r.start_s), 0);
|
|
3099
|
+
const clamped = durationSeconds > 0 ? Math.min(raw, durationSeconds) : raw;
|
|
3100
|
+
return roundVideoSeconds(clamped);
|
|
3101
|
+
}
|
|
3102
|
+
|
|
3103
|
+
// ../tracking-core/src/events/video.ts
|
|
3104
|
+
var videoIdSchema = z16.string().check(z16.minLength(1), z16.maxLength(VIDEO_ID_MAX_LENGTH), z16.regex(VIDEO_ID_PATTERN));
|
|
3105
|
+
var videoVariantSchema = z16.enum(["16x9", "9x16"]);
|
|
3106
|
+
var videoProgressTriggerReasonSchema = z16.enum([
|
|
3107
|
+
"checkpoint",
|
|
3108
|
+
"goal",
|
|
3109
|
+
"pause",
|
|
3110
|
+
"seek",
|
|
3111
|
+
"ended",
|
|
3112
|
+
"page_exit"
|
|
3113
|
+
]);
|
|
3114
|
+
var videoRangeSchema = z16.strictObject({
|
|
3115
|
+
start_s: z16.number().check(z16.gte(0)),
|
|
3116
|
+
end_s: z16.number().check(z16.gte(0))
|
|
3117
|
+
});
|
|
3118
|
+
var videoPlayMetadataSchema = z16.strictObject({
|
|
3119
|
+
video_id: videoIdSchema,
|
|
3120
|
+
variant: videoVariantSchema,
|
|
3121
|
+
current_s: z16.number().check(z16.gte(0)),
|
|
3122
|
+
duration_s: z16.number().check(z16.gte(0)),
|
|
3123
|
+
play_sequence: z16.int().check(z16.gte(1)),
|
|
3124
|
+
page: z16.strictObject({
|
|
3125
|
+
path: z16.string()
|
|
3126
|
+
})
|
|
3127
|
+
});
|
|
3128
|
+
var videoPlayConfigSchema = z16.strictObject({});
|
|
3129
|
+
var videoProgressMetadataSchema = z16.strictObject({
|
|
3130
|
+
video_id: videoIdSchema,
|
|
3131
|
+
variant: videoVariantSchema,
|
|
3132
|
+
trigger: videoProgressTriggerReasonSchema,
|
|
3133
|
+
current_s: z16.number().check(z16.gte(0)),
|
|
3134
|
+
furthest_s: z16.number().check(z16.gte(0)),
|
|
3135
|
+
watched_s: z16.number().check(z16.gte(0)),
|
|
3136
|
+
duration_s: z16.number().check(z16.gte(0)),
|
|
3137
|
+
max_percent: z16.int().check(z16.gte(0), z16.lte(100)),
|
|
3138
|
+
watched_percent: z16.int().check(z16.gte(0), z16.lte(100)),
|
|
3139
|
+
play_count: z16.int().check(z16.gte(1)),
|
|
3140
|
+
seek_count: z16.int().check(z16.gte(0)),
|
|
3141
|
+
ranges: z16.array(videoRangeSchema),
|
|
3142
|
+
page: z16.strictObject({
|
|
3143
|
+
path: z16.string()
|
|
3144
|
+
})
|
|
3145
|
+
});
|
|
3146
|
+
var videoProgressConfigSchema = z16.strictObject({});
|
|
3147
|
+
|
|
2912
3148
|
// ../tracking-core/src/events/registry.ts
|
|
2913
3149
|
var EVENT_REGISTRY = {
|
|
2914
3150
|
// --- automatic triggers ---
|
|
@@ -2975,6 +3211,18 @@ var EVENT_REGISTRY = {
|
|
|
2975
3211
|
metadataSchema: siteLinkArrivalMetadataSchema,
|
|
2976
3212
|
configSchema: siteLinkArrivalConfigSchema
|
|
2977
3213
|
},
|
|
3214
|
+
video_play: {
|
|
3215
|
+
kind: "automatic",
|
|
3216
|
+
semantics: EVENT_SEMANTICS.video_play,
|
|
3217
|
+
metadataSchema: videoPlayMetadataSchema,
|
|
3218
|
+
configSchema: videoPlayConfigSchema
|
|
3219
|
+
},
|
|
3220
|
+
video_progress: {
|
|
3221
|
+
kind: "automatic",
|
|
3222
|
+
semantics: EVENT_SEMANTICS.video_progress,
|
|
3223
|
+
metadataSchema: videoProgressMetadataSchema,
|
|
3224
|
+
configSchema: videoProgressConfigSchema
|
|
3225
|
+
},
|
|
2978
3226
|
// --- manual triggers ---
|
|
2979
3227
|
form_submit: {
|
|
2980
3228
|
kind: "manual",
|
|
@@ -2988,6 +3236,12 @@ var EVENT_REGISTRY = {
|
|
|
2988
3236
|
metadataSchema: formStepMetadataSchema,
|
|
2989
3237
|
configSchema: formStepConfigSchema
|
|
2990
3238
|
},
|
|
3239
|
+
form_details: {
|
|
3240
|
+
kind: "manual",
|
|
3241
|
+
semantics: EVENT_SEMANTICS.form_details,
|
|
3242
|
+
metadataSchema: formDetailsMetadataSchema,
|
|
3243
|
+
configSchema: formDetailsConfigSchema
|
|
3244
|
+
},
|
|
2991
3245
|
phone_click: {
|
|
2992
3246
|
kind: "manual",
|
|
2993
3247
|
semantics: EVENT_SEMANTICS.phone_click,
|
|
@@ -3026,6 +3280,7 @@ function salvageFormSubmit(metadata) {
|
|
|
3026
3280
|
...valid("contract_version", form.contract_version),
|
|
3027
3281
|
...valid("contract_hash", form.contract_hash),
|
|
3028
3282
|
...valid("extra", form.extra),
|
|
3283
|
+
...valid("submission_id", form.submission_id),
|
|
3029
3284
|
contract_violations: [...reported, INVALID_SHAPE].slice(-MAX_CONTRACT_VIOLATIONS)
|
|
3030
3285
|
},
|
|
3031
3286
|
page: { path: typeof page.path === "string" ? page.path : currentPath2() }
|
|
@@ -3068,6 +3323,17 @@ function currentPath2() {
|
|
|
3068
3323
|
|
|
3069
3324
|
// ../tracking-core/src/ingest-typed.ts
|
|
3070
3325
|
var clientSettings = /* @__PURE__ */ new WeakMap();
|
|
3326
|
+
var latestTrackingConfig;
|
|
3327
|
+
var latestRawClient = null;
|
|
3328
|
+
function setDefaultTrackingConfig(ref) {
|
|
3329
|
+
if (ref) latestTrackingConfig = ref;
|
|
3330
|
+
}
|
|
3331
|
+
function getActiveTrackingEnv() {
|
|
3332
|
+
return {
|
|
3333
|
+
rawClient: latestRawClient,
|
|
3334
|
+
trackingConfig: latestTrackingConfig
|
|
3335
|
+
};
|
|
3336
|
+
}
|
|
3071
3337
|
function typedClientSettings(client) {
|
|
3072
3338
|
return clientSettings.get(client) ?? {};
|
|
3073
3339
|
}
|
|
@@ -3098,7 +3364,9 @@ function createTypedClient(raw, registry, options = {}) {
|
|
|
3098
3364
|
getSessionId: raw.getSessionId.bind(raw),
|
|
3099
3365
|
getVisitorId: raw.getVisitorId.bind(raw)
|
|
3100
3366
|
};
|
|
3101
|
-
|
|
3367
|
+
latestRawClient = raw;
|
|
3368
|
+
if (options.trackingConfig) latestTrackingConfig = options.trackingConfig;
|
|
3369
|
+
clientSettings.set(client, { ...options, rawClient: raw });
|
|
3102
3370
|
return client;
|
|
3103
3371
|
}
|
|
3104
3372
|
|
|
@@ -3306,7 +3574,7 @@ function attachScrollDepth(client, config) {
|
|
|
3306
3574
|
}
|
|
3307
3575
|
const thresholds = new Set(config.thresholds);
|
|
3308
3576
|
let firedForPath = /* @__PURE__ */ new Set();
|
|
3309
|
-
let
|
|
3577
|
+
let currentPath4 = window.location.pathname;
|
|
3310
3578
|
let rafId = null;
|
|
3311
3579
|
const gate = createBaselineGate();
|
|
3312
3580
|
function checkThresholds() {
|
|
@@ -3322,7 +3590,7 @@ function attachScrollDepth(client, config) {
|
|
|
3322
3590
|
eventType: "scroll_depth",
|
|
3323
3591
|
metadata: {
|
|
3324
3592
|
depth_percent: threshold,
|
|
3325
|
-
page: { path:
|
|
3593
|
+
page: { path: currentPath4 }
|
|
3326
3594
|
},
|
|
3327
3595
|
pageUrl: window.location.href,
|
|
3328
3596
|
occurredAt: null
|
|
@@ -3339,8 +3607,8 @@ function attachScrollDepth(client, config) {
|
|
|
3339
3607
|
}
|
|
3340
3608
|
function resetIfPathChanged() {
|
|
3341
3609
|
const newPath = window.location.pathname;
|
|
3342
|
-
if (newPath ===
|
|
3343
|
-
|
|
3610
|
+
if (newPath === currentPath4) return;
|
|
3611
|
+
currentPath4 = newPath;
|
|
3344
3612
|
firedForPath = /* @__PURE__ */ new Set();
|
|
3345
3613
|
gate.rebaseline();
|
|
3346
3614
|
}
|
|
@@ -3403,13 +3671,13 @@ function attachMultiPageSession(client, config) {
|
|
|
3403
3671
|
return storage.getItem(FIRED_KEY) === "1";
|
|
3404
3672
|
}
|
|
3405
3673
|
function check2() {
|
|
3406
|
-
const
|
|
3407
|
-
if (
|
|
3408
|
-
lastCheckedPath =
|
|
3674
|
+
const currentPath4 = window.location.pathname;
|
|
3675
|
+
if (currentPath4 === lastCheckedPath) return;
|
|
3676
|
+
lastCheckedPath = currentPath4;
|
|
3409
3677
|
resetIfSessionChanged();
|
|
3410
3678
|
if (hasFired()) return;
|
|
3411
3679
|
const paths = getDistinctPaths();
|
|
3412
|
-
paths.add(
|
|
3680
|
+
paths.add(currentPath4);
|
|
3413
3681
|
saveDistinctPaths(paths);
|
|
3414
3682
|
if (paths.size >= pageThreshold) {
|
|
3415
3683
|
storage.setItem(FIRED_KEY, "1");
|
|
@@ -3454,7 +3722,7 @@ function attachFormStart(client, config) {
|
|
|
3454
3722
|
}
|
|
3455
3723
|
const selector = config.selector ?? "form";
|
|
3456
3724
|
let firedForms = /* @__PURE__ */ new Set();
|
|
3457
|
-
let
|
|
3725
|
+
let currentPath4 = window.location.pathname;
|
|
3458
3726
|
let pendingTap = null;
|
|
3459
3727
|
function getFormKey(form) {
|
|
3460
3728
|
if (form.id) return `id:${form.id}`;
|
|
@@ -3505,8 +3773,8 @@ function attachFormStart(client, config) {
|
|
|
3505
3773
|
}
|
|
3506
3774
|
function resetIfPathChanged() {
|
|
3507
3775
|
const newPath = window.location.pathname;
|
|
3508
|
-
if (newPath ===
|
|
3509
|
-
|
|
3776
|
+
if (newPath === currentPath4) return;
|
|
3777
|
+
currentPath4 = newPath;
|
|
3510
3778
|
firedForms = /* @__PURE__ */ new Set();
|
|
3511
3779
|
}
|
|
3512
3780
|
const originalPushState = history.pushState.bind(history);
|
|
@@ -3547,7 +3815,7 @@ function attachPageExit(client) {
|
|
|
3547
3815
|
return () => {
|
|
3548
3816
|
};
|
|
3549
3817
|
}
|
|
3550
|
-
let
|
|
3818
|
+
let currentPath4 = window.location.pathname;
|
|
3551
3819
|
let activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
3552
3820
|
let accumulatedMs = 0;
|
|
3553
3821
|
let maxScrollPercent = null;
|
|
@@ -3597,9 +3865,9 @@ function attachPageExit(client) {
|
|
|
3597
3865
|
}
|
|
3598
3866
|
function onNavigate() {
|
|
3599
3867
|
const newPath = window.location.pathname;
|
|
3600
|
-
if (newPath ===
|
|
3601
|
-
emitSegment(
|
|
3602
|
-
|
|
3868
|
+
if (newPath === currentPath4) return;
|
|
3869
|
+
emitSegment(currentPath4, false);
|
|
3870
|
+
currentPath4 = newPath;
|
|
3603
3871
|
maxScrollPercent = null;
|
|
3604
3872
|
gate.rebaseline();
|
|
3605
3873
|
accumulatedMs = 0;
|
|
@@ -3607,15 +3875,18 @@ function attachPageExit(client) {
|
|
|
3607
3875
|
}
|
|
3608
3876
|
function onVisibilityChange() {
|
|
3609
3877
|
if (document.visibilityState === "hidden") {
|
|
3610
|
-
emitSegment(
|
|
3878
|
+
emitSegment(currentPath4, true);
|
|
3611
3879
|
} else {
|
|
3612
3880
|
activeSince = Date.now();
|
|
3613
3881
|
}
|
|
3614
3882
|
}
|
|
3615
3883
|
function onPageHide() {
|
|
3616
|
-
emitSegment(
|
|
3884
|
+
emitSegment(currentPath4, true);
|
|
3617
3885
|
}
|
|
3618
3886
|
const unsubscribeNav = onHistoryChange(onNavigate);
|
|
3887
|
+
const unsubscribeBeforeUnload = client.onBeforeUnload?.(() => {
|
|
3888
|
+
emitSegment(currentPath4, false);
|
|
3889
|
+
});
|
|
3619
3890
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
3620
3891
|
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
3621
3892
|
window.addEventListener("pagehide", onPageHide);
|
|
@@ -3624,6 +3895,7 @@ function attachPageExit(client) {
|
|
|
3624
3895
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
3625
3896
|
gate.cancel();
|
|
3626
3897
|
unsubscribeNav();
|
|
3898
|
+
unsubscribeBeforeUnload?.();
|
|
3627
3899
|
window.removeEventListener("scroll", onScroll);
|
|
3628
3900
|
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3629
3901
|
window.removeEventListener("pagehide", onPageHide);
|
|
@@ -3793,7 +4065,7 @@ function attachPhoneClickCapture(client, config) {
|
|
|
3793
4065
|
}
|
|
3794
4066
|
|
|
3795
4067
|
// ../tracking-core/src/lead-forms/lead-forms.gen.ts
|
|
3796
|
-
import * as
|
|
4068
|
+
import * as z17 from "zod/mini";
|
|
3797
4069
|
var LEAD_FORM_REGISTRY_VERSION = 2;
|
|
3798
4070
|
var LEAD_FORM_ROLES = [
|
|
3799
4071
|
"given_name",
|
|
@@ -3819,28 +4091,28 @@ var LEAD_FORM_ROLES = [
|
|
|
3819
4091
|
"attribution"
|
|
3820
4092
|
];
|
|
3821
4093
|
var leadFormPrimitiveSchemas = /* @__PURE__ */ (() => ({
|
|
3822
|
-
string:
|
|
3823
|
-
text:
|
|
3824
|
-
enum:
|
|
3825
|
-
multi_enum:
|
|
3826
|
-
bool:
|
|
3827
|
-
date:
|
|
3828
|
-
time_window:
|
|
3829
|
-
start:
|
|
3830
|
-
end:
|
|
3831
|
-
label:
|
|
4094
|
+
string: z17.string().check(z17.maxLength(120)),
|
|
4095
|
+
text: z17.string().check(z17.maxLength(2e3)),
|
|
4096
|
+
enum: z17.string().check(z17.regex(/^[a-z0-9-]{1,48}$/)),
|
|
4097
|
+
multi_enum: z17.array(z17.string().check(z17.regex(/^[a-z0-9-]{1,48}$/))).check(z17.maxLength(10)),
|
|
4098
|
+
bool: z17.boolean(),
|
|
4099
|
+
date: z17.string().check(z17.regex(/^\d{4}-\d{2}-\d{2}$/)),
|
|
4100
|
+
time_window: z17.strictObject({
|
|
4101
|
+
start: z17.string().check(z17.regex(/^([01]\d|2[0-3]):[0-5]\d$/)),
|
|
4102
|
+
end: z17.nullable(z17.string().check(z17.regex(/^([01]\d|2[0-3]):[0-5]\d$/))),
|
|
4103
|
+
label: z17.optional(z17.string().check(z17.maxLength(60)))
|
|
3832
4104
|
}),
|
|
3833
|
-
phone:
|
|
3834
|
-
email:
|
|
3835
|
-
address:
|
|
3836
|
-
line1:
|
|
3837
|
-
line2:
|
|
3838
|
-
city:
|
|
3839
|
-
region:
|
|
3840
|
-
postal_code:
|
|
3841
|
-
country:
|
|
4105
|
+
phone: z17.string().check(z17.regex(/^\+[1-9]\d{6,14}$/)),
|
|
4106
|
+
email: z17.string().check(z17.maxLength(320), z17.regex(/^[^\s@]+@[^\s@]+$/)),
|
|
4107
|
+
address: z17.strictObject({
|
|
4108
|
+
line1: z17.string().check(z17.maxLength(120)),
|
|
4109
|
+
line2: z17.optional(z17.string().check(z17.maxLength(120))),
|
|
4110
|
+
city: z17.optional(z17.string().check(z17.maxLength(120))),
|
|
4111
|
+
region: z17.optional(z17.string().check(z17.maxLength(120))),
|
|
4112
|
+
postal_code: z17.optional(z17.string().check(z17.maxLength(120))),
|
|
4113
|
+
country: z17.optional(z17.string().check(z17.maxLength(120)))
|
|
3842
4114
|
}),
|
|
3843
|
-
number:
|
|
4115
|
+
number: z17.number()
|
|
3844
4116
|
}))();
|
|
3845
4117
|
var LEAD_FORM_ROLE_SPECS = {
|
|
3846
4118
|
given_name: { primitive: "string", smsLabel: "", contactIdentity: true },
|
|
@@ -3922,34 +4194,70 @@ function createLeadFormSubmit(tracking, contracts, options = {}) {
|
|
|
3922
4194
|
contracts,
|
|
3923
4195
|
settings
|
|
3924
4196
|
);
|
|
4197
|
+
const submission = { submissionId: uuidV4(), formId: input.formId, kind: input.kind };
|
|
3925
4198
|
const metadata = {
|
|
3926
4199
|
form: {
|
|
3927
4200
|
id: input.formId,
|
|
3928
4201
|
action: input.action ?? null,
|
|
3929
|
-
fields: fields.map(
|
|
3930
|
-
name: role,
|
|
3931
|
-
type: INPUT_TYPES[primitiveOf(role) ?? "string"],
|
|
3932
|
-
label: labelOf(role),
|
|
3933
|
-
value,
|
|
3934
|
-
role
|
|
3935
|
-
})),
|
|
4202
|
+
fields: fields.map(fieldEntry),
|
|
3936
4203
|
kind: input.kind,
|
|
3937
4204
|
contract_version: LEAD_FORM_REGISTRY_VERSION,
|
|
3938
4205
|
...hash ? { contract_hash: hash } : {},
|
|
3939
4206
|
...input.extra?.length ? { extra: input.extra } : {},
|
|
3940
|
-
...violations.length > 0 ? { contract_violations: violations.slice(0, MAX_CONTRACT_VIOLATIONS) } : {}
|
|
4207
|
+
...violations.length > 0 ? { contract_violations: violations.slice(0, MAX_CONTRACT_VIOLATIONS) } : {},
|
|
4208
|
+
submission_id: submission.submissionId
|
|
3941
4209
|
},
|
|
3942
|
-
page: { path:
|
|
4210
|
+
page: { path: currentPath3() }
|
|
3943
4211
|
};
|
|
3944
4212
|
tracking.trackEvent("form_submit", metadata);
|
|
3945
|
-
return metadata;
|
|
4213
|
+
return { ...metadata, submission };
|
|
4214
|
+
},
|
|
4215
|
+
addDetails(submission, input) {
|
|
4216
|
+
const fields = presentFields(input.fields);
|
|
4217
|
+
const extra = (input.extra ?? []).filter((item) => !isBlank(item.value));
|
|
4218
|
+
if (fields.length === 0 && extra.length === 0) return { sent: false, reason: "no_fields" };
|
|
4219
|
+
const { violations, hash } = judgeLeadForm(
|
|
4220
|
+
submission.kind,
|
|
4221
|
+
submission.formId,
|
|
4222
|
+
fields,
|
|
4223
|
+
contracts,
|
|
4224
|
+
settings,
|
|
4225
|
+
{ partial: true }
|
|
4226
|
+
);
|
|
4227
|
+
const metadata = {
|
|
4228
|
+
form: {
|
|
4229
|
+
id: submission.formId,
|
|
4230
|
+
submission_id: submission.submissionId,
|
|
4231
|
+
kind: submission.kind,
|
|
4232
|
+
fields: fields.map(fieldEntry),
|
|
4233
|
+
contract_version: LEAD_FORM_REGISTRY_VERSION,
|
|
4234
|
+
...hash ? { contract_hash: hash } : {},
|
|
4235
|
+
...extra.length > 0 ? { extra } : {},
|
|
4236
|
+
...violations.length > 0 ? { contract_violations: violations.slice(0, MAX_CONTRACT_VIOLATIONS) } : {}
|
|
4237
|
+
},
|
|
4238
|
+
page: { path: currentPath3() }
|
|
4239
|
+
};
|
|
4240
|
+
tracking.trackEvent("form_details", metadata);
|
|
4241
|
+
return { sent: true };
|
|
3946
4242
|
}
|
|
3947
4243
|
};
|
|
3948
4244
|
}
|
|
3949
|
-
function
|
|
4245
|
+
function fieldEntry([role, value]) {
|
|
4246
|
+
return {
|
|
4247
|
+
name: role,
|
|
4248
|
+
type: INPUT_TYPES[primitiveOf(role) ?? "string"],
|
|
4249
|
+
label: labelOf(role),
|
|
4250
|
+
value,
|
|
4251
|
+
role
|
|
4252
|
+
};
|
|
4253
|
+
}
|
|
4254
|
+
function currentPath3() {
|
|
4255
|
+
return typeof window === "undefined" ? "/" : window.location.pathname;
|
|
4256
|
+
}
|
|
4257
|
+
function judgeLeadForm(kind, formId, fields, contracts, settings, { partial = false } = {}) {
|
|
3950
4258
|
const generated = contracts?.contracts[kind];
|
|
3951
4259
|
const live = liveContract(settings.trackingConfig, kind);
|
|
3952
|
-
const violations = check(live === void 0 ? generated : fromLive(live), fields);
|
|
4260
|
+
const violations = check(live === void 0 ? generated : fromLive(live), fields, partial);
|
|
3953
4261
|
const liveHash = live === void 0 ? void 0 : live?.contract_hash ?? null;
|
|
3954
4262
|
if (contracts && (liveHash !== void 0 && (generated?.hash ?? null) !== liveHash || contracts.registryVersion !== LEAD_FORM_REGISTRY_VERSION)) {
|
|
3955
4263
|
violations.push({ role: null, rule: "contract_behind" });
|
|
@@ -3995,7 +4303,7 @@ function normalize(role, value) {
|
|
|
3995
4303
|
function isBlank(value) {
|
|
3996
4304
|
return value === void 0 || value === null || typeof value === "string" && value.trim() === "" || Array.isArray(value) && value.length === 0;
|
|
3997
4305
|
}
|
|
3998
|
-
function check(contract, fields) {
|
|
4306
|
+
function check(contract, fields, partial) {
|
|
3999
4307
|
const answered = new Map(fields);
|
|
4000
4308
|
const violations = [];
|
|
4001
4309
|
for (const [role, value] of fields) {
|
|
@@ -4013,6 +4321,7 @@ function check(contract, fields) {
|
|
|
4013
4321
|
violations.push({ role, rule: "unknown_option" });
|
|
4014
4322
|
}
|
|
4015
4323
|
}
|
|
4324
|
+
if (partial) return violations;
|
|
4016
4325
|
for (const { role, requiredWhen } of contract?.requires ?? []) {
|
|
4017
4326
|
const owing = requiredWhen === null || optionKeys(answered.get(requiredWhen.role)).some((key) => requiredWhen.anyOf.includes(key));
|
|
4018
4327
|
if (owing && !answered.has(role)) violations.push({ role, rule: "missing_required" });
|
|
@@ -4375,7 +4684,7 @@ function GoogleAdsTracking(props) {
|
|
|
4375
4684
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
4376
4685
|
|
|
4377
4686
|
// package.json
|
|
4378
|
-
var version = "1.
|
|
4687
|
+
var version = "1.19.0";
|
|
4379
4688
|
|
|
4380
4689
|
// ../tracking-core/src/phone-react.tsx
|
|
4381
4690
|
import {
|
|
@@ -4493,6 +4802,7 @@ function createTracking(options) {
|
|
|
4493
4802
|
trackingConfig
|
|
4494
4803
|
} = options;
|
|
4495
4804
|
registerCapability("base_tracking");
|
|
4805
|
+
setDefaultTrackingConfig(trackingConfig);
|
|
4496
4806
|
if (trackingConfig) registerCapability("conversion_goals_auto");
|
|
4497
4807
|
if (!apiKey || !endpoint) {
|
|
4498
4808
|
if (apiKey || endpoint) {
|
|
@@ -4760,14 +5070,1429 @@ function useBookingSubmit(bookings, options = {}) {
|
|
|
4760
5070
|
const status = submitting ? "submitting" : outcome?.status ?? "idle";
|
|
4761
5071
|
return { status, outcome, booked, submit, updateBooking, reset };
|
|
4762
5072
|
}
|
|
5073
|
+
|
|
5074
|
+
// ../tracking-core/src/video-react.tsx
|
|
5075
|
+
import {
|
|
5076
|
+
useCallback as useCallback4,
|
|
5077
|
+
useEffect as useEffect6,
|
|
5078
|
+
useLayoutEffect,
|
|
5079
|
+
useMemo as useMemo6,
|
|
5080
|
+
useRef as useRef2,
|
|
5081
|
+
useState as useState5,
|
|
5082
|
+
useSyncExternalStore as useSyncExternalStore2
|
|
5083
|
+
} from "react";
|
|
5084
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
5085
|
+
var DEFAULT_VIDEO_CHECKPOINTS = [25, 50, 75, 90, 100];
|
|
5086
|
+
var streamManifestUrl = (host, uid) => `https://${host}/${uid}/manifest/video.m3u8`;
|
|
5087
|
+
var streamPosterUrl = (host, uid, time = 4) => `https://${host}/${uid}/thumbnails/thumbnail.jpg?time=${time}s`;
|
|
5088
|
+
var TV_SKIN_STYLE_ATTR = "data-aranova-tv-skin";
|
|
5089
|
+
var TV_SKIN_CSS = `
|
|
5090
|
+
.tv-skin {
|
|
5091
|
+
container-type: inline-size;
|
|
5092
|
+
position: relative;
|
|
5093
|
+
overflow: hidden;
|
|
5094
|
+
border-radius: 18px;
|
|
5095
|
+
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
5096
|
+
background: #0a0e1a;
|
|
5097
|
+
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.32);
|
|
5098
|
+
}
|
|
5099
|
+
.tv-skin-desktop {
|
|
5100
|
+
display: none;
|
|
5101
|
+
aspect-ratio: 16 / 9;
|
|
5102
|
+
width: 100%;
|
|
5103
|
+
}
|
|
5104
|
+
.tv-skin-mobile {
|
|
5105
|
+
display: block;
|
|
5106
|
+
margin-left: auto;
|
|
5107
|
+
margin-right: auto;
|
|
5108
|
+
aspect-ratio: 9 / 16;
|
|
5109
|
+
width: 100%;
|
|
5110
|
+
max-width: 420px;
|
|
5111
|
+
}
|
|
5112
|
+
@media (min-width: 768px) {
|
|
5113
|
+
.tv-skin-desktop {
|
|
5114
|
+
display: block;
|
|
5115
|
+
}
|
|
5116
|
+
.tv-skin-mobile {
|
|
5117
|
+
display: none;
|
|
5118
|
+
}
|
|
5119
|
+
}
|
|
5120
|
+
.tv-skin media-controller {
|
|
5121
|
+
display: block;
|
|
5122
|
+
width: 100%;
|
|
5123
|
+
height: 100%;
|
|
5124
|
+
background: #000;
|
|
5125
|
+
--media-primary-color: #ffffff;
|
|
5126
|
+
--media-text-color: rgba(255, 255, 255, 0.82);
|
|
5127
|
+
--media-icon-color: #ffffff;
|
|
5128
|
+
--media-secondary-color: transparent;
|
|
5129
|
+
--media-control-background: transparent;
|
|
5130
|
+
--media-control-hover-background: transparent;
|
|
5131
|
+
--media-control-padding: 0;
|
|
5132
|
+
--media-control-height: 40px;
|
|
5133
|
+
--media-tooltip-display: none;
|
|
5134
|
+
--media-font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
5135
|
+
--media-font-size: 11.5px;
|
|
5136
|
+
--media-focus-box-shadow: 0 0 0 2px #74a0ff;
|
|
5137
|
+
--media-button-icon-width: 20px;
|
|
5138
|
+
--media-button-icon-height: 20px;
|
|
5139
|
+
--media-range-padding: 0;
|
|
5140
|
+
--media-range-bar-color: #ffffff;
|
|
5141
|
+
--media-range-track-background: rgba(255, 255, 255, 0.25);
|
|
5142
|
+
--media-range-track-border-radius: 3px;
|
|
5143
|
+
--media-time-range-buffered-color: transparent;
|
|
5144
|
+
--media-time-range-hover-display: none;
|
|
5145
|
+
--media-preview-time-background: transparent;
|
|
5146
|
+
--media-range-thumb-background: #ffffff;
|
|
5147
|
+
--media-range-thumb-width: 12px;
|
|
5148
|
+
--media-range-thumb-height: 12px;
|
|
5149
|
+
--media-range-thumb-opacity: 0;
|
|
5150
|
+
}
|
|
5151
|
+
.tv-skin media-controller::part(vertical-layer),
|
|
5152
|
+
.tv-skin media-controller::part(centered-layer) {
|
|
5153
|
+
background: transparent;
|
|
5154
|
+
}
|
|
5155
|
+
.tv-chrome {
|
|
5156
|
+
position: absolute;
|
|
5157
|
+
inset: auto 0 0 0;
|
|
5158
|
+
padding-top: 56px;
|
|
5159
|
+
background: linear-gradient(to top, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0));
|
|
5160
|
+
transition: opacity 0.25s ease;
|
|
5161
|
+
}
|
|
5162
|
+
.tv-skin media-controller[userinactive]:not([mediapaused]) .tv-chrome {
|
|
5163
|
+
opacity: 0;
|
|
5164
|
+
pointer-events: none;
|
|
5165
|
+
}
|
|
5166
|
+
.tv-row {
|
|
5167
|
+
display: flex;
|
|
5168
|
+
align-items: center;
|
|
5169
|
+
gap: 2px;
|
|
5170
|
+
padding: 0 4px;
|
|
5171
|
+
}
|
|
5172
|
+
.tv-spacer {
|
|
5173
|
+
flex: 1 1 auto;
|
|
5174
|
+
}
|
|
5175
|
+
.tv-ctl,
|
|
5176
|
+
.tv-btn {
|
|
5177
|
+
display: inline-flex;
|
|
5178
|
+
align-items: center;
|
|
5179
|
+
justify-content: center;
|
|
5180
|
+
width: 40px;
|
|
5181
|
+
height: 40px;
|
|
5182
|
+
padding: 0;
|
|
5183
|
+
border: 0;
|
|
5184
|
+
border-radius: 0;
|
|
5185
|
+
background: transparent;
|
|
5186
|
+
box-shadow: none;
|
|
5187
|
+
color: rgba(255, 255, 255, 0.92);
|
|
5188
|
+
cursor: pointer;
|
|
5189
|
+
transition: color 0.15s;
|
|
5190
|
+
}
|
|
5191
|
+
.tv-ctl:hover,
|
|
5192
|
+
.tv-btn:hover {
|
|
5193
|
+
background: transparent;
|
|
5194
|
+
color: #ffffff;
|
|
5195
|
+
}
|
|
5196
|
+
.tv-ctl:focus-visible,
|
|
5197
|
+
.tv-btn:focus-visible,
|
|
5198
|
+
.tv-menu-item:focus-visible {
|
|
5199
|
+
outline: 2px solid #74a0ff;
|
|
5200
|
+
outline-offset: -4px;
|
|
5201
|
+
box-shadow: none;
|
|
5202
|
+
}
|
|
5203
|
+
.tv-time {
|
|
5204
|
+
width: auto;
|
|
5205
|
+
padding: 0 4px 0 6px;
|
|
5206
|
+
background: transparent;
|
|
5207
|
+
letter-spacing: 0.02em;
|
|
5208
|
+
white-space: nowrap;
|
|
5209
|
+
--media-control-background: transparent;
|
|
5210
|
+
}
|
|
5211
|
+
.tv-time-cur {
|
|
5212
|
+
display: none;
|
|
5213
|
+
}
|
|
5214
|
+
.tv-seek {
|
|
5215
|
+
display: block;
|
|
5216
|
+
width: 100%;
|
|
5217
|
+
height: 16px;
|
|
5218
|
+
margin: 0;
|
|
5219
|
+
padding: 0;
|
|
5220
|
+
background: transparent;
|
|
5221
|
+
box-shadow: none;
|
|
5222
|
+
border: 0;
|
|
5223
|
+
--media-range-track-height: 3px;
|
|
5224
|
+
--media-control-background: transparent;
|
|
5225
|
+
--media-control-hover-background: transparent;
|
|
5226
|
+
}
|
|
5227
|
+
.tv-seek:hover,
|
|
5228
|
+
.tv-seek:focus-visible {
|
|
5229
|
+
--media-range-track-height: 6px;
|
|
5230
|
+
--media-range-thumb-opacity: 1;
|
|
5231
|
+
}
|
|
5232
|
+
.tv-vol {
|
|
5233
|
+
display: flex;
|
|
5234
|
+
align-items: center;
|
|
5235
|
+
}
|
|
5236
|
+
.tv-volrange {
|
|
5237
|
+
width: 64px;
|
|
5238
|
+
height: 40px;
|
|
5239
|
+
margin-right: 4px;
|
|
5240
|
+
padding: 0;
|
|
5241
|
+
opacity: 0;
|
|
5242
|
+
pointer-events: none;
|
|
5243
|
+
transform: scaleX(0.75);
|
|
5244
|
+
transform-origin: right center;
|
|
5245
|
+
background: transparent;
|
|
5246
|
+
transition: transform 0.2s ease, opacity 0.2s ease;
|
|
5247
|
+
--media-control-background: transparent;
|
|
5248
|
+
--media-range-track-height: 3px;
|
|
5249
|
+
}
|
|
5250
|
+
.tv-vol:hover .tv-volrange,
|
|
5251
|
+
.tv-vol:focus-within .tv-volrange {
|
|
5252
|
+
opacity: 1;
|
|
5253
|
+
pointer-events: auto;
|
|
5254
|
+
transform: scaleX(1);
|
|
5255
|
+
}
|
|
5256
|
+
@media (hover: none) {
|
|
5257
|
+
.tv-volrange {
|
|
5258
|
+
display: none;
|
|
5259
|
+
}
|
|
5260
|
+
}
|
|
5261
|
+
@container (max-width: 479px) {
|
|
5262
|
+
.tv-vol,
|
|
5263
|
+
.tv-time-full {
|
|
5264
|
+
display: none;
|
|
5265
|
+
}
|
|
5266
|
+
.tv-time-cur {
|
|
5267
|
+
display: inline-flex;
|
|
5268
|
+
}
|
|
5269
|
+
}
|
|
5270
|
+
@container (max-width: 767px) {
|
|
5271
|
+
.tv-theater {
|
|
5272
|
+
display: none;
|
|
5273
|
+
}
|
|
5274
|
+
}
|
|
5275
|
+
.tv-menu-wrap {
|
|
5276
|
+
position: relative;
|
|
5277
|
+
display: flex;
|
|
5278
|
+
align-items: center;
|
|
5279
|
+
}
|
|
5280
|
+
.tv-menu {
|
|
5281
|
+
position: absolute;
|
|
5282
|
+
right: 0;
|
|
5283
|
+
bottom: calc(100% + 8px);
|
|
5284
|
+
z-index: 5;
|
|
5285
|
+
width: 136px;
|
|
5286
|
+
max-height: 232px;
|
|
5287
|
+
margin: 0;
|
|
5288
|
+
padding: 4px 0;
|
|
5289
|
+
overflow-y: auto;
|
|
5290
|
+
list-style: none;
|
|
5291
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
5292
|
+
border-radius: 10px;
|
|
5293
|
+
background: linear-gradient(rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.12)), rgba(10, 14, 26, 0.55);
|
|
5294
|
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 12px 32px rgba(0, 0, 0, 0.35);
|
|
5295
|
+
}
|
|
5296
|
+
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
|
|
5297
|
+
.tv-menu {
|
|
5298
|
+
-webkit-backdrop-filter: blur(16px) saturate(140%);
|
|
5299
|
+
backdrop-filter: blur(16px) saturate(140%);
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
.tv-menu-item {
|
|
5303
|
+
position: relative;
|
|
5304
|
+
display: flex;
|
|
5305
|
+
width: 100%;
|
|
5306
|
+
height: 32px;
|
|
5307
|
+
align-items: center;
|
|
5308
|
+
padding: 0 12px 0 24px;
|
|
5309
|
+
border: 0;
|
|
5310
|
+
background: transparent;
|
|
5311
|
+
color: rgba(255, 255, 255, 0.75);
|
|
5312
|
+
font-family: var(--font-sans, system-ui, -apple-system, sans-serif);
|
|
5313
|
+
font-size: 13px;
|
|
5314
|
+
font-weight: 500;
|
|
5315
|
+
text-align: left;
|
|
5316
|
+
cursor: pointer;
|
|
5317
|
+
}
|
|
5318
|
+
.tv-menu-item:hover,
|
|
5319
|
+
.tv-menu-item:focus-visible {
|
|
5320
|
+
background: rgba(255, 255, 255, 0.1);
|
|
5321
|
+
color: #ffffff;
|
|
5322
|
+
outline: none;
|
|
5323
|
+
}
|
|
5324
|
+
.tv-menu-item[aria-checked='true'] {
|
|
5325
|
+
color: #ffffff;
|
|
5326
|
+
font-weight: 600;
|
|
5327
|
+
}
|
|
5328
|
+
.tv-menu-item[aria-checked='true']::before {
|
|
5329
|
+
content: '';
|
|
5330
|
+
position: absolute;
|
|
5331
|
+
left: 12px;
|
|
5332
|
+
width: 5px;
|
|
5333
|
+
height: 5px;
|
|
5334
|
+
border-radius: 50%;
|
|
5335
|
+
background: #ffffff;
|
|
5336
|
+
}
|
|
5337
|
+
.tv-menu-sub {
|
|
5338
|
+
margin-left: 4px;
|
|
5339
|
+
font-size: 11.5px;
|
|
5340
|
+
font-weight: 400;
|
|
5341
|
+
color: rgba(255, 255, 255, 0.55);
|
|
5342
|
+
}
|
|
5343
|
+
.tv-menu-note {
|
|
5344
|
+
height: 20px;
|
|
5345
|
+
padding: 0 12px 0 24px;
|
|
5346
|
+
color: rgba(255, 255, 255, 0.55);
|
|
5347
|
+
font-family: var(--font-sans, system-ui, -apple-system, sans-serif);
|
|
5348
|
+
font-size: 11.5px;
|
|
5349
|
+
line-height: 20px;
|
|
5350
|
+
}
|
|
5351
|
+
.tv-poster-overlay {
|
|
5352
|
+
position: absolute;
|
|
5353
|
+
inset: 0;
|
|
5354
|
+
}
|
|
5355
|
+
.tv-poster-img {
|
|
5356
|
+
width: 100%;
|
|
5357
|
+
height: 100%;
|
|
5358
|
+
object-fit: cover;
|
|
5359
|
+
display: block;
|
|
5360
|
+
}
|
|
5361
|
+
.tv-play-trigger {
|
|
5362
|
+
position: absolute;
|
|
5363
|
+
inset: 0;
|
|
5364
|
+
width: 100%;
|
|
5365
|
+
height: 100%;
|
|
5366
|
+
border: 0;
|
|
5367
|
+
padding: 0;
|
|
5368
|
+
background: transparent;
|
|
5369
|
+
cursor: pointer;
|
|
5370
|
+
display: flex;
|
|
5371
|
+
align-items: center;
|
|
5372
|
+
justify-content: center;
|
|
5373
|
+
transition: filter 0.2s ease;
|
|
5374
|
+
}
|
|
5375
|
+
.tv-play-trigger:hover {
|
|
5376
|
+
filter: brightness(1.1);
|
|
5377
|
+
}
|
|
5378
|
+
.tv-play-trigger:focus-visible {
|
|
5379
|
+
outline: 2px solid #74a0ff;
|
|
5380
|
+
outline-offset: -4px;
|
|
5381
|
+
}
|
|
5382
|
+
.tv-play-pill {
|
|
5383
|
+
display: flex;
|
|
5384
|
+
width: 64px;
|
|
5385
|
+
height: 64px;
|
|
5386
|
+
align-items: center;
|
|
5387
|
+
justify-content: center;
|
|
5388
|
+
border-radius: 9999px;
|
|
5389
|
+
border: 2px solid rgba(255, 255, 255, 0.72);
|
|
5390
|
+
background: rgba(255, 255, 255, 0.15);
|
|
5391
|
+
color: #ffffff;
|
|
5392
|
+
backdrop-filter: blur(2px);
|
|
5393
|
+
-webkit-backdrop-filter: blur(2px);
|
|
5394
|
+
transition: transform 0.3s ease;
|
|
5395
|
+
}
|
|
5396
|
+
.tv-play-trigger:hover .tv-play-pill {
|
|
5397
|
+
transform: scale(1.05);
|
|
5398
|
+
}
|
|
5399
|
+
`;
|
|
5400
|
+
function ensureTvSkinStyles() {
|
|
5401
|
+
if (typeof document === "undefined") return;
|
|
5402
|
+
if (document.querySelector(`style[${TV_SKIN_STYLE_ATTR}]`)) return;
|
|
5403
|
+
const style = document.createElement("style");
|
|
5404
|
+
style.setAttribute(TV_SKIN_STYLE_ATTR, "1");
|
|
5405
|
+
style.textContent = TV_SKIN_CSS;
|
|
5406
|
+
document.head.append(style);
|
|
5407
|
+
}
|
|
5408
|
+
function IconPlay({
|
|
5409
|
+
slot,
|
|
5410
|
+
size = 20,
|
|
5411
|
+
filled = false
|
|
5412
|
+
}) {
|
|
5413
|
+
return /* @__PURE__ */ jsx5(
|
|
5414
|
+
"svg",
|
|
5415
|
+
{
|
|
5416
|
+
slot,
|
|
5417
|
+
width: size,
|
|
5418
|
+
height: size,
|
|
5419
|
+
viewBox: "0 0 24 24",
|
|
5420
|
+
fill: filled ? "currentColor" : "none",
|
|
5421
|
+
stroke: "currentColor",
|
|
5422
|
+
strokeWidth: filled ? 0 : 1.75,
|
|
5423
|
+
strokeLinecap: "round",
|
|
5424
|
+
strokeLinejoin: "round",
|
|
5425
|
+
"aria-hidden": "true",
|
|
5426
|
+
style: filled ? { marginLeft: 3 } : void 0,
|
|
5427
|
+
children: /* @__PURE__ */ jsx5("polygon", { points: "6 3 20 12 6 21 6 3" })
|
|
5428
|
+
}
|
|
5429
|
+
);
|
|
5430
|
+
}
|
|
5431
|
+
function IconPause({ slot }) {
|
|
5432
|
+
return /* @__PURE__ */ jsxs2(
|
|
5433
|
+
"svg",
|
|
5434
|
+
{
|
|
5435
|
+
slot,
|
|
5436
|
+
width: 20,
|
|
5437
|
+
height: 20,
|
|
5438
|
+
viewBox: "0 0 24 24",
|
|
5439
|
+
fill: "none",
|
|
5440
|
+
stroke: "currentColor",
|
|
5441
|
+
strokeWidth: 1.75,
|
|
5442
|
+
strokeLinecap: "round",
|
|
5443
|
+
strokeLinejoin: "round",
|
|
5444
|
+
"aria-hidden": "true",
|
|
5445
|
+
children: [
|
|
5446
|
+
/* @__PURE__ */ jsx5("rect", { x: "14", y: "4", width: "4", height: "16", rx: "1" }),
|
|
5447
|
+
/* @__PURE__ */ jsx5("rect", { x: "6", y: "4", width: "4", height: "16", rx: "1" })
|
|
5448
|
+
]
|
|
5449
|
+
}
|
|
5450
|
+
);
|
|
5451
|
+
}
|
|
5452
|
+
function IconVolumeHigh({ slot }) {
|
|
5453
|
+
return /* @__PURE__ */ jsxs2(
|
|
5454
|
+
"svg",
|
|
5455
|
+
{
|
|
5456
|
+
slot,
|
|
5457
|
+
width: 20,
|
|
5458
|
+
height: 20,
|
|
5459
|
+
viewBox: "0 0 24 24",
|
|
5460
|
+
fill: "none",
|
|
5461
|
+
stroke: "currentColor",
|
|
5462
|
+
strokeWidth: 1.75,
|
|
5463
|
+
strokeLinecap: "round",
|
|
5464
|
+
strokeLinejoin: "round",
|
|
5465
|
+
"aria-hidden": "true",
|
|
5466
|
+
children: [
|
|
5467
|
+
/* @__PURE__ */ jsx5("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
|
|
5468
|
+
/* @__PURE__ */ jsx5("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07" }),
|
|
5469
|
+
/* @__PURE__ */ jsx5("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14" })
|
|
5470
|
+
]
|
|
5471
|
+
}
|
|
5472
|
+
);
|
|
5473
|
+
}
|
|
5474
|
+
function IconVolumeLow({ slot }) {
|
|
5475
|
+
return /* @__PURE__ */ jsxs2(
|
|
5476
|
+
"svg",
|
|
5477
|
+
{
|
|
5478
|
+
slot,
|
|
5479
|
+
width: 20,
|
|
5480
|
+
height: 20,
|
|
5481
|
+
viewBox: "0 0 24 24",
|
|
5482
|
+
fill: "none",
|
|
5483
|
+
stroke: "currentColor",
|
|
5484
|
+
strokeWidth: 1.75,
|
|
5485
|
+
strokeLinecap: "round",
|
|
5486
|
+
strokeLinejoin: "round",
|
|
5487
|
+
"aria-hidden": "true",
|
|
5488
|
+
children: [
|
|
5489
|
+
/* @__PURE__ */ jsx5("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
|
|
5490
|
+
/* @__PURE__ */ jsx5("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07" })
|
|
5491
|
+
]
|
|
5492
|
+
}
|
|
5493
|
+
);
|
|
5494
|
+
}
|
|
5495
|
+
function IconVolumeOff({ slot }) {
|
|
5496
|
+
return /* @__PURE__ */ jsxs2(
|
|
5497
|
+
"svg",
|
|
5498
|
+
{
|
|
5499
|
+
slot,
|
|
5500
|
+
width: 20,
|
|
5501
|
+
height: 20,
|
|
5502
|
+
viewBox: "0 0 24 24",
|
|
5503
|
+
fill: "none",
|
|
5504
|
+
stroke: "currentColor",
|
|
5505
|
+
strokeWidth: 1.75,
|
|
5506
|
+
strokeLinecap: "round",
|
|
5507
|
+
strokeLinejoin: "round",
|
|
5508
|
+
"aria-hidden": "true",
|
|
5509
|
+
children: [
|
|
5510
|
+
/* @__PURE__ */ jsx5("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
|
|
5511
|
+
/* @__PURE__ */ jsx5("line", { x1: "22", y1: "9", x2: "16", y2: "15" }),
|
|
5512
|
+
/* @__PURE__ */ jsx5("line", { x1: "16", y1: "9", x2: "22", y2: "15" })
|
|
5513
|
+
]
|
|
5514
|
+
}
|
|
5515
|
+
);
|
|
5516
|
+
}
|
|
5517
|
+
function IconSettings() {
|
|
5518
|
+
return /* @__PURE__ */ jsxs2(
|
|
5519
|
+
"svg",
|
|
5520
|
+
{
|
|
5521
|
+
width: 20,
|
|
5522
|
+
height: 20,
|
|
5523
|
+
viewBox: "0 0 24 24",
|
|
5524
|
+
fill: "none",
|
|
5525
|
+
stroke: "currentColor",
|
|
5526
|
+
strokeWidth: 1.75,
|
|
5527
|
+
strokeLinecap: "round",
|
|
5528
|
+
strokeLinejoin: "round",
|
|
5529
|
+
"aria-hidden": "true",
|
|
5530
|
+
children: [
|
|
5531
|
+
/* @__PURE__ */ jsx5("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }),
|
|
5532
|
+
/* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "3" })
|
|
5533
|
+
]
|
|
5534
|
+
}
|
|
5535
|
+
);
|
|
5536
|
+
}
|
|
5537
|
+
function IconTheaterExpand() {
|
|
5538
|
+
return /* @__PURE__ */ jsxs2(
|
|
5539
|
+
"svg",
|
|
5540
|
+
{
|
|
5541
|
+
width: 20,
|
|
5542
|
+
height: 20,
|
|
5543
|
+
viewBox: "0 0 24 24",
|
|
5544
|
+
fill: "none",
|
|
5545
|
+
stroke: "currentColor",
|
|
5546
|
+
strokeWidth: 1.75,
|
|
5547
|
+
strokeLinecap: "round",
|
|
5548
|
+
strokeLinejoin: "round",
|
|
5549
|
+
"aria-hidden": "true",
|
|
5550
|
+
children: [
|
|
5551
|
+
/* @__PURE__ */ jsx5("polyline", { points: "15 3 21 3 21 9" }),
|
|
5552
|
+
/* @__PURE__ */ jsx5("polyline", { points: "9 21 3 21 3 15" }),
|
|
5553
|
+
/* @__PURE__ */ jsx5("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
|
|
5554
|
+
/* @__PURE__ */ jsx5("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
|
|
5555
|
+
]
|
|
5556
|
+
}
|
|
5557
|
+
);
|
|
5558
|
+
}
|
|
5559
|
+
function IconTheaterShrink() {
|
|
5560
|
+
return /* @__PURE__ */ jsxs2(
|
|
5561
|
+
"svg",
|
|
5562
|
+
{
|
|
5563
|
+
width: 20,
|
|
5564
|
+
height: 20,
|
|
5565
|
+
viewBox: "0 0 24 24",
|
|
5566
|
+
fill: "none",
|
|
5567
|
+
stroke: "currentColor",
|
|
5568
|
+
strokeWidth: 1.75,
|
|
5569
|
+
strokeLinecap: "round",
|
|
5570
|
+
strokeLinejoin: "round",
|
|
5571
|
+
"aria-hidden": "true",
|
|
5572
|
+
children: [
|
|
5573
|
+
/* @__PURE__ */ jsx5("polyline", { points: "4 14 10 14 10 20" }),
|
|
5574
|
+
/* @__PURE__ */ jsx5("polyline", { points: "20 10 14 10 14 4" }),
|
|
5575
|
+
/* @__PURE__ */ jsx5("line", { x1: "14", y1: "10", x2: "21", y2: "3" }),
|
|
5576
|
+
/* @__PURE__ */ jsx5("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
|
|
5577
|
+
]
|
|
5578
|
+
}
|
|
5579
|
+
);
|
|
5580
|
+
}
|
|
5581
|
+
function IconFullscreenEnter({ slot }) {
|
|
5582
|
+
return /* @__PURE__ */ jsxs2(
|
|
5583
|
+
"svg",
|
|
5584
|
+
{
|
|
5585
|
+
slot,
|
|
5586
|
+
width: 20,
|
|
5587
|
+
height: 20,
|
|
5588
|
+
viewBox: "0 0 24 24",
|
|
5589
|
+
fill: "none",
|
|
5590
|
+
stroke: "currentColor",
|
|
5591
|
+
strokeWidth: 1.75,
|
|
5592
|
+
strokeLinecap: "round",
|
|
5593
|
+
strokeLinejoin: "round",
|
|
5594
|
+
"aria-hidden": "true",
|
|
5595
|
+
children: [
|
|
5596
|
+
/* @__PURE__ */ jsx5("path", { d: "M8 3H5a2 2 0 0 0-2 2v3" }),
|
|
5597
|
+
/* @__PURE__ */ jsx5("path", { d: "M21 8V5a2 2 0 0 0-2-2h-3" }),
|
|
5598
|
+
/* @__PURE__ */ jsx5("path", { d: "M3 16v3a2 2 0 0 0 2 2h3" }),
|
|
5599
|
+
/* @__PURE__ */ jsx5("path", { d: "M16 21h3a2 2 0 0 0 2-2v-3" })
|
|
5600
|
+
]
|
|
5601
|
+
}
|
|
5602
|
+
);
|
|
5603
|
+
}
|
|
5604
|
+
function IconFullscreenExit({ slot }) {
|
|
5605
|
+
return /* @__PURE__ */ jsxs2(
|
|
5606
|
+
"svg",
|
|
5607
|
+
{
|
|
5608
|
+
slot,
|
|
5609
|
+
width: 20,
|
|
5610
|
+
height: 20,
|
|
5611
|
+
viewBox: "0 0 24 24",
|
|
5612
|
+
fill: "none",
|
|
5613
|
+
stroke: "currentColor",
|
|
5614
|
+
strokeWidth: 1.75,
|
|
5615
|
+
strokeLinecap: "round",
|
|
5616
|
+
strokeLinejoin: "round",
|
|
5617
|
+
"aria-hidden": "true",
|
|
5618
|
+
children: [
|
|
5619
|
+
/* @__PURE__ */ jsx5("path", { d: "M8 3v3a2 2 0 0 1-2 2H3" }),
|
|
5620
|
+
/* @__PURE__ */ jsx5("path", { d: "M21 8h-3a2 2 0 0 1-2-2V3" }),
|
|
5621
|
+
/* @__PURE__ */ jsx5("path", { d: "M3 16h3a2 2 0 0 1 2 2v3" }),
|
|
5622
|
+
/* @__PURE__ */ jsx5("path", { d: "M16 21v-3a2 2 0 0 1 2-2h3" })
|
|
5623
|
+
]
|
|
5624
|
+
}
|
|
5625
|
+
);
|
|
5626
|
+
}
|
|
5627
|
+
var EMPTY_GOALS2 = [];
|
|
5628
|
+
function serverVideoSnapshot() {
|
|
5629
|
+
return null;
|
|
5630
|
+
}
|
|
5631
|
+
function serverGoalsSnapshot() {
|
|
5632
|
+
return EMPTY_GOALS2;
|
|
5633
|
+
}
|
|
5634
|
+
function useTrackedVideoConfig(videoKey, trackingConfig, fallbackConfig) {
|
|
5635
|
+
registerCapability("video_tracking");
|
|
5636
|
+
const effectiveRef = trackingConfig ?? getActiveTrackingEnv().trackingConfig;
|
|
5637
|
+
const subscribe = useCallback4(
|
|
5638
|
+
(listener) => effectiveRef ? getTrackingConfigRuntime(effectiveRef).subscribe(listener) : () => {
|
|
5639
|
+
},
|
|
5640
|
+
[effectiveRef]
|
|
5641
|
+
);
|
|
5642
|
+
const live = useSyncExternalStore2(
|
|
5643
|
+
subscribe,
|
|
5644
|
+
() => effectiveRef && videoKey ? getTrackingConfigRuntime(effectiveRef).getVideo(videoKey) : null,
|
|
5645
|
+
serverVideoSnapshot
|
|
5646
|
+
);
|
|
5647
|
+
return live ?? fallbackConfig ?? null;
|
|
5648
|
+
}
|
|
5649
|
+
function useActiveVideoGoals(videoId, trackingConfig) {
|
|
5650
|
+
const effectiveRef = trackingConfig ?? getActiveTrackingEnv().trackingConfig;
|
|
5651
|
+
const subscribe = useCallback4(
|
|
5652
|
+
(listener) => effectiveRef ? getTrackingConfigRuntime(effectiveRef).subscribe(listener) : () => {
|
|
5653
|
+
},
|
|
5654
|
+
[effectiveRef]
|
|
5655
|
+
);
|
|
5656
|
+
const goals = useSyncExternalStore2(
|
|
5657
|
+
subscribe,
|
|
5658
|
+
() => effectiveRef ? getTrackingConfigRuntime(effectiveRef).listGoals() : EMPTY_GOALS2,
|
|
5659
|
+
serverGoalsSnapshot
|
|
5660
|
+
);
|
|
5661
|
+
return useMemo6(() => {
|
|
5662
|
+
const out = [];
|
|
5663
|
+
for (const goal of goals) {
|
|
5664
|
+
if (goal.kind !== "event" || !goal.trigger) continue;
|
|
5665
|
+
if (goal.trigger.event_type !== "video_progress") continue;
|
|
5666
|
+
if (goal.trigger.video_id && goal.trigger.video_id !== videoId) continue;
|
|
5667
|
+
const metric = goal.trigger.metric;
|
|
5668
|
+
const threshold = goal.trigger.threshold;
|
|
5669
|
+
if ((metric === "percent" || metric === "seconds") && typeof threshold === "number") {
|
|
5670
|
+
out.push({ key: goal.key, metric, threshold });
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5673
|
+
return out;
|
|
5674
|
+
}, [goals, videoId]);
|
|
5675
|
+
}
|
|
5676
|
+
function renditionsOf(h) {
|
|
5677
|
+
const best = /* @__PURE__ */ new Map();
|
|
5678
|
+
h.levels.forEach((l, index) => {
|
|
5679
|
+
const px = Math.min(l.width || Infinity, l.height || Infinity);
|
|
5680
|
+
if (!Number.isFinite(px)) return;
|
|
5681
|
+
const cur = best.get(px);
|
|
5682
|
+
if (!cur || l.bitrate > cur.bitrate) best.set(px, { height: px, index, bitrate: l.bitrate });
|
|
5683
|
+
});
|
|
5684
|
+
return [...best.values()].sort((a, b) => b.height - a.height).map(({ height, index }) => ({ height, index }));
|
|
5685
|
+
}
|
|
5686
|
+
var MEDIA_CHROME_CDN_URL = "https://cdn.jsdelivr.net/npm/media-chrome@4/+esm";
|
|
5687
|
+
var HLS_JS_CDN_URL = "https://cdn.jsdelivr.net/npm/hls.js@1/dist/hls.min.js";
|
|
5688
|
+
var defaultLibsPromise = null;
|
|
5689
|
+
function loadScriptOnce(src, attr, isModule = false) {
|
|
5690
|
+
if (typeof document === "undefined") return Promise.resolve();
|
|
5691
|
+
const existing = document.querySelector(`script[${attr}]`);
|
|
5692
|
+
if (existing) return Promise.resolve();
|
|
5693
|
+
return new Promise((resolve) => {
|
|
5694
|
+
const s = document.createElement("script");
|
|
5695
|
+
if (isModule) s.type = "module";
|
|
5696
|
+
s.async = true;
|
|
5697
|
+
s.src = src;
|
|
5698
|
+
s.setAttribute(attr, "1");
|
|
5699
|
+
s.addEventListener("load", () => resolve(), { once: true });
|
|
5700
|
+
s.addEventListener("error", () => resolve(), { once: true });
|
|
5701
|
+
document.head.append(s);
|
|
5702
|
+
if (typeof navigator !== "undefined" && /jsdom/i.test(navigator.userAgent)) {
|
|
5703
|
+
setTimeout(resolve, 0);
|
|
5704
|
+
}
|
|
5705
|
+
});
|
|
5706
|
+
}
|
|
5707
|
+
function loadDefaultPlayerLibs() {
|
|
5708
|
+
if (typeof window === "undefined") return Promise.resolve({});
|
|
5709
|
+
if (defaultLibsPromise) return defaultLibsPromise;
|
|
5710
|
+
defaultLibsPromise = Promise.all([
|
|
5711
|
+
typeof customElements !== "undefined" && customElements.get("media-controller") ? Promise.resolve() : loadScriptOnce(MEDIA_CHROME_CDN_URL, "data-aranova-media-chrome", true),
|
|
5712
|
+
window.Hls ? Promise.resolve() : loadScriptOnce(HLS_JS_CDN_URL, "data-aranova-hls-js", false)
|
|
5713
|
+
]).then(() => ({
|
|
5714
|
+
hls: window.Hls
|
|
5715
|
+
}));
|
|
5716
|
+
return defaultLibsPromise;
|
|
5717
|
+
}
|
|
5718
|
+
function Cut({
|
|
5719
|
+
id,
|
|
5720
|
+
variant,
|
|
5721
|
+
uid,
|
|
5722
|
+
host,
|
|
5723
|
+
title,
|
|
5724
|
+
posterTime,
|
|
5725
|
+
posterUrl,
|
|
5726
|
+
renderPoster,
|
|
5727
|
+
theater,
|
|
5728
|
+
onTheaterChange,
|
|
5729
|
+
autoExpandOnPlay,
|
|
5730
|
+
checkpoints,
|
|
5731
|
+
videoGoals,
|
|
5732
|
+
client,
|
|
5733
|
+
loadPlayerLibs,
|
|
5734
|
+
className,
|
|
5735
|
+
...cb
|
|
5736
|
+
}) {
|
|
5737
|
+
const root = useRef2(null);
|
|
5738
|
+
const video = useRef2(null);
|
|
5739
|
+
const hls = useRef2(null);
|
|
5740
|
+
const lastTime = useRef2(0);
|
|
5741
|
+
const seekFrom = useRef2(0);
|
|
5742
|
+
const cbRef = useRef2(cb);
|
|
5743
|
+
cbRef.current = cb;
|
|
5744
|
+
const clientRef = useRef2(client);
|
|
5745
|
+
clientRef.current = client;
|
|
5746
|
+
const goalsRef = useRef2(videoGoals);
|
|
5747
|
+
goalsRef.current = videoGoals;
|
|
5748
|
+
const rangesRef = useRef2([]);
|
|
5749
|
+
const activeSegmentStartRef = useRef2(null);
|
|
5750
|
+
const furthestSecondsRef = useRef2(0);
|
|
5751
|
+
const maxPercentRef = useRef2(0);
|
|
5752
|
+
const durationRef = useRef2(0);
|
|
5753
|
+
const playCountRef = useRef2(0);
|
|
5754
|
+
const seekCountRef = useRef2(0);
|
|
5755
|
+
const firedCheckpointsRef = useRef2(/* @__PURE__ */ new Set());
|
|
5756
|
+
const firedGoalsRef = useRef2(/* @__PURE__ */ new Set());
|
|
5757
|
+
const dirtySinceLastEmitRef = useRef2(false);
|
|
5758
|
+
const [started, setStarted] = useState5(false);
|
|
5759
|
+
const [ready, setReady] = useState5(false);
|
|
5760
|
+
const [playing, setPlaying] = useState5(false);
|
|
5761
|
+
const [renditions, setRenditions] = useState5([]);
|
|
5762
|
+
const [selected, setSelected] = useState5("auto");
|
|
5763
|
+
const [live, setLive] = useState5(null);
|
|
5764
|
+
const [menu, setMenu] = useState5(false);
|
|
5765
|
+
const [pending, setPending] = useState5(null);
|
|
5766
|
+
const pendingRef = useRef2(null);
|
|
5767
|
+
const wrap = useRef2(null);
|
|
5768
|
+
const gear = useRef2(null);
|
|
5769
|
+
const selectedRef = useRef2("auto");
|
|
5770
|
+
const pendingTimer = useRef2(null);
|
|
5771
|
+
const liveRef = useRef2(null);
|
|
5772
|
+
const videoId = `${id}-${variant}`;
|
|
5773
|
+
const getCurrentRanges = useCallback4(() => {
|
|
5774
|
+
const v = video.current;
|
|
5775
|
+
const cur = v ? v.currentTime : lastTime.current;
|
|
5776
|
+
const list = [...rangesRef.current];
|
|
5777
|
+
if (activeSegmentStartRef.current !== null && cur > activeSegmentStartRef.current) {
|
|
5778
|
+
list.push({
|
|
5779
|
+
start_s: activeSegmentStartRef.current,
|
|
5780
|
+
end_s: cur
|
|
5781
|
+
});
|
|
5782
|
+
}
|
|
5783
|
+
return mergeVideoRanges(list);
|
|
5784
|
+
}, []);
|
|
5785
|
+
const commitActiveSegment = useCallback4((endTime) => {
|
|
5786
|
+
const end = endTime ?? video.current?.currentTime ?? lastTime.current;
|
|
5787
|
+
if (activeSegmentStartRef.current !== null && end > activeSegmentStartRef.current) {
|
|
5788
|
+
rangesRef.current = mergeVideoRanges([
|
|
5789
|
+
...rangesRef.current,
|
|
5790
|
+
{ start_s: activeSegmentStartRef.current, end_s: end }
|
|
5791
|
+
]);
|
|
5792
|
+
}
|
|
5793
|
+
activeSegmentStartRef.current = null;
|
|
5794
|
+
}, []);
|
|
5795
|
+
const snap = useCallback4(() => {
|
|
5796
|
+
const v = video.current;
|
|
5797
|
+
const currentTime = roundVideoSeconds(v?.currentTime ?? lastTime.current);
|
|
5798
|
+
const rawDuration = v?.duration;
|
|
5799
|
+
const duration = typeof rawDuration === "number" && Number.isFinite(rawDuration) && rawDuration > 0 ? roundVideoSeconds(rawDuration) : durationRef.current;
|
|
5800
|
+
if (duration > 0) durationRef.current = duration;
|
|
5801
|
+
if (currentTime > furthestSecondsRef.current) {
|
|
5802
|
+
furthestSecondsRef.current = currentTime;
|
|
5803
|
+
}
|
|
5804
|
+
const ranges = getCurrentRanges();
|
|
5805
|
+
const watchedSeconds = sumVideoRangesSeconds(ranges, duration);
|
|
5806
|
+
const watchedPercent = duration > 0 ? Math.min(100, Math.round(watchedSeconds / duration * 100)) : 0;
|
|
5807
|
+
const curPercent = duration > 0 ? Math.min(100, Math.round(furthestSecondsRef.current / duration * 100)) : 0;
|
|
5808
|
+
if (curPercent > maxPercentRef.current) {
|
|
5809
|
+
maxPercentRef.current = curPercent;
|
|
5810
|
+
}
|
|
5811
|
+
return {
|
|
5812
|
+
id,
|
|
5813
|
+
videoId,
|
|
5814
|
+
variant,
|
|
5815
|
+
currentTime,
|
|
5816
|
+
duration,
|
|
5817
|
+
watchedSeconds,
|
|
5818
|
+
watchedPercent,
|
|
5819
|
+
maxPercent: maxPercentRef.current,
|
|
5820
|
+
ranges
|
|
5821
|
+
};
|
|
5822
|
+
}, [getCurrentRanges, id, variant, videoId]);
|
|
5823
|
+
const emitProgress = useCallback4(
|
|
5824
|
+
(trigger, snapshotOverride) => {
|
|
5825
|
+
const activeClient = clientRef.current ?? getActiveTrackingEnv().rawClient;
|
|
5826
|
+
if (!activeClient || playCountRef.current <= 0) return;
|
|
5827
|
+
const s = snapshotOverride ?? snap();
|
|
5828
|
+
if (s.ranges.length === 0 && s.currentTime <= 0 && trigger !== "ended") return;
|
|
5829
|
+
dirtySinceLastEmitRef.current = false;
|
|
5830
|
+
const path = typeof window === "undefined" ? "/" : window.location.pathname;
|
|
5831
|
+
activeClient.trackEvent({
|
|
5832
|
+
eventType: "video_progress",
|
|
5833
|
+
metadata: {
|
|
5834
|
+
video_id: id,
|
|
5835
|
+
variant,
|
|
5836
|
+
trigger,
|
|
5837
|
+
current_s: s.currentTime,
|
|
5838
|
+
furthest_s: roundVideoSeconds(furthestSecondsRef.current),
|
|
5839
|
+
watched_s: s.watchedSeconds,
|
|
5840
|
+
duration_s: s.duration,
|
|
5841
|
+
max_percent: s.maxPercent,
|
|
5842
|
+
watched_percent: s.watchedPercent,
|
|
5843
|
+
play_count: playCountRef.current,
|
|
5844
|
+
seek_count: seekCountRef.current,
|
|
5845
|
+
ranges: s.ranges,
|
|
5846
|
+
page: { path }
|
|
5847
|
+
}
|
|
5848
|
+
});
|
|
5849
|
+
},
|
|
5850
|
+
[id, snap, variant]
|
|
5851
|
+
);
|
|
5852
|
+
const clearPending = () => {
|
|
5853
|
+
if (pendingTimer.current) clearTimeout(pendingTimer.current);
|
|
5854
|
+
pendingTimer.current = null;
|
|
5855
|
+
pendingRef.current = null;
|
|
5856
|
+
setPending(null);
|
|
5857
|
+
};
|
|
5858
|
+
useEffect6(() => {
|
|
5859
|
+
ensureTvSkinStyles();
|
|
5860
|
+
registerCapability("video_tracking");
|
|
5861
|
+
return () => {
|
|
5862
|
+
if (pendingTimer.current) clearTimeout(pendingTimer.current);
|
|
5863
|
+
hls.current?.destroy();
|
|
5864
|
+
hls.current = null;
|
|
5865
|
+
};
|
|
5866
|
+
}, []);
|
|
5867
|
+
useEffect6(() => {
|
|
5868
|
+
if (!started || typeof window === "undefined") return;
|
|
5869
|
+
const flushExitProgress = (useBeacon) => {
|
|
5870
|
+
if (playCountRef.current <= 0 || !dirtySinceLastEmitRef.current) return;
|
|
5871
|
+
commitActiveSegment();
|
|
5872
|
+
emitProgress("page_exit");
|
|
5873
|
+
if (useBeacon) {
|
|
5874
|
+
const activeClient2 = clientRef.current ?? getActiveTrackingEnv().rawClient;
|
|
5875
|
+
activeClient2?.flushBeacon();
|
|
5876
|
+
}
|
|
5877
|
+
};
|
|
5878
|
+
const activeClient = clientRef.current ?? getActiveTrackingEnv().rawClient;
|
|
5879
|
+
const unsubscribeBeforeUnload = activeClient?.onBeforeUnload?.(() => {
|
|
5880
|
+
flushExitProgress(false);
|
|
5881
|
+
});
|
|
5882
|
+
const onVisibilityChange = () => {
|
|
5883
|
+
if (document.visibilityState === "hidden") {
|
|
5884
|
+
flushExitProgress(true);
|
|
5885
|
+
}
|
|
5886
|
+
};
|
|
5887
|
+
const onPageHide = () => {
|
|
5888
|
+
flushExitProgress(true);
|
|
5889
|
+
};
|
|
5890
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
5891
|
+
window.addEventListener("pagehide", onPageHide);
|
|
5892
|
+
return () => {
|
|
5893
|
+
unsubscribeBeforeUnload?.();
|
|
5894
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
5895
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
5896
|
+
};
|
|
5897
|
+
}, [started, commitActiveSegment, emitProgress]);
|
|
5898
|
+
useEffect6(() => {
|
|
5899
|
+
if (!started) return;
|
|
5900
|
+
let was = false;
|
|
5901
|
+
const report = (fullscreen) => {
|
|
5902
|
+
if (fullscreen === was) return;
|
|
5903
|
+
was = fullscreen;
|
|
5904
|
+
cbRef.current.onFullscreenChange?.({ ...snap(), fullscreen });
|
|
5905
|
+
};
|
|
5906
|
+
const onDoc = () => {
|
|
5907
|
+
const el = root.current;
|
|
5908
|
+
const fe = document.fullscreenElement ?? document.webkitFullscreenElement;
|
|
5909
|
+
report(Boolean(el && fe && el.contains(fe)));
|
|
5910
|
+
};
|
|
5911
|
+
const v = video.current;
|
|
5912
|
+
const begin = () => report(true);
|
|
5913
|
+
const end = () => report(false);
|
|
5914
|
+
document.addEventListener("fullscreenchange", onDoc);
|
|
5915
|
+
document.addEventListener("webkitfullscreenchange", onDoc);
|
|
5916
|
+
v?.addEventListener("webkitbeginfullscreen", begin);
|
|
5917
|
+
v?.addEventListener("webkitendfullscreen", end);
|
|
5918
|
+
return () => {
|
|
5919
|
+
document.removeEventListener("fullscreenchange", onDoc);
|
|
5920
|
+
document.removeEventListener("webkitfullscreenchange", onDoc);
|
|
5921
|
+
v?.removeEventListener("webkitbeginfullscreen", begin);
|
|
5922
|
+
v?.removeEventListener("webkitendfullscreen", end);
|
|
5923
|
+
};
|
|
5924
|
+
}, [started, snap]);
|
|
5925
|
+
useEffect6(() => {
|
|
5926
|
+
if (!menu) return;
|
|
5927
|
+
const outside = (e) => {
|
|
5928
|
+
if (wrap.current && !wrap.current.contains(e.target)) setMenu(false);
|
|
5929
|
+
};
|
|
5930
|
+
document.addEventListener("pointerdown", outside);
|
|
5931
|
+
return () => document.removeEventListener("pointerdown", outside);
|
|
5932
|
+
}, [menu]);
|
|
5933
|
+
const closeMenu = (refocus) => {
|
|
5934
|
+
setMenu(false);
|
|
5935
|
+
if (refocus) gear.current?.focus();
|
|
5936
|
+
};
|
|
5937
|
+
const onMenuKey = (e) => {
|
|
5938
|
+
if (e.key === "Escape") {
|
|
5939
|
+
e.preventDefault();
|
|
5940
|
+
e.stopPropagation();
|
|
5941
|
+
closeMenu(true);
|
|
5942
|
+
} else if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
5943
|
+
e.preventDefault();
|
|
5944
|
+
const items = [
|
|
5945
|
+
...wrap.current?.querySelectorAll('[role="menuitemradio"]') ?? []
|
|
5946
|
+
];
|
|
5947
|
+
const i = items.indexOf(document.activeElement);
|
|
5948
|
+
items[(i + (e.key === "ArrowDown" ? 1 : items.length - 1)) % items.length]?.focus();
|
|
5949
|
+
}
|
|
5950
|
+
};
|
|
5951
|
+
const emitQuality = (from, to, source) => cbRef.current.onQualityChange?.({ ...snap(), from, to, source });
|
|
5952
|
+
const start = async () => {
|
|
5953
|
+
const v = video.current;
|
|
5954
|
+
if (!v || started) return;
|
|
5955
|
+
setStarted(true);
|
|
5956
|
+
if (variant === "16x9" && autoExpandOnPlay) {
|
|
5957
|
+
onTheaterChange?.(true);
|
|
5958
|
+
}
|
|
5959
|
+
const src = streamManifestUrl(host, uid);
|
|
5960
|
+
try {
|
|
5961
|
+
const loaded = await (loadPlayerLibs ? loadPlayerLibs() : loadDefaultPlayerLibs());
|
|
5962
|
+
setReady(true);
|
|
5963
|
+
const rawHls = (loaded && typeof loaded === "object" && "hls" in loaded ? loaded.hls : null) ?? (typeof window !== "undefined" ? window.Hls : void 0);
|
|
5964
|
+
const HlsLib = rawHls && typeof rawHls === "object" && "default" in rawHls ? rawHls.default : rawHls;
|
|
5965
|
+
if (!HlsLib || !HlsLib.isSupported()) {
|
|
5966
|
+
v.src = src;
|
|
5967
|
+
} else {
|
|
5968
|
+
const h = new HlsLib({ capLevelToPlayerSize: true });
|
|
5969
|
+
hls.current = h;
|
|
5970
|
+
h.on(HlsLib.Events.MANIFEST_PARSED, () => setRenditions(renditionsOf(h)));
|
|
5971
|
+
h.on(HlsLib.Events.LEVEL_SWITCHED, (_e, data) => {
|
|
5972
|
+
const lv = h.levels[data.level];
|
|
5973
|
+
const height = lv ? Math.min(lv.width || Infinity, lv.height || Infinity) : null;
|
|
5974
|
+
const from = liveRef.current;
|
|
5975
|
+
liveRef.current = height;
|
|
5976
|
+
setLive(height);
|
|
5977
|
+
const want = pendingRef.current;
|
|
5978
|
+
if (want !== null && want === height) clearPending();
|
|
5979
|
+
if (selectedRef.current === "auto" && height && from && from !== height) {
|
|
5980
|
+
emitQuality(from, height, "auto");
|
|
5981
|
+
}
|
|
5982
|
+
});
|
|
5983
|
+
h.on(HlsLib.Events.ERROR, () => clearPending());
|
|
5984
|
+
h.loadSource(src);
|
|
5985
|
+
h.attachMedia(v);
|
|
5986
|
+
}
|
|
5987
|
+
} catch {
|
|
5988
|
+
setReady(true);
|
|
5989
|
+
v.src = src;
|
|
5990
|
+
}
|
|
5991
|
+
try {
|
|
5992
|
+
await v.play();
|
|
5993
|
+
} catch {
|
|
5994
|
+
}
|
|
5995
|
+
};
|
|
5996
|
+
const pick = (q) => {
|
|
5997
|
+
const h = hls.current;
|
|
5998
|
+
const from = selectedRef.current;
|
|
5999
|
+
setMenu(false);
|
|
6000
|
+
if (!h || q === from) return;
|
|
6001
|
+
if (q === "auto") h.nextLevel = -1;
|
|
6002
|
+
else {
|
|
6003
|
+
const r = renditions.find((x) => x.height === q);
|
|
6004
|
+
if (r) h.nextLevel = r.index;
|
|
6005
|
+
}
|
|
6006
|
+
selectedRef.current = q;
|
|
6007
|
+
setSelected(q);
|
|
6008
|
+
clearPending();
|
|
6009
|
+
if (typeof q === "number" && q !== liveRef.current) {
|
|
6010
|
+
pendingRef.current = q;
|
|
6011
|
+
setPending(q);
|
|
6012
|
+
pendingTimer.current = setTimeout(clearPending, 4e3);
|
|
6013
|
+
}
|
|
6014
|
+
emitQuality(from, q, "manual");
|
|
6015
|
+
};
|
|
6016
|
+
const qualityLabel = selected === "auto" ? live ? `Auto (${live}p)` : "Auto" : `${selected}p`;
|
|
6017
|
+
const resolvedPosterUrl = posterUrl ?? streamPosterUrl(host, uid, posterTime);
|
|
6018
|
+
const posterWidth = variant === "16x9" ? 1280 : 720;
|
|
6019
|
+
const posterHeight = variant === "16x9" ? 720 : 1280;
|
|
6020
|
+
return /* @__PURE__ */ jsxs2(
|
|
6021
|
+
"div",
|
|
6022
|
+
{
|
|
6023
|
+
ref: root,
|
|
6024
|
+
className: `tv-skin ${variant === "16x9" ? "tv-skin-desktop" : "tv-skin-mobile"} ${className ?? ""}`,
|
|
6025
|
+
"data-video-id": videoId,
|
|
6026
|
+
children: [
|
|
6027
|
+
/* @__PURE__ */ jsxs2("media-controller", { class: "absolute inset-0 block", autohide: menu ? "-1" : "2", children: [
|
|
6028
|
+
/* @__PURE__ */ jsx5(
|
|
6029
|
+
"video",
|
|
6030
|
+
{
|
|
6031
|
+
ref: video,
|
|
6032
|
+
slot: "media",
|
|
6033
|
+
style: { width: "100%", height: "100%", backgroundColor: "#000", objectFit: "contain" },
|
|
6034
|
+
preload: "none",
|
|
6035
|
+
playsInline: true,
|
|
6036
|
+
title,
|
|
6037
|
+
"aria-label": title,
|
|
6038
|
+
"data-video-id": videoId,
|
|
6039
|
+
onPlay: () => {
|
|
6040
|
+
const v = video.current;
|
|
6041
|
+
const cur = roundVideoSeconds(v?.currentTime ?? 0);
|
|
6042
|
+
activeSegmentStartRef.current = cur;
|
|
6043
|
+
playCountRef.current += 1;
|
|
6044
|
+
dirtySinceLastEmitRef.current = true;
|
|
6045
|
+
const s = snap();
|
|
6046
|
+
const activeClient = clientRef.current ?? getActiveTrackingEnv().rawClient;
|
|
6047
|
+
if (activeClient) {
|
|
6048
|
+
const path = typeof window === "undefined" ? "/" : window.location.pathname;
|
|
6049
|
+
activeClient.trackEvent({
|
|
6050
|
+
eventType: "video_play",
|
|
6051
|
+
metadata: {
|
|
6052
|
+
video_id: id,
|
|
6053
|
+
variant,
|
|
6054
|
+
current_s: s.currentTime,
|
|
6055
|
+
duration_s: s.duration,
|
|
6056
|
+
play_sequence: playCountRef.current,
|
|
6057
|
+
page: { path }
|
|
6058
|
+
}
|
|
6059
|
+
});
|
|
6060
|
+
}
|
|
6061
|
+
cbRef.current.onPlay?.(s);
|
|
6062
|
+
},
|
|
6063
|
+
onPlaying: () => setPlaying(true),
|
|
6064
|
+
onPause: () => {
|
|
6065
|
+
const v = video.current;
|
|
6066
|
+
if (v?.ended) return;
|
|
6067
|
+
commitActiveSegment(v?.currentTime);
|
|
6068
|
+
const s = snap();
|
|
6069
|
+
emitProgress("pause", s);
|
|
6070
|
+
cbRef.current.onPause?.(s);
|
|
6071
|
+
},
|
|
6072
|
+
onEnded: () => {
|
|
6073
|
+
const v = video.current;
|
|
6074
|
+
const dur = typeof v?.duration === "number" && Number.isFinite(v.duration) ? v.duration : durationRef.current;
|
|
6075
|
+
commitActiveSegment(dur > 0 ? dur : v?.currentTime);
|
|
6076
|
+
maxPercentRef.current = 100;
|
|
6077
|
+
const s = snap();
|
|
6078
|
+
if (!firedCheckpointsRef.current.has(100) && checkpoints.includes(100)) {
|
|
6079
|
+
firedCheckpointsRef.current.add(100);
|
|
6080
|
+
cbRef.current.onCheckpoint?.({ ...s, checkpoint: 100 });
|
|
6081
|
+
}
|
|
6082
|
+
emitProgress("ended", s);
|
|
6083
|
+
cbRef.current.onEnded?.(s);
|
|
6084
|
+
},
|
|
6085
|
+
onWaiting: () => cbRef.current.onWaiting?.(snap()),
|
|
6086
|
+
onTimeUpdate: () => {
|
|
6087
|
+
const v = video.current;
|
|
6088
|
+
if (v && !v.seeking) {
|
|
6089
|
+
if (activeSegmentStartRef.current === null && !v.paused) {
|
|
6090
|
+
activeSegmentStartRef.current = lastTime.current;
|
|
6091
|
+
}
|
|
6092
|
+
lastTime.current = v.currentTime;
|
|
6093
|
+
dirtySinceLastEmitRef.current = true;
|
|
6094
|
+
}
|
|
6095
|
+
const s = snap();
|
|
6096
|
+
let hitCheckpoint = false;
|
|
6097
|
+
let hitGoal = false;
|
|
6098
|
+
for (const goal of goalsRef.current) {
|
|
6099
|
+
if (firedGoalsRef.current.has(goal.key)) continue;
|
|
6100
|
+
const met = goal.metric === "seconds" ? s.watchedSeconds >= goal.threshold : s.watchedPercent >= goal.threshold;
|
|
6101
|
+
if (met) {
|
|
6102
|
+
firedGoalsRef.current.add(goal.key);
|
|
6103
|
+
hitGoal = true;
|
|
6104
|
+
}
|
|
6105
|
+
}
|
|
6106
|
+
const newlyFiredCheckpoints = [];
|
|
6107
|
+
for (const cp of checkpoints) {
|
|
6108
|
+
if (firedCheckpointsRef.current.has(cp)) continue;
|
|
6109
|
+
if (s.watchedPercent >= cp || s.maxPercent >= cp) {
|
|
6110
|
+
firedCheckpointsRef.current.add(cp);
|
|
6111
|
+
newlyFiredCheckpoints.push(cp);
|
|
6112
|
+
hitCheckpoint = true;
|
|
6113
|
+
}
|
|
6114
|
+
}
|
|
6115
|
+
if (hitCheckpoint || hitGoal) {
|
|
6116
|
+
commitActiveSegment(v?.currentTime);
|
|
6117
|
+
if (v && !v.paused) activeSegmentStartRef.current = v.currentTime;
|
|
6118
|
+
const emittedSnap = snap();
|
|
6119
|
+
emitProgress(hitCheckpoint ? "checkpoint" : "goal", emittedSnap);
|
|
6120
|
+
for (const cp of newlyFiredCheckpoints) {
|
|
6121
|
+
cbRef.current.onCheckpoint?.({ ...emittedSnap, checkpoint: cp });
|
|
6122
|
+
}
|
|
6123
|
+
}
|
|
6124
|
+
cbRef.current.onTimeUpdate?.(s);
|
|
6125
|
+
},
|
|
6126
|
+
onSeeking: () => {
|
|
6127
|
+
seekFrom.current = lastTime.current;
|
|
6128
|
+
commitActiveSegment(seekFrom.current);
|
|
6129
|
+
},
|
|
6130
|
+
onSeeked: () => {
|
|
6131
|
+
const v = video.current;
|
|
6132
|
+
const to = roundVideoSeconds(v?.currentTime ?? 0);
|
|
6133
|
+
const from = roundVideoSeconds(seekFrom.current);
|
|
6134
|
+
lastTime.current = to;
|
|
6135
|
+
if (v && !v.paused) {
|
|
6136
|
+
activeSegmentStartRef.current = to;
|
|
6137
|
+
}
|
|
6138
|
+
if (Math.abs(to - from) >= 1) {
|
|
6139
|
+
seekCountRef.current += 1;
|
|
6140
|
+
const s = snap();
|
|
6141
|
+
emitProgress("seek", s);
|
|
6142
|
+
cbRef.current.onSeek?.({ ...s, from, to });
|
|
6143
|
+
}
|
|
6144
|
+
},
|
|
6145
|
+
children: /* @__PURE__ */ jsx5("track", { kind: "captions" })
|
|
6146
|
+
}
|
|
6147
|
+
),
|
|
6148
|
+
ready && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
6149
|
+
/* @__PURE__ */ jsx5("media-loading-indicator", { slot: "centered-chrome" }),
|
|
6150
|
+
/* @__PURE__ */ jsxs2("div", { className: "tv-chrome", children: [
|
|
6151
|
+
/* @__PURE__ */ jsxs2("div", { className: "tv-row", children: [
|
|
6152
|
+
/* @__PURE__ */ jsxs2("media-play-button", { class: "tv-ctl", children: [
|
|
6153
|
+
/* @__PURE__ */ jsx5(IconPlay, { slot: "play" }),
|
|
6154
|
+
/* @__PURE__ */ jsx5(IconPause, { slot: "pause" })
|
|
6155
|
+
] }),
|
|
6156
|
+
/* @__PURE__ */ jsx5("media-time-display", { class: "tv-time tv-time-full", showduration: true }),
|
|
6157
|
+
/* @__PURE__ */ jsx5("media-time-display", { class: "tv-time tv-time-cur" }),
|
|
6158
|
+
/* @__PURE__ */ jsx5("span", { className: "tv-spacer" }),
|
|
6159
|
+
/* @__PURE__ */ jsxs2("div", { className: "tv-vol", children: [
|
|
6160
|
+
/* @__PURE__ */ jsxs2("media-mute-button", { class: "tv-ctl", children: [
|
|
6161
|
+
/* @__PURE__ */ jsx5(IconVolumeHigh, { slot: "high" }),
|
|
6162
|
+
/* @__PURE__ */ jsx5(IconVolumeLow, { slot: "medium" }),
|
|
6163
|
+
/* @__PURE__ */ jsx5(IconVolumeLow, { slot: "low" }),
|
|
6164
|
+
/* @__PURE__ */ jsx5(IconVolumeOff, { slot: "off" })
|
|
6165
|
+
] }),
|
|
6166
|
+
/* @__PURE__ */ jsx5("media-volume-range", { class: "tv-volrange" })
|
|
6167
|
+
] }),
|
|
6168
|
+
renditions.length > 1 && /* @__PURE__ */ jsxs2("div", { className: "tv-menu-wrap", ref: wrap, children: [
|
|
6169
|
+
/* @__PURE__ */ jsx5(
|
|
6170
|
+
"button",
|
|
6171
|
+
{
|
|
6172
|
+
ref: gear,
|
|
6173
|
+
type: "button",
|
|
6174
|
+
className: "tv-btn",
|
|
6175
|
+
"aria-haspopup": "menu",
|
|
6176
|
+
"aria-expanded": menu,
|
|
6177
|
+
"aria-label": `Settings, quality ${qualityLabel}`,
|
|
6178
|
+
title: "Settings",
|
|
6179
|
+
onClick: () => setMenu((m) => !m),
|
|
6180
|
+
onKeyDown: onMenuKey,
|
|
6181
|
+
children: /* @__PURE__ */ jsx5(IconSettings, {})
|
|
6182
|
+
}
|
|
6183
|
+
),
|
|
6184
|
+
/* @__PURE__ */ jsx5("span", { role: "status", className: "sr-only", children: pending !== null ? `Switching to ${pending}p` : "" }),
|
|
6185
|
+
menu && /* @__PURE__ */ jsxs2(
|
|
6186
|
+
"ul",
|
|
6187
|
+
{
|
|
6188
|
+
role: "menu",
|
|
6189
|
+
"aria-label": "Quality",
|
|
6190
|
+
className: "tv-menu",
|
|
6191
|
+
onKeyDown: onMenuKey,
|
|
6192
|
+
children: [
|
|
6193
|
+
["auto", ...renditions.map((r) => r.height)].map(
|
|
6194
|
+
(q) => /* @__PURE__ */ jsx5("li", { role: "none", children: /* @__PURE__ */ jsx5(
|
|
6195
|
+
"button",
|
|
6196
|
+
{
|
|
6197
|
+
type: "button",
|
|
6198
|
+
role: "menuitemradio",
|
|
6199
|
+
"aria-checked": selected === q,
|
|
6200
|
+
className: "tv-menu-item",
|
|
6201
|
+
onClick: () => pick(q),
|
|
6202
|
+
children: q === "auto" ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
6203
|
+
"Auto",
|
|
6204
|
+
live ? /* @__PURE__ */ jsxs2("span", { className: "tv-menu-sub", children: [
|
|
6205
|
+
" ",
|
|
6206
|
+
live,
|
|
6207
|
+
"p"
|
|
6208
|
+
] }) : null
|
|
6209
|
+
] }) : `${q}p`
|
|
6210
|
+
}
|
|
6211
|
+
) }, String(q))
|
|
6212
|
+
),
|
|
6213
|
+
/* @__PURE__ */ jsx5("li", { "aria-hidden": "true", className: "tv-menu-note", children: pending !== null ? `Switching to ${pending}p\u2026` : "" })
|
|
6214
|
+
]
|
|
6215
|
+
}
|
|
6216
|
+
)
|
|
6217
|
+
] }),
|
|
6218
|
+
variant === "16x9" && onTheaterChange && /* @__PURE__ */ jsx5(
|
|
6219
|
+
"button",
|
|
6220
|
+
{
|
|
6221
|
+
type: "button",
|
|
6222
|
+
className: "tv-btn tv-theater",
|
|
6223
|
+
"aria-pressed": theater,
|
|
6224
|
+
"aria-label": theater ? "Shrink the player" : "Expand the player",
|
|
6225
|
+
title: theater ? "Shrink" : "Expand",
|
|
6226
|
+
onClick: () => onTheaterChange(!theater),
|
|
6227
|
+
children: theater ? /* @__PURE__ */ jsx5(IconTheaterShrink, {}) : /* @__PURE__ */ jsx5(IconTheaterExpand, {})
|
|
6228
|
+
}
|
|
6229
|
+
),
|
|
6230
|
+
/* @__PURE__ */ jsxs2("media-fullscreen-button", { class: "tv-ctl", children: [
|
|
6231
|
+
/* @__PURE__ */ jsx5(IconFullscreenEnter, { slot: "enter" }),
|
|
6232
|
+
/* @__PURE__ */ jsx5(IconFullscreenExit, { slot: "exit" })
|
|
6233
|
+
] })
|
|
6234
|
+
] }),
|
|
6235
|
+
/* @__PURE__ */ jsx5("media-time-range", { class: "tv-seek" })
|
|
6236
|
+
] })
|
|
6237
|
+
] })
|
|
6238
|
+
] }),
|
|
6239
|
+
!playing && /* @__PURE__ */ jsxs2("div", { className: "tv-poster-overlay", children: [
|
|
6240
|
+
renderPoster ? renderPoster({
|
|
6241
|
+
src: resolvedPosterUrl,
|
|
6242
|
+
variant,
|
|
6243
|
+
title,
|
|
6244
|
+
width: posterWidth,
|
|
6245
|
+
height: posterHeight
|
|
6246
|
+
}) : /* @__PURE__ */ jsx5(
|
|
6247
|
+
"img",
|
|
6248
|
+
{
|
|
6249
|
+
src: resolvedPosterUrl,
|
|
6250
|
+
alt: "",
|
|
6251
|
+
width: posterWidth,
|
|
6252
|
+
height: posterHeight,
|
|
6253
|
+
loading: "lazy",
|
|
6254
|
+
decoding: "async",
|
|
6255
|
+
className: "tv-poster-img"
|
|
6256
|
+
}
|
|
6257
|
+
),
|
|
6258
|
+
!started && /* @__PURE__ */ jsx5(
|
|
6259
|
+
"button",
|
|
6260
|
+
{
|
|
6261
|
+
type: "button",
|
|
6262
|
+
onClick: start,
|
|
6263
|
+
"aria-label": `Play video: ${title}`,
|
|
6264
|
+
className: "tv-play-trigger",
|
|
6265
|
+
children: /* @__PURE__ */ jsx5("span", { className: "tv-play-pill", children: /* @__PURE__ */ jsx5(IconPlay, { size: 26, filled: true }) })
|
|
6266
|
+
}
|
|
6267
|
+
)
|
|
6268
|
+
] })
|
|
6269
|
+
]
|
|
6270
|
+
}
|
|
6271
|
+
);
|
|
6272
|
+
}
|
|
6273
|
+
function TrackedVideo(props) {
|
|
6274
|
+
const {
|
|
6275
|
+
id,
|
|
6276
|
+
video,
|
|
6277
|
+
host,
|
|
6278
|
+
sources,
|
|
6279
|
+
title,
|
|
6280
|
+
posterTime,
|
|
6281
|
+
posterUrl,
|
|
6282
|
+
renderPoster,
|
|
6283
|
+
theater: controlledTheater,
|
|
6284
|
+
defaultTheater = false,
|
|
6285
|
+
onTheaterChange,
|
|
6286
|
+
expandMode = "inline",
|
|
6287
|
+
autoExpandOnPlay = true,
|
|
6288
|
+
expandedMaxWidth = 1100,
|
|
6289
|
+
checkpoints = DEFAULT_VIDEO_CHECKPOINTS,
|
|
6290
|
+
trackingConfig,
|
|
6291
|
+
fallbackConfig,
|
|
6292
|
+
client = null,
|
|
6293
|
+
loadPlayerLibs,
|
|
6294
|
+
className = "",
|
|
6295
|
+
style,
|
|
6296
|
+
...callbacks
|
|
6297
|
+
} = props;
|
|
6298
|
+
const videoKey = id ?? video ?? fallbackConfig?.key ?? "";
|
|
6299
|
+
const r2Video = useTrackedVideoConfig(videoKey || void 0, trackingConfig, fallbackConfig);
|
|
6300
|
+
const videoGoals = useActiveVideoGoals(videoKey, trackingConfig);
|
|
6301
|
+
const [internalTheater, setInternalTheater] = useState5(defaultTheater);
|
|
6302
|
+
const isTheaterControlled = controlledTheater !== void 0;
|
|
6303
|
+
const activeTheater = isTheaterControlled ? controlledTheater : internalTheater;
|
|
6304
|
+
const handleTheaterChange = useCallback4(
|
|
6305
|
+
(next) => {
|
|
6306
|
+
if (!isTheaterControlled) {
|
|
6307
|
+
setInternalTheater(next);
|
|
6308
|
+
}
|
|
6309
|
+
onTheaterChange?.(next);
|
|
6310
|
+
},
|
|
6311
|
+
[isTheaterControlled, onTheaterChange]
|
|
6312
|
+
);
|
|
6313
|
+
const resolvedHost = host ?? r2Video?.host ?? "";
|
|
6314
|
+
const desktopUid = sources?.desktop ?? r2Video?.sources.desktop ?? "";
|
|
6315
|
+
const mobileUid = sources?.mobile ?? r2Video?.sources.mobile ?? desktopUid;
|
|
6316
|
+
const resolvedTitle = title ?? r2Video?.title ?? videoKey;
|
|
6317
|
+
const resolvedPosterTime = posterTime ?? r2Video?.poster_time ?? r2Video?.poster_time_s ?? 4;
|
|
6318
|
+
if (!videoKey || !resolvedHost || !desktopUid) {
|
|
6319
|
+
return null;
|
|
6320
|
+
}
|
|
6321
|
+
const showTheaterControl = expandMode !== "none" && (expandMode === "theater" || Boolean(onTheaterChange));
|
|
6322
|
+
const wrapperStyle = !isTheaterControlled && expandMode === "theater" && activeTheater ? {
|
|
6323
|
+
maxWidth: typeof expandedMaxWidth === "number" ? `${expandedMaxWidth}px` : expandedMaxWidth,
|
|
6324
|
+
marginLeft: "auto",
|
|
6325
|
+
marginRight: "auto",
|
|
6326
|
+
width: "100%",
|
|
6327
|
+
transition: "max-width 360ms cubic-bezier(0.2, 0.7, 0.2, 1)",
|
|
6328
|
+
...style
|
|
6329
|
+
} : style;
|
|
6330
|
+
return /* @__PURE__ */ jsxs2("div", { className, style: wrapperStyle, "data-tracked-video": videoKey, children: [
|
|
6331
|
+
/* @__PURE__ */ jsx5(
|
|
6332
|
+
Cut,
|
|
6333
|
+
{
|
|
6334
|
+
...callbacks,
|
|
6335
|
+
id: videoKey,
|
|
6336
|
+
variant: "16x9",
|
|
6337
|
+
uid: desktopUid,
|
|
6338
|
+
host: resolvedHost,
|
|
6339
|
+
title: resolvedTitle,
|
|
6340
|
+
posterTime: resolvedPosterTime,
|
|
6341
|
+
posterUrl,
|
|
6342
|
+
renderPoster,
|
|
6343
|
+
theater: activeTheater,
|
|
6344
|
+
onTheaterChange: showTheaterControl ? handleTheaterChange : void 0,
|
|
6345
|
+
autoExpandOnPlay,
|
|
6346
|
+
checkpoints,
|
|
6347
|
+
videoGoals,
|
|
6348
|
+
client,
|
|
6349
|
+
loadPlayerLibs
|
|
6350
|
+
}
|
|
6351
|
+
),
|
|
6352
|
+
/* @__PURE__ */ jsx5(
|
|
6353
|
+
Cut,
|
|
6354
|
+
{
|
|
6355
|
+
...callbacks,
|
|
6356
|
+
id: videoKey,
|
|
6357
|
+
variant: "9x16",
|
|
6358
|
+
uid: mobileUid || desktopUid,
|
|
6359
|
+
host: resolvedHost,
|
|
6360
|
+
title: resolvedTitle,
|
|
6361
|
+
posterTime: resolvedPosterTime,
|
|
6362
|
+
posterUrl,
|
|
6363
|
+
renderPoster,
|
|
6364
|
+
theater: false,
|
|
6365
|
+
onTheaterChange: void 0,
|
|
6366
|
+
autoExpandOnPlay: false,
|
|
6367
|
+
checkpoints,
|
|
6368
|
+
videoGoals,
|
|
6369
|
+
client,
|
|
6370
|
+
loadPlayerLibs
|
|
6371
|
+
}
|
|
6372
|
+
)
|
|
6373
|
+
] });
|
|
6374
|
+
}
|
|
6375
|
+
var STAGE_DURATION_MS = 360;
|
|
6376
|
+
var STAGE_EASE = "cubic-bezier(0.2, 0.7, 0.2, 1)";
|
|
6377
|
+
function TrackedVideoStage({
|
|
6378
|
+
video,
|
|
6379
|
+
children,
|
|
6380
|
+
expandedMaxWidth = 1100,
|
|
6381
|
+
collapsedTextMaxWidth = 760,
|
|
6382
|
+
className = ""
|
|
6383
|
+
}) {
|
|
6384
|
+
const [theater, setTheater] = useState5(video.defaultTheater ?? false);
|
|
6385
|
+
const videoBox = useRef2(null);
|
|
6386
|
+
const textBox = useRef2(null);
|
|
6387
|
+
const first = useRef2(null);
|
|
6388
|
+
const activeTheater = video.theater !== void 0 ? video.theater : theater;
|
|
6389
|
+
const change = useCallback4(
|
|
6390
|
+
(next) => {
|
|
6391
|
+
if (next === activeTheater) return;
|
|
6392
|
+
if (next && typeof window !== "undefined" && !window.matchMedia("(min-width: 768px)").matches) {
|
|
6393
|
+
return;
|
|
6394
|
+
}
|
|
6395
|
+
if (videoBox.current && textBox.current) {
|
|
6396
|
+
first.current = {
|
|
6397
|
+
v: videoBox.current.getBoundingClientRect(),
|
|
6398
|
+
t: textBox.current.getBoundingClientRect()
|
|
6399
|
+
};
|
|
6400
|
+
}
|
|
6401
|
+
if (video.theater === void 0) {
|
|
6402
|
+
setTheater(next);
|
|
6403
|
+
}
|
|
6404
|
+
video.onTheaterChange?.(next);
|
|
6405
|
+
},
|
|
6406
|
+
[activeTheater, video]
|
|
6407
|
+
);
|
|
6408
|
+
useLayoutEffect(() => {
|
|
6409
|
+
if (typeof window === "undefined") return;
|
|
6410
|
+
const f = first.current;
|
|
6411
|
+
const vb = videoBox.current;
|
|
6412
|
+
const tb = textBox.current;
|
|
6413
|
+
first.current = null;
|
|
6414
|
+
if (!f || !vb || !tb) return;
|
|
6415
|
+
const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
6416
|
+
const lv = vb.getBoundingClientRect();
|
|
6417
|
+
const lt = tb.getBoundingClientRect();
|
|
6418
|
+
if (!reduce && typeof vb.animate === "function" && lv.width > 0) {
|
|
6419
|
+
const s = f.v.width / lv.width;
|
|
6420
|
+
vb.animate(
|
|
6421
|
+
[
|
|
6422
|
+
{
|
|
6423
|
+
transformOrigin: "top left",
|
|
6424
|
+
transform: `translate(${f.v.left - lv.left}px, ${f.v.top - lv.top}px) scale(${s})`
|
|
6425
|
+
},
|
|
6426
|
+
{ transformOrigin: "top left", transform: "none" }
|
|
6427
|
+
],
|
|
6428
|
+
{ duration: STAGE_DURATION_MS, easing: STAGE_EASE }
|
|
6429
|
+
);
|
|
6430
|
+
tb.animate(
|
|
6431
|
+
[
|
|
6432
|
+
{
|
|
6433
|
+
transform: `translate(${f.t.left - lt.left}px, ${f.t.top - lt.top}px)`,
|
|
6434
|
+
opacity: 0.4
|
|
6435
|
+
},
|
|
6436
|
+
{ transform: "none", opacity: 1 }
|
|
6437
|
+
],
|
|
6438
|
+
{ duration: STAGE_DURATION_MS, easing: STAGE_EASE }
|
|
6439
|
+
);
|
|
6440
|
+
}
|
|
6441
|
+
if (lv.top < 80 || lv.bottom > window.innerHeight - 24) {
|
|
6442
|
+
const top = window.scrollY + lv.top - Math.max(96, (window.innerHeight - lv.height) / 2);
|
|
6443
|
+
window.scrollTo({ top, behavior: reduce ? "auto" : "smooth" });
|
|
6444
|
+
}
|
|
6445
|
+
}, [activeTheater]);
|
|
6446
|
+
const maxVideoWidthCss = typeof expandedMaxWidth === "number" ? `${expandedMaxWidth}px` : expandedMaxWidth;
|
|
6447
|
+
const maxTextWidthCss = typeof collapsedTextMaxWidth === "number" ? `${collapsedTextMaxWidth}px` : collapsedTextMaxWidth;
|
|
6448
|
+
return /* @__PURE__ */ jsxs2(
|
|
6449
|
+
"div",
|
|
6450
|
+
{
|
|
6451
|
+
className: activeTheater ? `grid gap-10 md:gap-12 ${className}` : `grid items-start gap-10 lg:grid-cols-[1fr_1fr] lg:gap-16 ${className}`,
|
|
6452
|
+
children: [
|
|
6453
|
+
/* @__PURE__ */ jsx5(
|
|
6454
|
+
"div",
|
|
6455
|
+
{
|
|
6456
|
+
ref: textBox,
|
|
6457
|
+
className: activeTheater ? "md:order-2" : "",
|
|
6458
|
+
style: activeTheater ? { maxWidth: maxTextWidthCss } : void 0,
|
|
6459
|
+
children
|
|
6460
|
+
}
|
|
6461
|
+
),
|
|
6462
|
+
/* @__PURE__ */ jsx5(
|
|
6463
|
+
"div",
|
|
6464
|
+
{
|
|
6465
|
+
ref: videoBox,
|
|
6466
|
+
className: activeTheater ? "md:order-1 md:mx-auto md:w-full" : "",
|
|
6467
|
+
style: activeTheater ? { maxWidth: maxVideoWidthCss, width: "100%" } : void 0,
|
|
6468
|
+
children: /* @__PURE__ */ jsx5(
|
|
6469
|
+
TrackedVideo,
|
|
6470
|
+
{
|
|
6471
|
+
...video,
|
|
6472
|
+
theater: activeTheater,
|
|
6473
|
+
onTheaterChange: change,
|
|
6474
|
+
className: video.className ?? "w-full"
|
|
6475
|
+
}
|
|
6476
|
+
)
|
|
6477
|
+
}
|
|
6478
|
+
)
|
|
6479
|
+
]
|
|
6480
|
+
}
|
|
6481
|
+
);
|
|
6482
|
+
}
|
|
4763
6483
|
export {
|
|
4764
6484
|
AdPlatformTracking,
|
|
4765
6485
|
BookingHandoffLink,
|
|
4766
6486
|
ConsentBanner,
|
|
6487
|
+
DEFAULT_VIDEO_CHECKPOINTS,
|
|
4767
6488
|
GoogleAdsTracking,
|
|
4768
6489
|
PhoneField,
|
|
6490
|
+
TrackedVideo,
|
|
6491
|
+
TrackedVideoStage,
|
|
4769
6492
|
createLeadFormSubmit,
|
|
4770
6493
|
createTracking,
|
|
6494
|
+
streamManifestUrl,
|
|
6495
|
+
streamPosterUrl,
|
|
4771
6496
|
useBookingHandoffUrl,
|
|
4772
6497
|
useBookingIntegration,
|
|
4773
6498
|
useBookingSlots,
|
|
@@ -4778,6 +6503,7 @@ export {
|
|
|
4778
6503
|
useGclid,
|
|
4779
6504
|
usePhoneConfig,
|
|
4780
6505
|
usePhoneField,
|
|
6506
|
+
useTrackedVideoConfig,
|
|
4781
6507
|
useTrackingParams
|
|
4782
6508
|
};
|
|
4783
6509
|
//# sourceMappingURL=client.mjs.map
|