@unseenco/theatre-core 0.4.2 → 0.5.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/index.js CHANGED
@@ -241,32 +241,88 @@ var require_propose = __commonJS({
241
241
  // core/src/index.ts
242
242
  var index_exports = {};
243
243
  __export(index_exports, {
244
+ PAGE_MODE_SEQUENCE_LENGTH: () => PAGE_MODE_SEQUENCE_LENGTH,
245
+ PAGE_MODE_SUB_UNITS_PER_UNIT: () => PAGE_MODE_SUB_UNITS_PER_UNIT,
246
+ attachGsapSequenceBridge: () => attachGsapSequenceBridge,
247
+ attachSheetScrollDriver: () => attachSheetScrollDriver,
248
+ attachTheatrePageScroll: () => attachTheatrePageScroll,
249
+ configureTheatrePageScroll: () => configureTheatrePageScroll,
250
+ createDefaultPageScrollDriver: () => createDefaultPageScrollDriver,
251
+ createElementHorizontalScrollDriver: () => createElementHorizontalScrollDriver,
252
+ createElementScrollDriver: () => createElementScrollDriver,
253
+ createNativeDocumentHorizontalScrollDriver: () => createNativeDocumentHorizontalScrollDriver,
254
+ createNativeDocumentScrollDriver: () => createNativeDocumentScrollDriver,
244
255
  createRafDriver: () => createRafDriver,
256
+ defaultPageScrollContext: () => defaultPageScrollContext,
257
+ getActivePageScrollContext: () => getActivePageScrollContext,
245
258
  getProject: () => getProject,
259
+ getSheetScrollDriver: () => getSheetScrollDriver,
260
+ getTheatreCoreRafDriver: () => getTheatreCoreRafDriver,
261
+ getTheatrePageScrollConfig: () => getTheatrePageScrollConfig,
262
+ getTheatrePageScrollContext: () => getTheatrePageScrollContext,
263
+ isNativeDocumentScroller: () => isNativeDocumentScroller,
264
+ isPageScrollTrigger: () => isPageScrollTrigger,
246
265
  isRemoteEditorWindow: () => isRemoteEditorWindow,
266
+ isVerticalPageScrollTrigger: () => isVerticalPageScrollTrigger,
247
267
  notify: () => notify,
248
268
  onChange: () => onChange,
269
+ pageScrollProgressFromSequence: () => pageScrollProgressFromSequence,
270
+ pageScrollScrollersMatch: () => pageScrollScrollersMatch,
249
271
  privateAPI: () => privateAPI,
272
+ resolvePageScrollAxis: () => resolvePageScrollAxis,
273
+ resolvePageScrollScroller: () => resolvePageScrollScroller,
274
+ setActivePageScrollContext: () => setActivePageScrollContext,
250
275
  setCoreRafDriver: () => setCoreRafDriver,
276
+ setPageScrollProgress: () => setPageScrollProgress,
251
277
  setPrivateAPI: () => setPrivateAPI,
278
+ syncNativeDocumentScrollToSequencePosition: () => syncNativeDocumentScrollToSequencePosition,
279
+ syncPageScrollToSequencePosition: () => syncPageScrollToSequencePosition,
252
280
  types: () => propTypes_exports,
253
- val: () => val10
281
+ val: () => val12
254
282
  });
255
283
  module.exports = __toCommonJS(index_exports);
256
284
 
257
285
  // core/src/coreExports.ts
258
286
  var coreExports_exports = {};
259
287
  __export(coreExports_exports, {
288
+ PAGE_MODE_SEQUENCE_LENGTH: () => PAGE_MODE_SEQUENCE_LENGTH,
289
+ PAGE_MODE_SUB_UNITS_PER_UNIT: () => PAGE_MODE_SUB_UNITS_PER_UNIT,
290
+ attachGsapSequenceBridge: () => attachGsapSequenceBridge,
291
+ attachSheetScrollDriver: () => attachSheetScrollDriver,
292
+ attachTheatrePageScroll: () => attachTheatrePageScroll,
293
+ configureTheatrePageScroll: () => configureTheatrePageScroll,
294
+ createDefaultPageScrollDriver: () => createDefaultPageScrollDriver,
295
+ createElementHorizontalScrollDriver: () => createElementHorizontalScrollDriver,
296
+ createElementScrollDriver: () => createElementScrollDriver,
297
+ createNativeDocumentHorizontalScrollDriver: () => createNativeDocumentHorizontalScrollDriver,
298
+ createNativeDocumentScrollDriver: () => createNativeDocumentScrollDriver,
260
299
  createRafDriver: () => createRafDriver,
300
+ defaultPageScrollContext: () => defaultPageScrollContext,
301
+ getActivePageScrollContext: () => getActivePageScrollContext,
261
302
  getProject: () => getProject,
303
+ getSheetScrollDriver: () => getSheetScrollDriver,
304
+ getTheatreCoreRafDriver: () => getTheatreCoreRafDriver,
305
+ getTheatrePageScrollConfig: () => getTheatrePageScrollConfig,
306
+ getTheatrePageScrollContext: () => getTheatrePageScrollContext,
307
+ isNativeDocumentScroller: () => isNativeDocumentScroller,
308
+ isPageScrollTrigger: () => isPageScrollTrigger,
262
309
  isRemoteEditorWindow: () => isRemoteEditorWindow,
310
+ isVerticalPageScrollTrigger: () => isVerticalPageScrollTrigger,
263
311
  notify: () => notify,
264
312
  onChange: () => onChange,
313
+ pageScrollProgressFromSequence: () => pageScrollProgressFromSequence,
314
+ pageScrollScrollersMatch: () => pageScrollScrollersMatch,
265
315
  privateAPI: () => privateAPI,
316
+ resolvePageScrollAxis: () => resolvePageScrollAxis,
317
+ resolvePageScrollScroller: () => resolvePageScrollScroller,
318
+ setActivePageScrollContext: () => setActivePageScrollContext,
266
319
  setCoreRafDriver: () => setCoreRafDriver,
320
+ setPageScrollProgress: () => setPageScrollProgress,
267
321
  setPrivateAPI: () => setPrivateAPI,
322
+ syncNativeDocumentScrollToSequencePosition: () => syncNativeDocumentScrollToSequencePosition,
323
+ syncPageScrollToSequencePosition: () => syncPageScrollToSequencePosition,
268
324
  types: () => propTypes_exports,
269
- val: () => val10
325
+ val: () => val12
270
326
  });
271
327
 
272
328
  // core/src/projects/projectsSingleton.ts
@@ -291,6 +347,82 @@ var ProjectsSingleton = class {
291
347
  var singleton = new ProjectsSingleton();
292
348
  var projectsSingleton_default = singleton;
293
349
 
350
+ // core/src/rafDrivers.ts
351
+ var import_theatre_dataverse2 = require("@unseenco/theatre-dataverse");
352
+ var lastDriverId = 0;
353
+ function createRafDriver(conf) {
354
+ const tick = (time) => {
355
+ ticker.tick(time);
356
+ };
357
+ const ticker = new import_theatre_dataverse2.Ticker({
358
+ onActive() {
359
+ conf?.start?.();
360
+ },
361
+ onDormant() {
362
+ conf?.stop?.();
363
+ }
364
+ });
365
+ const driverPublicApi = {
366
+ tick,
367
+ id: lastDriverId++,
368
+ name: conf?.name ?? "CustomRafDriver-".concat(lastDriverId),
369
+ type: "Theatre_RafDriver_PublicAPI"
370
+ };
371
+ const driverPrivateApi = {
372
+ type: "Theatre_RafDriver_PrivateAPI",
373
+ publicApi: driverPublicApi,
374
+ ticker,
375
+ start: conf?.start,
376
+ stop: conf?.stop
377
+ };
378
+ setPrivateAPI(driverPublicApi, driverPrivateApi);
379
+ return driverPublicApi;
380
+ }
381
+
382
+ // core/src/coreTicker.ts
383
+ function createBasicRafDriver() {
384
+ let rafId = null;
385
+ const start = () => {
386
+ if (typeof window !== "undefined") {
387
+ const onAnimationFrame = (t2) => {
388
+ driver.tick(t2);
389
+ rafId = window.requestAnimationFrame(onAnimationFrame);
390
+ };
391
+ rafId = window.requestAnimationFrame(onAnimationFrame);
392
+ } else {
393
+ driver.tick(0);
394
+ setTimeout(() => driver.tick(1), 0);
395
+ }
396
+ };
397
+ const stop = () => {
398
+ if (typeof window !== "undefined") {
399
+ if (rafId !== null) {
400
+ window.cancelAnimationFrame(rafId);
401
+ }
402
+ } else {
403
+ }
404
+ };
405
+ const driver = createRafDriver({ name: "DefaultCoreRafDriver", start, stop });
406
+ return driver;
407
+ }
408
+ var coreRafDriver;
409
+ function getCoreRafDriver() {
410
+ if (!coreRafDriver) {
411
+ setCoreRafDriver(createBasicRafDriver());
412
+ }
413
+ return coreRafDriver;
414
+ }
415
+ function getCoreTicker() {
416
+ return getCoreRafDriver().ticker;
417
+ }
418
+ function setCoreRafDriver(driver) {
419
+ if (coreRafDriver) {
420
+ throw new Error("`setCoreRafDriver()` is already called.");
421
+ }
422
+ const driverPrivateApi = privateAPI(driver);
423
+ coreRafDriver = driverPrivateApi;
424
+ }
425
+
294
426
  // core/src/privateAPIs.ts
295
427
  var publicAPIToPrivateAPIMap = /* @__PURE__ */ new WeakMap();
296
428
  function privateAPI(pub) {
@@ -299,6 +431,23 @@ function privateAPI(pub) {
299
431
  function setPrivateAPI(pub, priv) {
300
432
  publicAPIToPrivateAPIMap.set(pub, priv);
301
433
  }
434
+ function getTheatreCoreRafDriver() {
435
+ return getCoreRafDriver().publicApi;
436
+ }
437
+
438
+ // core/src/sheets/applySheetRuntimeOptions.ts
439
+ function applySheetRuntimeOptions(sheet, opts) {
440
+ if (!opts) return;
441
+ if (opts.sequenceMode !== void 0) {
442
+ sheet.setSequenceMode(opts.sequenceMode);
443
+ }
444
+ if (opts.scrollDriver !== void 0) {
445
+ sheet.setPageScrollDriver(opts.scrollDriver);
446
+ }
447
+ if (opts.gsap === true) {
448
+ sheet.enableGsapSequenceBridge();
449
+ }
450
+ }
302
451
 
303
452
  // shared/src/utils/index.ts
304
453
  var emptyArray = [];
@@ -865,7 +1014,7 @@ var SimpleCache = class {
865
1014
  };
866
1015
 
867
1016
  // core/src/sheetObjects/SheetObjectTemplate.ts
868
- var import_theatre_dataverse7 = require("@unseenco/theatre-dataverse");
1017
+ var import_theatre_dataverse8 = require("@unseenco/theatre-dataverse");
869
1018
 
870
1019
  // ../node_modules/lodash-es/_defineProperty.js
871
1020
  var defineProperty = (function() {
@@ -977,23 +1126,23 @@ function generateDefaultsForCompound(config) {
977
1126
  }
978
1127
 
979
1128
  // core/src/sequences/interpolationTripleAtPosition.ts
980
- var import_theatre_dataverse2 = require("@unseenco/theatre-dataverse");
1129
+ var import_theatre_dataverse3 = require("@unseenco/theatre-dataverse");
981
1130
  var import_UnitBezier = __toESM(require_UnitBezier());
982
1131
  function interpolationTripleAtPosition(ctx, trackP, timeD) {
983
- return (0, import_theatre_dataverse2.prism)(() => {
984
- const track = (0, import_theatre_dataverse2.val)(trackP);
985
- const driverD = import_theatre_dataverse2.prism.memo(
1132
+ return (0, import_theatre_dataverse3.prism)(() => {
1133
+ const track = (0, import_theatre_dataverse3.val)(trackP);
1134
+ const driverD = import_theatre_dataverse3.prism.memo(
986
1135
  "driver",
987
1136
  () => {
988
1137
  if (!track) {
989
- return (0, import_theatre_dataverse2.prism)(() => void 0);
1138
+ return (0, import_theatre_dataverse3.prism)(() => void 0);
990
1139
  } else if (track.type === "BasicKeyframedTrack") {
991
1140
  return _forKeyframedTrack(ctx, track, timeD);
992
1141
  } else if (track.type === "GsapClipTrack") {
993
- return (0, import_theatre_dataverse2.prism)(() => void 0);
1142
+ return (0, import_theatre_dataverse3.prism)(() => void 0);
994
1143
  } else {
995
1144
  ctx.logger.error("Track type not yet supported.");
996
- return (0, import_theatre_dataverse2.prism)(() => void 0);
1145
+ return (0, import_theatre_dataverse3.prism)(() => void 0);
997
1146
  }
998
1147
  },
999
1148
  [track]
@@ -1002,8 +1151,8 @@ function interpolationTripleAtPosition(ctx, trackP, timeD) {
1002
1151
  });
1003
1152
  }
1004
1153
  function _forKeyframedTrack(ctx, track, timeD) {
1005
- return (0, import_theatre_dataverse2.prism)(() => {
1006
- let stateRef = import_theatre_dataverse2.prism.ref("state", { started: false });
1154
+ return (0, import_theatre_dataverse3.prism)(() => {
1155
+ let stateRef = import_theatre_dataverse3.prism.ref("state", { started: false });
1007
1156
  let state = stateRef.current;
1008
1157
  const time = timeD.getValue();
1009
1158
  if (!state.started || time < state.validFrom || state.validTo <= time) {
@@ -1012,7 +1161,7 @@ function _forKeyframedTrack(ctx, track, timeD) {
1012
1161
  return state.der.getValue();
1013
1162
  });
1014
1163
  }
1015
- var undefinedConstD = (0, import_theatre_dataverse2.prism)(() => void 0);
1164
+ var undefinedConstD = (0, import_theatre_dataverse3.prism)(() => void 0);
1016
1165
  function updateState(ctx, progressionD, track) {
1017
1166
  const progression = progressionD.getValue();
1018
1167
  if (track.keyframes.length === 0) {
@@ -1077,7 +1226,7 @@ var states = {
1077
1226
  started: true,
1078
1227
  validFrom: -Infinity,
1079
1228
  validTo: kf.position,
1080
- der: (0, import_theatre_dataverse2.prism)(() => ({ left: kf.value, progression: 0 }))
1229
+ der: (0, import_theatre_dataverse3.prism)(() => ({ left: kf.value, progression: 0 }))
1081
1230
  };
1082
1231
  },
1083
1232
  lastKeyframe(kf) {
@@ -1085,7 +1234,7 @@ var states = {
1085
1234
  started: true,
1086
1235
  validFrom: kf.position,
1087
1236
  validTo: Infinity,
1088
- der: (0, import_theatre_dataverse2.prism)(() => ({ left: kf.value, progression: 0 }))
1237
+ der: (0, import_theatre_dataverse3.prism)(() => ({ left: kf.value, progression: 0 }))
1089
1238
  };
1090
1239
  },
1091
1240
  between(left, right, progressionD) {
@@ -1094,7 +1243,7 @@ var states = {
1094
1243
  started: true,
1095
1244
  validFrom: left.position,
1096
1245
  validTo: right.position,
1097
- der: (0, import_theatre_dataverse2.prism)(() => ({ left: left.value, progression: 0 }))
1246
+ der: (0, import_theatre_dataverse3.prism)(() => ({ left: left.value, progression: 0 }))
1098
1247
  };
1099
1248
  }
1100
1249
  const globalProgressionToLocalProgression = (globalProgression) => {
@@ -1107,7 +1256,7 @@ var states = {
1107
1256
  right.handles[0],
1108
1257
  right.handles[1]
1109
1258
  );
1110
- const bezierDer = (0, import_theatre_dataverse2.prism)(() => {
1259
+ const bezierDer = (0, import_theatre_dataverse3.prism)(() => {
1111
1260
  const progression = globalProgressionToLocalProgression(
1112
1261
  progressionD.getValue()
1113
1262
  );
@@ -1125,7 +1274,7 @@ var states = {
1125
1274
  der: bezierDer
1126
1275
  };
1127
1276
  }
1128
- const holdDer = (0, import_theatre_dataverse2.prism)(() => {
1277
+ const holdDer = (0, import_theatre_dataverse3.prism)(() => {
1129
1278
  const progression = globalProgressionToLocalProgression(
1130
1279
  progressionD.getValue()
1131
1280
  );
@@ -1182,18 +1331,18 @@ function pointerDeep(base, toAppend) {
1182
1331
  }
1183
1332
 
1184
1333
  // shared/src/utils/valToAtom.ts
1185
- var import_theatre_dataverse3 = require("@unseenco/theatre-dataverse");
1334
+ var import_theatre_dataverse4 = require("@unseenco/theatre-dataverse");
1186
1335
  var valToAtom = (key, vals) => {
1187
- const a2 = import_theatre_dataverse3.prism.memo(key, () => new import_theatre_dataverse3.Atom(vals), []);
1336
+ const a2 = import_theatre_dataverse4.prism.memo(key, () => new import_theatre_dataverse4.Atom(vals), []);
1188
1337
  a2.set(vals);
1189
1338
  return a2;
1190
1339
  };
1191
1340
 
1192
1341
  // core/src/sheetObjects/SheetObject.ts
1193
- var import_theatre_dataverse6 = require("@unseenco/theatre-dataverse");
1342
+ var import_theatre_dataverse7 = require("@unseenco/theatre-dataverse");
1194
1343
 
1195
1344
  // core/src/sheetObjects/TheatreSheetObject.ts
1196
- var import_theatre_dataverse4 = require("@unseenco/theatre-dataverse");
1345
+ var import_theatre_dataverse5 = require("@unseenco/theatre-dataverse");
1197
1346
 
1198
1347
  // core/src/propTypes/index.ts
1199
1348
  var propTypes_exports = {};
@@ -3234,11 +3383,11 @@ function sanitizeCompoundProps(props) {
3234
3383
  );
3235
3384
  }
3236
3385
  }
3237
- const val11 = props[key];
3238
- if (isLonghandPropType(val11)) {
3239
- sanitizedProps[key] = val11;
3386
+ const val13 = props[key];
3387
+ if (isLonghandPropType(val13)) {
3388
+ sanitizedProps[key] = val13;
3240
3389
  } else {
3241
- sanitizedProps[key] = toLonghandProp(val11);
3390
+ sanitizedProps[key] = toLonghandProp(val13);
3242
3391
  }
3243
3392
  }
3244
3393
  return sanitizedProps;
@@ -3336,15 +3485,15 @@ var file = (defaultValue, opts = {}) => {
3336
3485
  deserializeAndSanitize: _ensureFile
3337
3486
  };
3338
3487
  };
3339
- var _ensureFile = (val11) => {
3340
- if (!val11) return void 0;
3488
+ var _ensureFile = (val13) => {
3489
+ if (!val13) return void 0;
3341
3490
  let valid = true;
3342
- if (typeof val11.id !== "string" && ![null, void 0].includes(val11.id)) {
3491
+ if (typeof val13.id !== "string" && ![null, void 0].includes(val13.id)) {
3343
3492
  valid = false;
3344
3493
  }
3345
- if (val11.type !== "file") valid = false;
3494
+ if (val13.type !== "file") valid = false;
3346
3495
  if (!valid) return void 0;
3347
- return val11;
3496
+ return val13;
3348
3497
  };
3349
3498
  var image = (defaultValue, opts = {}) => {
3350
3499
  if (process.env.NODE_ENV !== "production") {
@@ -3368,15 +3517,15 @@ var image = (defaultValue, opts = {}) => {
3368
3517
  deserializeAndSanitize: _ensureImage
3369
3518
  };
3370
3519
  };
3371
- var _ensureImage = (val11) => {
3372
- if (!val11) return void 0;
3520
+ var _ensureImage = (val13) => {
3521
+ if (!val13) return void 0;
3373
3522
  let valid = true;
3374
- if (typeof val11.id !== "string" && ![null, void 0].includes(val11.id)) {
3523
+ if (typeof val13.id !== "string" && ![null, void 0].includes(val13.id)) {
3375
3524
  valid = false;
3376
3525
  }
3377
- if (val11.type !== "image") valid = false;
3526
+ if (val13.type !== "image") valid = false;
3378
3527
  if (!valid) return void 0;
3379
- return val11;
3528
+ return val13;
3380
3529
  };
3381
3530
  var number = (defaultValue, opts = {}) => {
3382
3531
  if (process.env.NODE_ENV !== "production") {
@@ -3499,11 +3648,11 @@ var rgba = (defaultValue = { r: 0, g: 0, b: 0, a: 1 }, opts = {}) => {
3499
3648
  deserializeAndSanitize: _sanitizeRgba
3500
3649
  };
3501
3650
  };
3502
- var _sanitizeRgba = (val11) => {
3503
- if (!val11) return void 0;
3651
+ var _sanitizeRgba = (val13) => {
3652
+ if (!val13) return void 0;
3504
3653
  let valid = true;
3505
3654
  for (const c2 of ["r", "g", "b", "a"]) {
3506
- if (!Object.prototype.hasOwnProperty.call(val11, c2) || typeof val11[c2] !== "number") {
3655
+ if (!Object.prototype.hasOwnProperty.call(val13, c2) || typeof val13[c2] !== "number") {
3507
3656
  valid = false;
3508
3657
  }
3509
3658
  }
@@ -3512,7 +3661,7 @@ var _sanitizeRgba = (val11) => {
3512
3661
  for (const c2 of ["r", "g", "b", "a"]) {
3513
3662
  ;
3514
3663
  sanitized[c2] = Math.min(
3515
- Math.max(val11[c2], 0),
3664
+ Math.max(val13[c2], 0),
3516
3665
  1
3517
3666
  );
3518
3667
  }
@@ -3551,8 +3700,8 @@ var boolean = (defaultValue, opts = {}) => {
3551
3700
  deserializeAndSanitize: _ensureBoolean
3552
3701
  };
3553
3702
  };
3554
- var _ensureBoolean = (val11) => {
3555
- return typeof val11 === "boolean" ? val11 : void 0;
3703
+ var _ensureBoolean = (val13) => {
3704
+ return typeof val13 === "boolean" ? val13 : void 0;
3556
3705
  };
3557
3706
  function leftInterpolate(left) {
3558
3707
  return left;
@@ -3710,8 +3859,8 @@ var TheatreSheetObject = class {
3710
3859
  _valuesPrism() {
3711
3860
  return this._cache.get("_valuesPrism", () => {
3712
3861
  const sheetObject = privateAPI(this);
3713
- const d2 = (0, import_theatre_dataverse4.prism)(() => {
3714
- return (0, import_theatre_dataverse4.val)(sheetObject.getValues().getValue());
3862
+ const d2 = (0, import_theatre_dataverse5.prism)(() => {
3863
+ return (0, import_theatre_dataverse5.val)(sheetObject.getValues().getValue());
3715
3864
  });
3716
3865
  return d2;
3717
3866
  });
@@ -3719,10 +3868,10 @@ var TheatreSheetObject = class {
3719
3868
  _valuesWithVariantPrism() {
3720
3869
  return this._cache.get("_valuesWithVariantPrism", () => {
3721
3870
  const sheetObject = privateAPI(this);
3722
- return (0, import_theatre_dataverse4.prism)(() => {
3871
+ return (0, import_theatre_dataverse5.prism)(() => {
3723
3872
  return {
3724
- values: (0, import_theatre_dataverse4.val)(sheetObject.getValues().getValue()),
3725
- variant: (0, import_theatre_dataverse4.val)(sheetObject.sheet.effectiveActiveSequenceVariantD)
3873
+ values: (0, import_theatre_dataverse5.val)(sheetObject.getValues().getValue()),
3874
+ variant: (0, import_theatre_dataverse5.val)(sheetObject.sheet.effectiveActiveSequenceVariantD)
3726
3875
  };
3727
3876
  });
3728
3877
  });
@@ -3759,8 +3908,8 @@ var TheatreSheetObject = class {
3759
3908
  }
3760
3909
  return der.getValue();
3761
3910
  }
3762
- set initialValue(val11) {
3763
- privateAPI(this).setInitialValue(val11);
3911
+ set initialValue(val13) {
3912
+ privateAPI(this).setInitialValue(val13);
3764
3913
  }
3765
3914
  showPropsOf(objects) {
3766
3915
  const host = privateAPI(this);
@@ -4155,7 +4304,7 @@ function setDeepImmutable(obj, path, replace) {
4155
4304
  }
4156
4305
 
4157
4306
  // core/src/sequences/sequenceVariants.ts
4158
- var import_theatre_dataverse5 = require("@unseenco/theatre-dataverse");
4307
+ var import_theatre_dataverse6 = require("@unseenco/theatre-dataverse");
4159
4308
 
4160
4309
  // shared/src/utils/sheetProps.ts
4161
4310
  var SHEET_PROPS_OBJECT_KEY = "__theatre_sheet_props__";
@@ -4223,17 +4372,17 @@ function getSequenceStateFromSheet(sheetState, variantId) {
4223
4372
  return void 0;
4224
4373
  }
4225
4374
  function valTrackIdByPropPathForObject(sheetStatePointer, variantId, objectKey) {
4226
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById);
4227
- const sequenceFromMap = (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId]);
4375
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById);
4376
+ const sequenceFromMap = (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId]);
4228
4377
  if (sequenceFromMap !== void 0) {
4229
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4230
- return (0, import_theatre_dataverse5.val)(
4378
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4379
+ return (0, import_theatre_dataverse6.val)(
4231
4380
  sheetStatePointer.sequencesById[variantId].tracksByObject[objectKey]?.trackIdByPropPath
4232
4381
  );
4233
4382
  }
4234
4383
  if (variantId === DEFAULT_SEQUENCE_VARIANT) {
4235
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequence?.tracksByObject);
4236
- return (0, import_theatre_dataverse5.val)(
4384
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequence?.tracksByObject);
4385
+ return (0, import_theatre_dataverse6.val)(
4237
4386
  sheetStatePointer.sequence?.tracksByObject[objectKey]?.trackIdByPropPath
4238
4387
  );
4239
4388
  }
@@ -4241,11 +4390,11 @@ function valTrackIdByPropPathForObject(sheetStatePointer, variantId, objectKey)
4241
4390
  }
4242
4391
  function valUnsequencedPropPathsForObject(sheetStatePointer, variantId, objectKey) {
4243
4392
  if (variantId === DEFAULT_SEQUENCE_VARIANT) return void 0;
4244
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById);
4245
- const sequenceFromMap = (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId]);
4393
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById);
4394
+ const sequenceFromMap = (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId]);
4246
4395
  if (sequenceFromMap !== void 0) {
4247
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4248
- return (0, import_theatre_dataverse5.val)(
4396
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4397
+ return (0, import_theatre_dataverse6.val)(
4249
4398
  sheetStatePointer.sequencesById[variantId].tracksByObject[objectKey]?.unsequencedPropPaths
4250
4399
  );
4251
4400
  }
@@ -4273,7 +4422,7 @@ function validateSequenceVariantIdOrThrow(value, fnName) {
4273
4422
  return idTrimmed;
4274
4423
  }
4275
4424
  function pointerToSequenceTrackData(sheetStatePointer, variantId, objectKey, trackId) {
4276
- const sheetState = (0, import_theatre_dataverse5.val)(sheetStatePointer);
4425
+ const sheetState = (0, import_theatre_dataverse6.val)(sheetStatePointer);
4277
4426
  if (sheetState?.sequencesById?.[variantId]) {
4278
4427
  return sheetStatePointer.sequencesById[variantId].tracksByObject[objectKey].trackData[trackId];
4279
4428
  }
@@ -4316,19 +4465,19 @@ var SheetObject = class {
4316
4465
  __publicField(this, "$$isPointerToPrismProvider", true);
4317
4466
  __publicField(this, "address");
4318
4467
  __publicField(this, "publicApi");
4319
- __publicField(this, "_initialValue", new import_theatre_dataverse6.Atom({}));
4468
+ __publicField(this, "_initialValue", new import_theatre_dataverse7.Atom({}));
4320
4469
  /**
4321
4470
  * Highest-priority override layer, written to by `RemoteSync` when a value
4322
4471
  * update arrives from a remote editor window (see `internal/RemoteSync.ts`).
4323
4472
  * Empty (`{}`) unless a remote editor is actually connected, so it's a
4324
4473
  * no-op merge for every app that never uses the remote-sync feature.
4325
4474
  */
4326
- __publicField(this, "_remoteOverride", new import_theatre_dataverse6.Atom({}));
4475
+ __publicField(this, "_remoteOverride", new import_theatre_dataverse7.Atom({}));
4327
4476
  /**
4328
4477
  * Session-only overrides for props with `persist: false`. Not written to
4329
4478
  * persisted project state and cleared on refresh.
4330
4479
  */
4331
- __publicField(this, "_sessionOverrides", new import_theatre_dataverse6.Atom({}));
4480
+ __publicField(this, "_sessionOverrides", new import_theatre_dataverse7.Atom({}));
4332
4481
  __publicField(this, "_cache", new SimpleCache());
4333
4482
  __publicField(this, "_logger");
4334
4483
  __publicField(this, "_internalUtilCtx");
@@ -4350,10 +4499,10 @@ var SheetObject = class {
4350
4499
  getValues() {
4351
4500
  return this._cache.get(
4352
4501
  "getValues()",
4353
- () => (0, import_theatre_dataverse6.prism)(() => {
4354
- const defaults = (0, import_theatre_dataverse6.val)(this.template.getDefaultValues());
4355
- const initial = (0, import_theatre_dataverse6.val)(this._initialValue.pointer);
4356
- const withInitialCache = import_theatre_dataverse6.prism.memo(
4502
+ () => (0, import_theatre_dataverse7.prism)(() => {
4503
+ const defaults = (0, import_theatre_dataverse7.val)(this.template.getDefaultValues());
4504
+ const initial = (0, import_theatre_dataverse7.val)(this._initialValue.pointer);
4505
+ const withInitialCache = import_theatre_dataverse7.prism.memo(
4357
4506
  "withInitialCache",
4358
4507
  () => /* @__PURE__ */ new WeakMap(),
4359
4508
  []
@@ -4363,8 +4512,8 @@ var SheetObject = class {
4363
4512
  initial,
4364
4513
  withInitialCache
4365
4514
  );
4366
- const ahistoricStatics = (0, import_theatre_dataverse6.val)(this.template.getAhistoricStaticValues());
4367
- const withAhistoricStaticsCache = import_theatre_dataverse6.prism.memo(
4515
+ const ahistoricStatics = (0, import_theatre_dataverse7.val)(this.template.getAhistoricStaticValues());
4516
+ const withAhistoricStaticsCache = import_theatre_dataverse7.prism.memo(
4368
4517
  "withAhistoricStatics",
4369
4518
  () => /* @__PURE__ */ new WeakMap(),
4370
4519
  []
@@ -4374,10 +4523,10 @@ var SheetObject = class {
4374
4523
  ahistoricStatics,
4375
4524
  withAhistoricStaticsCache
4376
4525
  );
4377
- const activeVariant = (0, import_theatre_dataverse6.val)(this.sheet.effectiveActiveSequenceVariantD);
4526
+ const activeVariant = (0, import_theatre_dataverse7.val)(this.sheet.effectiveActiveSequenceVariantD);
4378
4527
  const staticVariant = isSheetPropsObjectKey(this.address.objectKey) ? DEFAULT_SEQUENCE_VARIANT : activeVariant;
4379
- const statics = (0, import_theatre_dataverse6.val)(this.template.getStaticValues(staticVariant));
4380
- const withStaticsCache = import_theatre_dataverse6.prism.memo(
4528
+ const statics = (0, import_theatre_dataverse7.val)(this.template.getStaticValues(staticVariant));
4529
+ const withStaticsCache = import_theatre_dataverse7.prism.memo(
4381
4530
  "withStatics",
4382
4531
  () => /* @__PURE__ */ new WeakMap(),
4383
4532
  []
@@ -4390,22 +4539,22 @@ var SheetObject = class {
4390
4539
  let final = withStatics;
4391
4540
  let sequenced;
4392
4541
  {
4393
- const pointerToSequencedValuesD = import_theatre_dataverse6.prism.memo(
4542
+ const pointerToSequencedValuesD = import_theatre_dataverse7.prism.memo(
4394
4543
  "seq",
4395
4544
  () => this.getSequencedValues(),
4396
4545
  []
4397
4546
  );
4398
- const withSeqsCache = import_theatre_dataverse6.prism.memo(
4547
+ const withSeqsCache = import_theatre_dataverse7.prism.memo(
4399
4548
  "withSeqsCache",
4400
4549
  () => /* @__PURE__ */ new WeakMap(),
4401
4550
  []
4402
4551
  );
4403
- sequenced = (0, import_theatre_dataverse6.val)((0, import_theatre_dataverse6.val)(pointerToSequencedValuesD));
4552
+ sequenced = (0, import_theatre_dataverse7.val)((0, import_theatre_dataverse7.val)(pointerToSequencedValuesD));
4404
4553
  const withSeqs = deepMergeWithCache(final, sequenced, withSeqsCache);
4405
4554
  final = withSeqs;
4406
4555
  }
4407
- const sessionOverrides = (0, import_theatre_dataverse6.val)(this._sessionOverrides.pointer);
4408
- const withSessionOverridesCache = import_theatre_dataverse6.prism.memo(
4556
+ const sessionOverrides = (0, import_theatre_dataverse7.val)(this._sessionOverrides.pointer);
4557
+ const withSessionOverridesCache = import_theatre_dataverse7.prism.memo(
4409
4558
  "withSessionOverridesCache",
4410
4559
  () => /* @__PURE__ */ new WeakMap(),
4411
4560
  []
@@ -4415,8 +4564,8 @@ var SheetObject = class {
4415
4564
  sessionOverrides,
4416
4565
  withSessionOverridesCache
4417
4566
  );
4418
- const remoteOverride = (0, import_theatre_dataverse6.val)(this._remoteOverride.pointer);
4419
- const withRemoteOverrideCache = import_theatre_dataverse6.prism.memo(
4567
+ const remoteOverride = (0, import_theatre_dataverse7.val)(this._remoteOverride.pointer);
4568
+ const withRemoteOverrideCache = import_theatre_dataverse7.prism.memo(
4420
4569
  "withRemoteOverrideCache",
4421
4570
  () => /* @__PURE__ */ new WeakMap(),
4422
4571
  []
@@ -4432,35 +4581,35 @@ var SheetObject = class {
4432
4581
  );
4433
4582
  }
4434
4583
  getValueByPointer(pointer3) {
4435
- const allValuesP = (0, import_theatre_dataverse6.val)(this.getValues());
4436
- const { path } = (0, import_theatre_dataverse6.getPointerParts)(pointer3);
4437
- return (0, import_theatre_dataverse6.val)(
4584
+ const allValuesP = (0, import_theatre_dataverse7.val)(this.getValues());
4585
+ const { path } = (0, import_theatre_dataverse7.getPointerParts)(pointer3);
4586
+ return (0, import_theatre_dataverse7.val)(
4438
4587
  pointerDeep(allValuesP, path)
4439
4588
  );
4440
4589
  }
4441
4590
  pointerToPrism(pointer3) {
4442
- const { path } = (0, import_theatre_dataverse6.getPointerParts)(pointer3);
4443
- return (0, import_theatre_dataverse6.prism)(() => {
4444
- const allValuesP = (0, import_theatre_dataverse6.val)(this.getValues());
4445
- return (0, import_theatre_dataverse6.val)(pointerDeep(allValuesP, path));
4591
+ const { path } = (0, import_theatre_dataverse7.getPointerParts)(pointer3);
4592
+ return (0, import_theatre_dataverse7.prism)(() => {
4593
+ const allValuesP = (0, import_theatre_dataverse7.val)(this.getValues());
4594
+ return (0, import_theatre_dataverse7.val)(pointerDeep(allValuesP, path));
4446
4595
  });
4447
4596
  }
4448
4597
  /**
4449
4598
  * Returns values of props that are sequenced.
4450
4599
  */
4451
4600
  getSequencedValues() {
4452
- return (0, import_theatre_dataverse6.prism)(() => {
4453
- const activeVariant = (0, import_theatre_dataverse6.val)(this.sheet.effectiveActiveSequenceVariantD);
4601
+ return (0, import_theatre_dataverse7.prism)(() => {
4602
+ const activeVariant = (0, import_theatre_dataverse7.val)(this.sheet.effectiveActiveSequenceVariantD);
4454
4603
  const sequenceVariant = isSheetPropsObjectKey(this.address.objectKey) ? DEFAULT_SEQUENCE_VARIANT : activeVariant;
4455
- const tracksToProcessD = import_theatre_dataverse6.prism.memo(
4604
+ const tracksToProcessD = import_theatre_dataverse7.prism.memo(
4456
4605
  "tracksToProcess",
4457
4606
  () => this.template.getArrayOfValidSequenceTracks(sequenceVariant),
4458
4607
  [sequenceVariant]
4459
4608
  );
4460
- const tracksToProcess = (0, import_theatre_dataverse6.val)(tracksToProcessD);
4461
- const valsAtom = new import_theatre_dataverse6.Atom({});
4462
- const config = (0, import_theatre_dataverse6.val)(this.template.configPointer);
4463
- import_theatre_dataverse6.prism.effect(
4609
+ const tracksToProcess = (0, import_theatre_dataverse7.val)(tracksToProcessD);
4610
+ const valsAtom = new import_theatre_dataverse7.Atom({});
4611
+ const config = (0, import_theatre_dataverse7.val)(this.template.configPointer);
4612
+ import_theatre_dataverse7.prism.effect(
4464
4613
  "processTracks",
4465
4614
  () => {
4466
4615
  const untaps = [];
@@ -4510,7 +4659,7 @@ var SheetObject = class {
4510
4659
  });
4511
4660
  }
4512
4661
  _trackIdToPrism(trackId, trackVariant) {
4513
- const activeVariant = (0, import_theatre_dataverse6.val)(this.sheet.effectiveActiveSequenceVariantD);
4662
+ const activeVariant = (0, import_theatre_dataverse7.val)(this.sheet.effectiveActiveSequenceVariantD);
4514
4663
  const trackP = pointerToSequenceTrackData(
4515
4664
  this.template.project.pointers.historic.sheetsById[this.address.sheetId],
4516
4665
  trackVariant,
@@ -4523,14 +4672,14 @@ var SheetObject = class {
4523
4672
  get propsP() {
4524
4673
  return this._cache.get(
4525
4674
  "propsP",
4526
- () => (0, import_theatre_dataverse6.pointer)({ root: this, path: [] })
4675
+ () => (0, import_theatre_dataverse7.pointer)({ root: this, path: [] })
4527
4676
  );
4528
4677
  }
4529
4678
  validateValue(pointer3, value) {
4530
4679
  }
4531
- setInitialValue(val11) {
4532
- this.validateValue(this.propsP, val11);
4533
- this._initialValue.set(val11);
4680
+ setInitialValue(val13) {
4681
+ this.validateValue(this.propsP, val13);
4682
+ this._initialValue.set(val13);
4534
4683
  }
4535
4684
  setSessionOverride(path, value) {
4536
4685
  const propConfig = getPropConfigByPath(this.template.staticConfig, path);
@@ -4550,8 +4699,8 @@ var SheetObject = class {
4550
4699
  * Internal: called by `RemoteSync` when a value update for this object
4551
4700
  * arrives from a remote editor window. Not exposed on the public API.
4552
4701
  */
4553
- setRemoteOverride(val11) {
4554
- this._remoteOverride.set(val11);
4702
+ setRemoteOverride(val13) {
4703
+ this._remoteOverride.set(val13);
4555
4704
  }
4556
4705
  /**
4557
4706
  * Internal: used by `RemoteSync` to subscribe to this object's fully
@@ -4560,7 +4709,7 @@ var SheetObject = class {
4560
4709
  */
4561
4710
  onFinalValueChange(fn2) {
4562
4711
  return onChange(
4563
- (0, import_theatre_dataverse6.prism)(() => (0, import_theatre_dataverse6.val)(this.getValues().getValue())),
4712
+ (0, import_theatre_dataverse7.prism)(() => (0, import_theatre_dataverse7.val)(this.getValues().getValue())),
4564
4713
  fn2
4565
4714
  );
4566
4715
  }
@@ -5131,9 +5280,9 @@ var SheetObjectTemplate = class {
5131
5280
  config,
5132
5281
  sheetTemplate.project
5133
5282
  );
5134
- this._config = new import_theatre_dataverse7.Atom(configWithPrecisionDefaults);
5135
- this._temp_actions_atom = new import_theatre_dataverse7.Atom(_temp_actions);
5136
- this.showPropsOf_atom = new import_theatre_dataverse7.Atom([]);
5283
+ this._config = new import_theatre_dataverse8.Atom(configWithPrecisionDefaults);
5284
+ this._temp_actions_atom = new import_theatre_dataverse8.Atom(_temp_actions);
5285
+ this.showPropsOf_atom = new import_theatre_dataverse8.Atom([]);
5137
5286
  this._transientPropPaths = normalizeTransientPropPaths(
5138
5287
  transient,
5139
5288
  config,
@@ -5190,7 +5339,7 @@ var SheetObjectTemplate = class {
5190
5339
  return this.showPropsOf_atom.pointer;
5191
5340
  }
5192
5341
  _stripNonPersistingPropsFromAhistoricState() {
5193
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5342
+ const config = (0, import_theatre_dataverse8.val)(this.configPointer);
5194
5343
  this.project._stripNonPersistingPropsFromAhistoric(
5195
5344
  this.address.sheetId,
5196
5345
  this.address.objectKey,
@@ -5319,8 +5468,8 @@ var SheetObjectTemplate = class {
5319
5468
  getDefaultValues() {
5320
5469
  return this._cache.get(
5321
5470
  "getDefaultValues()",
5322
- () => (0, import_theatre_dataverse7.prism)(() => {
5323
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5471
+ () => (0, import_theatre_dataverse8.prism)(() => {
5472
+ const config = (0, import_theatre_dataverse8.val)(this.configPointer);
5324
5473
  return getPropDefaultsOfSheetObject(config);
5325
5474
  })
5326
5475
  );
@@ -5332,14 +5481,14 @@ var SheetObjectTemplate = class {
5332
5481
  getStaticValues(sequenceVariant = DEFAULT_SEQUENCE_VARIANT) {
5333
5482
  return this._cache.get(
5334
5483
  "getStaticValues:".concat(sequenceVariant),
5335
- () => (0, import_theatre_dataverse7.prism)(() => {
5336
- const sheetState = (0, import_theatre_dataverse7.val)(this.pointerToSheetState);
5484
+ () => (0, import_theatre_dataverse8.prism)(() => {
5485
+ const sheetState = (0, import_theatre_dataverse8.val)(this.pointerToSheetState);
5337
5486
  const json = getEffectiveStaticOverrideForObject(
5338
5487
  sheetState,
5339
5488
  sequenceVariant,
5340
5489
  this.address.objectKey
5341
5490
  ) ?? {};
5342
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5491
+ const config = (0, import_theatre_dataverse8.val)(this.configPointer);
5343
5492
  const deserialized = config.deserializeAndSanitize(json) || {};
5344
5493
  const withoutNonPersisting = stripNonPersistingPropValuesFromMap(
5345
5494
  deserialized,
@@ -5362,9 +5511,9 @@ var SheetObjectTemplate = class {
5362
5511
  getAhistoricStaticValues() {
5363
5512
  return this._cache.get(
5364
5513
  "getAhistoricStaticValues",
5365
- () => (0, import_theatre_dataverse7.prism)(() => {
5366
- const json = (0, import_theatre_dataverse7.val)(this.pointerToAhistoricStaticOverrides) ?? {};
5367
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5514
+ () => (0, import_theatre_dataverse8.prism)(() => {
5515
+ const json = (0, import_theatre_dataverse8.val)(this.pointerToAhistoricStaticOverrides) ?? {};
5516
+ const config = (0, import_theatre_dataverse8.val)(this.configPointer);
5368
5517
  const deserialized = config.deserializeAndSanitize(json) || {};
5369
5518
  return stripNonPersistingPropValuesFromMap(deserialized, config);
5370
5519
  })
@@ -5379,13 +5528,13 @@ var SheetObjectTemplate = class {
5379
5528
  getArrayOfValidSequenceTracks(sequenceVariant) {
5380
5529
  return this._cache.get(
5381
5530
  "getArrayOfValidSequenceTracks:".concat(sequenceVariant),
5382
- () => (0, import_theatre_dataverse7.prism)(
5531
+ () => (0, import_theatre_dataverse8.prism)(
5383
5532
  () => {
5384
5533
  const effectiveSequenceVariant = isSheetPropsObjectKey(
5385
5534
  this.address.objectKey
5386
5535
  ) ? DEFAULT_SEQUENCE_VARIANT : sequenceVariant;
5387
5536
  const pointerToSheetState = this.project.pointers.historic.sheetsById[this.address.sheetId];
5388
- (0, import_theatre_dataverse7.val)(pointerToSheetState.variantObjectOverrides);
5537
+ (0, import_theatre_dataverse8.val)(pointerToSheetState.variantObjectOverrides);
5389
5538
  const defaultTrackIdByPropPath = valTrackIdByPropPathForObject(
5390
5539
  pointerToSheetState,
5391
5540
  DEFAULT_SEQUENCE_VARIANT,
@@ -5411,7 +5560,7 @@ var SheetObjectTemplate = class {
5411
5560
  return emptyArray;
5412
5561
  }
5413
5562
  const arrayOfIds = [];
5414
- const objectConfig = (0, import_theatre_dataverse7.val)(this.configPointer);
5563
+ const objectConfig = (0, import_theatre_dataverse8.val)(this.configPointer);
5415
5564
  for (const [pathToPropInString, effectiveTrack] of Object.entries(
5416
5565
  mergedTrackMap
5417
5566
  )) {
@@ -5461,8 +5610,8 @@ var SheetObjectTemplate = class {
5461
5610
  getMapOfValidSequenceTracks_forStudio(sequenceVariant) {
5462
5611
  return this._cache.get(
5463
5612
  "getMapOfValidSequenceTracks_forStudio:".concat(sequenceVariant),
5464
- () => (0, import_theatre_dataverse7.prism)(() => {
5465
- const arr = (0, import_theatre_dataverse7.val)(this.getArrayOfValidSequenceTracks(sequenceVariant));
5613
+ () => (0, import_theatre_dataverse8.prism)(() => {
5614
+ const arr = (0, import_theatre_dataverse8.val)(this.getArrayOfValidSequenceTracks(sequenceVariant));
5466
5615
  let map = {};
5467
5616
  for (const { pathToProp, trackId } of arr) {
5468
5617
  set_default(map, pathToProp, trackId);
@@ -5482,9 +5631,9 @@ var SheetObjectTemplate = class {
5482
5631
  getStaticButNotSequencedOverrides(sequenceVariant) {
5483
5632
  return this._cache.get(
5484
5633
  "getStaticButNotSequencedOverrides:".concat(sequenceVariant),
5485
- () => (0, import_theatre_dataverse7.prism)(() => {
5486
- const staticOverrides = (0, import_theatre_dataverse7.val)(this.getStaticValues(sequenceVariant));
5487
- const arrayOfValidSequenceTracks = (0, import_theatre_dataverse7.val)(
5634
+ () => (0, import_theatre_dataverse8.prism)(() => {
5635
+ const staticOverrides = (0, import_theatre_dataverse8.val)(this.getStaticValues(sequenceVariant));
5636
+ const arrayOfValidSequenceTracks = (0, import_theatre_dataverse8.val)(
5488
5637
  this.getArrayOfValidSequenceTracks(sequenceVariant)
5489
5638
  );
5490
5639
  const staticButNotSequencedOverrides = cloneDeep_default(staticOverrides);
@@ -5510,7 +5659,7 @@ var SheetObjectTemplate = class {
5510
5659
  );
5511
5660
  }
5512
5661
  getDefaultsAtPointer(pointer3) {
5513
- const { path } = (0, import_theatre_dataverse7.getPointerParts)(pointer3);
5662
+ const { path } = (0, import_theatre_dataverse8.getPointerParts)(pointer3);
5514
5663
  const defaults = this.getDefaultValues().getValue();
5515
5664
  const defaultsAtPath = getDeep(defaults, path);
5516
5665
  return defaultsAtPath;
@@ -5531,7 +5680,7 @@ function parsePathToProp(pathToPropInString) {
5531
5680
  }
5532
5681
 
5533
5682
  // core/src/sheets/SheetTemplate.ts
5534
- var import_theatre_dataverse16 = require("@unseenco/theatre-dataverse");
5683
+ var import_theatre_dataverse19 = require("@unseenco/theatre-dataverse");
5535
5684
 
5536
5685
  // shared/src/utils/didYouMean.ts
5537
5686
  var import_propose = __toESM(require_propose());
@@ -5547,10 +5696,10 @@ function didYouMean(str, dictionary, prepend = "Did you mean ", append = "?") {
5547
5696
  }
5548
5697
 
5549
5698
  // core/src/sequences/Sequence.ts
5550
- var import_theatre_dataverse11 = require("@unseenco/theatre-dataverse");
5551
5699
  var import_theatre_dataverse12 = require("@unseenco/theatre-dataverse");
5552
5700
  var import_theatre_dataverse13 = require("@unseenco/theatre-dataverse");
5553
5701
  var import_theatre_dataverse14 = require("@unseenco/theatre-dataverse");
5702
+ var import_theatre_dataverse15 = require("@unseenco/theatre-dataverse");
5554
5703
 
5555
5704
  // shared/src/utils/defer.ts
5556
5705
  function defer() {
@@ -5581,11 +5730,11 @@ var noop = () => {
5581
5730
  var noop_default = noop;
5582
5731
 
5583
5732
  // core/src/sequences/playbackControllers/DefaultPlaybackController.ts
5584
- var import_theatre_dataverse8 = require("@unseenco/theatre-dataverse");
5733
+ var import_theatre_dataverse9 = require("@unseenco/theatre-dataverse");
5585
5734
  var DefaultPlaybackController = class {
5586
5735
  constructor() {
5587
5736
  __publicField(this, "_stopPlayCallback", noop_default);
5588
- __publicField(this, "_state", new import_theatre_dataverse8.Atom({
5737
+ __publicField(this, "_state", new import_theatre_dataverse9.Atom({
5589
5738
  position: 0,
5590
5739
  playing: false
5591
5740
  }));
@@ -5751,7 +5900,7 @@ var DefaultPlaybackController = class {
5751
5900
  };
5752
5901
 
5753
5902
  // core/src/sequences/playbackControllers/AudioPlaybackController.ts
5754
- var import_theatre_dataverse9 = require("@unseenco/theatre-dataverse");
5903
+ var import_theatre_dataverse10 = require("@unseenco/theatre-dataverse");
5755
5904
 
5756
5905
  // shared/src/globalVariableNames.ts
5757
5906
  var studioBundle = "__TheatreJS_StudioBundle";
@@ -5809,7 +5958,7 @@ var AudioPlaybackController = class {
5809
5958
  this._audioContext = _audioContext;
5810
5959
  this._nodeDestination = _nodeDestination;
5811
5960
  __publicField(this, "_mainGain");
5812
- __publicField(this, "_state", new import_theatre_dataverse9.Atom({
5961
+ __publicField(this, "_state", new import_theatre_dataverse10.Atom({
5813
5962
  position: 0,
5814
5963
  playing: false
5815
5964
  }));
@@ -5929,11 +6078,11 @@ var AudioPlaybackController = class {
5929
6078
  "The sequence will still play, but only 1000 times. The `iterationCount: ".concat(iterationCount, "` provided to `sequence.play()`\nis too high for a sequence with audio.\n\nTo fix this, either set `iterationCount` to a lower value, or remove the audio from the sequence."),
5930
6079
  [
5931
6080
  {
5932
- url: "https://www.theatrejs.com/docs/latest/manual/audio",
6081
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/audio",
5933
6082
  title: "Using Audio"
5934
6083
  },
5935
6084
  {
5936
- url: "https://www.theatrejs.com/docs/latest/api/core#sequence.attachaudio",
6085
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#sequence.attachaudio",
5937
6086
  title: "Audio API"
5938
6087
  }
5939
6088
  ]
@@ -5986,82 +6135,6 @@ var AudioPlaybackController = class {
5986
6135
  }
5987
6136
  };
5988
6137
 
5989
- // core/src/rafDrivers.ts
5990
- var import_theatre_dataverse10 = require("@unseenco/theatre-dataverse");
5991
- var lastDriverId = 0;
5992
- function createRafDriver(conf) {
5993
- const tick = (time) => {
5994
- ticker.tick(time);
5995
- };
5996
- const ticker = new import_theatre_dataverse10.Ticker({
5997
- onActive() {
5998
- conf?.start?.();
5999
- },
6000
- onDormant() {
6001
- conf?.stop?.();
6002
- }
6003
- });
6004
- const driverPublicApi = {
6005
- tick,
6006
- id: lastDriverId++,
6007
- name: conf?.name ?? "CustomRafDriver-".concat(lastDriverId),
6008
- type: "Theatre_RafDriver_PublicAPI"
6009
- };
6010
- const driverPrivateApi = {
6011
- type: "Theatre_RafDriver_PrivateAPI",
6012
- publicApi: driverPublicApi,
6013
- ticker,
6014
- start: conf?.start,
6015
- stop: conf?.stop
6016
- };
6017
- setPrivateAPI(driverPublicApi, driverPrivateApi);
6018
- return driverPublicApi;
6019
- }
6020
-
6021
- // core/src/coreTicker.ts
6022
- function createBasicRafDriver() {
6023
- let rafId = null;
6024
- const start = () => {
6025
- if (typeof window !== "undefined") {
6026
- const onAnimationFrame = (t2) => {
6027
- driver.tick(t2);
6028
- rafId = window.requestAnimationFrame(onAnimationFrame);
6029
- };
6030
- rafId = window.requestAnimationFrame(onAnimationFrame);
6031
- } else {
6032
- driver.tick(0);
6033
- setTimeout(() => driver.tick(1), 0);
6034
- }
6035
- };
6036
- const stop = () => {
6037
- if (typeof window !== "undefined") {
6038
- if (rafId !== null) {
6039
- window.cancelAnimationFrame(rafId);
6040
- }
6041
- } else {
6042
- }
6043
- };
6044
- const driver = createRafDriver({ name: "DefaultCoreRafDriver", start, stop });
6045
- return driver;
6046
- }
6047
- var coreRafDriver;
6048
- function getCoreRafDriver() {
6049
- if (!coreRafDriver) {
6050
- setCoreRafDriver(createBasicRafDriver());
6051
- }
6052
- return coreRafDriver;
6053
- }
6054
- function getCoreTicker() {
6055
- return getCoreRafDriver().ticker;
6056
- }
6057
- function setCoreRafDriver(driver) {
6058
- if (coreRafDriver) {
6059
- throw new Error("`setCoreRafDriver()` is already called.");
6060
- }
6061
- const driverPrivateApi = privateAPI(driver);
6062
- coreRafDriver = driverPrivateApi;
6063
- }
6064
-
6065
6138
  // core/src/sequences/TheatreSequence.ts
6066
6139
  var TheatreSequence = class {
6067
6140
  get type() {
@@ -6085,7 +6158,7 @@ var TheatreSequence = class {
6085
6158
  "You seem to have called `sequence.play()` before the project has finished loading.\n\nThis would **not** a problem in production when using `@unseenco/theatre-core`, since Theatre.js loads instantly in core mode. However, when using `@unseenco/theatre-studio`, it takes a few milliseconds for it to load your project's state, before which your sequences cannot start playing.\n\nTo fix this, simply defer calling `sequence.play()` until after the project is loaded, like this:\n\n```\nproject.ready.then(() => {\n sequence.play()\n})\n```",
6086
6159
  [
6087
6160
  {
6088
- url: "https://www.theatrejs.com/docs/0.5/api/core#project.ready",
6161
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#project.ready",
6089
6162
  title: "Project.ready"
6090
6163
  }
6091
6164
  ]
@@ -6111,14 +6184,27 @@ var TheatreSequence = class {
6111
6184
  __experimental_getGsapClips() {
6112
6185
  return privateAPI(this).getGsapClips();
6113
6186
  }
6187
+ __experimental_getGsapScrollTriggers() {
6188
+ return privateAPI(this).getGsapScrollTriggers();
6189
+ }
6114
6190
  async attachAudio(args) {
6191
+ const priv = privateAPI(this);
6192
+ if (priv._sheet.getSequenceMode() === "page") {
6193
+ notify.warning(
6194
+ "Audio is not supported in page mode",
6195
+ "Sequence audio expects time in seconds. Use time mode for attachAudio(), or scrub scroll-driven animation without audio."
6196
+ );
6197
+ return Promise.reject(
6198
+ new Error("sequence.attachAudio() is not supported in page mode")
6199
+ );
6200
+ }
6115
6201
  const { audioContext, destinationNode, decodedBuffer, gainNode } = await resolveAudioBuffer(args);
6116
6202
  const playbackController = new AudioPlaybackController(
6117
6203
  decodedBuffer,
6118
6204
  audioContext,
6119
6205
  gainNode
6120
6206
  );
6121
- privateAPI(this).replacePlaybackController(playbackController);
6207
+ priv.replacePlaybackController(playbackController);
6122
6208
  return { audioContext, destinationNode, decodedBuffer, gainNode };
6123
6209
  }
6124
6210
  get pointer() {
@@ -6216,6 +6302,31 @@ async function resolveAudioBuffer(args) {
6216
6302
  };
6217
6303
  }
6218
6304
 
6305
+ // shared/src/gsap/gsapStudioRegistryRevision.ts
6306
+ var import_theatre_dataverse11 = require("@unseenco/theatre-dataverse");
6307
+ var revisionAtom = new import_theatre_dataverse11.Atom(0);
6308
+ var gsapStudioRegistryRevisionPointer = revisionAtom.pointer;
6309
+
6310
+ // shared/src/gsap/scrollTriggerRegistry.ts
6311
+ var DEFAULT_SHEET_INSTANCE_ID = "default";
6312
+ var REGISTRY_KEY = "__unseenco_theatre_gsap_scrollTriggerRegistry__";
6313
+ function sheetAddressKey(address) {
6314
+ const sheetInstanceId = address.sheetInstanceId ?? DEFAULT_SHEET_INSTANCE_ID;
6315
+ return "".concat(address.projectId, "|").concat(address.sheetId, "|").concat(sheetInstanceId);
6316
+ }
6317
+ function getStore() {
6318
+ const g2 = globalThis;
6319
+ if (!g2[REGISTRY_KEY]) {
6320
+ g2[REGISTRY_KEY] = { bySheetAddress: /* @__PURE__ */ new Map() };
6321
+ }
6322
+ return g2[REGISTRY_KEY];
6323
+ }
6324
+ function listScrollTriggerEntriesForSheet(sheetKey) {
6325
+ const map = getStore().bySheetAddress.get(sheetKey);
6326
+ if (!map) return [];
6327
+ return [...map.values()].sort((a2, b2) => a2.layout.start - b2.layout.start);
6328
+ }
6329
+
6219
6330
  // shared/src/sequence/trackData.ts
6220
6331
  function isBasicKeyframedTrack(track) {
6221
6332
  return track.type === "BasicKeyframedTrack";
@@ -6223,6 +6334,19 @@ function isBasicKeyframedTrack(track) {
6223
6334
  function isGsapClipTrack(track) {
6224
6335
  return track.type === "GsapClipTrack";
6225
6336
  }
6337
+ function gsapClipEndTime(clip) {
6338
+ return clip.start + clip.duration;
6339
+ }
6340
+ function gsapClipSyncProgress(sequencePosition, clip) {
6341
+ if (clip.duration <= 0) return 0;
6342
+ if (sequencePosition < clip.start) return 0;
6343
+ const clipEnd = gsapClipEndTime(clip);
6344
+ if (sequencePosition >= clipEnd - 1e-5) return 1;
6345
+ const raw = (sequencePosition - clip.start) / clip.duration;
6346
+ if (raw <= 0) return 0;
6347
+ if (raw >= 1) return 1;
6348
+ return raw;
6349
+ }
6226
6350
 
6227
6351
  // core/src/sequences/Sequence.ts
6228
6352
  var possibleDirections = [
@@ -6245,7 +6369,7 @@ var Sequence = class {
6245
6369
  __publicField(this, "_positionD");
6246
6370
  __publicField(this, "_positionFormatterD");
6247
6371
  __publicField(this, "_playableRangeD");
6248
- __publicField(this, "pointer", (0, import_theatre_dataverse13.pointer)({ root: this, path: [] }));
6372
+ __publicField(this, "pointer", (0, import_theatre_dataverse14.pointer)({ root: this, path: [] }));
6249
6373
  __publicField(this, "$$isPointerToPrismProvider", true);
6250
6374
  __publicField(this, "_logger");
6251
6375
  __publicField(this, "closestGridPosition", (posInUnitSpace) => {
@@ -6258,32 +6382,35 @@ var Sequence = class {
6258
6382
  this._logger = _project._logger.named("Sheet", _sheet.address.sheetId).named("Instance", _sheet.address.sheetInstanceId).named("Variant", _sequenceVariant);
6259
6383
  this.address = { ...this._sheet.address, sequenceName: _sequenceVariant };
6260
6384
  this.publicApi = new TheatreSequence(this);
6261
- this._playbackControllerBox = new import_theatre_dataverse12.Atom(
6385
+ this._playbackControllerBox = new import_theatre_dataverse13.Atom(
6262
6386
  playbackController ?? new DefaultPlaybackController()
6263
6387
  );
6264
- this._prismOfStatePointer = (0, import_theatre_dataverse14.prism)(
6388
+ this._prismOfStatePointer = (0, import_theatre_dataverse15.prism)(
6265
6389
  () => this._playbackControllerBox.prism.getValue().statePointer
6266
6390
  );
6267
- this._positionD = (0, import_theatre_dataverse14.prism)(() => {
6391
+ this._positionD = (0, import_theatre_dataverse15.prism)(() => {
6268
6392
  const statePointer = this._prismOfStatePointer.getValue();
6269
- return (0, import_theatre_dataverse14.val)(statePointer.position);
6393
+ return (0, import_theatre_dataverse15.val)(statePointer.position);
6270
6394
  });
6271
- this._positionFormatterD = (0, import_theatre_dataverse14.prism)(() => {
6272
- const subUnitsPerUnit = (0, import_theatre_dataverse14.val)(this._subUnitsPerUnitD);
6395
+ this._positionFormatterD = (0, import_theatre_dataverse15.prism)(() => {
6396
+ const subUnitsPerUnit = (0, import_theatre_dataverse15.val)(this._subUnitsPerUnitD);
6397
+ if (this._sheet.getSequenceMode() === "page") {
6398
+ return new PercentBasedPositionFormatter(subUnitsPerUnit);
6399
+ }
6273
6400
  return new TimeBasedPositionFormatter(subUnitsPerUnit);
6274
6401
  });
6275
6402
  }
6276
6403
  pointerToPrism(pointer3) {
6277
- const { path } = (0, import_theatre_dataverse11.getPointerParts)(pointer3);
6404
+ const { path } = (0, import_theatre_dataverse12.getPointerParts)(pointer3);
6278
6405
  if (path.length === 0) {
6279
- return (0, import_theatre_dataverse14.prism)(() => ({
6280
- length: (0, import_theatre_dataverse14.val)(this.pointer.length),
6281
- playing: (0, import_theatre_dataverse14.val)(this.pointer.playing),
6282
- position: (0, import_theatre_dataverse14.val)(this.pointer.position)
6406
+ return (0, import_theatre_dataverse15.prism)(() => ({
6407
+ length: (0, import_theatre_dataverse15.val)(this.pointer.length),
6408
+ playing: (0, import_theatre_dataverse15.val)(this.pointer.playing),
6409
+ position: (0, import_theatre_dataverse15.val)(this.pointer.position)
6283
6410
  }));
6284
6411
  }
6285
6412
  if (path.length > 1) {
6286
- return (0, import_theatre_dataverse14.prism)(() => void 0);
6413
+ return (0, import_theatre_dataverse15.prism)(() => void 0);
6287
6414
  }
6288
6415
  const [prop] = path;
6289
6416
  if (prop === "length") {
@@ -6291,11 +6418,11 @@ var Sequence = class {
6291
6418
  } else if (prop === "position") {
6292
6419
  return this._positionD;
6293
6420
  } else if (prop === "playing") {
6294
- return (0, import_theatre_dataverse14.prism)(() => {
6295
- return (0, import_theatre_dataverse14.val)(this._prismOfStatePointer.getValue().playing);
6421
+ return (0, import_theatre_dataverse15.prism)(() => {
6422
+ return (0, import_theatre_dataverse15.val)(this._prismOfStatePointer.getValue().playing);
6296
6423
  });
6297
6424
  } else {
6298
- return (0, import_theatre_dataverse14.prism)(() => void 0);
6425
+ return (0, import_theatre_dataverse15.prism)(() => void 0);
6299
6426
  }
6300
6427
  }
6301
6428
  /**
@@ -6304,13 +6431,13 @@ var Sequence = class {
6304
6431
  * Theoretically, this method can be called from inside a prism so it can be reactive.
6305
6432
  */
6306
6433
  getKeyframesOfSimpleProp(prop) {
6307
- const { path, root: root2 } = (0, import_theatre_dataverse11.getPointerParts)(prop);
6434
+ const { path, root: root2 } = (0, import_theatre_dataverse12.getPointerParts)(prop);
6308
6435
  if (!isSheetObject(root2)) {
6309
6436
  throw new InvalidArgumentError(
6310
6437
  "Argument prop must be a pointer to a SheetObject property"
6311
6438
  );
6312
6439
  }
6313
- const sheetState = (0, import_theatre_dataverse14.val)(
6440
+ const sheetState = (0, import_theatre_dataverse15.val)(
6314
6441
  this._project.pointers.historic.sheetsById[this._sheet.address.sheetId]
6315
6442
  );
6316
6443
  const trackP = getSequenceStateFromSheet(sheetState, this._sequenceVariant)?.tracksByObject[root2.address.objectKey];
@@ -6333,7 +6460,7 @@ var Sequence = class {
6333
6460
  * @internal Used by the public sequence API.
6334
6461
  */
6335
6462
  getGsapClipsForObject(objectKey) {
6336
- const sheetState = (0, import_theatre_dataverse14.val)(
6463
+ const sheetState = (0, import_theatre_dataverse15.val)(
6337
6464
  this._project.pointers.historic.sheetsById[this._sheet.address.sheetId]
6338
6465
  );
6339
6466
  const tracksOfObject = getSequenceStateFromSheet(
@@ -6350,7 +6477,7 @@ var Sequence = class {
6350
6477
  return result.sort((a2, b2) => a2.clip.start - b2.clip.start);
6351
6478
  }
6352
6479
  getGsapClips() {
6353
- const sheetState = (0, import_theatre_dataverse14.val)(
6480
+ const sheetState = (0, import_theatre_dataverse15.val)(
6354
6481
  this._project.pointers.historic.sheetsById[this._sheet.address.sheetId]
6355
6482
  );
6356
6483
  const sequenceState = getSequenceStateFromSheet(
@@ -6375,6 +6502,21 @@ var Sequence = class {
6375
6502
  }
6376
6503
  return result.sort((a2, b2) => a2.clip.start - b2.clip.start);
6377
6504
  }
6505
+ getGsapScrollTriggers() {
6506
+ if (this._sheet.getSequenceMode() !== "page") {
6507
+ return [];
6508
+ }
6509
+ const key = sheetAddressKey(this._sheet.address);
6510
+ return listScrollTriggerEntriesForSheet(key).filter((entry) => entry.sheetObject != null).map((entry) => ({
6511
+ objectKey: entry.sheetObject.address.objectKey,
6512
+ scrollTriggerId: entry.id,
6513
+ label: entry.label,
6514
+ layout: entry.layout,
6515
+ kind: entry.kind,
6516
+ animationSpanSeconds: entry.animationSpanSeconds,
6517
+ timelineChildren: entry.timelineChildren
6518
+ }));
6519
+ }
6378
6520
  get positionFormatter() {
6379
6521
  return this._positionFormatterD.getValue();
6380
6522
  }
@@ -6423,11 +6565,11 @@ var Sequence = class {
6423
6565
  return this._lengthD.getValue();
6424
6566
  }
6425
6567
  get playing() {
6426
- return (0, import_theatre_dataverse14.val)(this._playbackControllerBox.get().statePointer.playing);
6568
+ return (0, import_theatre_dataverse15.val)(this._playbackControllerBox.get().statePointer.playing);
6427
6569
  }
6428
6570
  _makeRangeFromSequenceTemplate() {
6429
- return (0, import_theatre_dataverse14.prism)(() => {
6430
- return [0, (0, import_theatre_dataverse14.val)(this._lengthD)];
6571
+ return (0, import_theatre_dataverse15.prism)(() => {
6572
+ return [0, (0, import_theatre_dataverse15.val)(this._lengthD)];
6431
6573
  });
6432
6574
  }
6433
6575
  /**
@@ -6445,6 +6587,13 @@ var Sequence = class {
6445
6587
  return this._playbackControllerBox.get().playDynamicRange(rangeD, ticker);
6446
6588
  }
6447
6589
  async play(conf, ticker) {
6590
+ if (this._sheet.getSequenceMode() === "page") {
6591
+ notify.warning(
6592
+ "Playback is disabled in page mode",
6593
+ "The sequence is driven by page scroll. Scrub the playhead or scroll the page instead of calling sequence.play()."
6594
+ );
6595
+ return false;
6596
+ }
6448
6597
  const sequenceDuration = this.length;
6449
6598
  const range = conf && conf.range ? conf.range : [0, sequenceDuration];
6450
6599
  if (process.env.NODE_ENV !== "production") {
@@ -6477,11 +6626,11 @@ var Sequence = class {
6477
6626
  ), "s) is longer than the duration of the sequence (").concat(sequenceDuration, "s).\n\nTo fix this, either set `conf.range[1]` to be less the duration of the sequence, or adjust the sequence duration in the UI."),
6478
6627
  [
6479
6628
  {
6480
- url: "https://www.theatrejs.com/docs/latest/manual/sequences",
6629
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/sequences",
6481
6630
  title: "Sequences"
6482
6631
  },
6483
6632
  {
6484
- url: "https://www.theatrejs.com/docs/latest/manual/sequences",
6633
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/sequences",
6485
6634
  title: "Playback API"
6486
6635
  }
6487
6636
  ]
@@ -6635,6 +6784,33 @@ var TimeBasedPositionFormatter = class {
6635
6784
  return posInUnitSpace.toFixed(2) + "s";
6636
6785
  }
6637
6786
  };
6787
+ var PercentBasedPositionFormatter = class {
6788
+ constructor(_subUnitsPerUnit) {
6789
+ this._subUnitsPerUnit = _subUnitsPerUnit;
6790
+ }
6791
+ formatSubUnitForGrid(posInUnitSpace) {
6792
+ const subUnitSize = 1 / this._subUnitsPerUnit;
6793
+ const withinUnit = posInUnitSpace % 1;
6794
+ const tenths = Math.round(withinUnit / subUnitSize);
6795
+ return tenths + "t";
6796
+ }
6797
+ formatFullUnitForGrid(posInUnitSpace) {
6798
+ return Math.round(posInUnitSpace) + "%";
6799
+ }
6800
+ formatForPlayhead(posInUnitSpace) {
6801
+ const whole = Math.floor(posInUnitSpace);
6802
+ const subUnitSize = 1 / this._subUnitsPerUnit;
6803
+ const withinUnit = posInUnitSpace - whole;
6804
+ const tenths = Math.round(withinUnit / subUnitSize);
6805
+ if (tenths <= 0) {
6806
+ return whole + "%";
6807
+ }
6808
+ return whole + "." + tenths + "%";
6809
+ }
6810
+ formatBasic(posInUnitSpace) {
6811
+ return posInUnitSpace.toFixed(1) + "%";
6812
+ }
6813
+ };
6638
6814
  var second = 1;
6639
6815
  var minute = second * 60;
6640
6816
  var hour = minute * 60;
@@ -6669,11 +6845,11 @@ function validateAndSanitiseSlashedPathOrThrow(unsanitisedPath, fnName) {
6669
6845
  "The path in `".concat(fnName, '("').concat(unsanitisedPath, '")` was sanitized to `"').concat(sanitisedPath, '"`.\n\n') + "Please replace the path with the sanitized one, otherwise it will likely break in the future.",
6670
6846
  [
6671
6847
  {
6672
- url: "https://www.theatrejs.com/docs/latest/manual/objects#creating-sheet-objects",
6848
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/objects#creating-objects",
6673
6849
  title: "Sheet Objects"
6674
6850
  },
6675
6851
  {
6676
- url: "https://www.theatrejs.com/docs/latest/api/core#sheet.object",
6852
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#sheet.object",
6677
6853
  title: "API"
6678
6854
  }
6679
6855
  ]
@@ -6888,6 +7064,15 @@ var TheatreSheet = class {
6888
7064
  getActiveSequenceVariant() {
6889
7065
  return privateAPI(this).getActiveSequenceVariant();
6890
7066
  }
7067
+ getSequenceMode() {
7068
+ return privateAPI(this).getSequenceMode();
7069
+ }
7070
+ setSequenceMode(mode) {
7071
+ privateAPI(this).setSequenceMode(mode);
7072
+ }
7073
+ setPageScrollDriver(driver) {
7074
+ privateAPI(this).setPageScrollDriver(driver);
7075
+ }
6891
7076
  get project() {
6892
7077
  return privateAPI(this).project.publicApi;
6893
7078
  }
@@ -6945,14 +7130,373 @@ var TheatreSheet = class {
6945
7130
  };
6946
7131
 
6947
7132
  // core/src/sheets/Sheet.ts
6948
- var import_theatre_dataverse15 = require("@unseenco/theatre-dataverse");
7133
+ var import_theatre_dataverse18 = require("@unseenco/theatre-dataverse");
7134
+
7135
+ // core/src/sheets/sheetSequenceMode.ts
7136
+ var PAGE_MODE_SEQUENCE_LENGTH = 100;
7137
+ var PAGE_MODE_SUB_UNITS_PER_UNIT = 10;
7138
+
7139
+ // shared/src/gsap/applyTimelineChildTiming.ts
7140
+ function applyTimelineChildTimingToGsap(rootAnimation, timelineChildren, childById, onRebuild) {
7141
+ if (!timelineChildren.length) return true;
7142
+ let ok = applyTimelineChildTimingToGsapInner(
7143
+ rootAnimation,
7144
+ timelineChildren,
7145
+ childById
7146
+ );
7147
+ if (!ok && onRebuild) {
7148
+ const rebuilt = onRebuild();
7149
+ if (rebuilt) {
7150
+ ok = applyTimelineChildTimingToGsapInner(
7151
+ rebuilt,
7152
+ timelineChildren,
7153
+ childById
7154
+ );
7155
+ }
7156
+ }
7157
+ return ok;
7158
+ }
7159
+ function applyTimelineChildTimingToGsapInner(rootAnimation, timelineChildren, childById) {
7160
+ if (!childById || timelineChildren.length === 0) return true;
7161
+ let ok = true;
7162
+ for (const childState of timelineChildren) {
7163
+ const tween = childById.get(childState.childId);
7164
+ if (!tween) continue;
7165
+ try {
7166
+ const t2 = tween;
7167
+ if (typeof t2.startTime === "function") {
7168
+ t2.startTime(childState.localStart);
7169
+ }
7170
+ if (typeof t2.duration === "function") {
7171
+ t2.duration(childState.localDuration);
7172
+ }
7173
+ } catch {
7174
+ ok = false;
7175
+ }
7176
+ }
7177
+ return ok;
7178
+ }
7179
+
7180
+ // shared/src/gsap/syncGsapClipProgress.ts
7181
+ function getGsapAnimationTargetKey(animation, fallbackAnimationId) {
7182
+ const tween = animation;
7183
+ const targets = tween.targets?.();
7184
+ if (targets && targets.length > 0) {
7185
+ return targets[0];
7186
+ }
7187
+ return fallbackAnimationId;
7188
+ }
7189
+ function syncRegisteredGsapAnimationsForClips(sequencePosition, clips) {
7190
+ const enriched = [];
7191
+ for (const clip of clips) {
7192
+ const entry = getAnimationEntryBySheetAddressKey(
7193
+ clip.sheetObjectAddressKey,
7194
+ clip.gsapAnimationId
7195
+ );
7196
+ if (!entry?.animation) continue;
7197
+ enriched.push({
7198
+ ...clip,
7199
+ entry,
7200
+ targetKey: getGsapAnimationTargetKey(
7201
+ entry.animation,
7202
+ clip.gsapAnimationId
7203
+ )
7204
+ });
7205
+ }
7206
+ const byTarget = /* @__PURE__ */ new Map();
7207
+ for (const item of enriched) {
7208
+ const list = byTarget.get(item.targetKey) ?? [];
7209
+ list.push(item);
7210
+ byTarget.set(item.targetKey, list);
7211
+ }
7212
+ for (const group of byTarget.values()) {
7213
+ const sorted = [...group].sort((a2, b2) => a2.start - b2.start);
7214
+ for (const clip of sorted) {
7215
+ const progress = gsapClipSyncProgress(sequencePosition, clip);
7216
+ const entry = clip.entry;
7217
+ const animation = entry.animation;
7218
+ if (entry.kind === "timeline" && clip.timelineChildren && clip.timelineChildren.length > 0) {
7219
+ applyTimelineChildTimingToGsap(
7220
+ entry.animation,
7221
+ clip.timelineChildren,
7222
+ entry.timelineChildById,
7223
+ entry.onRebuildTimeline
7224
+ );
7225
+ const span = clip.timelineSpan ?? readGsapTweenTimelineDuration(entry.animation);
7226
+ const t2 = progress * Math.max(span, 0.01);
7227
+ if (typeof animation.time === "function") {
7228
+ animation.time(t2, true);
7229
+ } else {
7230
+ animation.progress?.(progress, true);
7231
+ }
7232
+ } else {
7233
+ animation.progress?.(progress, true);
7234
+ }
7235
+ }
7236
+ }
7237
+ }
7238
+ function readGsapTweenTimelineDuration(animation) {
7239
+ const tween = animation;
7240
+ const total = tween.totalDuration?.();
7241
+ if (typeof total === "number" && total > 0) return total;
7242
+ const d2 = tween.duration();
7243
+ return d2 > 0 ? d2 : 1;
7244
+ }
7245
+
7246
+ // shared/src/gsap/gsapAnimationRegistry.ts
7247
+ var DEFAULT_SHEET_INSTANCE_ID2 = "default";
7248
+ var REGISTRY_KEY2 = "__unseenco_theatre_gsap_animationRegistry__";
7249
+ function sheetObjectAddressKeyFromParts(address) {
7250
+ const sheetInstanceId = address.sheetInstanceId ?? DEFAULT_SHEET_INSTANCE_ID2;
7251
+ return "".concat(address.projectId, "|").concat(address.sheetId, "|").concat(sheetInstanceId, "|").concat(address.objectKey);
7252
+ }
7253
+ function getStore2() {
7254
+ const g2 = globalThis;
7255
+ if (!g2[REGISTRY_KEY2]) {
7256
+ g2[REGISTRY_KEY2] = {
7257
+ bySheetAddress: /* @__PURE__ */ new Map()
7258
+ };
7259
+ }
7260
+ return g2[REGISTRY_KEY2];
7261
+ }
7262
+ function getAnimationEntryBySheetAddressKey(sheetObjectAddressKey, animationId) {
7263
+ return getStore2().bySheetAddress.get(sheetObjectAddressKey)?.get(animationId);
7264
+ }
7265
+
7266
+ // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
7267
+ var import_theatre_dataverse16 = require("@unseenco/theatre-dataverse");
7268
+
7269
+ // shared/src/gsap/syncGsapClipsAtSequencePosition.ts
7270
+ function syncGsapClipsAtSequencePosition(position, clips) {
7271
+ syncRegisteredGsapAnimationsForClips(
7272
+ position,
7273
+ clips
7274
+ );
7275
+ }
7276
+
7277
+ // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
7278
+ function subscribeGsapClipSyncAtPlayhead(source) {
7279
+ const positionPointer = source.pointer.position;
7280
+ const positionPrism = (0, import_theatre_dataverse16.pointerToPrism)(positionPointer);
7281
+ const clipsPrism = (0, import_theatre_dataverse16.prism)(() => source.getGsapClipTimings());
7282
+ const syncNow = () => {
7283
+ const clips = clipsPrism.getValue();
7284
+ if (clips.length === 0) return;
7285
+ syncGsapClipsAtSequencePosition((0, import_theatre_dataverse16.val)(positionPointer), clips);
7286
+ };
7287
+ const untapPosition = positionPrism.onStale(syncNow);
7288
+ const untapClips = clipsPrism.onStale(syncNow);
7289
+ syncNow();
7290
+ return () => {
7291
+ untapPosition();
7292
+ untapClips();
7293
+ };
7294
+ }
7295
+
7296
+ // core/src/gsap/attachGsapSequenceBridge.ts
7297
+ function attachGsapSequenceBridge(sheet) {
7298
+ const sequence = sheet.sequence;
7299
+ const sheetAddress = privateAPI(sheet).address;
7300
+ return subscribeGsapClipSyncAtPlayhead({
7301
+ pointer: sequence.pointer,
7302
+ getGsapClipTimings: () => sequence.__experimental_getGsapClips().map(({ objectKey, clip }) => ({
7303
+ sheetObjectAddressKey: sheetObjectAddressKeyFromParts({
7304
+ projectId: sheetAddress.projectId,
7305
+ sheetId: sheetAddress.sheetId,
7306
+ sheetInstanceId: sheetAddress.sheetInstanceId,
7307
+ objectKey
7308
+ }),
7309
+ gsapAnimationId: clip.gsapAnimationId,
7310
+ start: clip.start,
7311
+ duration: clip.duration,
7312
+ timelineChildren: clip.timelineChildren,
7313
+ timelineSpan: clip.timelineSpan
7314
+ }))
7315
+ });
7316
+ }
7317
+
7318
+ // core/src/sheets/attachSheetScrollDriver.ts
7319
+ var import_theatre_dataverse17 = require("@unseenco/theatre-dataverse");
7320
+ var sheetScrollDrivers = /* @__PURE__ */ new WeakMap();
7321
+ var pageScrollDrivenSequencePositionListeners = /* @__PURE__ */ new Set();
7322
+ function onPageScrollDrivenSequencePosition(listener) {
7323
+ pageScrollDrivenSequencePositionListeners.add(listener);
7324
+ return () => {
7325
+ pageScrollDrivenSequencePositionListeners.delete(listener);
7326
+ };
7327
+ }
7328
+ function notifyPageScrollDrivenSequencePosition(sheet, position) {
7329
+ for (const listener of pageScrollDrivenSequencePositionListeners) {
7330
+ listener(sheet, position);
7331
+ }
7332
+ }
7333
+ function getSheetScrollDriver(sheet) {
7334
+ return sheetScrollDrivers.get(sheet);
7335
+ }
7336
+ function rememberSheetScrollDriver(sheet, driver) {
7337
+ sheetScrollDrivers.set(sheet, driver);
7338
+ }
7339
+ function progressFromScrollPosition(position, max) {
7340
+ if (max <= 0) return 0;
7341
+ if (position <= 0) return 0;
7342
+ if (position >= max - 1) return 1;
7343
+ return position / max;
7344
+ }
7345
+ function getNativeDocumentScrollingElement() {
7346
+ return document.scrollingElement ?? document.documentElement;
7347
+ }
7348
+ function addNativeDocumentScrollListener(handler) {
7349
+ document.addEventListener("scroll", handler, { passive: true, capture: true });
7350
+ return () => document.removeEventListener("scroll", handler, { capture: true });
7351
+ }
7352
+ function createScrollDriverFromElement(getMaxScroll, getScrollPos, setScrollPos, addScrollListener) {
7353
+ let suppressScrollEvents = false;
7354
+ let suppressGeneration = 0;
7355
+ const getProgress = () => {
7356
+ const max = getMaxScroll();
7357
+ return progressFromScrollPosition(getScrollPos(), max);
7358
+ };
7359
+ const setProgress = (progress) => {
7360
+ const max = getMaxScroll();
7361
+ const clamped = Math.max(0, Math.min(1, progress));
7362
+ const gen = ++suppressGeneration;
7363
+ suppressScrollEvents = true;
7364
+ setScrollPos(clamped * max);
7365
+ const release = () => {
7366
+ if (gen === suppressGeneration) {
7367
+ suppressScrollEvents = false;
7368
+ }
7369
+ };
7370
+ requestAnimationFrame(() => requestAnimationFrame(release));
7371
+ };
7372
+ return {
7373
+ getProgress,
7374
+ setProgress,
7375
+ subscribe(onProgressChange) {
7376
+ let rafId = 0;
7377
+ const flush = () => {
7378
+ rafId = 0;
7379
+ if (suppressScrollEvents) return;
7380
+ onProgressChange(getProgress());
7381
+ };
7382
+ const scheduleFlush = () => {
7383
+ if (rafId !== 0) return;
7384
+ rafId = requestAnimationFrame(flush);
7385
+ };
7386
+ const handler = () => scheduleFlush();
7387
+ const removeScroll = addScrollListener(handler);
7388
+ const onResize = () => scheduleFlush();
7389
+ window.addEventListener("resize", onResize);
7390
+ return () => {
7391
+ removeScroll();
7392
+ window.removeEventListener("resize", onResize);
7393
+ if (rafId !== 0) cancelAnimationFrame(rafId);
7394
+ };
7395
+ }
7396
+ };
7397
+ }
7398
+ function createNativeDocumentScrollDriver() {
7399
+ const getMaxScroll = () => {
7400
+ const el = document.documentElement;
7401
+ return Math.max(0, el.scrollHeight - window.innerHeight);
7402
+ };
7403
+ return createScrollDriverFromElement(
7404
+ getMaxScroll,
7405
+ () => window.scrollY,
7406
+ (y2) => window.scrollTo({ top: y2, behavior: "instant" }),
7407
+ addNativeDocumentScrollListener
7408
+ );
7409
+ }
7410
+ function createNativeDocumentHorizontalScrollDriver() {
7411
+ const getMaxScroll = () => {
7412
+ const el = getNativeDocumentScrollingElement();
7413
+ return Math.max(0, el.scrollWidth - el.clientWidth);
7414
+ };
7415
+ const getScrollLeft = () => {
7416
+ const el = getNativeDocumentScrollingElement();
7417
+ return el.scrollLeft;
7418
+ };
7419
+ return createScrollDriverFromElement(
7420
+ getMaxScroll,
7421
+ getScrollLeft,
7422
+ (x2) => {
7423
+ getNativeDocumentScrollingElement().scrollLeft = x2;
7424
+ },
7425
+ addNativeDocumentScrollListener
7426
+ );
7427
+ }
7428
+ function createElementScrollDriver(element) {
7429
+ const getMaxScroll = () => Math.max(0, element.scrollHeight - element.clientHeight);
7430
+ return createScrollDriverFromElement(
7431
+ getMaxScroll,
7432
+ () => element.scrollTop,
7433
+ (y2) => {
7434
+ element.scrollTop = y2;
7435
+ },
7436
+ (handler) => {
7437
+ element.addEventListener("scroll", handler, { passive: true });
7438
+ return () => element.removeEventListener("scroll", handler);
7439
+ }
7440
+ );
7441
+ }
7442
+ function createElementHorizontalScrollDriver(element) {
7443
+ const getMaxScroll = () => Math.max(0, element.scrollWidth - element.clientWidth);
7444
+ return createScrollDriverFromElement(
7445
+ getMaxScroll,
7446
+ () => element.scrollLeft,
7447
+ (x2) => {
7448
+ element.scrollLeft = x2;
7449
+ },
7450
+ (handler) => {
7451
+ element.addEventListener("scroll", handler, { passive: true });
7452
+ return () => element.removeEventListener("scroll", handler);
7453
+ }
7454
+ );
7455
+ }
7456
+ function attachSheetScrollDriver(sheet, driver = createNativeDocumentScrollDriver()) {
7457
+ rememberSheetScrollDriver(sheet, driver);
7458
+ const sequence = sheet.sequence;
7459
+ const syncPositionFromScroll = (progress) => {
7460
+ const length = (0, import_theatre_dataverse17.val)(sequence.pointer.length);
7461
+ if (length <= 0) return;
7462
+ sequence.position = progress * length;
7463
+ };
7464
+ const untapScroll = driver.subscribe((progress) => {
7465
+ syncPositionFromScroll(progress);
7466
+ notifyPageScrollDrivenSequencePosition(sheet, sequence.position);
7467
+ });
7468
+ syncPositionFromScroll(driver.getProgress());
7469
+ return () => {
7470
+ untapScroll();
7471
+ };
7472
+ }
7473
+ function pageScrollProgressFromSequence(sheet) {
7474
+ const length = (0, import_theatre_dataverse17.val)(sheet.sequence.pointer.length);
7475
+ if (length <= 0) return 0;
7476
+ return sheet.sequence.position / length;
7477
+ }
7478
+ function setPageScrollProgress(sheet, progress) {
7479
+ const length = (0, import_theatre_dataverse17.val)(sheet.sequence.pointer.length);
7480
+ if (length <= 0) return;
7481
+ const clamped = Math.max(0, Math.min(1, progress));
7482
+ sheet.sequence.position = clamped * length;
7483
+ }
7484
+ function syncPageScrollToSequencePosition(sheet, driver = getSheetScrollDriver(sheet) ?? createNativeDocumentScrollDriver()) {
7485
+ const progress = pageScrollProgressFromSequence(sheet);
7486
+ driver.setProgress(progress);
7487
+ }
7488
+ function syncNativeDocumentScrollToSequencePosition(sheet) {
7489
+ syncPageScrollToSequencePosition(sheet, createNativeDocumentScrollDriver());
7490
+ }
7491
+
7492
+ // core/src/sheets/Sheet.ts
6949
7493
  var Sheet = class {
6950
7494
  constructor(template, instanceId) {
6951
7495
  this.template = template;
6952
7496
  this.instanceId = instanceId;
6953
- __publicField(this, "_objects", new import_theatre_dataverse15.Atom({}));
7497
+ __publicField(this, "_objects", new import_theatre_dataverse18.Atom({}));
6954
7498
  __publicField(this, "_sequences", {});
6955
- __publicField(this, "_activeSequenceVariant", new import_theatre_dataverse15.Atom(
7499
+ __publicField(this, "_activeSequenceVariant", new import_theatre_dataverse18.Atom(
6956
7500
  DEFAULT_SEQUENCE_VARIANT
6957
7501
  ));
6958
7502
  /**
@@ -6960,7 +7504,12 @@ var Sheet = class {
6960
7504
  * value resolution (preview). User code can still update `_activeSequenceVariant`
6961
7505
  * via `setActiveSequenceVariant()` without affecting the Studio preview.
6962
7506
  */
6963
- __publicField(this, "_studioPreviewVariantOverride", new import_theatre_dataverse15.Atom(void 0));
7507
+ __publicField(this, "_studioPreviewVariantOverride", new import_theatre_dataverse18.Atom(void 0));
7508
+ __publicField(this, "_sequenceMode", new import_theatre_dataverse18.Atom("time"));
7509
+ __publicField(this, "sequenceModeP", this._sequenceMode.pointer);
7510
+ __publicField(this, "_pageScrollDisposer");
7511
+ __publicField(this, "_customPageScrollDriver");
7512
+ __publicField(this, "_gsapBridgeDisposer");
6964
7513
  __publicField(this, "activeSequenceVariantP", this._activeSequenceVariant.pointer);
6965
7514
  __publicField(this, "effectiveActiveSequenceVariantD");
6966
7515
  __publicField(this, "address");
@@ -6977,12 +7526,12 @@ var Sheet = class {
6977
7526
  sheetInstanceId: this.instanceId
6978
7527
  };
6979
7528
  this.publicApi = new TheatreSheet(this);
6980
- this.effectiveActiveSequenceVariantD = (0, import_theatre_dataverse15.prism)(() => {
6981
- const studioOverride = (0, import_theatre_dataverse15.val)(this._studioPreviewVariantOverride.pointer);
7529
+ this.effectiveActiveSequenceVariantD = (0, import_theatre_dataverse18.prism)(() => {
7530
+ const studioOverride = (0, import_theatre_dataverse18.val)(this._studioPreviewVariantOverride.pointer);
6982
7531
  if (studioOverride !== void 0) {
6983
7532
  return studioOverride;
6984
7533
  }
6985
- return (0, import_theatre_dataverse15.val)(this._activeSequenceVariant.pointer);
7534
+ return (0, import_theatre_dataverse18.val)(this._activeSequenceVariant.pointer);
6986
7535
  });
6987
7536
  }
6988
7537
  /**
@@ -7033,6 +7582,7 @@ var Sheet = class {
7033
7582
  * this sheet instance from the project. Persisted state is kept.
7034
7583
  */
7035
7584
  unload() {
7585
+ this.disposeRuntimeIntegrations();
7036
7586
  for (const sequence of Object.values(this._sequences)) {
7037
7587
  sequence.pause();
7038
7588
  }
@@ -7044,10 +7594,13 @@ var Sheet = class {
7044
7594
  this.project._unloadSheetInstance(this);
7045
7595
  }
7046
7596
  getSequence(variant) {
7047
- const variantId = variant ?? (0, import_theatre_dataverse15.val)(this._activeSequenceVariant.pointer);
7597
+ const variantId = variant ?? (0, import_theatre_dataverse18.val)(this._activeSequenceVariant.pointer);
7048
7598
  if (!this._sequences[variantId]) {
7049
- const lengthD = (0, import_theatre_dataverse15.prism)(() => {
7050
- const sheetState = (0, import_theatre_dataverse15.val)(
7599
+ const lengthD = (0, import_theatre_dataverse18.prism)(() => {
7600
+ if ((0, import_theatre_dataverse18.val)(this._sequenceMode.pointer) === "page") {
7601
+ return PAGE_MODE_SEQUENCE_LENGTH;
7602
+ }
7603
+ const sheetState = (0, import_theatre_dataverse18.val)(
7051
7604
  this.project.pointers.historic.sheetsById[this.address.sheetId]
7052
7605
  );
7053
7606
  const unsanitized = getSequenceStateFromSheet(
@@ -7056,8 +7609,11 @@ var Sheet = class {
7056
7609
  )?.length;
7057
7610
  return sanitizeSequenceLength(unsanitized);
7058
7611
  });
7059
- const subUnitsPerUnitD = (0, import_theatre_dataverse15.prism)(() => {
7060
- const sheetState = (0, import_theatre_dataverse15.val)(
7612
+ const subUnitsPerUnitD = (0, import_theatre_dataverse18.prism)(() => {
7613
+ if ((0, import_theatre_dataverse18.val)(this._sequenceMode.pointer) === "page") {
7614
+ return PAGE_MODE_SUB_UNITS_PER_UNIT;
7615
+ }
7616
+ const sheetState = (0, import_theatre_dataverse18.val)(
7061
7617
  this.project.pointers.historic.sheetsById[this.address.sheetId]
7062
7618
  );
7063
7619
  const unsanitized = getSequenceStateFromSheet(
@@ -7109,6 +7665,44 @@ var Sheet = class {
7109
7665
  }
7110
7666
  this._studioPreviewVariantOverride.set(variantId);
7111
7667
  }
7668
+ getSequenceMode() {
7669
+ return this._sequenceMode.get();
7670
+ }
7671
+ setSequenceMode(mode) {
7672
+ if (this._sequenceMode.get() === mode) return;
7673
+ this._sequenceMode.set(mode);
7674
+ this.syncPageScrollDriver();
7675
+ if (this._gsapBridgeDisposer) {
7676
+ this._gsapBridgeDisposer();
7677
+ this._gsapBridgeDisposer = attachGsapSequenceBridge(this.publicApi);
7678
+ }
7679
+ }
7680
+ enableGsapSequenceBridge() {
7681
+ if (this._gsapBridgeDisposer) return;
7682
+ this._gsapBridgeDisposer = attachGsapSequenceBridge(this.publicApi);
7683
+ this.syncPageScrollDriver();
7684
+ }
7685
+ disposeRuntimeIntegrations() {
7686
+ this._pageScrollDisposer?.();
7687
+ this._pageScrollDisposer = void 0;
7688
+ this._gsapBridgeDisposer?.();
7689
+ this._gsapBridgeDisposer = void 0;
7690
+ }
7691
+ syncPageScrollDriver() {
7692
+ this._pageScrollDisposer?.();
7693
+ this._pageScrollDisposer = void 0;
7694
+ if (this.getSequenceMode() === "page") {
7695
+ const driver = this._customPageScrollDriver ?? createNativeDocumentScrollDriver();
7696
+ this._pageScrollDisposer = attachSheetScrollDriver(this.publicApi, driver);
7697
+ }
7698
+ }
7699
+ setPageScrollDriver(driver) {
7700
+ this._customPageScrollDriver = driver;
7701
+ this.syncPageScrollDriver();
7702
+ }
7703
+ getPageScrollDriver() {
7704
+ return this._customPageScrollDriver;
7705
+ }
7112
7706
  };
7113
7707
  var sanitizeSequenceLength = (len) => typeof len === "number" && isFinite(len) && len > 0 ? len : 10;
7114
7708
  var sanitizeSequenceSubUnitsPerUnit = (subs) => typeof subs === "number" && isInteger_default(subs) && subs >= 1 && subs <= 1e3 ? subs : 30;
@@ -7119,13 +7713,13 @@ var SheetTemplate = class {
7119
7713
  this.project = project;
7120
7714
  __publicField(this, "type", "Theatre_SheetTemplate");
7121
7715
  __publicField(this, "address");
7122
- __publicField(this, "_instances", new import_theatre_dataverse16.Atom({}));
7716
+ __publicField(this, "_instances", new import_theatre_dataverse19.Atom({}));
7123
7717
  __publicField(this, "instancesP", this._instances.pointer);
7124
- __publicField(this, "_objectTemplates", new import_theatre_dataverse16.Atom({}));
7718
+ __publicField(this, "_objectTemplates", new import_theatre_dataverse19.Atom({}));
7125
7719
  __publicField(this, "objectTemplatesP", this._objectTemplates.pointer);
7126
7720
  __publicField(this, "_pendingOutlineNamespaces", {});
7127
7721
  __publicField(this, "_sequenceVariants", [DEFAULT_SEQUENCE_VARIANT]);
7128
- __publicField(this, "_visibleInOutline", new import_theatre_dataverse16.Atom(true));
7722
+ __publicField(this, "_visibleInOutline", new import_theatre_dataverse19.Atom(true));
7129
7723
  __publicField(this, "visibleInOutlineP", this._visibleInOutline.pointer);
7130
7724
  this.address = { ...project.address, sheetId };
7131
7725
  }
@@ -7207,8 +7801,8 @@ var SheetTemplate = class {
7207
7801
  };
7208
7802
 
7209
7803
  // core/src/projects/Project.ts
7210
- var import_theatre_dataverse19 = require("@unseenco/theatre-dataverse");
7211
- var import_theatre_dataverse20 = require("@unseenco/theatre-dataverse");
7804
+ var import_theatre_dataverse22 = require("@unseenco/theatre-dataverse");
7805
+ var import_theatre_dataverse23 = require("@unseenco/theatre-dataverse");
7212
7806
 
7213
7807
  // shared/src/utils/delay.ts
7214
7808
  var delay = (dur) => new Promise((resolve) => setTimeout(resolve, dur));
@@ -7646,8 +8240,165 @@ async function initialiseProjectState(studio, project, onDiskState) {
7646
8240
  });
7647
8241
  }
7648
8242
 
8243
+ // shared/src/sheets/pageScrollContext.ts
8244
+ var defaultPageScrollContext = {
8245
+ scroller: null,
8246
+ axis: "vertical"
8247
+ };
8248
+ var activePageScrollContext = defaultPageScrollContext;
8249
+ function setActivePageScrollContext(context) {
8250
+ activePageScrollContext = {
8251
+ scroller: context.scroller,
8252
+ axis: context.axis ?? "vertical"
8253
+ };
8254
+ }
8255
+ function getActivePageScrollContext() {
8256
+ return activePageScrollContext;
8257
+ }
8258
+ function resolvePageScrollAxis(context = defaultPageScrollContext) {
8259
+ return context.axis ?? "vertical";
8260
+ }
8261
+ function resolvePageScrollScroller(st, defaultsScroller) {
8262
+ const surface = st;
8263
+ const fromSt = surface.scroller ?? surface.vars?.scroller;
8264
+ if (fromSt != null) {
8265
+ return fromSt;
8266
+ }
8267
+ if (defaultsScroller !== void 0) {
8268
+ return defaultsScroller;
8269
+ }
8270
+ return null;
8271
+ }
8272
+ function isWindowLike(value) {
8273
+ return typeof Window !== "undefined" && (value === window || value instanceof Window);
8274
+ }
8275
+ function isNativeDocumentScroller(scroller) {
8276
+ if (scroller == null) return true;
8277
+ if (isWindowLike(scroller)) return true;
8278
+ if (typeof document === "undefined") return false;
8279
+ return scroller === document.documentElement || scroller === document.body;
8280
+ }
8281
+ function pageScrollScrollersMatch(a2, b2) {
8282
+ if (a2 === b2) return true;
8283
+ if (isNativeDocumentScroller(a2) && isNativeDocumentScroller(b2)) return true;
8284
+ return false;
8285
+ }
8286
+ function isScrollTriggerHorizontal(st) {
8287
+ const surface = st;
8288
+ return surface.horizontal === true || surface.vars?.horizontal === true;
8289
+ }
8290
+ function isPageScrollTrigger(st, context = defaultPageScrollContext) {
8291
+ const axis = resolvePageScrollAxis(context);
8292
+ const stHorizontal = isScrollTriggerHorizontal(st);
8293
+ if (stHorizontal !== (axis === "horizontal")) {
8294
+ return false;
8295
+ }
8296
+ const stScroller = resolvePageScrollScroller(st, context.scroller);
8297
+ return pageScrollScrollersMatch(stScroller, context.scroller);
8298
+ }
8299
+ function isVerticalPageScrollTrigger(st, context = defaultPageScrollContext) {
8300
+ return isPageScrollTrigger(st, {
8301
+ scroller: context.scroller,
8302
+ axis: "vertical"
8303
+ });
8304
+ }
8305
+
8306
+ // shared/src/gsap/scrollTriggerLayout.ts
8307
+ function getNativeDocumentMaxScroll(axis = "vertical") {
8308
+ if (typeof document === "undefined" || typeof window === "undefined") {
8309
+ return 0;
8310
+ }
8311
+ const el = document.documentElement;
8312
+ if (axis === "horizontal") {
8313
+ const scrolling = document.scrollingElement ?? el;
8314
+ return Math.max(0, scrolling.scrollWidth - scrolling.clientWidth);
8315
+ }
8316
+ return Math.max(0, el.scrollHeight - window.innerHeight);
8317
+ }
8318
+ function getMaxScrollForScroller(scroller, axis = "vertical") {
8319
+ if (typeof document === "undefined" || typeof window === "undefined") {
8320
+ return 0;
8321
+ }
8322
+ if (isNativeDocumentScroller(scroller)) {
8323
+ return getNativeDocumentMaxScroll(axis);
8324
+ }
8325
+ const el = scroller;
8326
+ if (axis === "horizontal") {
8327
+ return Math.max(0, el.scrollWidth - el.clientWidth);
8328
+ }
8329
+ return Math.max(0, el.scrollHeight - el.clientHeight);
8330
+ }
8331
+ function getMaxScrollForPageScrollContext(scroller, axis = "vertical") {
8332
+ return getMaxScrollForScroller(scroller, axis);
8333
+ }
8334
+
8335
+ // shared/src/gsap/domElementHighlightTarget.ts
8336
+ function resolveDomElementHighlightTarget(target) {
8337
+ if (typeof document === "undefined") {
8338
+ return null;
8339
+ }
8340
+ if (target.type === "id") {
8341
+ return document.getElementById(target.id);
8342
+ }
8343
+ try {
8344
+ const match = document.querySelector(target.selector);
8345
+ return match instanceof Element ? match : null;
8346
+ } catch {
8347
+ return null;
8348
+ }
8349
+ }
8350
+
8351
+ // shared/src/sheets/remoteDomElementHighlight.ts
8352
+ var listeners = /* @__PURE__ */ new Set();
8353
+ function setRemoteDomElementHighlight(element) {
8354
+ for (const listener of listeners) {
8355
+ listener(element);
8356
+ }
8357
+ }
8358
+
8359
+ // shared/src/sheets/remotePageScrollMetrics.ts
8360
+ var remoteMetrics;
8361
+ var listeners2 = /* @__PURE__ */ new Set();
8362
+ function setRemotePageScrollMetrics(metrics) {
8363
+ const prev = remoteMetrics;
8364
+ remoteMetrics = metrics;
8365
+ if (prev?.maxScroll !== metrics?.maxScroll || prev?.axis !== metrics?.axis) {
8366
+ for (const listener of listeners2) {
8367
+ listener();
8368
+ }
8369
+ }
8370
+ }
8371
+
7649
8372
  // core/src/internal/RemoteSync.ts
7650
- var import_theatre_dataverse17 = require("@unseenco/theatre-dataverse");
8373
+ var import_theatre_dataverse20 = require("@unseenco/theatre-dataverse");
8374
+
8375
+ // core/src/internal/createDebouncedCallback.ts
8376
+ function createDebouncedCallback(fn2, delayMs) {
8377
+ let timeoutId;
8378
+ const clearPending = () => {
8379
+ if (timeoutId !== void 0) {
8380
+ clearTimeout(timeoutId);
8381
+ timeoutId = void 0;
8382
+ }
8383
+ };
8384
+ return {
8385
+ schedule() {
8386
+ clearPending();
8387
+ timeoutId = setTimeout(() => {
8388
+ timeoutId = void 0;
8389
+ fn2();
8390
+ }, delayMs);
8391
+ },
8392
+ flush() {
8393
+ if (timeoutId === void 0) return;
8394
+ clearPending();
8395
+ fn2();
8396
+ },
8397
+ cancel() {
8398
+ clearPending();
8399
+ }
8400
+ };
8401
+ }
7651
8402
 
7652
8403
  // core/src/internal/remoteEditor.ts
7653
8404
  function isRemoteEditorWindow() {
@@ -7655,6 +8406,10 @@ function isRemoteEditorWindow() {
7655
8406
  }
7656
8407
 
7657
8408
  // core/src/internal/RemoteSync.ts
8409
+ var REMOTE_HISTORIC_SYNC_DEBOUNCE_MS = 100;
8410
+ function shouldSyncPageScrollWhenApplyingTimelineUpdate(isEditor, sequenceMode) {
8411
+ return !isEditor && sequenceMode === "page";
8412
+ }
7658
8413
  var RemoteSync = class {
7659
8414
  constructor(project) {
7660
8415
  this.project = project;
@@ -7665,34 +8420,37 @@ var RemoteSync = class {
7665
8420
  __publicField(this, "objectUnsubs", /* @__PURE__ */ new Map());
7666
8421
  __publicField(this, "studio");
7667
8422
  __publicField(this, "activeSheet");
8423
+ __publicField(this, "historicSyncDebounce");
8424
+ __publicField(this, "lastBroadcastHistoricFingerprint");
8425
+ __publicField(this, "historicSyncUnsubs", []);
8426
+ __publicField(this, "remoteEditorActive", false);
8427
+ __publicField(this, "suppressTimelineBroadcast", false);
8428
+ __publicField(this, "listenerTimelineUnsub");
8429
+ __publicField(this, "listenerMetricsUnsubs", []);
8430
+ __publicField(this, "broadcastPageScrollMetrics");
7668
8431
  if (typeof BroadcastChannel === "undefined") return;
7669
8432
  this.channel = new BroadcastChannel(
7670
8433
  "theatre-remote:".concat(project.address.projectId)
7671
8434
  );
8435
+ this.channel.onmessage = (event) => {
8436
+ this._handleIncoming(event.data);
8437
+ };
7672
8438
  if (!this.isEditor) {
7673
- this.channel.onmessage = (event) => {
7674
- this._handleIncoming(event.data);
7675
- };
8439
+ this.listenerTimelineUnsub = onPageScrollDrivenSequencePosition(
8440
+ (sheet, position) => {
8441
+ this._broadcastTimelineFromListener(sheet, position);
8442
+ }
8443
+ );
7676
8444
  } else {
7677
8445
  const channel = this.channel;
7678
8446
  window.addEventListener("pagehide", () => {
7679
- const data = {};
7680
- if (this.studio) {
7681
- const projectId = this.project.address.projectId;
7682
- const historic = (0, import_theatre_dataverse17.val)(
7683
- this.studio.atomP.historic.coreByProject[projectId]
7684
- );
7685
- const ahistoric = (0, import_theatre_dataverse17.val)(
7686
- this.studio.atomP.ahistoric.coreByProject[projectId]
7687
- );
7688
- if (historic) {
7689
- data.historic = JSON.parse(JSON.stringify(historic));
7690
- if (ahistoric) {
7691
- data.ahistoric = JSON.parse(JSON.stringify(ahistoric));
7692
- }
7693
- }
8447
+ this.historicSyncDebounce?.flush();
8448
+ const data = this._readHistoricSnapshotFromStudio();
8449
+ if (data && this.lastBroadcastHistoricFingerprint === fingerprintHistoricSnapshot(data)) {
8450
+ channel.postMessage({ event: "disconnect", data: {} });
8451
+ return;
7694
8452
  }
7695
- channel.postMessage({ event: "disconnect", data });
8453
+ channel.postMessage({ event: "disconnect", data: data ?? {} });
7696
8454
  });
7697
8455
  }
7698
8456
  }
@@ -7743,8 +8501,13 @@ var RemoteSync = class {
7743
8501
  }
7744
8502
  attachStudio(studio) {
7745
8503
  this.studio = studio;
7746
- if (!this.isEditor || !this.channel) return;
8504
+ if (!this.channel) return;
8505
+ if (!this.isEditor) {
8506
+ this._attachListenerPageScrollMetricsBroadcast();
8507
+ return;
8508
+ }
7747
8509
  const channel = this.channel;
8510
+ channel.postMessage({ event: "editorHello", data: {} });
7748
8511
  const projectId = this.project.address.projectId;
7749
8512
  studio.publicApi.onSelectionChange((selection) => {
7750
8513
  for (const item of selection) {
@@ -7769,7 +8532,7 @@ var RemoteSync = class {
7769
8532
  let lastPosition;
7770
8533
  const ticker = getCoreTicker();
7771
8534
  const pollTimelinePosition = () => {
7772
- if (this.activeSheet) {
8535
+ if (this.activeSheet && !this.suppressTimelineBroadcast) {
7773
8536
  const position = this.activeSheet.publicApi.sequence.position;
7774
8537
  if (position !== lastPosition) {
7775
8538
  lastPosition = position;
@@ -7783,9 +8546,117 @@ var RemoteSync = class {
7783
8546
  ticker.onNextTick(pollTimelinePosition);
7784
8547
  };
7785
8548
  ticker.onNextTick(pollTimelinePosition);
8549
+ this.historicSyncDebounce = createDebouncedCallback(() => {
8550
+ this._broadcastHistoricSnapshot();
8551
+ }, REMOTE_HISTORIC_SYNC_DEBOUNCE_MS);
8552
+ const scheduleHistoricSync = () => {
8553
+ this.historicSyncDebounce?.schedule();
8554
+ };
8555
+ void studio.initialized.then(() => {
8556
+ this.historicSyncUnsubs.push(
8557
+ (0, import_theatre_dataverse20.pointerToPrism)(studio.atomP.historic.coreByProject[projectId]).onChange(
8558
+ studio.ticker,
8559
+ scheduleHistoricSync,
8560
+ true
8561
+ ),
8562
+ (0, import_theatre_dataverse20.pointerToPrism)(
8563
+ studio.atomP.ahistoric.coreByProject[projectId]
8564
+ ).onChange(studio.ticker, scheduleHistoricSync, true)
8565
+ );
8566
+ });
8567
+ }
8568
+ _readHistoricSnapshotFromStudio() {
8569
+ if (!this.studio) return void 0;
8570
+ const projectId = this.project.address.projectId;
8571
+ const historic = (0, import_theatre_dataverse20.val)(
8572
+ this.studio.atomP.historic.coreByProject[projectId]
8573
+ );
8574
+ if (!historic) return void 0;
8575
+ const data = {
8576
+ historic: JSON.parse(JSON.stringify(historic))
8577
+ };
8578
+ const ahistoric = (0, import_theatre_dataverse20.val)(
8579
+ this.studio.atomP.ahistoric.coreByProject[projectId]
8580
+ );
8581
+ if (ahistoric) {
8582
+ data.ahistoric = JSON.parse(JSON.stringify(ahistoric));
8583
+ }
8584
+ return data;
8585
+ }
8586
+ _broadcastHistoricSnapshot(options) {
8587
+ if (!this.channel) return;
8588
+ const data = this._readHistoricSnapshotFromStudio();
8589
+ if (!data) return;
8590
+ const fingerprint = fingerprintHistoricSnapshot(data);
8591
+ if (!options?.force && fingerprint === this.lastBroadcastHistoricFingerprint) {
8592
+ return;
8593
+ }
8594
+ this.lastBroadcastHistoricFingerprint = fingerprint;
8595
+ const message = { event: "updateHistoric", data };
8596
+ this.channel.postMessage(message);
8597
+ }
8598
+ _applyHistoricSnapshot(historic, ahistoric) {
8599
+ if (!this.studio) return;
8600
+ const projectId = this.project.address.projectId;
8601
+ this.studio.transaction(({ drafts }) => {
8602
+ drafts.historic.coreByProject[projectId] = historic;
8603
+ if (ahistoric) {
8604
+ drafts.ahistoric.coreByProject[projectId] = ahistoric;
8605
+ }
8606
+ drafts.ephemeral.coreByProject[projectId].loadingState = {
8607
+ type: "loaded"
8608
+ };
8609
+ });
8610
+ }
8611
+ _broadcastTimelineFromListener(sheet, position) {
8612
+ if (this.isEditor || !this.channel || !this.remoteEditorActive || this.suppressTimelineBroadcast) {
8613
+ return;
8614
+ }
8615
+ const registered = this.sheets.get(sheet.address.sheetId);
8616
+ if (!registered || registered.getSequenceMode() !== "page") return;
8617
+ const message = {
8618
+ event: "updateTimeline",
8619
+ data: { sheet: sheet.address.sheetId, position }
8620
+ };
8621
+ this.channel.postMessage(message);
8622
+ }
8623
+ _postPageScrollMetrics() {
8624
+ if (!this.remoteEditorActive || !this.channel) return;
8625
+ const ctx = getActivePageScrollContext();
8626
+ const axis = resolvePageScrollAxis(ctx);
8627
+ const maxScroll = getMaxScrollForPageScrollContext(ctx.scroller, axis);
8628
+ const message = {
8629
+ event: "pageScrollMetrics",
8630
+ data: { maxScroll, axis }
8631
+ };
8632
+ this.channel.postMessage(message);
8633
+ }
8634
+ _attachListenerPageScrollMetricsBroadcast() {
8635
+ if (this.isEditor || !this.channel) return;
8636
+ const broadcast = () => this._postPageScrollMetrics();
8637
+ this.broadcastPageScrollMetrics = broadcast;
8638
+ const onScroll = () => broadcast();
8639
+ document.addEventListener("scroll", onScroll, { passive: true, capture: true });
8640
+ const onResize = () => broadcast();
8641
+ window.addEventListener("resize", onResize);
8642
+ const ScrollTrigger = globalThis.ScrollTrigger;
8643
+ ScrollTrigger?.addEventListener?.("refresh", broadcast);
8644
+ broadcast();
8645
+ this.listenerMetricsUnsubs.push(() => {
8646
+ document.removeEventListener("scroll", onScroll, { capture: true });
8647
+ window.removeEventListener("resize", onResize);
8648
+ ScrollTrigger?.removeEventListener?.("refresh", broadcast);
8649
+ });
7786
8650
  }
7787
8651
  _handleIncoming(msg) {
7788
8652
  switch (msg.event) {
8653
+ case "editorHello": {
8654
+ if (this.isEditor) break;
8655
+ this.remoteEditorActive = true;
8656
+ this.broadcastPageScrollMetrics?.();
8657
+ this._broadcastHistoricSnapshot({ force: true });
8658
+ break;
8659
+ }
7789
8660
  case "setSheet": {
7790
8661
  const sheet = this.sheets.get(msg.data.sheet);
7791
8662
  if (sheet && this.studio) {
@@ -7810,32 +8681,67 @@ var RemoteSync = class {
7810
8681
  const sheet = this.sheets.get(msg.data.sheet);
7811
8682
  if (sheet) {
7812
8683
  this.activeSheet = sheet;
8684
+ this.suppressTimelineBroadcast = true;
7813
8685
  sheet.publicApi.sequence.position = msg.data.position;
8686
+ if (shouldSyncPageScrollWhenApplyingTimelineUpdate(
8687
+ this.isEditor,
8688
+ sheet.getSequenceMode()
8689
+ )) {
8690
+ syncPageScrollToSequencePosition(sheet.publicApi);
8691
+ }
8692
+ requestAnimationFrame(() => {
8693
+ this.suppressTimelineBroadcast = false;
8694
+ });
8695
+ }
8696
+ break;
8697
+ }
8698
+ case "pageScrollMetrics": {
8699
+ if (!this.isEditor) break;
8700
+ const { maxScroll, axis } = msg.data;
8701
+ setRemotePageScrollMetrics({ maxScroll, axis });
8702
+ break;
8703
+ }
8704
+ case "highlightDomTarget": {
8705
+ if (this.isEditor || !this.remoteEditorActive) break;
8706
+ const target = msg.data.target;
8707
+ const element = resolveDomElementHighlightTarget(target);
8708
+ setRemoteDomElementHighlight(element);
8709
+ break;
8710
+ }
8711
+ case "clearDomHighlight": {
8712
+ if (this.isEditor || !this.remoteEditorActive) break;
8713
+ setRemoteDomElementHighlight(null);
8714
+ break;
8715
+ }
8716
+ case "updateHistoric": {
8717
+ const { historic, ahistoric } = msg.data;
8718
+ if (historic) {
8719
+ this._applyHistoricSnapshot(historic, ahistoric);
7814
8720
  }
7815
8721
  break;
7816
8722
  }
7817
8723
  case "disconnect": {
7818
8724
  const { historic, ahistoric } = msg.data;
7819
- if (historic && this.studio) {
7820
- const projectId = this.project.address.projectId;
7821
- this.studio.transaction(({ drafts }) => {
7822
- drafts.historic.coreByProject[projectId] = historic;
7823
- if (ahistoric) {
7824
- drafts.ahistoric.coreByProject[projectId] = ahistoric;
7825
- }
7826
- drafts.ephemeral.coreByProject[projectId].loadingState = {
7827
- type: "loaded"
7828
- };
7829
- });
8725
+ if (historic) {
8726
+ this._applyHistoricSnapshot(historic, ahistoric);
7830
8727
  }
7831
8728
  for (const obj of this.objects.values()) {
7832
8729
  obj.setRemoteOverride({});
7833
8730
  }
8731
+ if (!this.isEditor) {
8732
+ this.remoteEditorActive = false;
8733
+ setRemoteDomElementHighlight(null);
8734
+ } else {
8735
+ setRemotePageScrollMetrics(void 0);
8736
+ }
7834
8737
  break;
7835
8738
  }
7836
8739
  }
7837
8740
  }
7838
8741
  };
8742
+ function fingerprintHistoricSnapshot(data) {
8743
+ return JSON.stringify(data);
8744
+ }
7839
8745
 
7840
8746
  // core/src/_coreLogger.ts
7841
8747
  function noop2() {
@@ -7862,7 +8768,7 @@ function _coreLogger(config) {
7862
8768
  }
7863
8769
 
7864
8770
  // shared/src/utils/assets.ts
7865
- var import_theatre_dataverse18 = require("@unseenco/theatre-dataverse");
8771
+ var import_theatre_dataverse21 = require("@unseenco/theatre-dataverse");
7866
8772
 
7867
8773
  // shared/src/utils/forEachDeep.ts
7868
8774
  function forEachPropDeep(m, fn2, startingPath = []) {
@@ -7932,7 +8838,7 @@ var Project = class {
7932
8838
  __publicField(this, "_studioReadyDeferred");
7933
8839
  __publicField(this, "_assetStorageReadyDeferred");
7934
8840
  __publicField(this, "_readyPromise");
7935
- __publicField(this, "_sheetTemplates", new import_theatre_dataverse20.Atom({}));
8841
+ __publicField(this, "_sheetTemplates", new import_theatre_dataverse23.Atom({}));
7936
8842
  __publicField(this, "sheetTemplatesP", this._sheetTemplates.pointer);
7937
8843
  __publicField(this, "_studio");
7938
8844
  __publicField(this, "_onDiskStateAtom");
@@ -7945,7 +8851,7 @@ var Project = class {
7945
8851
  this._logger.traceDev("creating project");
7946
8852
  this.address = { projectId: id };
7947
8853
  this._remoteSync = new RemoteSync(this);
7948
- const onDiskStateAtom = new import_theatre_dataverse20.Atom({
8854
+ const onDiskStateAtom = new import_theatre_dataverse23.Atom({
7949
8855
  ahistoric: {
7950
8856
  ahistoricStuff: ""
7951
8857
  },
@@ -7971,9 +8877,9 @@ var Project = class {
7971
8877
  }
7972
8878
  };
7973
8879
  this._pointerProxies = {
7974
- historic: new import_theatre_dataverse19.PointerProxy(onDiskStateAtom.pointer.historic),
7975
- ahistoric: new import_theatre_dataverse19.PointerProxy(onDiskStateAtom.pointer.ahistoric),
7976
- ephemeral: new import_theatre_dataverse19.PointerProxy(onDiskStateAtom.pointer.ephemeral)
8880
+ historic: new import_theatre_dataverse22.PointerProxy(onDiskStateAtom.pointer.historic),
8881
+ ahistoric: new import_theatre_dataverse22.PointerProxy(onDiskStateAtom.pointer.ahistoric),
8882
+ ephemeral: new import_theatre_dataverse22.PointerProxy(onDiskStateAtom.pointer.ephemeral)
7977
8883
  };
7978
8884
  this.pointers = {
7979
8885
  historic: this._pointerProxies.historic.pointer,
@@ -8000,14 +8906,14 @@ var Project = class {
8000
8906
  if (typeof window === "undefined") {
8001
8907
  if (process.env.NODE_ENV === "production") {
8002
8908
  console.error(
8003
- 'Argument config.state in Theatre.getProject("'.concat(id, '", config) is empty. ') + "You can safely ignore this message if you're developing a Next.js/Remix project in development mode. But if you are shipping to your end-users, then you need to set config.state, otherwise your project's state will be empty and nothing will animate. Learn more at https://www.theatrejs.com/docs/latest/manual/projects#state"
8909
+ 'Argument config.state in Theatre.getProject("'.concat(id, '", config) is empty. ') + "You can safely ignore this message if you're developing a Next.js/Remix project in development mode. But if you are shipping to your end-users, then you need to set config.state, otherwise your project's state will be empty and nothing will animate. Learn more at https://unseen-theatre.netlify.app/docs/guide/manual/projects#state"
8004
8910
  );
8005
8911
  }
8006
8912
  } else {
8007
8913
  setTimeout(() => {
8008
8914
  if (!this._studio) {
8009
8915
  throw new Error(
8010
- 'Argument config.state in Theatre.getProject("'.concat(id, '", config) is empty. This is fine ') + "while you are using @unseenco/theatre-core along with @unseenco/theatre-studio. But since @unseenco/theatre-studio " + 'is not loaded, the state of project "'.concat(id, '" will be empty.\n\n') + "To fix this, you need to add @unseenco/theatre-studio into the bundle and export the project's state. Learn how to do that at https://www.theatrejs.com/docs/latest/manual/projects#state\n"
8916
+ 'Argument config.state in Theatre.getProject("'.concat(id, '", config) is empty. This is fine ') + "while you are using @unseenco/theatre-core along with @unseenco/theatre-studio. But since @unseenco/theatre-studio " + 'is not loaded, the state of project "'.concat(id, '" will be empty.\n\n') + "To fix this, you need to add @unseenco/theatre-studio into the bundle and export the project's state. Learn how to do that at https://unseen-theatre.netlify.app/docs/guide/manual/projects#state\n"
8011
8917
  );
8012
8918
  }
8013
8919
  }, 1e3);
@@ -8071,6 +8977,7 @@ var Project = class {
8071
8977
  template.setVisibleInOutline(opts.visible);
8072
8978
  }
8073
8979
  const sheet = template.getInstance(instanceId);
8980
+ applySheetRuntimeOptions(sheet, opts);
8074
8981
  this._remoteSync.registerSheet(sheet);
8075
8982
  return sheet;
8076
8983
  }
@@ -8351,13 +9258,13 @@ var Project = class {
8351
9258
  };
8352
9259
 
8353
9260
  // shared/src/utils/sanitizers.ts
8354
- var _validateSym = (val11, thingy, range) => {
8355
- if (typeof val11 !== "string") {
8356
- return "".concat(thingy, " must be a string. ").concat(userReadableTypeOfValue_default(val11), " given.");
8357
- } else if (val11.trim().length !== val11.length) {
8358
- return "".concat(thingy, " must not have leading or trailing spaces. '").concat(val11, "' given.");
8359
- } else if (val11.length < range[0] || val11.length > range[1]) {
8360
- return "".concat(thingy, " must have between ").concat(range[0], " and ").concat(range[1], " characters. '").concat(val11, "' given.");
9261
+ var _validateSym = (val13, thingy, range) => {
9262
+ if (typeof val13 !== "string") {
9263
+ return "".concat(thingy, " must be a string. ").concat(userReadableTypeOfValue_default(val13), " given.");
9264
+ } else if (val13.trim().length !== val13.length) {
9265
+ return "".concat(thingy, " must not have leading or trailing spaces. '").concat(val13, "' given.");
9266
+ } else if (val13.length < range[0] || val13.length > range[1]) {
9267
+ return "".concat(thingy, " must have between ").concat(range[0], " and ").concat(range[1], " characters. '").concat(val13, "' given.");
8361
9268
  }
8362
9269
  };
8363
9270
  var validateName = (name, thingy, shouldThrow = false) => {
@@ -8473,8 +9380,62 @@ var TheatreProject = class {
8473
9380
 
8474
9381
  // core/src/coreExports.ts
8475
9382
  var import_fast_deep_equal3 = __toESM(require_fast_deep_equal());
8476
- var import_theatre_dataverse21 = require("@unseenco/theatre-dataverse");
8477
- var import_theatre_dataverse22 = require("@unseenco/theatre-dataverse");
9383
+ var import_theatre_dataverse24 = require("@unseenco/theatre-dataverse");
9384
+ var import_theatre_dataverse25 = require("@unseenco/theatre-dataverse");
9385
+
9386
+ // core/src/sheets/theatrePageScroll.ts
9387
+ var pageScrollConfig = {};
9388
+ function buildPageScrollContextFromConfig() {
9389
+ return {
9390
+ scroller: pageScrollConfig.scroller ?? defaultPageScrollContext.scroller,
9391
+ axis: pageScrollConfig.axis ?? defaultPageScrollContext.axis
9392
+ };
9393
+ }
9394
+ function configureTheatrePageScroll(config) {
9395
+ const prev = pageScrollConfig;
9396
+ pageScrollConfig = {
9397
+ scroller: config.scroller ?? prev.scroller,
9398
+ axis: config.axis ?? prev.axis
9399
+ };
9400
+ if (config.scroller !== void 0 || config.axis !== void 0) {
9401
+ setActivePageScrollContext(buildPageScrollContextFromConfig());
9402
+ }
9403
+ return {
9404
+ reset() {
9405
+ pageScrollConfig = prev;
9406
+ setActivePageScrollContext(
9407
+ prev.scroller !== void 0 || prev.axis !== void 0 ? {
9408
+ scroller: prev.scroller ?? defaultPageScrollContext.scroller,
9409
+ axis: prev.axis ?? defaultPageScrollContext.axis
9410
+ } : defaultPageScrollContext
9411
+ );
9412
+ }
9413
+ };
9414
+ }
9415
+ function getTheatrePageScrollConfig() {
9416
+ return pageScrollConfig;
9417
+ }
9418
+ function getTheatrePageScrollContext() {
9419
+ const ctx = buildPageScrollContextFromConfig();
9420
+ setActivePageScrollContext(ctx);
9421
+ return ctx;
9422
+ }
9423
+ function createDefaultPageScrollDriver(scroller = getTheatrePageScrollContext().scroller, axis = resolvePageScrollAxis(getTheatrePageScrollContext())) {
9424
+ if (typeof document !== "undefined" && scroller != null && !isNativeDocumentScroller(scroller) && scroller instanceof HTMLElement) {
9425
+ return axis === "horizontal" ? createElementHorizontalScrollDriver(scroller) : createElementScrollDriver(scroller);
9426
+ }
9427
+ return axis === "horizontal" ? createNativeDocumentHorizontalScrollDriver() : createNativeDocumentScrollDriver();
9428
+ }
9429
+ function attachTheatrePageScroll(sheet, options = {}) {
9430
+ const ctx = getTheatrePageScrollContext();
9431
+ const driver = options.driver ?? createDefaultPageScrollDriver(ctx.scroller, resolvePageScrollAxis(ctx));
9432
+ sheet.setPageScrollDriver(driver);
9433
+ return () => {
9434
+ sheet.setPageScrollDriver(void 0);
9435
+ };
9436
+ }
9437
+
9438
+ // core/src/coreExports.ts
8478
9439
  function getProject(id, config = {}) {
8479
9440
  const existingProject = projectsSingleton_default.get(id);
8480
9441
  if (existingProject) {
@@ -8515,7 +9476,7 @@ var shallowValidateOnDiskState = (projectId, s2) => {
8515
9476
  throw new InvalidArgumentError(
8516
9477
  "Error validating conf.state in Theatre.getProject(".concat(JSON.stringify(
8517
9478
  projectId
8518
- ), ", conf). The state seems to be formatted in a way that is unreadable to Theatre.js. Read more at https://www.theatrejs.com/docs/latest/manual/projects#state")
9479
+ ), ", conf). The state seems to be formatted in a way that is unreadable to Theatre.js. Read more at https://unseen-theatre.netlify.app/docs/guide/manual/projects#state")
8519
9480
  );
8520
9481
  }
8521
9482
  };
@@ -8554,10 +9515,10 @@ var validateProjectIdOrThrow = (value) => {
8554
9515
  };
8555
9516
  function onChange(pointer3, callback, rafDriver) {
8556
9517
  const ticker = rafDriver ? privateAPI(rafDriver).ticker : getCoreTicker();
8557
- if ((0, import_theatre_dataverse21.isPointer)(pointer3)) {
8558
- const pr = (0, import_theatre_dataverse22.pointerToPrism)(pointer3);
9518
+ if ((0, import_theatre_dataverse24.isPointer)(pointer3)) {
9519
+ const pr = (0, import_theatre_dataverse25.pointerToPrism)(pointer3);
8559
9520
  return pr.onChange(ticker, callback, true);
8560
- } else if ((0, import_theatre_dataverse22.isPrism)(pointer3)) {
9521
+ } else if ((0, import_theatre_dataverse25.isPrism)(pointer3)) {
8561
9522
  return pointer3.onChange(ticker, callback, true);
8562
9523
  } else {
8563
9524
  throw new Error(
@@ -8565,9 +9526,9 @@ function onChange(pointer3, callback, rafDriver) {
8565
9526
  );
8566
9527
  }
8567
9528
  }
8568
- function val10(pointer3) {
8569
- if ((0, import_theatre_dataverse21.isPointer)(pointer3)) {
8570
- return (0, import_theatre_dataverse22.pointerToPrism)(pointer3).getValue();
9529
+ function val12(pointer3) {
9530
+ if ((0, import_theatre_dataverse24.isPointer)(pointer3)) {
9531
+ return (0, import_theatre_dataverse25.pointerToPrism)(pointer3).getValue();
8571
9532
  } else {
8572
9533
  throw new Error("Called val(p) where p is not a pointer.");
8573
9534
  }
@@ -8582,7 +9543,7 @@ var CoreBundle = class {
8582
9543
  return "Theatre_CoreBundle";
8583
9544
  }
8584
9545
  get version() {
8585
- return "0.4.2";
9546
+ return "0.5.0";
8586
9547
  }
8587
9548
  getBitsForStudio(studio, callback) {
8588
9549
  if (this._studio) {