@fxi/zartigl 0.5.0 → 0.7.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/dist/story.js ADDED
@@ -0,0 +1,561 @@
1
+ async function D(t, e) {
2
+ return t(), e();
3
+ }
4
+ function n(t, e) {
5
+ if (!t)
6
+ throw new Error(`Invalid story document: ${e}`);
7
+ }
8
+ function d(t) {
9
+ return typeof t == "object" && t !== null && !Array.isArray(t);
10
+ }
11
+ function p(t, e, s) {
12
+ n(d(t), `${e} must be a localized object`), n(
13
+ typeof t[s] == "string",
14
+ `${e}.${s} must be a string`
15
+ );
16
+ }
17
+ function y(t, e) {
18
+ n(typeof t == "string", `${e} must be a string`);
19
+ let s;
20
+ try {
21
+ s = new URL(t);
22
+ } catch {
23
+ throw new Error(`Invalid story document: ${e} must be a valid URL`);
24
+ }
25
+ n(
26
+ s.protocol === "https:" || s.protocol === "http:",
27
+ `${e} must use HTTP or HTTPS`
28
+ );
29
+ }
30
+ function b(t, e, s) {
31
+ n(d(t), `${e} must be an object`), n(
32
+ typeof t.id == "string" && t.id.length > 0,
33
+ `${e}.id is required`
34
+ ), n(
35
+ ["copy", "stage", "analysis", "edge"].includes(String(t.slot)),
36
+ `${e}.slot is invalid`
37
+ ), n(
38
+ ["copy", "view", "widget", "text", "credit", "label"].includes(
39
+ String(t.type)
40
+ ),
41
+ `${e}.type is invalid`
42
+ ), t.type === "copy" && (p(t.heading, `${e}.heading`, s), t.text !== void 0 && p(t.text, `${e}.text`, s), t.references !== void 0 && (n(
43
+ Array.isArray(t.references) && t.references.length > 0,
44
+ `${e}.references must not be empty`
45
+ ), t.references.forEach((r, i) => {
46
+ const o = `${e}.references[${i}]`;
47
+ n(d(r), `${o} must be an object`), p(
48
+ r.label,
49
+ `${o}.label`,
50
+ s
51
+ ), y(r.url, `${o}.url`);
52
+ })), t.backdrop !== void 0 && n(
53
+ ["none", "dark-gradient"].includes(String(t.backdrop)),
54
+ `${e}.backdrop is invalid`
55
+ )), t.type === "view" && n(typeof t.view == "string", `${e}.view is required`), t.type === "widget" && (n(typeof t.widget == "string", `${e}.widget is required`), t.caption !== void 0 && p(t.caption, `${e}.caption`, s)), ["text", "credit", "label"].includes(String(t.type)) && p(t.text, `${e}.text`, s);
56
+ }
57
+ const v = [
58
+ "full",
59
+ "split-left",
60
+ "split-right",
61
+ "overlay"
62
+ ];
63
+ function w(t, e = {}) {
64
+ const s = e.layouts ?? v;
65
+ n(d(t), "root must be an object"), n(t.schemaVersion === 1, "schemaVersion must be 1"), n(
66
+ typeof t.defaultLocale == "string",
67
+ "defaultLocale is required"
68
+ );
69
+ const r = t.defaultLocale;
70
+ p(t.title, "title", r), n(
71
+ d(t.themes) && Object.keys(t.themes).length > 0,
72
+ "themes must not be empty"
73
+ ), n(
74
+ Array.isArray(t.scenes) && t.scenes.length > 0,
75
+ "scenes must not be empty"
76
+ );
77
+ const i = /* @__PURE__ */ new Set();
78
+ for (const [o, a] of t.scenes.entries()) {
79
+ const l = `scenes[${o}]`;
80
+ n(d(a), `${l} must be an object`), n(
81
+ typeof a.id == "string" && a.id.length > 0,
82
+ `${l}.id is required`
83
+ ), n(!i.has(a.id), `${l}.id is duplicated`), i.add(a.id), n(
84
+ typeof a.theme == "string" && a.theme in t.themes,
85
+ `${l}.theme is unknown`
86
+ ), n(
87
+ s.includes(String(a.layout)),
88
+ `${l}.layout is invalid`
89
+ ), p(a.name, `${l}.name`, r), n(
90
+ Array.isArray(a.blocks),
91
+ `${l}.blocks must be an array`
92
+ ), n(
93
+ !("scrollVh" in a),
94
+ `${l}.scrollVh is not supported by scene navigation`
95
+ ), n(
96
+ a.durationMs === void 0 || typeof a.durationMs == "number" && Number.isFinite(a.durationMs) && a.durationMs > 0,
97
+ `${l}.durationMs must be a positive finite number`
98
+ ), a.playback !== void 0 && (n(
99
+ d(a.playback),
100
+ `${l}.playback must be an object`
101
+ ), n(
102
+ ["none", "autoplay", "sequence"].includes(
103
+ String(a.playback.mode)
104
+ ),
105
+ `${l}.playback.mode is invalid`
106
+ ), a.playback.mode === "sequence" && (n(
107
+ Array.isArray(a.playback.times) && a.playback.times.length > 0,
108
+ `${l}.playback.times must not be empty`
109
+ ), n(
110
+ a.playback.times.every(
111
+ (h) => typeof h == "string" && Number.isFinite(Date.parse(h))
112
+ ),
113
+ `${l}.playback.times contains an invalid date`
114
+ ), n(
115
+ typeof a.playback.intervalMs == "number" && a.playback.intervalMs > 0,
116
+ `${l}.playback.intervalMs must be positive`
117
+ )));
118
+ const c = /* @__PURE__ */ new Set();
119
+ a.blocks.forEach((h, u) => {
120
+ b(h, `${l}.blocks[${u}]`, r), n(
121
+ !c.has(h.id),
122
+ `${l}.blocks[${u}].id is duplicated`
123
+ ), c.add(h.id);
124
+ });
125
+ }
126
+ }
127
+ function T(t) {
128
+ n(d(t), "views root must be an object"), n(t.schemaVersion === 1, "views schemaVersion must be 1"), n(Array.isArray(t.views), "views must be an array");
129
+ const e = /* @__PURE__ */ new Set();
130
+ for (const [s, r] of t.views.entries())
131
+ n(d(r), `views[${s}] must be an object`), n(
132
+ typeof r.id == "string" && r.id.length > 0,
133
+ `views[${s}].id is required`
134
+ ), n(!e.has(r.id), `views[${s}].id is duplicated`), e.add(r.id), n(
135
+ typeof r.type == "string" && r.type.length > 0,
136
+ `views[${s}].type is required`
137
+ ), n(
138
+ d(r.config),
139
+ `views[${s}].config must be an object`
140
+ );
141
+ }
142
+ function A(t, e) {
143
+ const s = new Set(e.views.map((r) => r.id));
144
+ for (const r of t.scenes)
145
+ for (const i of r.blocks)
146
+ i.type === "view" && n(
147
+ s.has(i.view),
148
+ `scene ${r.id} references unknown view ${i.view}`
149
+ );
150
+ }
151
+ function I(t, e, s, r = []) {
152
+ for (const i of [e, ...r, s])
153
+ if (t[i])
154
+ return t[i];
155
+ return Object.values(t).find(Boolean) ?? "";
156
+ }
157
+ function k(t, e, s = {}) {
158
+ return w(t, s), T(e), A(t, e), { story: t, views: e };
159
+ }
160
+ function q(t) {
161
+ return t.blocks.find((e) => e.type === "view")?.view;
162
+ }
163
+ function P(t, e) {
164
+ return {
165
+ href: t.url,
166
+ target: "_blank",
167
+ rel: "noopener noreferrer",
168
+ textContent: e
169
+ };
170
+ }
171
+ class V {
172
+ constructor(e, s = {}) {
173
+ this.update = e, this.revealTimer = null, this.hideTimer = null, this.shownAt = 0, this.visible = !1, this.revealDelayMs = s.revealDelayMs ?? 120, this.minimumVisibleMs = s.minimumVisibleMs ?? 450;
174
+ }
175
+ show() {
176
+ this.clearHideTimer(), !(this.visible || this.revealTimer !== null) && (this.revealTimer = setTimeout(() => {
177
+ this.revealTimer = null, this.visible = !0, this.shownAt = Date.now(), this.update(!0);
178
+ }, this.revealDelayMs));
179
+ }
180
+ hide(e = !1) {
181
+ if (this.clearRevealTimer(), this.clearHideTimer(), !this.visible)
182
+ return;
183
+ const s = e ? 0 : Math.max(0, this.minimumVisibleMs - (Date.now() - this.shownAt));
184
+ if (s === 0) {
185
+ this.setVisible(!1);
186
+ return;
187
+ }
188
+ this.hideTimer = setTimeout(() => {
189
+ this.hideTimer = null, this.setVisible(!1);
190
+ }, s);
191
+ }
192
+ setVisible(e) {
193
+ this.visible !== e && (this.visible = e, this.update(e));
194
+ }
195
+ clearRevealTimer() {
196
+ this.revealTimer !== null && (clearTimeout(this.revealTimer), this.revealTimer = null);
197
+ }
198
+ clearHideTimer() {
199
+ this.hideTimer !== null && (clearTimeout(this.hideTimer), this.hideTimer = null);
200
+ }
201
+ }
202
+ function _(t, e, s) {
203
+ return s <= 0 ? 0 : Math.max(0, Math.min(s - 1, t + e));
204
+ }
205
+ function $(t) {
206
+ return t.blocks.some(
207
+ (e) => e.type === "copy" && e.showTime === !0
208
+ );
209
+ }
210
+ class L {
211
+ constructor() {
212
+ this.enabled = !1;
213
+ }
214
+ get visible() {
215
+ return this.enabled;
216
+ }
217
+ setScene(e) {
218
+ this.enabled = $(e);
219
+ }
220
+ accept(e) {
221
+ return this.enabled && Number.isFinite(e) ? e : null;
222
+ }
223
+ }
224
+ function F(t, e, s, r) {
225
+ if (s <= 1)
226
+ return { index: 0, direction: 1 };
227
+ const i = t + e;
228
+ if (i >= 0 && i < s)
229
+ return { index: i, direction: e };
230
+ if (r === "loop")
231
+ return { index: e === 1 ? 0 : s - 1, direction: e };
232
+ const o = e === 1 ? -1 : 1;
233
+ return { index: t + o, direction: o };
234
+ }
235
+ function j(t, e) {
236
+ if (t.length === 0)
237
+ return 0;
238
+ let s = 0;
239
+ for (let r = 1; r < t.length && !(Date.parse(t[r]) > e); r++)
240
+ s = r;
241
+ return s;
242
+ }
243
+ class C {
244
+ constructor() {
245
+ this.viewFactories = /* @__PURE__ */ new Map(), this.viewAdapters = /* @__PURE__ */ new Map(), this.widgets = /* @__PURE__ */ new Map();
246
+ }
247
+ registerViewType(e, s) {
248
+ if (this.viewFactories.has(e))
249
+ throw new Error(`View type already registered: ${e}`);
250
+ return this.viewFactories.set(e, s), this;
251
+ }
252
+ registerWidgetType(e, s) {
253
+ if (this.widgets.has(e))
254
+ throw new Error(`Widget type already registered: ${e}`);
255
+ return this.widgets.set(e, s), this;
256
+ }
257
+ getViewAdapter(e) {
258
+ const s = this.viewAdapters.get(e);
259
+ if (s)
260
+ return s;
261
+ const r = this.viewFactories.get(e);
262
+ if (!r)
263
+ throw new Error(`Unregistered view type: ${e}`);
264
+ const i = r();
265
+ return this.viewAdapters.set(e, i), i;
266
+ }
267
+ getWidget(e) {
268
+ const s = this.widgets.get(e);
269
+ if (!s)
270
+ throw new Error(`Unregistered widget type: ${e}`);
271
+ return s;
272
+ }
273
+ destroy() {
274
+ for (const e of this.viewAdapters.values())
275
+ e.destroy();
276
+ this.viewAdapters.clear();
277
+ }
278
+ }
279
+ const M = {
280
+ request: (t) => requestAnimationFrame(t),
281
+ cancel: (t) => cancelAnimationFrame(t)
282
+ };
283
+ class N {
284
+ constructor(e, s = M) {
285
+ this.callbacks = e, this.frames = s, this.active = !1, this.resumeAfterInteraction = !1, this.latestTime = null, this.appliedTime = null, this.frame = null;
286
+ }
287
+ get interacting() {
288
+ return this.active;
289
+ }
290
+ begin() {
291
+ this.active || (this.active = !0, this.resumeAfterInteraction = this.callbacks.isPlaying(), this.latestTime = null, this.appliedTime = null, this.callbacks.pause());
292
+ }
293
+ request(e) {
294
+ !this.active || !Number.isFinite(e) || (this.latestTime = e, this.callbacks.present(e), this.frame === null && (this.frame = this.frames.request(() => {
295
+ this.frame = null, !(!this.active || this.latestTime === null) && this.applyLatest();
296
+ })));
297
+ }
298
+ end() {
299
+ if (!this.active)
300
+ return;
301
+ this.cancelFrame(), this.latestTime !== null && this.latestTime !== this.appliedTime && this.applyLatest();
302
+ const e = this.latestTime, s = this.resumeAfterInteraction;
303
+ this.active = !1, this.latestTime = null, this.appliedTime = null, this.resumeAfterInteraction = !1, this.callbacks.finish(e, s);
304
+ }
305
+ /** Abandons pending work without resuming playback (for navigation/cleanup). */
306
+ cancel() {
307
+ this.cancelFrame(), this.active = !1, this.latestTime = null, this.appliedTime = null, this.resumeAfterInteraction = !1;
308
+ }
309
+ applyLatest() {
310
+ const e = this.latestTime;
311
+ e !== null && (this.appliedTime = e, this.callbacks.apply(e));
312
+ }
313
+ cancelFrame() {
314
+ this.frame !== null && (this.frames.cancel(this.frame), this.frame = null);
315
+ }
316
+ }
317
+ class R {
318
+ constructor(e = console.error) {
319
+ this.onCleanupError = e, this.generation = 0, this.controller = null, this.cleanup = null;
320
+ }
321
+ begin() {
322
+ this.cancel();
323
+ const e = this.generation, s = new AbortController();
324
+ return this.controller = s, {
325
+ signal: s.signal,
326
+ isCurrent: () => this.generation === e && !s.signal.aborted,
327
+ runIfCurrent: (r) => this.generation !== e || s.signal.aborted ? !1 : (r(), !0),
328
+ settle: (r) => {
329
+ if (r) {
330
+ if (this.generation !== e || s.signal.aborted) {
331
+ this.invoke(r);
332
+ return;
333
+ }
334
+ this.cleanup = r;
335
+ }
336
+ }
337
+ };
338
+ }
339
+ cancel() {
340
+ this.generation++, this.controller?.abort(), this.controller = null;
341
+ const e = this.cleanup;
342
+ this.cleanup = null, e && this.invoke(e);
343
+ }
344
+ invoke(e) {
345
+ try {
346
+ e();
347
+ } catch (s) {
348
+ this.onCleanupError(s);
349
+ }
350
+ }
351
+ }
352
+ function x(t, e, s = 7) {
353
+ const r = (c, h) => Array.from({ length: h - c + 1 }, (u, g) => c + g), i = Math.max(0, Math.floor((s - 5) / 2)), o = 2 * i + 5;
354
+ if (t <= o)
355
+ return r(0, t - 1);
356
+ const a = Math.max(0, Math.min(t - 1, e)), l = o - 2;
357
+ return a <= i + 2 ? [...r(0, l - 1), "gap", t - 1] : a >= t - 3 - i ? [0, "gap", ...r(t - l, t - 1)] : [0, "gap", ...r(a - i, a + i), "gap", t - 1];
358
+ }
359
+ function H(t = customElements, e = "story-pager") {
360
+ if (t.get(e))
361
+ return;
362
+ class s extends HTMLElement {
363
+ constructor() {
364
+ super(), this.count = 0, this.labels = null, this.current = 0, this.isPlaying = !1, this.fill = 0, this.isDisabled = !1;
365
+ const i = this.ownerDocument, o = (a, l) => {
366
+ const c = i.createElement("button");
367
+ return c.type = "button", c.className = a, c.addEventListener("click", l), c;
368
+ };
369
+ this.nav = i.createElement("nav"), this.nav.className = "story-pager__nav", this.previous = o(
370
+ "story-pager__previous",
371
+ () => this.request(this.current - 1)
372
+ ), this.next = o(
373
+ "story-pager__next",
374
+ () => this.request(this.current + 1)
375
+ ), this.toggle = o(
376
+ "story-pager__toggle",
377
+ () => this.dispatchEvent(new Event("story-pager-toggle", { bubbles: !0 }))
378
+ ), this.steps = i.createElement("ol"), this.steps.className = "story-pager__steps", this.steps.addEventListener("click", (a) => {
379
+ const l = a.target.closest(
380
+ "[data-step]"
381
+ );
382
+ l && this.request(Number(l.dataset.step));
383
+ }), this.nav.append(this.previous, this.steps, this.next, this.toggle);
384
+ }
385
+ connectedCallback() {
386
+ this.nav.isConnected || this.append(this.nav);
387
+ }
388
+ configure(i, o) {
389
+ this.count = i, this.labels = o, this.nav.setAttribute("aria-label", o.navigation), this.previous.setAttribute("aria-label", o.previous), this.next.setAttribute("aria-label", o.next), this.render();
390
+ }
391
+ get index() {
392
+ return this.current;
393
+ }
394
+ set index(i) {
395
+ this.current = i, this.fill = 0, this.render();
396
+ }
397
+ get playing() {
398
+ return this.isPlaying;
399
+ }
400
+ set playing(i) {
401
+ this.isPlaying = i, this.syncToggle();
402
+ }
403
+ get progress() {
404
+ return this.fill;
405
+ }
406
+ set progress(i) {
407
+ this.fill = Math.max(0, Math.min(1, i)), this.steps.querySelector('[aria-current="step"]')?.style.setProperty("--progress", String(this.fill));
408
+ }
409
+ get disabled() {
410
+ return this.isDisabled;
411
+ }
412
+ set disabled(i) {
413
+ this.isDisabled = i, this.render();
414
+ }
415
+ request(i) {
416
+ this.isDisabled || i < 0 || i >= this.count || this.dispatchEvent(
417
+ new CustomEvent("story-pager-navigate", {
418
+ bubbles: !0,
419
+ detail: { index: i }
420
+ })
421
+ );
422
+ }
423
+ syncToggle() {
424
+ const i = this.labels;
425
+ this.toggle.classList.toggle("is-playing", this.isPlaying), this.toggle.setAttribute("aria-pressed", String(this.isPlaying)), i && this.toggle.setAttribute(
426
+ "aria-label",
427
+ this.isPlaying ? i.pause : i.play
428
+ );
429
+ }
430
+ render() {
431
+ const i = this.labels;
432
+ if (!i)
433
+ return;
434
+ const o = this.ownerDocument, a = o.activeElement, l = a instanceof HTMLElement && this.steps.contains(a) ? a.dataset.step : void 0;
435
+ this.steps.replaceChildren(
436
+ ...x(this.count, this.current).map((c) => {
437
+ const h = o.createElement("li");
438
+ if (c === "gap")
439
+ return h.className = "story-pager__gap", h.textContent = "…", h.setAttribute("aria-hidden", "true"), h;
440
+ const u = o.createElement("button");
441
+ return u.type = "button", u.className = "story-pager__step", u.dataset.step = String(c), u.textContent = String(c + 1), u.setAttribute("aria-label", i.step(c)), u.disabled = this.isDisabled, c === this.current && (u.setAttribute("aria-current", "step"), u.style.setProperty("--progress", String(this.fill))), h.append(u), h;
442
+ })
443
+ ), l !== void 0 && this.steps.querySelector(`[data-step="${l}"]`)?.focus(), this.previous.disabled = this.isDisabled || this.current <= 0, this.next.disabled = this.isDisabled || this.current >= this.count - 1, this.toggle.disabled = this.isDisabled, this.syncToggle();
444
+ }
445
+ }
446
+ t.define(e, s);
447
+ }
448
+ class O {
449
+ constructor(e, s = () => performance.now()) {
450
+ this.onDone = e, this.now = s, this.durationMs = 0, this.elapsedMs = 0, this.startedAt = null, this.timer = null;
451
+ }
452
+ /** Restart from zero; runs at once unless `paused`. */
453
+ start(e, s = !1) {
454
+ this.stop(), this.durationMs = Math.max(0, e), this.elapsedMs = 0, s || this.resume();
455
+ }
456
+ get running() {
457
+ return this.startedAt !== null;
458
+ }
459
+ /** Elapsed share of the duration, 0–1. */
460
+ get progress() {
461
+ if (this.durationMs <= 0)
462
+ return 0;
463
+ const e = this.startedAt === null ? 0 : this.now() - this.startedAt;
464
+ return Math.min(1, (this.elapsedMs + e) / this.durationMs);
465
+ }
466
+ pause() {
467
+ this.startedAt !== null && (this.elapsedMs += this.now() - this.startedAt, this.startedAt = null, this.clear());
468
+ }
469
+ resume() {
470
+ if (this.startedAt !== null || this.durationMs <= 0)
471
+ return;
472
+ const e = this.durationMs - this.elapsedMs;
473
+ e <= 0 || (this.startedAt = this.now(), this.timer = setTimeout(() => {
474
+ this.timer = null, this.elapsedMs = this.durationMs, this.startedAt = null, this.onDone();
475
+ }, e));
476
+ }
477
+ /** Stop without firing; the progress drops to zero. */
478
+ stop() {
479
+ this.clear(), this.startedAt = null, this.elapsedMs = 0;
480
+ }
481
+ clear() {
482
+ this.timer !== null && (clearTimeout(this.timer), this.timer = null);
483
+ }
484
+ }
485
+ function U(t) {
486
+ const e = new URLSearchParams(t.replace(/^#/, "")), s = {}, r = e.get("s");
487
+ r && (s.scene = r);
488
+ const i = e.get("paused");
489
+ return (i === "1" || i === "0") && (s.paused = i === "1"), s;
490
+ }
491
+ function z(t, e) {
492
+ const s = new URLSearchParams({ s: t });
493
+ return e && s.set("paused", "1"), s.toString();
494
+ }
495
+ const f = 1;
496
+ function S(t) {
497
+ const e = Math.min(100 - f, Math.max(0, t * 100)), s = 100 - f - e;
498
+ return `-${m(e)}% 0px -${m(s)}% 0px`;
499
+ }
500
+ const m = (t) => Math.round(t * 100) / 100, E = (t, e) => new IntersectionObserver(t, e);
501
+ class B {
502
+ /**
503
+ * @param sections Scene sections in document order.
504
+ * @param onActivate Called once each time another section becomes active.
505
+ */
506
+ constructor(e, s, r = {}) {
507
+ this.sections = e, this.onActivate = s, this.crossing = /* @__PURE__ */ new Set(), this.activeIndex = -1;
508
+ const i = r.createObserver ?? E;
509
+ this.observer = i((o) => this.update(o), {
510
+ root: r.root ?? null,
511
+ rootMargin: S(r.line ?? 0.5),
512
+ threshold: 0
513
+ });
514
+ for (const o of e)
515
+ this.observer.observe(o);
516
+ }
517
+ /** Index of the active section, -1 before the first one is reached. */
518
+ get active() {
519
+ return this.activeIndex;
520
+ }
521
+ destroy() {
522
+ this.observer.disconnect(), this.crossing.clear();
523
+ }
524
+ update(e) {
525
+ for (const r of e) {
526
+ const i = this.sections.indexOf(r.target);
527
+ i < 0 || (r.isIntersecting ? this.crossing.add(i) : this.crossing.delete(i));
528
+ }
529
+ if (this.crossing.size === 0)
530
+ return;
531
+ const s = Math.max(...this.crossing);
532
+ s !== this.activeIndex && (this.activeIndex = s, this.onActivate(s, this.sections[s]));
533
+ }
534
+ }
535
+ export {
536
+ v as DEFAULT_STORY_LAYOUTS,
537
+ V as LoadingIndicator,
538
+ C as StoryRegistry,
539
+ O as StorySceneTimer,
540
+ B as StoryScroller,
541
+ N as StoryTimeInteraction,
542
+ L as StoryTimePresentation,
543
+ R as StoryWidgetLifecycle,
544
+ S as activationMargin,
545
+ F as advanceStorySequence,
546
+ H as defineStoryPager,
547
+ D as initializeAfterStaticRender,
548
+ _ as nextStoryIndex,
549
+ k as parseStoryDocuments,
550
+ U as parseStoryHash,
551
+ I as resolveLocalizedText,
552
+ $ as sceneShowsTime,
553
+ q as sceneViewId,
554
+ j as sequenceIndexAtOrBefore,
555
+ P as storyExternalLinkAttributes,
556
+ z as storyHash,
557
+ x as storyPagerItems,
558
+ w as validateStoryDocument,
559
+ A as validateStoryReferences,
560
+ T as validateViewsDocument
561
+ };