@norskvideo/norsk-studio-built-ins 1.27.0-2026-01-14-d7f304fc → 1.27.0-2026-01-16-f39c004b

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/client/info.js CHANGED
@@ -74503,7 +74503,7 @@ var PRESETS = {
74503
74503
  }))
74504
74504
  }
74505
74505
  }),
74506
- quarters: (sources, _config, res) => {
74506
+ quarters: (sources, _config, res, transitionContext) => {
74507
74507
  const half_w = res.width / 2;
74508
74508
  const half_h = res.height / 2;
74509
74509
  const quarters = sources.slice(0, 4);
@@ -74563,22 +74563,78 @@ var PRESETS = {
74563
74563
  ]
74564
74564
  },
74565
74565
  to: {
74566
- fullscreen: [
74567
- // Reverse: move all to center, fade out all but first
74568
- {
74569
- durationMs: 500,
74570
- layout: {
74571
- layers: quarters.map((s, i) => ({
74572
- sourceName: s,
74573
- zIndex: i,
74574
- opacity: i === 0 ? 1 : 0,
74575
- id: s,
74576
- sourceRect: void 0,
74577
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
74578
- }))
74579
- }
74566
+ fullscreen: (() => {
74567
+ const targetSources = transitionContext?.targetSources ?? [];
74568
+ const targetSource = targetSources[0];
74569
+ const targetInQuarters = targetSource && quarters.includes(targetSource);
74570
+ if (targetInQuarters) {
74571
+ return [
74572
+ {
74573
+ durationMs: 500,
74574
+ layout: {
74575
+ layers: quarters.map((s, i) => ({
74576
+ sourceName: s,
74577
+ zIndex: i,
74578
+ opacity: s === targetSource ? 1 : 0,
74579
+ id: s,
74580
+ sourceRect: void 0,
74581
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
74582
+ }))
74583
+ }
74584
+ },
74585
+ // Final step: target source only
74586
+ {
74587
+ durationMs: 0,
74588
+ layout: {
74589
+ layers: [{
74590
+ sourceName: targetSource,
74591
+ zIndex: 0,
74592
+ opacity: 1,
74593
+ id: targetSource,
74594
+ sourceRect: void 0,
74595
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
74596
+ }]
74597
+ }
74598
+ }
74599
+ ];
74600
+ } else {
74601
+ return [
74602
+ // Step 1: Fade out all quarters
74603
+ {
74604
+ durationMs: 250,
74605
+ layout: {
74606
+ layers: quarters.map((s, i) => ({
74607
+ sourceName: s,
74608
+ zIndex: i,
74609
+ opacity: 0,
74610
+ id: s,
74611
+ sourceRect: void 0,
74612
+ destRect: {
74613
+ x: i % 2 * half_w,
74614
+ y: Math.floor(i / 2) * half_h,
74615
+ width: half_w,
74616
+ height: half_h
74617
+ }
74618
+ }))
74619
+ }
74620
+ },
74621
+ // Step 2: Show target source (if available)
74622
+ ...targetSource ? [{
74623
+ durationMs: 250,
74624
+ layout: {
74625
+ layers: [{
74626
+ sourceName: targetSource,
74627
+ zIndex: 0,
74628
+ opacity: 1,
74629
+ id: targetSource,
74630
+ sourceRect: void 0,
74631
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
74632
+ }]
74633
+ }
74634
+ }] : []
74635
+ ];
74580
74636
  }
74581
- ],
74637
+ })(),
74582
74638
  "mosaic-9": [
74583
74639
  // Quarters → Mosaic-9: move 4 sources to their 3×3 grid positions
74584
74640
  {
@@ -74691,8 +74747,9 @@ var PRESETS = {
74691
74747
  } : void 0
74692
74748
  };
74693
74749
  },
74694
- pip: (sources, config, res) => {
74750
+ pip: (sources, config, res, transitionContext) => {
74695
74751
  const [mainSource, pipSource] = sources;
74752
+ const pipSources = [mainSource, pipSource].filter(Boolean);
74696
74753
  const pipConfig = config;
74697
74754
  const corner = pipConfig?.corner ?? "bottom-right";
74698
74755
  const pipWidth = pipConfig?.width ?? Math.round(res.width * 0.2);
@@ -74826,37 +74883,91 @@ var PRESETS = {
74826
74883
  ]
74827
74884
  },
74828
74885
  to: {
74829
- fullscreen: [
74830
- // Reverse: move to center and fade out
74831
- {
74832
- durationMs: 500,
74833
- layout: {
74834
- layers: [
74835
- {
74836
- sourceName: mainSource,
74837
- zIndex: 0,
74838
- opacity: 1,
74839
- id: mainSource,
74840
- sourceRect: void 0,
74841
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
74842
- },
74843
- {
74844
- sourceName: pipSource,
74845
- zIndex: 1,
74846
- opacity: 0,
74847
- id: pipSource,
74848
- sourceRect: void 0,
74849
- destRect: {
74850
- x: res.width / 2 - pipWidth / 2,
74851
- y: res.height / 2 - pipHeight / 2,
74852
- width: pipWidth,
74853
- height: pipHeight
74854
- }
74886
+ fullscreen: (() => {
74887
+ const targetSources = transitionContext?.targetSources ?? [];
74888
+ const targetSource = targetSources[0];
74889
+ const targetInPip = targetSource && pipSources.includes(targetSource);
74890
+ if (targetInPip) {
74891
+ return [
74892
+ {
74893
+ durationMs: 500,
74894
+ layout: {
74895
+ layers: [
74896
+ {
74897
+ sourceName: mainSource,
74898
+ zIndex: 0,
74899
+ opacity: mainSource === targetSource ? 1 : 0,
74900
+ id: mainSource,
74901
+ sourceRect: void 0,
74902
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
74903
+ },
74904
+ ...pipSource ? [{
74905
+ sourceName: pipSource,
74906
+ zIndex: 1,
74907
+ opacity: pipSource === targetSource ? 1 : 0,
74908
+ id: pipSource,
74909
+ sourceRect: void 0,
74910
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
74911
+ }] : []
74912
+ ]
74855
74913
  }
74856
- ]
74857
- }
74914
+ },
74915
+ // Final step: target source only
74916
+ {
74917
+ durationMs: 0,
74918
+ layout: {
74919
+ layers: [{
74920
+ sourceName: targetSource,
74921
+ zIndex: 0,
74922
+ opacity: 1,
74923
+ id: targetSource,
74924
+ sourceRect: void 0,
74925
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
74926
+ }]
74927
+ }
74928
+ }
74929
+ ];
74930
+ } else {
74931
+ return [
74932
+ {
74933
+ durationMs: 250,
74934
+ layout: {
74935
+ layers: [
74936
+ {
74937
+ sourceName: mainSource,
74938
+ zIndex: 0,
74939
+ opacity: 0,
74940
+ id: mainSource,
74941
+ sourceRect: void 0,
74942
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
74943
+ },
74944
+ ...pipSource ? [{
74945
+ sourceName: pipSource,
74946
+ zIndex: 1,
74947
+ opacity: 0,
74948
+ id: pipSource,
74949
+ sourceRect: void 0,
74950
+ destRect: { x: pipX, y: pipY, width: pipWidth, height: pipHeight }
74951
+ }] : []
74952
+ ]
74953
+ }
74954
+ },
74955
+ ...targetSource ? [{
74956
+ durationMs: 250,
74957
+ layout: {
74958
+ layers: [{
74959
+ sourceName: targetSource,
74960
+ zIndex: 0,
74961
+ opacity: 1,
74962
+ id: targetSource,
74963
+ sourceRect: void 0,
74964
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
74965
+ }]
74966
+ }
74967
+ }] : []
74968
+ ];
74858
74969
  }
74859
- ],
74970
+ })(),
74860
74971
  "side-by-side": [
74861
74972
  // PiP → Side-by-side: background compresses to left, overlay expands to right
74862
74973
  {
@@ -74944,8 +75055,9 @@ var PRESETS = {
74944
75055
  } : void 0
74945
75056
  };
74946
75057
  },
74947
- "lower-third": (sources, config, res) => {
75058
+ "lower-third": (sources, config, res, transitionContext) => {
74948
75059
  const [mainSource, lowerThirdSource] = sources;
75060
+ const lowerThirdSources = [mainSource, lowerThirdSource].filter(Boolean);
74949
75061
  const lowerThirdConfig = config;
74950
75062
  const alignment = lowerThirdConfig?.alignment ?? "left";
74951
75063
  const lowerThirdWidth = lowerThirdConfig?.width ?? Math.round(res.width * 0.3);
@@ -75039,32 +75151,91 @@ var PRESETS = {
75039
75151
  ]
75040
75152
  },
75041
75153
  to: {
75042
- fullscreen: [
75043
- // Reverse: slide down off screen
75044
- {
75045
- durationMs: 500,
75046
- layout: {
75047
- layers: [
75048
- {
75049
- sourceName: mainSource,
75050
- zIndex: 0,
75051
- opacity: 1,
75052
- id: mainSource,
75053
- sourceRect: void 0,
75054
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
75055
- },
75056
- {
75057
- sourceName: lowerThirdSource,
75058
- zIndex: 1,
75059
- opacity: 1,
75060
- id: lowerThirdSource,
75061
- sourceRect: void 0,
75062
- destRect: { x: lowerThirdX, y: res.height, width: lowerThirdWidth, height: lowerThirdHeight }
75154
+ fullscreen: (() => {
75155
+ const targetSources = transitionContext?.targetSources ?? [];
75156
+ const targetSource = targetSources[0];
75157
+ const targetInLowerThird = targetSource && lowerThirdSources.includes(targetSource);
75158
+ if (targetInLowerThird) {
75159
+ return [
75160
+ {
75161
+ durationMs: 500,
75162
+ layout: {
75163
+ layers: [
75164
+ {
75165
+ sourceName: mainSource,
75166
+ zIndex: 0,
75167
+ opacity: mainSource === targetSource ? 1 : 0,
75168
+ id: mainSource,
75169
+ sourceRect: void 0,
75170
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75171
+ },
75172
+ {
75173
+ sourceName: lowerThirdSource,
75174
+ zIndex: 1,
75175
+ opacity: lowerThirdSource === targetSource ? 1 : 0,
75176
+ id: lowerThirdSource,
75177
+ sourceRect: void 0,
75178
+ destRect: lowerThirdSource === targetSource ? { x: 0, y: 0, width: res.width, height: res.height } : { x: lowerThirdX, y: res.height, width: lowerThirdWidth, height: lowerThirdHeight }
75179
+ }
75180
+ ]
75063
75181
  }
75064
- ]
75065
- }
75182
+ },
75183
+ // Final step: target source only
75184
+ {
75185
+ durationMs: 0,
75186
+ layout: {
75187
+ layers: [{
75188
+ sourceName: targetSource,
75189
+ zIndex: 0,
75190
+ opacity: 1,
75191
+ id: targetSource,
75192
+ sourceRect: void 0,
75193
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75194
+ }]
75195
+ }
75196
+ }
75197
+ ];
75198
+ } else {
75199
+ return [
75200
+ {
75201
+ durationMs: 250,
75202
+ layout: {
75203
+ layers: [
75204
+ {
75205
+ sourceName: mainSource,
75206
+ zIndex: 0,
75207
+ opacity: 0,
75208
+ id: mainSource,
75209
+ sourceRect: void 0,
75210
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75211
+ },
75212
+ {
75213
+ sourceName: lowerThirdSource,
75214
+ zIndex: 1,
75215
+ opacity: 0,
75216
+ id: lowerThirdSource,
75217
+ sourceRect: void 0,
75218
+ destRect: { x: lowerThirdX, y: res.height, width: lowerThirdWidth, height: lowerThirdHeight }
75219
+ }
75220
+ ]
75221
+ }
75222
+ },
75223
+ ...targetSource ? [{
75224
+ durationMs: 250,
75225
+ layout: {
75226
+ layers: [{
75227
+ sourceName: targetSource,
75228
+ zIndex: 0,
75229
+ opacity: 1,
75230
+ id: targetSource,
75231
+ sourceRect: void 0,
75232
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75233
+ }]
75234
+ }
75235
+ }] : []
75236
+ ];
75066
75237
  }
75067
- ],
75238
+ })(),
75068
75239
  pip: [
75069
75240
  // Lower-third → PiP: move overlay from bottom to corner, resize
75070
75241
  {
@@ -75100,9 +75271,10 @@ var PRESETS = {
75100
75271
  } : void 0
75101
75272
  };
75102
75273
  },
75103
- "side-by-side": (sources, _config, res) => {
75274
+ "side-by-side": (sources, _config, res, transitionContext) => {
75104
75275
  const [source1, source2] = sources.slice(0, 2);
75105
75276
  const halfWidth = res.width / 2;
75277
+ const sideBySideSources = [source1, source2].filter(Boolean);
75106
75278
  return {
75107
75279
  name: "side-by-side",
75108
75280
  finalConfig: {
@@ -75205,32 +75377,91 @@ var PRESETS = {
75205
75377
  ]
75206
75378
  },
75207
75379
  to: {
75208
- fullscreen: [
75209
- // Reverse: slide second off and expand first
75210
- {
75211
- durationMs: 500,
75212
- layout: {
75213
- layers: [
75214
- {
75215
- sourceName: source1,
75216
- zIndex: 0,
75217
- opacity: 1,
75218
- id: source1,
75219
- sourceRect: void 0,
75220
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
75221
- },
75222
- {
75223
- sourceName: source2,
75224
- zIndex: 1,
75225
- opacity: 1,
75226
- id: source2,
75227
- sourceRect: void 0,
75228
- destRect: { x: res.width, y: 0, width: halfWidth, height: res.height }
75380
+ fullscreen: (() => {
75381
+ const targetSources = transitionContext?.targetSources ?? [];
75382
+ const targetSource = targetSources[0];
75383
+ const targetInSideBySide = targetSource && sideBySideSources.includes(targetSource);
75384
+ if (targetInSideBySide) {
75385
+ return [
75386
+ {
75387
+ durationMs: 500,
75388
+ layout: {
75389
+ layers: [
75390
+ {
75391
+ sourceName: source1,
75392
+ zIndex: 0,
75393
+ opacity: 1,
75394
+ id: source1,
75395
+ sourceRect: void 0,
75396
+ destRect: source1 === targetSource ? { x: 0, y: 0, width: res.width, height: res.height } : { x: -halfWidth, y: 0, width: halfWidth, height: res.height }
75397
+ },
75398
+ ...source2 ? [{
75399
+ sourceName: source2,
75400
+ zIndex: 1,
75401
+ opacity: 1,
75402
+ id: source2,
75403
+ sourceRect: void 0,
75404
+ destRect: source2 === targetSource ? { x: 0, y: 0, width: res.width, height: res.height } : { x: res.width, y: 0, width: halfWidth, height: res.height }
75405
+ }] : []
75406
+ ]
75229
75407
  }
75230
- ]
75231
- }
75408
+ },
75409
+ // Final step: target source only
75410
+ {
75411
+ durationMs: 0,
75412
+ layout: {
75413
+ layers: [{
75414
+ sourceName: targetSource,
75415
+ zIndex: 0,
75416
+ opacity: 1,
75417
+ id: targetSource,
75418
+ sourceRect: void 0,
75419
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75420
+ }]
75421
+ }
75422
+ }
75423
+ ];
75424
+ } else {
75425
+ return [
75426
+ {
75427
+ durationMs: 250,
75428
+ layout: {
75429
+ layers: [
75430
+ {
75431
+ sourceName: source1,
75432
+ zIndex: 0,
75433
+ opacity: 0,
75434
+ id: source1,
75435
+ sourceRect: void 0,
75436
+ destRect: { x: 0, y: 0, width: halfWidth, height: res.height }
75437
+ },
75438
+ ...source2 ? [{
75439
+ sourceName: source2,
75440
+ zIndex: 1,
75441
+ opacity: 0,
75442
+ id: source2,
75443
+ sourceRect: void 0,
75444
+ destRect: { x: halfWidth, y: 0, width: halfWidth, height: res.height }
75445
+ }] : []
75446
+ ]
75447
+ }
75448
+ },
75449
+ ...targetSource ? [{
75450
+ durationMs: 250,
75451
+ layout: {
75452
+ layers: [{
75453
+ sourceName: targetSource,
75454
+ zIndex: 0,
75455
+ opacity: 1,
75456
+ id: targetSource,
75457
+ sourceRect: void 0,
75458
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75459
+ }]
75460
+ }
75461
+ }] : []
75462
+ ];
75232
75463
  }
75233
- ],
75464
+ })(),
75234
75465
  pip: [
75235
75466
  // Side-by-side → PiP: left expands to fullscreen, right shrinks to corner
75236
75467
  {
@@ -75318,13 +75549,14 @@ var PRESETS = {
75318
75549
  } : void 0
75319
75550
  };
75320
75551
  },
75321
- "lbar": (sources, config, res) => {
75552
+ "lbar": (sources, config, res, transitionContext) => {
75322
75553
  const [videoSource, overlaySource] = sources;
75323
75554
  const { videoWidth, videoHeight, videoX = 50, videoY = 50 } = config;
75324
- return createLBarPresetDefinition([videoSource, overlaySource], { videoWidth, videoHeight, videoX, videoY }, res);
75555
+ return createLBarPresetDefinition([videoSource, overlaySource], { videoWidth, videoHeight, videoX, videoY }, res, transitionContext);
75325
75556
  },
75326
- "qr-lbar": (sources, config, res) => {
75557
+ "qr-lbar": (sources, config, res, transitionContext) => {
75327
75558
  const [videoSource, qrSource, overlaySource] = sources;
75559
+ const qrLbarSources = [videoSource, qrSource, overlaySource].filter(Boolean);
75328
75560
  const { qrDurationMs, qrCorner, qrWidth, qrHeight, qrPadding = 20, videoWidth, videoHeight, videoX = 0, videoY = 0 } = config;
75329
75561
  const qrPosition = (() => {
75330
75562
  switch (qrCorner) {
@@ -75444,45 +75676,112 @@ var PRESETS = {
75444
75676
  ]
75445
75677
  },
75446
75678
  to: {
75447
- fullscreen: [
75448
- // Reverse: expand video, hide overlay and QR
75449
- {
75450
- durationMs: 500,
75451
- layout: {
75452
- layers: [
75453
- {
75454
- sourceName: overlaySource,
75455
- id: "overlay",
75456
- zIndex: 0,
75457
- opacity: 0,
75458
- sourceRect: void 0,
75459
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
75460
- },
75461
- {
75462
- sourceName: videoSource,
75463
- id: "video",
75464
- zIndex: 1,
75465
- opacity: 1,
75466
- sourceRect: void 0,
75467
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
75468
- },
75469
- {
75470
- sourceName: qrSource,
75471
- id: "qr",
75472
- zIndex: 2,
75473
- opacity: 0,
75474
- sourceRect: void 0,
75475
- destRect: { x: qrPosition.x, y: qrPosition.y, width: qrWidth, height: qrHeight }
75679
+ fullscreen: (() => {
75680
+ const targetSources = transitionContext?.targetSources ?? [];
75681
+ const targetSource = targetSources[0];
75682
+ const targetInQrLbar = targetSource && qrLbarSources.includes(targetSource);
75683
+ if (targetInQrLbar) {
75684
+ return [
75685
+ {
75686
+ durationMs: 500,
75687
+ layout: {
75688
+ layers: [
75689
+ {
75690
+ sourceName: overlaySource,
75691
+ id: "overlay",
75692
+ zIndex: 0,
75693
+ opacity: overlaySource === targetSource ? 1 : 0,
75694
+ sourceRect: void 0,
75695
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75696
+ },
75697
+ {
75698
+ sourceName: videoSource,
75699
+ id: "video",
75700
+ zIndex: 1,
75701
+ opacity: videoSource === targetSource ? 1 : 0,
75702
+ sourceRect: void 0,
75703
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75704
+ },
75705
+ {
75706
+ sourceName: qrSource,
75707
+ id: "qr",
75708
+ zIndex: 2,
75709
+ opacity: qrSource === targetSource ? 1 : 0,
75710
+ sourceRect: void 0,
75711
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75712
+ }
75713
+ ]
75476
75714
  }
75477
- ]
75478
- }
75715
+ },
75716
+ // Final step: target source only
75717
+ {
75718
+ durationMs: 0,
75719
+ layout: {
75720
+ layers: [{
75721
+ sourceName: targetSource,
75722
+ zIndex: 0,
75723
+ opacity: 1,
75724
+ id: targetSource,
75725
+ sourceRect: void 0,
75726
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75727
+ }]
75728
+ }
75729
+ }
75730
+ ];
75731
+ } else {
75732
+ return [
75733
+ {
75734
+ durationMs: 250,
75735
+ layout: {
75736
+ layers: [
75737
+ {
75738
+ sourceName: overlaySource,
75739
+ id: "overlay",
75740
+ zIndex: 0,
75741
+ opacity: 0,
75742
+ sourceRect: void 0,
75743
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75744
+ },
75745
+ {
75746
+ sourceName: videoSource,
75747
+ id: "video",
75748
+ zIndex: 1,
75749
+ opacity: 0,
75750
+ sourceRect: void 0,
75751
+ destRect: { x: videoX, y: videoY, width: videoWidth, height: videoHeight }
75752
+ },
75753
+ {
75754
+ sourceName: qrSource,
75755
+ id: "qr",
75756
+ zIndex: 2,
75757
+ opacity: 0,
75758
+ sourceRect: void 0,
75759
+ destRect: { x: qrPosition.x, y: qrPosition.y, width: qrWidth, height: qrHeight }
75760
+ }
75761
+ ]
75762
+ }
75763
+ },
75764
+ ...targetSource ? [{
75765
+ durationMs: 250,
75766
+ layout: {
75767
+ layers: [{
75768
+ sourceName: targetSource,
75769
+ zIndex: 0,
75770
+ opacity: 1,
75771
+ id: targetSource,
75772
+ sourceRect: void 0,
75773
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75774
+ }]
75775
+ }
75776
+ }] : []
75777
+ ];
75479
75778
  }
75480
- ]
75779
+ })()
75481
75780
  }
75482
75781
  }
75483
75782
  };
75484
75783
  },
75485
- "3-split": (sources, _config, res) => {
75784
+ "3-split": (sources, _config, res, transitionContext) => {
75486
75785
  const third_w = res.width / 3;
75487
75786
  const splits = sources.slice(0, 3);
75488
75787
  return {
@@ -75582,21 +75881,76 @@ var PRESETS = {
75582
75881
  ]
75583
75882
  },
75584
75883
  to: {
75585
- fullscreen: [
75586
- {
75587
- durationMs: 500,
75588
- layout: {
75589
- layers: splits.map((s, i) => ({
75590
- sourceName: s,
75591
- zIndex: i,
75592
- opacity: i === 0 ? 1 : 0,
75593
- id: s,
75594
- sourceRect: void 0,
75595
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
75596
- }))
75597
- }
75884
+ fullscreen: (() => {
75885
+ const targetSources = transitionContext?.targetSources ?? [];
75886
+ const targetSource = targetSources[0];
75887
+ const targetInSplits = targetSource && splits.includes(targetSource);
75888
+ if (targetInSplits) {
75889
+ return [
75890
+ {
75891
+ durationMs: 500,
75892
+ layout: {
75893
+ layers: splits.map((s, i) => ({
75894
+ sourceName: s,
75895
+ zIndex: i,
75896
+ opacity: s === targetSource ? 1 : 0,
75897
+ id: s,
75898
+ sourceRect: void 0,
75899
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75900
+ }))
75901
+ }
75902
+ },
75903
+ // Final step: target source only
75904
+ {
75905
+ durationMs: 0,
75906
+ layout: {
75907
+ layers: [{
75908
+ sourceName: targetSource,
75909
+ zIndex: 0,
75910
+ opacity: 1,
75911
+ id: targetSource,
75912
+ sourceRect: void 0,
75913
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75914
+ }]
75915
+ }
75916
+ }
75917
+ ];
75918
+ } else {
75919
+ return [
75920
+ {
75921
+ durationMs: 250,
75922
+ layout: {
75923
+ layers: splits.map((s, i) => ({
75924
+ sourceName: s,
75925
+ zIndex: i,
75926
+ opacity: 0,
75927
+ id: s,
75928
+ sourceRect: void 0,
75929
+ destRect: {
75930
+ x: i * third_w,
75931
+ y: 0,
75932
+ width: third_w,
75933
+ height: res.height
75934
+ }
75935
+ }))
75936
+ }
75937
+ },
75938
+ ...targetSource ? [{
75939
+ durationMs: 250,
75940
+ layout: {
75941
+ layers: [{
75942
+ sourceName: targetSource,
75943
+ zIndex: 0,
75944
+ opacity: 1,
75945
+ id: targetSource,
75946
+ sourceRect: void 0,
75947
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
75948
+ }]
75949
+ }
75950
+ }] : []
75951
+ ];
75598
75952
  }
75599
- ],
75953
+ })(),
75600
75954
  "side-by-side": [
75601
75955
  // 3-split → Side-by-side: expand first 2 from 33.33% to 50%, fade out third
75602
75956
  {
@@ -75665,9 +76019,10 @@ var PRESETS = {
75665
76019
  } : void 0
75666
76020
  };
75667
76021
  },
75668
- "2-crop": (sources, config, res) => {
76022
+ "2-crop": (sources, config, res, transitionContext) => {
75669
76023
  const [left, right] = sources.slice(0, 2);
75670
76024
  const half_w = res.width / 2;
76025
+ const cropSources = [left, right].filter(Boolean);
75671
76026
  const crops = config.crops || {};
75672
76027
  return {
75673
76028
  name: "2-crop",
@@ -75743,31 +76098,91 @@ var PRESETS = {
75743
76098
  ]
75744
76099
  },
75745
76100
  to: {
75746
- fullscreen: [
75747
- {
75748
- durationMs: 500,
75749
- layout: {
75750
- layers: [
75751
- {
75752
- sourceName: left,
75753
- zIndex: 0,
75754
- opacity: 1,
75755
- id: left,
75756
- sourceRect: void 0,
75757
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
75758
- },
75759
- {
75760
- sourceName: right,
75761
- zIndex: 1,
75762
- opacity: 0,
75763
- id: right,
75764
- sourceRect: void 0,
75765
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76101
+ fullscreen: (() => {
76102
+ const targetSources = transitionContext?.targetSources ?? [];
76103
+ const targetSource = targetSources[0];
76104
+ const targetInCrops = targetSource && cropSources.includes(targetSource);
76105
+ if (targetInCrops) {
76106
+ return [
76107
+ {
76108
+ durationMs: 500,
76109
+ layout: {
76110
+ layers: [
76111
+ {
76112
+ sourceName: left,
76113
+ zIndex: 0,
76114
+ opacity: left === targetSource ? 1 : 0,
76115
+ id: left,
76116
+ sourceRect: void 0,
76117
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76118
+ },
76119
+ {
76120
+ sourceName: right,
76121
+ zIndex: 1,
76122
+ opacity: right === targetSource ? 1 : 0,
76123
+ id: right,
76124
+ sourceRect: void 0,
76125
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76126
+ }
76127
+ ]
75766
76128
  }
75767
- ]
75768
- }
76129
+ },
76130
+ // Final step: target source only
76131
+ {
76132
+ durationMs: 0,
76133
+ layout: {
76134
+ layers: [{
76135
+ sourceName: targetSource,
76136
+ zIndex: 0,
76137
+ opacity: 1,
76138
+ id: targetSource,
76139
+ sourceRect: void 0,
76140
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76141
+ }]
76142
+ }
76143
+ }
76144
+ ];
76145
+ } else {
76146
+ return [
76147
+ {
76148
+ durationMs: 250,
76149
+ layout: {
76150
+ layers: [
76151
+ {
76152
+ sourceName: left,
76153
+ zIndex: 0,
76154
+ opacity: 0,
76155
+ id: left,
76156
+ sourceRect: crops[left] || void 0,
76157
+ destRect: { x: 0, y: 0, width: half_w, height: res.height }
76158
+ },
76159
+ {
76160
+ sourceName: right,
76161
+ zIndex: 1,
76162
+ opacity: 0,
76163
+ id: right,
76164
+ sourceRect: crops[right] || void 0,
76165
+ destRect: { x: half_w, y: 0, width: half_w, height: res.height }
76166
+ }
76167
+ ]
76168
+ }
76169
+ },
76170
+ ...targetSource ? [{
76171
+ durationMs: 250,
76172
+ layout: {
76173
+ layers: [{
76174
+ sourceName: targetSource,
76175
+ zIndex: 0,
76176
+ opacity: 1,
76177
+ id: targetSource,
76178
+ sourceRect: void 0,
76179
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76180
+ }]
76181
+ }
76182
+ }] : []
76183
+ ];
75769
76184
  }
75770
- ],
76185
+ })(),
75771
76186
  "3-crop": [
75772
76187
  // 2-crop → 3-crop: compress both from 50% to 33.33% width, adjust crop
75773
76188
  {
@@ -75824,7 +76239,7 @@ var PRESETS = {
75824
76239
  } : void 0
75825
76240
  };
75826
76241
  },
75827
- "3-crop": (sources, config, res) => {
76242
+ "3-crop": (sources, config, res, transitionContext) => {
75828
76243
  const third_w = res.width / 3;
75829
76244
  const cropSources = sources.slice(0, 3);
75830
76245
  const cropConfig = config.crops || {};
@@ -75882,21 +76297,76 @@ var PRESETS = {
75882
76297
  ]
75883
76298
  },
75884
76299
  to: {
75885
- fullscreen: [
75886
- {
75887
- durationMs: 500,
75888
- layout: {
75889
- layers: cropSources.map((s, i) => ({
75890
- sourceName: s,
75891
- zIndex: i,
75892
- opacity: i === 0 ? 1 : 0,
75893
- id: s,
75894
- sourceRect: void 0,
75895
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
75896
- }))
75897
- }
76300
+ fullscreen: (() => {
76301
+ const targetSources = transitionContext?.targetSources ?? [];
76302
+ const targetSource = targetSources[0];
76303
+ const targetInCrops = targetSource && cropSources.includes(targetSource);
76304
+ if (targetInCrops) {
76305
+ return [
76306
+ {
76307
+ durationMs: 500,
76308
+ layout: {
76309
+ layers: cropSources.map((s, i) => ({
76310
+ sourceName: s,
76311
+ zIndex: i,
76312
+ opacity: s === targetSource ? 1 : 0,
76313
+ id: s,
76314
+ sourceRect: void 0,
76315
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76316
+ }))
76317
+ }
76318
+ },
76319
+ // Final step: target source only
76320
+ {
76321
+ durationMs: 0,
76322
+ layout: {
76323
+ layers: [{
76324
+ sourceName: targetSource,
76325
+ zIndex: 0,
76326
+ opacity: 1,
76327
+ id: targetSource,
76328
+ sourceRect: void 0,
76329
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76330
+ }]
76331
+ }
76332
+ }
76333
+ ];
76334
+ } else {
76335
+ return [
76336
+ {
76337
+ durationMs: 250,
76338
+ layout: {
76339
+ layers: cropSources.map((s, i) => ({
76340
+ sourceName: s,
76341
+ zIndex: i,
76342
+ opacity: 0,
76343
+ id: s,
76344
+ sourceRect: cropConfig[s] || void 0,
76345
+ destRect: {
76346
+ x: i * third_w,
76347
+ y: 0,
76348
+ width: third_w,
76349
+ height: res.height
76350
+ }
76351
+ }))
76352
+ }
76353
+ },
76354
+ ...targetSource ? [{
76355
+ durationMs: 250,
76356
+ layout: {
76357
+ layers: [{
76358
+ sourceName: targetSource,
76359
+ zIndex: 0,
76360
+ opacity: 1,
76361
+ id: targetSource,
76362
+ sourceRect: void 0,
76363
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76364
+ }]
76365
+ }
76366
+ }] : []
76367
+ ];
75898
76368
  }
75899
- ],
76369
+ })(),
75900
76370
  "2-crop": [
75901
76371
  // 3-crop → 2-crop: expand first 2 from 33.33% to 50%, adjust crop, fade out 3rd
75902
76372
  {
@@ -75930,8 +76400,9 @@ var PRESETS = {
75930
76400
  } : void 0
75931
76401
  };
75932
76402
  },
75933
- "2-crop-left": (sources, config, res) => {
76403
+ "2-crop-left": (sources, config, res, transitionContext) => {
75934
76404
  const [background, left, right] = sources.slice(0, 3);
76405
+ const cropLeftSources = [background, left, right].filter(Boolean);
75935
76406
  const cropConfig = config.crops || {};
75936
76407
  const leftW = res.width * 0.34;
75937
76408
  const rightW = res.width * 0.66666;
@@ -76036,39 +76507,107 @@ var PRESETS = {
76036
76507
  ]
76037
76508
  },
76038
76509
  to: {
76039
- fullscreen: [
76040
- {
76041
- durationMs: 500,
76042
- layout: {
76043
- layers: [
76044
- {
76045
- sourceName: background,
76046
- zIndex: 0,
76047
- opacity: 1,
76048
- id: background,
76049
- sourceRect: void 0,
76050
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76051
- },
76052
- {
76053
- sourceName: left,
76054
- zIndex: 1,
76055
- opacity: 0,
76056
- id: left,
76057
- sourceRect: void 0,
76058
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76059
- },
76060
- {
76061
- sourceName: right,
76062
- zIndex: 2,
76063
- opacity: 0,
76064
- id: right,
76065
- sourceRect: void 0,
76066
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76510
+ fullscreen: (() => {
76511
+ const targetSources = transitionContext?.targetSources ?? [];
76512
+ const targetSource = targetSources[0];
76513
+ const targetInCrops = targetSource && cropLeftSources.includes(targetSource);
76514
+ if (targetInCrops) {
76515
+ return [
76516
+ {
76517
+ durationMs: 500,
76518
+ layout: {
76519
+ layers: [
76520
+ {
76521
+ sourceName: background,
76522
+ zIndex: 0,
76523
+ opacity: background === targetSource ? 1 : 0,
76524
+ id: background,
76525
+ sourceRect: void 0,
76526
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76527
+ },
76528
+ {
76529
+ sourceName: left,
76530
+ zIndex: 1,
76531
+ opacity: left === targetSource ? 1 : 0,
76532
+ id: left,
76533
+ sourceRect: void 0,
76534
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76535
+ },
76536
+ {
76537
+ sourceName: right,
76538
+ zIndex: 2,
76539
+ opacity: right === targetSource ? 1 : 0,
76540
+ id: right,
76541
+ sourceRect: void 0,
76542
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76543
+ }
76544
+ ]
76067
76545
  }
76068
- ]
76069
- }
76546
+ },
76547
+ // Final step: target source only
76548
+ {
76549
+ durationMs: 0,
76550
+ layout: {
76551
+ layers: [{
76552
+ sourceName: targetSource,
76553
+ zIndex: 0,
76554
+ opacity: 1,
76555
+ id: targetSource,
76556
+ sourceRect: void 0,
76557
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76558
+ }]
76559
+ }
76560
+ }
76561
+ ];
76562
+ } else {
76563
+ return [
76564
+ {
76565
+ durationMs: 250,
76566
+ layout: {
76567
+ layers: [
76568
+ {
76569
+ sourceName: background,
76570
+ zIndex: 0,
76571
+ opacity: 0,
76572
+ id: background,
76573
+ sourceRect: void 0,
76574
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76575
+ },
76576
+ {
76577
+ sourceName: left,
76578
+ zIndex: 1,
76579
+ opacity: 0,
76580
+ id: left,
76581
+ sourceRect: cropConfig[left] || void 0,
76582
+ destRect: { x: 0, y: yPos, width: leftW, height: boxH }
76583
+ },
76584
+ {
76585
+ sourceName: right,
76586
+ zIndex: 2,
76587
+ opacity: 0,
76588
+ id: right,
76589
+ sourceRect: void 0,
76590
+ destRect: { x: rightX, y: yPos, width: rightW, height: boxH }
76591
+ }
76592
+ ]
76593
+ }
76594
+ },
76595
+ ...targetSource ? [{
76596
+ durationMs: 250,
76597
+ layout: {
76598
+ layers: [{
76599
+ sourceName: targetSource,
76600
+ zIndex: 0,
76601
+ opacity: 1,
76602
+ id: targetSource,
76603
+ sourceRect: void 0,
76604
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76605
+ }]
76606
+ }
76607
+ }] : []
76608
+ ];
76070
76609
  }
76071
- ],
76610
+ })(),
76072
76611
  "2-crop-right": [
76073
76612
  // 2-crop-left → 2-crop-right: swap positions and crop states
76074
76613
  {
@@ -76109,8 +76648,9 @@ var PRESETS = {
76109
76648
  } : void 0
76110
76649
  };
76111
76650
  },
76112
- "2-crop-right": (sources, config, res) => {
76651
+ "2-crop-right": (sources, config, res, transitionContext) => {
76113
76652
  const [background, left, right] = sources.slice(0, 3);
76653
+ const cropRightSources = [background, left, right].filter(Boolean);
76114
76654
  const cropConfig = config.crops || {};
76115
76655
  const leftW = res.width * 0.67;
76116
76656
  const rightW = res.width * 0.33333;
@@ -76215,39 +76755,107 @@ var PRESETS = {
76215
76755
  ]
76216
76756
  },
76217
76757
  to: {
76218
- fullscreen: [
76219
- {
76220
- durationMs: 500,
76221
- layout: {
76222
- layers: [
76223
- {
76224
- sourceName: background,
76225
- zIndex: 0,
76226
- opacity: 1,
76227
- id: background,
76228
- sourceRect: void 0,
76229
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76230
- },
76231
- {
76232
- sourceName: left,
76233
- zIndex: 1,
76234
- opacity: 0,
76235
- id: left,
76236
- sourceRect: void 0,
76237
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76238
- },
76239
- {
76240
- sourceName: right,
76241
- zIndex: 2,
76242
- opacity: 0,
76243
- id: right,
76244
- sourceRect: void 0,
76245
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76758
+ fullscreen: (() => {
76759
+ const targetSources = transitionContext?.targetSources ?? [];
76760
+ const targetSource = targetSources[0];
76761
+ const targetInCrops = targetSource && cropRightSources.includes(targetSource);
76762
+ if (targetInCrops) {
76763
+ return [
76764
+ {
76765
+ durationMs: 500,
76766
+ layout: {
76767
+ layers: [
76768
+ {
76769
+ sourceName: background,
76770
+ zIndex: 0,
76771
+ opacity: background === targetSource ? 1 : 0,
76772
+ id: background,
76773
+ sourceRect: void 0,
76774
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76775
+ },
76776
+ {
76777
+ sourceName: left,
76778
+ zIndex: 1,
76779
+ opacity: left === targetSource ? 1 : 0,
76780
+ id: left,
76781
+ sourceRect: void 0,
76782
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76783
+ },
76784
+ {
76785
+ sourceName: right,
76786
+ zIndex: 2,
76787
+ opacity: right === targetSource ? 1 : 0,
76788
+ id: right,
76789
+ sourceRect: void 0,
76790
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76791
+ }
76792
+ ]
76246
76793
  }
76247
- ]
76248
- }
76794
+ },
76795
+ // Final step: target source only
76796
+ {
76797
+ durationMs: 0,
76798
+ layout: {
76799
+ layers: [{
76800
+ sourceName: targetSource,
76801
+ zIndex: 0,
76802
+ opacity: 1,
76803
+ id: targetSource,
76804
+ sourceRect: void 0,
76805
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76806
+ }]
76807
+ }
76808
+ }
76809
+ ];
76810
+ } else {
76811
+ return [
76812
+ {
76813
+ durationMs: 250,
76814
+ layout: {
76815
+ layers: [
76816
+ {
76817
+ sourceName: background,
76818
+ zIndex: 0,
76819
+ opacity: 0,
76820
+ id: background,
76821
+ sourceRect: void 0,
76822
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76823
+ },
76824
+ {
76825
+ sourceName: left,
76826
+ zIndex: 1,
76827
+ opacity: 0,
76828
+ id: left,
76829
+ sourceRect: void 0,
76830
+ destRect: { x: 0, y: yPos, width: leftW, height: boxH }
76831
+ },
76832
+ {
76833
+ sourceName: right,
76834
+ zIndex: 2,
76835
+ opacity: 0,
76836
+ id: right,
76837
+ sourceRect: cropConfig[right] || void 0,
76838
+ destRect: { x: rightX, y: yPos, width: rightW, height: boxH }
76839
+ }
76840
+ ]
76841
+ }
76842
+ },
76843
+ ...targetSource ? [{
76844
+ durationMs: 250,
76845
+ layout: {
76846
+ layers: [{
76847
+ sourceName: targetSource,
76848
+ zIndex: 0,
76849
+ opacity: 1,
76850
+ id: targetSource,
76851
+ sourceRect: void 0,
76852
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
76853
+ }]
76854
+ }
76855
+ }] : []
76856
+ ];
76249
76857
  }
76250
- ],
76858
+ })(),
76251
76859
  "2-crop-left": [
76252
76860
  // 2-crop-right → 2-crop-left: swap positions and crop states
76253
76861
  {
@@ -76288,9 +76896,10 @@ var PRESETS = {
76288
76896
  } : void 0
76289
76897
  };
76290
76898
  },
76291
- "5-split": (sources, config, res) => {
76899
+ "5-split": (sources, config, res, transitionContext) => {
76292
76900
  const [background, ...vidSources] = sources.slice(0, 6);
76293
76901
  const fiveSources = vidSources.slice(0, 5);
76902
+ const allSplitSources = [background, ...fiveSources].filter(Boolean);
76294
76903
  const cropConfig = config.crops || {};
76295
76904
  const boxW = res.width * 0.34;
76296
76905
  const boxH = res.height * 0.5;
@@ -76382,36 +76991,101 @@ var PRESETS = {
76382
76991
  ]
76383
76992
  },
76384
76993
  to: {
76385
- fullscreen: [
76386
- {
76387
- durationMs: 500,
76388
- layout: {
76389
- layers: [
76390
- {
76391
- sourceName: background,
76392
- zIndex: 0,
76393
- opacity: 1,
76394
- id: background,
76395
- sourceRect: void 0,
76396
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76397
- },
76398
- ...fiveSources.map((s, i) => ({
76399
- sourceName: s,
76400
- zIndex: i + 1,
76401
- opacity: 0,
76402
- id: s,
76403
- sourceRect: void 0,
76404
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76405
- }))
76406
- ]
76407
- }
76994
+ fullscreen: (() => {
76995
+ const targetSources = transitionContext?.targetSources ?? [];
76996
+ const targetSource = targetSources[0];
76997
+ const targetInSplit = targetSource && allSplitSources.includes(targetSource);
76998
+ if (targetInSplit) {
76999
+ return [
77000
+ {
77001
+ durationMs: 500,
77002
+ layout: {
77003
+ layers: [
77004
+ {
77005
+ sourceName: background,
77006
+ zIndex: 0,
77007
+ opacity: background === targetSource ? 1 : 0,
77008
+ id: background,
77009
+ sourceRect: void 0,
77010
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77011
+ },
77012
+ ...fiveSources.map((s, i) => ({
77013
+ sourceName: s,
77014
+ zIndex: i + 1,
77015
+ opacity: s === targetSource ? 1 : 0,
77016
+ id: s,
77017
+ sourceRect: void 0,
77018
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77019
+ }))
77020
+ ]
77021
+ }
77022
+ },
77023
+ // Final step: target source only
77024
+ {
77025
+ durationMs: 0,
77026
+ layout: {
77027
+ layers: [{
77028
+ sourceName: targetSource,
77029
+ zIndex: 0,
77030
+ opacity: 1,
77031
+ id: targetSource,
77032
+ sourceRect: void 0,
77033
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77034
+ }]
77035
+ }
77036
+ }
77037
+ ];
77038
+ } else {
77039
+ return [
77040
+ {
77041
+ durationMs: 250,
77042
+ layout: {
77043
+ layers: [
77044
+ {
77045
+ sourceName: background,
77046
+ zIndex: 0,
77047
+ opacity: 0,
77048
+ id: background,
77049
+ sourceRect: void 0,
77050
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77051
+ },
77052
+ ...fiveSources.map((s, i) => {
77053
+ const isTopRow = i < 2;
77054
+ const xPos = isTopRow ? topPositions[i] : bottomPositions[i - 2];
77055
+ const yPosCalc = isTopRow ? topY : bottomY;
77056
+ return {
77057
+ sourceName: s,
77058
+ zIndex: i + 1,
77059
+ opacity: 0,
77060
+ id: s,
77061
+ sourceRect: cropConfig[s] || void 0,
77062
+ destRect: { x: xPos - boxW / 2, y: yPosCalc - boxH / 2, width: boxW, height: boxH }
77063
+ };
77064
+ })
77065
+ ]
77066
+ }
77067
+ },
77068
+ ...targetSource ? [{
77069
+ durationMs: 250,
77070
+ layout: {
77071
+ layers: [{
77072
+ sourceName: targetSource,
77073
+ zIndex: 0,
77074
+ opacity: 1,
77075
+ id: targetSource,
77076
+ sourceRect: void 0,
77077
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77078
+ }]
77079
+ }
77080
+ }] : []
77081
+ ];
76408
77082
  }
76409
- ]
77083
+ })()
76410
77084
  }
76411
77085
  } : void 0
76412
77086
  };
76413
77087
  },
76414
- "6-split": (sources, config, res) => {
77088
+ "6-split": (sources, config, res, transitionContext) => {
76415
77089
  const sixSources = sources.slice(0, 6);
76416
77090
  const cropConfig = config.crops || {};
76417
77091
  const boxW = res.width * 0.34;
@@ -76475,21 +77149,77 @@ var PRESETS = {
76475
77149
  ]
76476
77150
  },
76477
77151
  to: {
76478
- fullscreen: [
76479
- {
76480
- durationMs: 500,
76481
- layout: {
76482
- layers: sixSources.map((s, i) => ({
76483
- sourceName: s,
76484
- zIndex: i,
76485
- opacity: i === 0 ? 1 : 0,
76486
- id: s,
76487
- sourceRect: void 0,
76488
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76489
- }))
76490
- }
77152
+ fullscreen: (() => {
77153
+ const targetSources = transitionContext?.targetSources ?? [];
77154
+ const targetSource = targetSources[0];
77155
+ const targetInSplit = targetSource && sixSources.includes(targetSource);
77156
+ if (targetInSplit) {
77157
+ return [
77158
+ {
77159
+ durationMs: 500,
77160
+ layout: {
77161
+ layers: sixSources.map((s, i) => ({
77162
+ sourceName: s,
77163
+ zIndex: i,
77164
+ opacity: s === targetSource ? 1 : 0,
77165
+ id: s,
77166
+ sourceRect: void 0,
77167
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77168
+ }))
77169
+ }
77170
+ },
77171
+ // Final step: target source only
77172
+ {
77173
+ durationMs: 0,
77174
+ layout: {
77175
+ layers: [{
77176
+ sourceName: targetSource,
77177
+ zIndex: 0,
77178
+ opacity: 1,
77179
+ id: targetSource,
77180
+ sourceRect: void 0,
77181
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77182
+ }]
77183
+ }
77184
+ }
77185
+ ];
77186
+ } else {
77187
+ return [
77188
+ {
77189
+ durationMs: 250,
77190
+ layout: {
77191
+ layers: sixSources.map((s, i) => {
77192
+ const row = Math.floor(i / 3);
77193
+ const col = i % 3;
77194
+ const yPos = row === 0 ? topY : bottomY;
77195
+ const xPos = xPositions[col];
77196
+ return {
77197
+ sourceName: s,
77198
+ zIndex: i,
77199
+ opacity: 0,
77200
+ id: s,
77201
+ sourceRect: cropConfig[s] || void 0,
77202
+ destRect: { x: xPos - boxW / 2, y: yPos - boxH / 2, width: boxW, height: boxH }
77203
+ };
77204
+ })
77205
+ }
77206
+ },
77207
+ ...targetSource ? [{
77208
+ durationMs: 250,
77209
+ layout: {
77210
+ layers: [{
77211
+ sourceName: targetSource,
77212
+ zIndex: 0,
77213
+ opacity: 1,
77214
+ id: targetSource,
77215
+ sourceRect: void 0,
77216
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77217
+ }]
77218
+ }
77219
+ }] : []
77220
+ ];
76491
77221
  }
76492
- ],
77222
+ })(),
76493
77223
  "mosaic-9": [
76494
77224
  // 6-split → mosaic-9: move to grid positions, fade to no crop
76495
77225
  {
@@ -76524,8 +77254,9 @@ var PRESETS = {
76524
77254
  };
76525
77255
  }
76526
77256
  };
76527
- function createLBarPresetDefinition(sources, config, res) {
77257
+ function createLBarPresetDefinition(sources, config, res, transitionContext) {
76528
77258
  const [videoSource, overlaySource] = sources;
77259
+ const lbarSources = [videoSource, overlaySource].filter(Boolean);
76529
77260
  const { videoWidth, videoHeight, videoX = 0, videoY = 0 } = config;
76530
77261
  return {
76531
77262
  name: "lbar",
@@ -76605,32 +77336,91 @@ function createLBarPresetDefinition(sources, config, res) {
76605
77336
  },
76606
77337
  // Transition from L-bar to fullscreen (reverse)
76607
77338
  to: {
76608
- fullscreen: [
76609
- // Step 1: Expand video and hide overlay (500ms)
76610
- {
76611
- durationMs: 500,
76612
- layout: {
76613
- layers: [
76614
- {
76615
- sourceName: overlaySource,
76616
- id: "overlay",
76617
- zIndex: 0,
76618
- opacity: 0,
76619
- sourceRect: void 0,
76620
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
76621
- },
76622
- {
76623
- sourceName: videoSource,
76624
- id: "video",
76625
- zIndex: 1,
76626
- opacity: 1,
76627
- sourceRect: void 0,
76628
- destRect: { x: 0, y: 0, width: res.width, height: res.height }
77339
+ fullscreen: (() => {
77340
+ const targetSources = transitionContext?.targetSources ?? [];
77341
+ const targetSource = targetSources[0];
77342
+ const targetInLbar = targetSource && lbarSources.includes(targetSource);
77343
+ if (targetInLbar) {
77344
+ return [
77345
+ {
77346
+ durationMs: 500,
77347
+ layout: {
77348
+ layers: [
77349
+ {
77350
+ sourceName: overlaySource,
77351
+ id: "overlay",
77352
+ zIndex: 0,
77353
+ opacity: overlaySource === targetSource ? 1 : 0,
77354
+ sourceRect: void 0,
77355
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77356
+ },
77357
+ {
77358
+ sourceName: videoSource,
77359
+ id: "video",
77360
+ zIndex: 1,
77361
+ opacity: videoSource === targetSource ? 1 : 0,
77362
+ sourceRect: void 0,
77363
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77364
+ }
77365
+ ]
76629
77366
  }
76630
- ]
76631
- }
77367
+ },
77368
+ // Final step: target source only
77369
+ {
77370
+ durationMs: 0,
77371
+ layout: {
77372
+ layers: [{
77373
+ sourceName: targetSource,
77374
+ zIndex: 0,
77375
+ opacity: 1,
77376
+ id: targetSource,
77377
+ sourceRect: void 0,
77378
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77379
+ }]
77380
+ }
77381
+ }
77382
+ ];
77383
+ } else {
77384
+ return [
77385
+ {
77386
+ durationMs: 250,
77387
+ layout: {
77388
+ layers: [
77389
+ {
77390
+ sourceName: overlaySource,
77391
+ id: "overlay",
77392
+ zIndex: 0,
77393
+ opacity: 0,
77394
+ sourceRect: void 0,
77395
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77396
+ },
77397
+ {
77398
+ sourceName: videoSource,
77399
+ id: "video",
77400
+ zIndex: 1,
77401
+ opacity: 0,
77402
+ sourceRect: void 0,
77403
+ destRect: { x: videoX, y: videoY, width: videoWidth, height: videoHeight }
77404
+ }
77405
+ ]
77406
+ }
77407
+ },
77408
+ ...targetSource ? [{
77409
+ durationMs: 250,
77410
+ layout: {
77411
+ layers: [{
77412
+ sourceName: targetSource,
77413
+ zIndex: 0,
77414
+ opacity: 1,
77415
+ id: targetSource,
77416
+ sourceRect: void 0,
77417
+ destRect: { x: 0, y: 0, width: res.width, height: res.height }
77418
+ }]
77419
+ }
77420
+ }] : []
77421
+ ];
76632
77422
  }
76633
- ]
77423
+ })()
76634
77424
  }
76635
77425
  }
76636
77426
  };